Can I run a job in each event loop iteration?

I’m trying to use SDL2 library with JUCE. Though it is working, I’m still wondering if I could run a custom job synchronized with JUCE’s event dispatching. This job would contain SDL’s event iteration.

Currently I use a JUCE timer to trigger the SDL event iteration at 60 Hz. I thought it may induce more latency than synchronously triggering.

This is the fake code of current implementation:

void sdl_mainloop_step()
{
    SDL_Event e;
    while ( SDL_PollEvent( &e ) )
    {
        switch ( e.type )
        {
        case SDL_QUIT:
            exit( 0 );
        case SDL_MOUSEMOTION:
        {
            auto win = SDL_GetWindowFromID( e.motion.windowID );
            // dispatch SDL event by SDL window
            break;
        }
        }
    }
}

// a global singleton that starts SDL trigger timer
// the SDL iteration is queued in JUCE message loop at 60Hz
struct SdlEventIterator : public juce::Timer
{
    static SdlEventIterator& getInstance()
    {
        static SdlEventIterator instance;
        return instance;
    }

private:
    SdlEventIterator()
    {
        startTimerHz( 60 );
    }

    void timerCallback() override
    {
        juce::MessageManager::callAsync( [](){ sdl_mainloop_step(); } );
    }
};

What I’m seeking for is something like:

juce::EventManager::registerExtraJobInEventLoop( [](){ sdl_mainloop_step(); } );
1 Like

Would it work to put the sdl event poll on a separate Thread, sync’ed to JUCE GUI Thread using standard primitives?

According to its document, all event-related SDL functions should be called in the thread that called SDL_init, which is preferably the JUCE message thread.

I’m not familiar with SDL, but if I correctly understood your request, one step in that direction would be to ditch the timer entirely and call:

juce::MessageManager::callAsync( [](){ sdl_mainloop_step(); } );

right at the end of your sdl_mainloop_step function.

That way, you instruct the message loop to call your function again very soon. That might not be exactly in the very next event loop, but certainly it doesn’t have to wait for the timer interval to elapse.

3 Likes

I’m also not familiar with SDL, but I was following this discussion because I also use a Timer to execute a sort of event loop situation, so I tried your suggestion - having the function call itself again.

My CPU use went up to 100% immediately. Maybe it depends on what the loop is doing, I guess… but some diagnostics I have showed me that this was now getting called nearly every 1 ms… unless I’m misunderstanding something.

1 Like