| 1 | // What does this file solves? |
| 2 | // - Since Dear ImGui 1.00 we took pride that most of our examples applications had their entire |
| 3 | // main-loop inside the main() function. That's because: |
| 4 | // - It makes the examples easier to read, keeping the code sequential. |
| 5 | // - It permit the use of local variables, making it easier to try things and perform quick |
| 6 | // changes when someone needs to quickly test something (vs having to structure the example |
| 7 | // in order to pass data around). This is very important because people use those examples |
| 8 | // to craft easy-to-past repro when they want to discuss features or report issues. |
| 9 | // - It conveys at a glance that this is a no-BS framework, it won't take your main loop away from you. |
| 10 | // - It is generally nice and elegant. |
| 11 | // - However, comes Emscripten... it is a wonderful and magical tech but it requires a "main loop" function. |
| 12 | // - Only some of our examples would run on Emscripten. Typically the ones rendering with GL or WGPU ones. |
| 13 | // - I tried to refactor those examples but felt it was problematic that other examples didn't follow the |
| 14 | // same layout. Why would the SDL+GL example be structured one way and the SGL+DX11 be structured differently? |
| 15 | // Especially as we are trying hard to convey that using a Dear ImGui backend in an *existing application* |
| 16 | // should requires only a few dozens lines of code, and this should be consistent and symmetrical for all backends. |
| 17 | // - So the next logical step was to refactor all examples to follow that layout of using a "main loop" function. |
| 18 | // This worked, but it made us lose all the nice things we had... |
| 19 | |
| 20 | // Since only about 4 examples really need to run with Emscripten, here's our solution: |
| 21 | // - Use some weird macros and capturing lambda to turn a loop in main() into a function. |
| 22 | // - Hide all that crap in this file so it doesn't make our examples unusually ugly. |
| 23 | // As a stance and principle of Dear ImGui development we don't use C++ headers and we don't |
| 24 | // want to suggest to the newcomer that we would ever use C++ headers as this would affect |
| 25 | // the initial judgment of many of our target audience. |
| 26 | // - Technique is based on this idea: https://github.com/ocornut/imgui/pull/2492/ |
| 27 | // - The do { } while (0) is to allow our code calling continue in the main loop. |
| 28 | #ifdef __EMSCRIPTEN__ |
| 29 | #include <emscripten.h> |
| 30 | #include <functional> |
| 31 | static std::function<void()> MainLoopForEmscriptenP; |
| 32 | static void MainLoopForEmscripten() { MainLoopForEmscriptenP(); } |
| 33 | #define EMSCRIPTEN_MAINLOOP_BEGIN MainLoopForEmscriptenP = [&]() { do |
| 34 | #define EMSCRIPTEN_MAINLOOP_END while (0); }; emscripten_set_main_loop(MainLoopForEmscripten, 0, true) |
| 35 | #else |
| 36 | #define EMSCRIPTEN_MAINLOOP_BEGIN |
| 37 | #define EMSCRIPTEN_MAINLOOP_END |
| 38 | #endif |