mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-06-21 18:53:38 +00:00
main: If SDL_MAIN_CALLBACK_RATE="waitevent", have at least one iteration run.
This way apps can at least draw an initial image to their windows before going into a deep, blocking wait for user interaction. Fixes #15027.
This commit is contained in:
@@ -2835,7 +2835,11 @@ extern "C" {
|
||||
* There are other strings that have special meaning. If set to "waitevent",
|
||||
* SDL_AppIterate will not be called until new event(s) have arrived (and been
|
||||
* processed by SDL_AppEvent). This can be useful for apps that are completely
|
||||
* idle except in response to input.
|
||||
* idle except in response to input. As of SDL 3.6.0, SDL will allow a single
|
||||
* call to SDL_AppIterate to proceed without an event immediately after this
|
||||
* hint is set to "waitevent", so apps can have a minimum of activity, perhaps
|
||||
* to render an initial image to a window before the user has otherwise
|
||||
* interacted with the app.
|
||||
*
|
||||
* On some platforms, or if you are using SDL_main instead of SDL_AppIterate,
|
||||
* this hint is ignored. When the hint can be used, it is allowed to be
|
||||
|
||||
@@ -58,6 +58,8 @@ static bool SDLCALL EmscriptenMainCallbackEventWatcher(void *userdata, SDL_Event
|
||||
|
||||
static void EmscriptenInternalMainloop(void)
|
||||
{
|
||||
const bool force_iterate = callback_rate_changed && iterate_after_waitevent;
|
||||
|
||||
// callback rate changed? Update emscripten's mainloop iteration speed.
|
||||
if (callback_rate_changed) {
|
||||
callback_rate_changed = false;
|
||||
@@ -70,7 +72,7 @@ static void EmscriptenInternalMainloop(void)
|
||||
|
||||
if (iterate_after_waitevent) {
|
||||
SDL_PumpEvents();
|
||||
if (!saw_new_event) {
|
||||
if (!saw_new_event && !force_iterate) {
|
||||
// do nothing yet. Note that we're still going to iterate here because we can't block,
|
||||
// but we can stop the app's iteration from progressing until there's an event.
|
||||
return;
|
||||
@@ -94,7 +96,9 @@ int SDL_EnterAppMainCallbacks(int argc, char *argv[], SDL_AppInit_func appinit,
|
||||
rc = SDL_APP_FAILURE;
|
||||
} else {
|
||||
SDL_AddHintCallback(SDL_HINT_MAIN_CALLBACK_RATE, MainCallbackRateHintChanged, NULL);
|
||||
callback_rate_changed = false;
|
||||
if (!iterate_after_waitevent) { // if we're doing waitevent, we need callback_rate_changed to stay true for the next iteration.
|
||||
callback_rate_changed = false;
|
||||
}
|
||||
emscripten_set_main_loop(EmscriptenInternalMainloop, 0, 0); // don't throw an exception since we do an orderly return.
|
||||
if (callback_rate_increment > 0.0) {
|
||||
emscripten_set_main_loop_timing(EM_TIMING_SETTIMEOUT, callback_rate_increment);
|
||||
|
||||
@@ -27,9 +27,11 @@
|
||||
|
||||
static Uint64 callback_rate_increment = 0;
|
||||
static bool iterate_after_waitevent = false;
|
||||
static bool callback_rate_changed = false;
|
||||
|
||||
static void SDLCALL MainCallbackRateHintChanged(void *userdata, const char *name, const char *oldValue, const char *newValue)
|
||||
{
|
||||
callback_rate_changed = true;
|
||||
iterate_after_waitevent = newValue && (SDL_strcmp(newValue, "waitevent") == 0);
|
||||
if (iterate_after_waitevent) {
|
||||
callback_rate_increment = 0;
|
||||
@@ -45,10 +47,22 @@ static void SDLCALL MainCallbackRateHintChanged(void *userdata, const char *name
|
||||
|
||||
static SDL_AppResult GenericIterateMainCallbacks(void)
|
||||
{
|
||||
if (iterate_after_waitevent) {
|
||||
bool should_wait = iterate_after_waitevent;
|
||||
|
||||
if (callback_rate_changed) {
|
||||
callback_rate_changed = false;
|
||||
if (iterate_after_waitevent) {
|
||||
// just go immediately for one iteration (it will do a PumpEvents),
|
||||
// and do a full blocking wait for more events next time.
|
||||
should_wait = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (should_wait) {
|
||||
SDL_WaitEvent(NULL);
|
||||
}
|
||||
return SDL_IterateMainCallbacks(!iterate_after_waitevent);
|
||||
|
||||
return SDL_IterateMainCallbacks(!should_wait);
|
||||
}
|
||||
|
||||
int SDL_EnterAppMainCallbacks(int argc, char *argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit)
|
||||
|
||||
Reference in New Issue
Block a user