summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2022-01-07 17:07:31 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2022-01-07 17:07:31 +0200
commitdbbeddecb55c7bd5ca5239f0c040886cde7e29d7 (patch)
treec0e0103322c6e97609695b1ed569bf664f6a0bdd
parent9d5a4c29efe45644d379eaaa020058beb4dd96f6 (diff)
App: Optimizing periodic events
IssueID #416
-rw-r--r--src/app.c12
-rw-r--r--src/app.h1
-rw-r--r--src/periodic.c25
-rw-r--r--src/periodic.h1
4 files changed, 31 insertions, 8 deletions
diff --git a/src/app.c b/src/app.c
index 1a24e86c..0a17a665 100644
--- a/src/app.c
+++ b/src/app.c
@@ -1237,9 +1237,6 @@ iBool findCachedContent_App(const iString *url, iString *mime_out, iBlock *data_
1237#endif 1237#endif
1238 1238
1239iLocalDef iBool isWaitingAllowed_App_(iApp *d) { 1239iLocalDef iBool isWaitingAllowed_App_(iApp *d) {
1240 if (!isEmpty_Periodic(&d->periodic)) {
1241 return iFalse;
1242 }
1243 if (d->warmupFrames > 0) { 1240 if (d->warmupFrames > 0) {
1244 return iFalse; 1241 return iFalse;
1245 } 1242 }
@@ -1253,10 +1250,6 @@ iLocalDef iBool isWaitingAllowed_App_(iApp *d) {
1253 1250
1254static iBool nextEvent_App_(iApp *d, enum iAppEventMode eventMode, SDL_Event *event) { 1251static iBool nextEvent_App_(iApp *d, enum iAppEventMode eventMode, SDL_Event *event) {
1255 if (eventMode == waitForNewEvents_AppEventMode && isWaitingAllowed_App_(d)) { 1252 if (eventMode == waitForNewEvents_AppEventMode && isWaitingAllowed_App_(d)) {
1256 /* If there are periodic commands pending, wait only for a short while. */
1257 if (!isEmpty_Periodic(&d->periodic)) {
1258 return SDL_WaitEventTimeout(event, 500);
1259 }
1260 /* We may be allowed to block here until an event comes in. */ 1253 /* We may be allowed to block here until an event comes in. */
1261 if (isWaitingAllowed_App_(d)) { 1254 if (isWaitingAllowed_App_(d)) {
1262 return SDL_WaitEvent(event); 1255 return SDL_WaitEvent(event);
@@ -1348,6 +1341,10 @@ void processEvents_App(enum iAppEventMode eventMode) {
1348 break; 1341 break;
1349 } 1342 }
1350 default: { 1343 default: {
1344 if (ev.type == SDL_USEREVENT && ev.user.code == periodic_UserEventCode) {
1345 dispatchCommands_Periodic(&d->periodic);
1346 continue;
1347 }
1351#if defined (LAGRANGE_ENABLE_IDLE_SLEEP) 1348#if defined (LAGRANGE_ENABLE_IDLE_SLEEP)
1352 if (ev.type == SDL_USEREVENT && ev.user.code == asleep_UserEventCode) { 1349 if (ev.type == SDL_USEREVENT && ev.user.code == asleep_UserEventCode) {
1353 if (SDL_GetTicks() - d->lastEventTime > idleThreshold_App_ && 1350 if (SDL_GetTicks() - d->lastEventTime > idleThreshold_App_ &&
@@ -1580,7 +1577,6 @@ static int run_App_(iApp *d) {
1580 SDL_AddEventWatch(resizeWatcher_, d); /* redraw window during resizing */ 1577 SDL_AddEventWatch(resizeWatcher_, d); /* redraw window during resizing */
1581#endif 1578#endif
1582 while (d->isRunning) { 1579 while (d->isRunning) {
1583 dispatchCommands_Periodic(&d->periodic);
1584 processEvents_App(waitForNewEvents_AppEventMode); 1580 processEvents_App(waitForNewEvents_AppEventMode);
1585 runTickers_App_(d); 1581 runTickers_App_(d);
1586 refresh_App(); 1582 refresh_App();
diff --git a/src/app.h b/src/app.h
index d15e1f21..5968de0d 100644
--- a/src/app.h
+++ b/src/app.h
@@ -61,6 +61,7 @@ enum iUserEventCode {
61 command_UserEventCode = 1, 61 command_UserEventCode = 1,
62 refresh_UserEventCode, 62 refresh_UserEventCode,
63 asleep_UserEventCode, 63 asleep_UserEventCode,
64 periodic_UserEventCode,
64 /* The start of a potential touch tap event is notified via a custom event because 65 /* The start of a potential touch tap event is notified via a custom event because
65 sending SDL_MOUSEBUTTONDOWN would be premature: we don't know how long the tap will 66 sending SDL_MOUSEBUTTONDOWN would be premature: we don't know how long the tap will
66 take, it could turn into a tap-and-hold for example. */ 67 take, it could turn into a tap-and-hold for example. */
diff --git a/src/periodic.c b/src/periodic.c
index c65c8b07..b4f51ed3 100644
--- a/src/periodic.c
+++ b/src/periodic.c
@@ -57,6 +57,25 @@ iDefineTypeConstructionArgs(PeriodicCommand, (iAny *ctx, const char *cmd), ctx,
57 57
58static const uint32_t postingInterval_Periodic_ = 500; 58static const uint32_t postingInterval_Periodic_ = 500;
59 59
60static uint32_t postEvent_Periodic_(uint32_t interval, void *context) {
61 iUnused(context);
62 SDL_UserEvent ev = { .type = SDL_USEREVENT,
63 .timestamp = SDL_GetTicks(),
64 .code = periodic_UserEventCode };
65 SDL_PushEvent((SDL_Event *) &ev);
66 return interval;
67}
68
69static void startOrStopWakeupTimer_Periodic_(iPeriodic *d, iBool start) {
70 if (start && !d->wakeupTimer) {
71 d->wakeupTimer = SDL_AddTimer(postingInterval_Periodic_, postEvent_Periodic_, d);
72 }
73 else if (!start && d->wakeupTimer) {
74 SDL_RemoveTimer(d->wakeupTimer);
75 d->wakeupTimer = 0;
76 }
77}
78
60static void removePending_Periodic_(iPeriodic *d) { 79static void removePending_Periodic_(iPeriodic *d) {
61 iForEach(PtrSet, i, &d->pendingRemoval) { 80 iForEach(PtrSet, i, &d->pendingRemoval) {
62 size_t pos; 81 size_t pos;
@@ -68,6 +87,9 @@ static void removePending_Periodic_(iPeriodic *d) {
68 } 87 }
69 } 88 }
70 clear_PtrSet(&d->pendingRemoval); 89 clear_PtrSet(&d->pendingRemoval);
90 if (isEmpty_SortedArray(&d->commands)) {
91 startOrStopWakeupTimer_Periodic_(d, iFalse);
92 }
71} 93}
72 94
73static iBool isDispatching_; 95static iBool isDispatching_;
@@ -109,9 +131,11 @@ void init_Periodic(iPeriodic *d) {
109 init_SortedArray(&d->commands, sizeof(iPeriodicCommand), cmp_PeriodicCommand_); 131 init_SortedArray(&d->commands, sizeof(iPeriodicCommand), cmp_PeriodicCommand_);
110 d->lastPostTime = 0; 132 d->lastPostTime = 0;
111 init_PtrSet(&d->pendingRemoval); 133 init_PtrSet(&d->pendingRemoval);
134 d->wakeupTimer = 0;
112} 135}
113 136
114void deinit_Periodic(iPeriodic *d) { 137void deinit_Periodic(iPeriodic *d) {
138 startOrStopWakeupTimer_Periodic_(d, iFalse);
115 deinit_PtrSet(&d->pendingRemoval); 139 deinit_PtrSet(&d->pendingRemoval);
116 iForEach(Array, i, &d->commands.values) { 140 iForEach(Array, i, &d->commands.values) {
117 deinit_PeriodicCommand(i.value); 141 deinit_PeriodicCommand(i.value);
@@ -134,6 +158,7 @@ void add_Periodic(iPeriodic *d, iAny *context, const char *command) {
134 init_PeriodicCommand(&pc, context, command); 158 init_PeriodicCommand(&pc, context, command);
135 insert_SortedArray(&d->commands, &pc); 159 insert_SortedArray(&d->commands, &pc);
136 } 160 }
161 startOrStopWakeupTimer_Periodic_(d, iTrue);
137 unlock_Mutex(d->mutex); 162 unlock_Mutex(d->mutex);
138} 163}
139 164
diff --git a/src/periodic.h b/src/periodic.h
index a56310a8..f65a4299 100644
--- a/src/periodic.h
+++ b/src/periodic.h
@@ -35,6 +35,7 @@ struct Impl_Periodic {
35 iSortedArray commands; 35 iSortedArray commands;
36 uint32_t lastPostTime; 36 uint32_t lastPostTime;
37 iPtrSet pendingRemoval; /* contexts */ 37 iPtrSet pendingRemoval; /* contexts */
38 int wakeupTimer; /* running while there are pending periodic commands */
38}; 39};
39 40
40void init_Periodic (iPeriodic *); 41void init_Periodic (iPeriodic *);