2016-07-10 5 views
1

私はSDLを使った小さなValaゲームプロジェクトを計画しています.GLibメインループにSDLを正しく組み込む方法がわかります。私がValaとSDLで何かしたのは、標準的なSDLイベントループを使用しましたが、正直なところ、これはすごいヒントで、素晴らしいValaやGLibシグナルシステム全体を破壊します。SDLをGLibメインループに統合

私はan integration for Coglを見つけました。私はSDLだけで同じものを探しています。

+0

あなたが何をしようとしているのか不明です。描画をしたいだけなら、ウィンドウに再描画コールバックを追加すれば十分です(何かが起こったときに表示されたイメージを変更する必要があるときに再描画をトリガーする)。もっと普通のものには、タイマーとアイドル機能があります。 – keltar

答えて

3

GLibの源は、3つのコールバックで構成されています。ソースがポーリングする前に準備ができているかどうかを確認(およびpoll呼び出しを避ける)ために

  • つのソースは、ポーリング後にまだ準備ができているかどうかを確認する
  • あなたは、ソースのチェックとかなり単純にイベントをディスパッチを持つことができます添付コールバック

を派遣する

  • 1。これは非常に基本的なものです

    var source = new SDLSource(); 
    
    source.add_callback ((event) => { 
        // handle event here 
        return Source.CONTINUE; 
    }); 
    
    source.attach ([email protected]()); 
    

    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でループでしょう、あなたのソースはSDL.EventMaskSDL.peepで特定のイベントをフィルタリングすることができます。また、単一のソースに対して複数のイベントをディスパッチし、関連するファイル記述子をアタッチする方が効率的です。あなたには、いくつかの非同期コードを使用する場合は

    、あなたがSource派遣から直接コルーチンをウェイクアップすることができます

    public async void next_event_async() 
    { 
        var source = new SDLSource(); 
        source.attach ([email protected]()); 
        source.add_callback (handle_event_async.callback); 
        yield; 
        return source.event; 
    } 
    
  • 1

    悲しいことSDLはこれを非常に困難にします。理想的には、SDL APIは、イベントが利用可能なときにいつでも通知されてglibメインループに追加できるファイル記述子を提供しますが、これはありません。

    これは理想的ではありませんが、SDLイベントを定期的にチェックするためのタイマーをインストールするだけです。 g_timeout_addでメインループを起動し、コールバックでSDL_PollEventを呼び出すだけで、これを行うことができます。

    これは、そこに与えられたアプローチが実際に100%CPUを使用して終了するように、ビジー待機を効果的に引き起こすことに注意してください(準備関数はイベントが利用できない場合、タイムアウトをゼロに戻します)。

    クラッタは以前はGitの履歴で見ることができるSDL backendでした。基本的には、g_timeout_addを使用する代わりにカスタムソースを作成することを除いて、定期的な間隔でメインループを起動するこのアプローチを採用しています。

    SDL_GL_SwapWindowで継続的に再描画してプロセスを定期的にブロックするとしたら、ゲームを書くことを考えると、アイドルハンドラーをg_idle_addにインストールしてSDLのすべての処理コールバックでアイドルコールバックの開始時にイベントをチェックし、最後にSDL_GL_SwapWindowを呼び出すと、再描画が完了するのを待っているので、100%CPUを消費しません。

    関連する問題