emscripten_mainloop_stub.h 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738
  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. // Since only about 4 examples really need to run with Emscripten, here's our solution:
  20. // - Use some weird macros and capturing lambda to turn a loop in main() into a function.
  21. // - Hide all that crap in this file so it doesn't make our examples unusually ugly.
  22. // As a stance and principle of Dear ImGui development we don't use C++ headers and we don't
  23. // want to suggest to the newcomer that we would ever use C++ headers as this would affect
  24. // the initial judgment of many of our target audience.
  25. // - Technique is based on this idea: https://github.com/ocornut/imgui/pull/2492/
  26. // - The do { } while (0) is to allow our code calling continue in the main loop.
  27. #ifdef __EMSCRIPTEN__
  28. #include <emscripten.h>
  29. #include <functional>
  30. static std::function<void()> MainLoopForEmscriptenP;
  31. static void MainLoopForEmscripten() { MainLoopForEmscriptenP(); }
  32. #define EMSCRIPTEN_MAINLOOP_BEGIN MainLoopForEmscriptenP = [&]() { do
  33. #define EMSCRIPTEN_MAINLOOP_END while (0); }; emscripten_set_main_loop(MainLoopForEmscripten, 0, true)
  34. #else
  35. #define EMSCRIPTEN_MAINLOOP_BEGIN
  36. #define EMSCRIPTEN_MAINLOOP_END
  37. #endif