Skip to content
This repository has been archived by the owner on Feb 17, 2022. It is now read-only.

Commit

Permalink
Emscripten: handle the return value from timer callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
Daft-Freak committed Jan 14, 2019
1 parent 2238804 commit 09b829b
Showing 1 changed file with 82 additions and 8 deletions.
90 changes: 82 additions & 8 deletions src/timer/SDL_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,36 @@ SDL_RemoveTimer(SDL_TimerID id)

#include <emscripten/emscripten.h>

typedef struct _SDL_TimerMap
{
int timerID;
int timeoutID;
struct _SDL_TimerMap *next;
} SDL_TimerMap;

typedef struct {
int nextID;
SDL_TimerMap *timermap;
} SDL_TimerData;

static SDL_TimerData SDL_timer_data;

static void
SDL_Emscripten_TimerHelper(SDL_TimerMap *entry, Uint32 interval, SDL_TimerCallback callback, void *param)
{
Uint32 new_timeout;

new_timeout = callback(interval, param);

if (new_timeout != 0) {
entry->timeoutID = EM_ASM_INT({
return Browser.safeSetTimeout(function() {
Runtime.dynCall('viiii', $0, [$1, $2, $3, $4]);
}, $2);
}, &SDL_Emscripten_TimerHelper, entry, interval, callback, param);
}
}

int
SDL_TimerInit(void)
{
Expand All @@ -385,25 +415,69 @@ SDL_TimerInit(void)
void
SDL_TimerQuit(void)
{
SDL_TimerData *data = &SDL_timer_data;
SDL_TimerMap *entry;

while (data->timermap) {
entry = data->timermap;
data->timermap = entry->next;
SDL_free(entry);
}
}

SDL_TimerID
SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
{
return EM_ASM_INT({
SDL_TimerData *data = &SDL_timer_data;
SDL_TimerMap *entry;

entry = (SDL_TimerMap *)SDL_malloc(sizeof(*entry));
if (!entry) {
SDL_OutOfMemory();
return 0;
}
entry->timerID = data->nextID++;

entry->timeoutID = EM_ASM_INT({
return Browser.safeSetTimeout(function() {
Runtime.dynCall('iii', $1, [$0, $2]);
}, $0);
}, interval, callback, param);
Runtime.dynCall('viiii', $0, [$1, $2, $3, $4]);
}, $2);
}, &SDL_Emscripten_TimerHelper, entry, interval, callback, param);

entry->next = data->timermap;
data->timermap = entry;

return entry->timerID;
}

SDL_bool
SDL_RemoveTimer(SDL_TimerID id)
{
EM_ASM_({
window.clearTimeout($0);
}, id);
return 1;
SDL_TimerData *data = &SDL_timer_data;
SDL_TimerMap *prev, *entry;

/* Find the timer */
prev = NULL;
for (entry = data->timermap; entry; prev = entry, entry = entry->next) {
if (entry->timerID == id) {
if (prev) {
prev->next = entry->next;
} else {
data->timermap = entry->next;
}
break;
}
}

if (entry) {
EM_ASM_({
window.clearTimeout($0);
}, entry->timeoutID);
SDL_free(entry);

return SDL_TRUE;
}
return SDL_FALSE;
}

#endif
Expand Down

0 comments on commit 09b829b

Please sign in to comment.