simple renames, remove a bunch of emscripten code
This commit is contained in:
@ -1,37 +0,0 @@
|
||||
// What does this file solves?
|
||||
// - Since Dear ImGui 1.00 we took pride that most of our examples applications had their entire
|
||||
// main-loop inside the main() function. That's because:
|
||||
// - It makes the examples easier to read, keeping the code sequential.
|
||||
// - It permit the use of local variables, making it easier to try things and perform quick
|
||||
// changes when someone needs to quickly test something (vs having to structure the example
|
||||
// in order to pass data around). This is very important because people use those examples
|
||||
// to craft easy-to-past repro when they want to discuss features or report issues.
|
||||
// - It conveys at a glance that this is a no-BS framework, it won't take your main loop away from you.
|
||||
// - It is generally nice and elegant.
|
||||
// - However, comes Emscripten... it is a wonderful and magical tech but it requires a "main loop" function.
|
||||
// - Only some of our examples would run on Emscripten. Typically the ones rendering with GL or WGPU ones.
|
||||
// - I tried to refactor those examples but felt it was problematic that other examples didn't follow the
|
||||
// same layout. Why would the SDL+GL example be structured one way and the SGL+DX11 be structured differently?
|
||||
// Especially as we are trying hard to convey that using a Dear ImGui backend in an *existing application*
|
||||
// should requires only a few dozens lines of code, and this should be consistent and symmetrical for all backends.
|
||||
// - So the next logical step was to refactor all examples to follow that layout of using a "main loop" function.
|
||||
// This worked, but it made us lose all the nice things we had...
|
||||
|
||||
// Since only about 3 examples really need to run with Emscripten, here's our solution:
|
||||
// - Use some weird macros and capturing lambda to turn a loop in main() into a function.
|
||||
// - Hide all that crap in this file so it doesn't make our examples unusually ugly.
|
||||
// As a stance and principle of Dear ImGui development we don't use C++ headers and we don't
|
||||
// want to suggest to the newcomer that we would ever use C++ headers as this would affect
|
||||
// the initial judgment of many of our target audience.
|
||||
// - Technique is based on this idea: https://github.com/ocornut/imgui/pull/2492/
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#include <functional>
|
||||
static std::function<void()> MainLoopForEmscriptenP;
|
||||
static void MainLoopForEmscripten() { MainLoopForEmscriptenP(); }
|
||||
#define EMSCRIPTEN_MAINLOOP_BEGIN MainLoopForEmscriptenP = [&]()
|
||||
#define EMSCRIPTEN_MAINLOOP_END ; emscripten_set_main_loop(MainLoopForEmscripten, 0, true)
|
||||
#else
|
||||
#define EMSCRIPTEN_MAINLOOP_BEGIN
|
||||
#define EMSCRIPTEN_MAINLOOP_END
|
||||
#endif
|
@ -1,65 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
|
||||
<title>Image Flow Editor</title>
|
||||
<style>
|
||||
body { margin: 0; background-color: black }
|
||||
/* FIXME: with our GLFW example this block seems to break resizing and io.DisplaySize gets stuck */
|
||||
.emscripten {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
margin: 0px;
|
||||
border: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
image-rendering: optimizeSpeed;
|
||||
image-rendering: -moz-crisp-edges;
|
||||
image-rendering: -o-crisp-edges;
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
image-rendering: optimize-contrast;
|
||||
image-rendering: crisp-edges;
|
||||
image-rendering: pixelated;
|
||||
-ms-interpolation-mode: nearest-neighbor;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
|
||||
<script type='text/javascript'>
|
||||
var Module = {
|
||||
preRun: [],
|
||||
postRun: [],
|
||||
print: (function() {
|
||||
return function(text) {
|
||||
text = Array.prototype.slice.call(arguments).join(' ');
|
||||
console.log(text);
|
||||
};
|
||||
})(),
|
||||
printErr: function(text) {
|
||||
text = Array.prototype.slice.call(arguments).join(' ');
|
||||
console.error(text);
|
||||
},
|
||||
canvas: (function() {
|
||||
var canvas = document.getElementById('canvas');
|
||||
//canvas.addEventListener("webglcontextlost", function(e) { alert('FIXME: WebGL context lost, please reload the page'); e.preventDefault(); }, false);
|
||||
return canvas;
|
||||
})(),
|
||||
setStatus: function(text) {
|
||||
console.log("status: " + text);
|
||||
},
|
||||
monitorRunDependencies: function(left) {
|
||||
// no run dependencies to log
|
||||
}
|
||||
};
|
||||
window.onerror = function() {
|
||||
console.log("onerror: " + event);
|
||||
};
|
||||
</script>
|
||||
{{{ SCRIPT }}}
|
||||
</body>
|
||||
</html>
|
@ -1,97 +0,0 @@
|
||||
#ifndef EMSCRIPTEN_UPLOAD_FILE_H_INCLUDED
|
||||
#define EMSCRIPTEN_UPLOAD_FILE_H_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <emscripten.h>
|
||||
|
||||
#define _EM_JS_INLINE(ret, c_name, js_name, params, code) \
|
||||
extern "C" { \
|
||||
ret c_name params EM_IMPORT(js_name); \
|
||||
EMSCRIPTEN_KEEPALIVE \
|
||||
__attribute__((section("em_js"), aligned(1))) inline char __em_js__##js_name[] = \
|
||||
#params "<::>" code; \
|
||||
}
|
||||
|
||||
#define EM_JS_INLINE(ret, name, params, ...) _EM_JS_INLINE(ret, name, name, params, #__VA_ARGS__)
|
||||
|
||||
namespace emscripten_browser_file {
|
||||
|
||||
/////////////////////////////////// Interface //////////////////////////////////
|
||||
|
||||
using upload_handler = void(*)(std::string const&, std::string const&, std::string_view buffer, void*);
|
||||
|
||||
inline void upload(std::string const &accept_types, upload_handler callback, void *callback_data = nullptr);
|
||||
inline void download(std::string const &filename, std::string const &mime_type, std::string_view buffer);
|
||||
|
||||
///////////////////////////////// Implementation ///////////////////////////////
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmissing-variable-declarations"
|
||||
EM_JS_INLINE(void, upload, (char const *accept_types, upload_handler callback, void *callback_data), {
|
||||
/// Prompt the browser to open the file selector dialogue, and pass the file to the given handler
|
||||
/// Accept-types are in the format ".png,.jpeg,.jpg" as per https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept
|
||||
/// Upload handler callback signature is:
|
||||
/// void my_handler(std::string const &filename, std::string const &mime_type, std::string_view buffer, void *callback_data = nullptr);
|
||||
globalThis["open_file"] = function(e) {
|
||||
const file_reader = new FileReader();
|
||||
file_reader.onload = (event) => {
|
||||
const uint8Arr = new Uint8Array(event.target.result);
|
||||
const data_ptr = Module["_malloc"](uint8Arr.length);
|
||||
const data_on_heap = new Uint8Array(Module["HEAPU8"].buffer, data_ptr, uint8Arr.length);
|
||||
data_on_heap.set(uint8Arr);
|
||||
Module["ccall"]('upload_file_return', 'number', ['string', 'string', 'number', 'number', 'number', 'number'], [event.target.filename, event.target.mime_type, data_on_heap.byteOffset, uint8Arr.length, callback, callback_data]);
|
||||
Module["_free"](data_ptr);
|
||||
};
|
||||
file_reader.filename = e.target.files[0].name;
|
||||
file_reader.mime_type = e.target.files[0].type;
|
||||
file_reader.readAsArrayBuffer(e.target.files[0]);
|
||||
};
|
||||
|
||||
var file_selector = document.createElement('input');
|
||||
file_selector.setAttribute('type', 'file');
|
||||
file_selector.setAttribute('onchange', 'globalThis["open_file"](event)');
|
||||
file_selector.setAttribute('accept', UTF8ToString(accept_types));
|
||||
file_selector.click();
|
||||
});
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
inline void upload(std::string const &accept_types, upload_handler callback, void *callback_data) {
|
||||
/// C++ wrapper for javascript upload call
|
||||
upload(accept_types.c_str(), callback, callback_data);
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmissing-variable-declarations"
|
||||
EM_JS_INLINE(void, download, (char const *filename, char const *mime_type, void const *buffer, size_t buffer_size), {
|
||||
/// Offer a buffer in memory as a file to download, specifying download filename and mime type
|
||||
var a = document.createElement('a');
|
||||
a.download = UTF8ToString(filename);
|
||||
a.href = URL.createObjectURL(new Blob([new Uint8Array(Module["HEAPU8"].buffer, buffer, buffer_size)], {type: UTF8ToString(mime_type)}));
|
||||
a.click();
|
||||
});
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
inline void download(std::string const &filename, std::string const &mime_type, std::string_view buffer) {
|
||||
/// C++ wrapper for javascript download call, accepting a string_view
|
||||
download(filename.c_str(), mime_type.c_str(), buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
extern "C" {
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE inline int upload_file_return(char const *filename, char const *mime_type, char *buffer, size_t buffer_size, upload_handler callback, void *callback_data);
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE inline int upload_file_return(char const *filename, char const *mime_type, char *buffer, size_t buffer_size, upload_handler callback, void *callback_data) {
|
||||
/// Load a file - this function is called from javascript when the file upload is activated
|
||||
callback(filename, mime_type, {buffer, buffer_size}, callback_data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // EMSCRIPTEN_UPLOAD_FILE_H_INCLUDED
|
Reference in New Issue
Block a user