sdlglibvala

Integrate SDL into GLib mainloop


I'm planning a small Vala game project with SDL and I wonder how to integrate SDL properly into the GLib mainloop. The last time I did something with Vala and SDL I used the standard SDL event loop, but honestly, it's a heap of crap and it breaks the whole nice Vala or rather GLib signal system.

I found an integration for Cogl and I'm looking for the same thing just with SDL.


Solution

  • GLib sources are composed of three callbacks:

    You could have a source checking and dispatching events fairly simply.

    public delegate bool SDLSourceFunc (SDL.Event event);
    
    public class SDLSource : Source 
    {
        public SDL.Event event;
    
        public bool prepare (out uint timeout) 
        {
            timeout = 0;
            return true;
        }
    
        public bool check ()
        {
            return SDL.Event.poll (out event) > 0;
        }
    
        public bool dispatch (SourceFunc callback) 
        {
            return ((SDLSourceFunc) callback) (event);
        }
    
        public void add_callback (SDLSourceFunc callback)
        {
            base.add_callback ((SourceFunc) callback);
        }
    }
    

    Then, you would loop with Source.CONTINUE:

    var source = new SDLSource ();
    
    source.add_callback ((event) => {
        // handle event here
        return Source.CONTINUE;
    });
    
    source.attach (MainContext.@default ());
    

    This is very basic: your source could filter specific events with a SDL.EventMask and SDL.peep. It's also more efficient to dispatch multiple events for a single source and attach related file descriptors.

    If you use some async code, you can wakeup the coroutine directly from a Source dispatch:

    public async void next_event_async () 
    {
        var source = new SDLSource ();
        source.attach (MainContext.@default ());
        source.add_callback (next_event_async.callback);
        yield;
        return source.event;
    }