diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-20 18:51:03 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-20 18:51:03 +0200 |
commit | 5dfb890cf841579edaeb2633025db218e86f45c2 (patch) | |
tree | a6937d904579b8d7051cf033e03e99464d298c98 /src/app.c | |
parent | aa70507d43d17ca2c426acd6bf91548fe267ac19 (diff) |
App: Periodic commands without timers/threads
Now the periodic commands get posted on the main thread at intervals, and the event loop cooperates by not sleeping if there are periodic commands pending.
The macOS animation hangup seems to be unrelated, though — perhaps some internal SDL/Metal machinery related to app refresh stopping for a while?
Diffstat (limited to 'src/app.c')
-rw-r--r-- | src/app.c | 32 |
1 files changed, 26 insertions, 6 deletions
@@ -837,6 +837,9 @@ void trimCache_App(void) { | |||
837 | } | 837 | } |
838 | 838 | ||
839 | iLocalDef iBool isWaitingAllowed_App_(iApp *d) { | 839 | iLocalDef iBool isWaitingAllowed_App_(iApp *d) { |
840 | if (!isEmpty_Periodic(&d->periodic)) { | ||
841 | return iFalse; | ||
842 | } | ||
840 | if (d->warmupFrames > 0) { | 843 | if (d->warmupFrames > 0) { |
841 | return iFalse; | 844 | return iFalse; |
842 | } | 845 | } |
@@ -853,14 +856,26 @@ iLocalDef iBool isWaitingAllowed_App_(iApp *d) { | |||
853 | return !value_Atomic(&d->pendingRefresh) && isEmpty_SortedArray(&d->tickers); | 856 | return !value_Atomic(&d->pendingRefresh) && isEmpty_SortedArray(&d->tickers); |
854 | } | 857 | } |
855 | 858 | ||
859 | static iBool nextEvent_App_(iApp *d, enum iAppEventMode eventMode, SDL_Event *event) { | ||
860 | if (eventMode == waitForNewEvents_AppEventMode && isWaitingAllowed_App_(d)) { | ||
861 | /* If there are periodic commands pending, wait only for a short while. */ | ||
862 | if (!isEmpty_Periodic(&d->periodic)) { | ||
863 | return SDL_WaitEventTimeout(event, 500); | ||
864 | } | ||
865 | /* We may be allowed to block here until an event comes in. */ | ||
866 | if (isWaitingAllowed_App_(d)) { | ||
867 | return SDL_WaitEvent(event); | ||
868 | } | ||
869 | } | ||
870 | return SDL_PollEvent(event); | ||
871 | } | ||
872 | |||
856 | void processEvents_App(enum iAppEventMode eventMode) { | 873 | void processEvents_App(enum iAppEventMode eventMode) { |
857 | iApp *d = &app_; | 874 | iApp *d = &app_; |
858 | SDL_Event ev; | 875 | SDL_Event ev; |
859 | iBool gotEvents = iFalse; | 876 | iBool gotEvents = iFalse; |
860 | while ((isWaitingAllowed_App_(d) && eventMode == waitForNewEvents_AppEventMode && | 877 | postCommands_Periodic(&d->periodic); |
861 | SDL_WaitEvent(&ev)) || | 878 | while (nextEvent_App_(d, eventMode, &ev)) { |
862 | ((!isWaitingAllowed_App_(d) || eventMode == postedEventsOnly_AppEventMode) && | ||
863 | SDL_PollEvent(&ev))) { | ||
864 | #if defined (iPlatformAppleMobile) | 879 | #if defined (iPlatformAppleMobile) |
865 | if (processEvent_iOS(&ev)) { | 880 | if (processEvent_iOS(&ev)) { |
866 | continue; | 881 | continue; |
@@ -1064,13 +1079,18 @@ static int run_App_(iApp *d) { | |||
1064 | 1079 | ||
1065 | void refresh_App(void) { | 1080 | void refresh_App(void) { |
1066 | iApp *d = &app_; | 1081 | iApp *d = &app_; |
1082 | destroyPending_Widget(); | ||
1067 | #if defined (LAGRANGE_IDLE_SLEEP) | 1083 | #if defined (LAGRANGE_IDLE_SLEEP) |
1068 | if (d->warmupFrames == 0 && d->isIdling) { | 1084 | if (d->warmupFrames == 0 && d->isIdling) { |
1069 | return; | 1085 | return; |
1070 | } | 1086 | } |
1071 | #endif | 1087 | #endif |
1072 | set_Atomic(&d->pendingRefresh, iFalse); | 1088 | if (!exchange_Atomic(&d->pendingRefresh, iFalse)) { |
1073 | destroyPending_Widget(); | 1089 | /* Refreshing wasn't pending. */ |
1090 | if (isFinished_Anim(&d->window->rootOffset)) { | ||
1091 | return; | ||
1092 | } | ||
1093 | } | ||
1074 | // iTime draw; | 1094 | // iTime draw; |
1075 | // initCurrent_Time(&draw); | 1095 | // initCurrent_Time(&draw); |
1076 | draw_Window(d->window); | 1096 | draw_Window(d->window); |