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

SDL_AddTimer doesn't work properly #67

Open
9chu opened this issue Dec 14, 2018 · 7 comments
Open

SDL_AddTimer doesn't work properly #67

9chu opened this issue Dec 14, 2018 · 7 comments

Comments

@9chu
Copy link

9chu commented Dec 14, 2018

SDL_TimerID
SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
{
    return EM_ASM_INT({
        return Browser.safeSetTimeout(function() {
            Runtime.dynCall('iii', $1, [$0, $2]);
        }, $0);
    }, interval, callback, param);
}

SetTimeout only emit the callback once, it should be setInterval.

@kripken
Copy link
Member

kripken commented Dec 17, 2018

I think that's what the SDL API says, though: that it will be called once?

https://wiki.libsdl.org/SDL_AddTimer

Or maybe I'm misreading that... For reference emscripten's SDL1 support also just calls it once, but maybe that's wrong too...

@9chu
Copy link
Author

9chu commented Dec 18, 2018

I think that's what the SDL API says, though: that it will be called once?

https://wiki.libsdl.org/SDL_AddTimer

Or maybe I'm misreading that... For reference emscripten's SDL1 support also just calls it once, but maybe that's wrong too...

To be honest, setInterval is still not correct.
Accroding to the SDL manual, the returned value of the timer's callback function indicates the next interval of the timer. If the returned value from the callback is 0, the timer is canceled.

So, I think the correct implementation may be:

// Cause I'm new to emscripten, I wrote it in pure js :)
mapping = {};
next_id = 0;

function SDL_AddTimer(interval, callback, param) {
    var id = next_id++;
    var internal_callback = function(interval) {
        var ret = callback(interval, param);
        if (ret == 0) {
            del mapping[id];
            return;
        }
        mapping[id] = setTimeout(function() { internal_callback(ret) }, ret); 
    };
    mapping[id] = setTimeout(function() { internal_callback(interval) }, interval);
    return id;
}

function SDL_RemoveTimer(id) {
    if (!(id in mapping))
        return false;
    
    clearTimeout(mapping[id]);
    del mapping[id];
    return true;
}

@Daft-Freak
Copy link
Member

09b829b should be it.

@Beuc
Copy link
Contributor

Beuc commented Jan 22, 2019

FYI 09b829b broke RenPyWeb.
Somehow SDL_AddTimer returned 0 while it didn't use to, causing an application error.

In addition there's no SDL_SetError, so I got an unrelated error which was quite confusing.

@Daft-Freak
Copy link
Member

Oops, looks like I need to init SDL_TimerData.nextID to 1...

@Daft-Freak
Copy link
Member

Or just move two characters... a8a4fde

@Beuc
Copy link
Contributor

Beuc commented Jan 22, 2019

This appears to work, thanks a lot!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants