我正在计划一个使用SDL的小型Vala游戏项目,我想知道如何将SDL正确地集成到GLib主循环中。 我最后一次使用Vala和SDL做了一些事情,我使用了标准的SDL事件循环,但老实说,它是一堆废话,它打破了整个不错的Vala或GLib信号系统。
我找到了Cogl的集成 ,我正在寻找与SDL相同的东西。
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.
最满意答案
GLib源由三个回调组成:
一个在轮询之前检查源是否就绪(并避免poll调用) 一个用于在轮询后检查源是否仍然准备就绪 一个派遣附加的回调您可以非常简单地检查和调度事件。
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); } }然后,您将使用Source.CONTINUE循环:
var source = new SDLSource (); source.add_callback ((event) => { // handle event here return Source.CONTINUE; }); source.attach (MainContext.@default ());这是非常基本的:您的源可以使用SDL.EventMask和SDL.peep过滤特定事件。 为单个源分派多个事件并附加相关文件描述符也更有效。
如果您使用某些异步代码,则可以直接从Source调度唤醒协程:
public async void next_event_async () { var source = new SDLSource (); source.attach (MainContext.@default ()); source.add_callback (handle_event_async.callback); yield; return source.event; }GLib sources are composed of three callbacks:
one to check if the source is ready before polling (and avoid a poll call) one to check if the source is still ready after polling one to dispatch the attached callbackYou 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 (handle_event_async.callback); yield; return source.event; }更多推荐
发布评论