目次 - API(機能別) - イベント処理 - SDL_SetEventFilter

SDL_SetEventFilter

内部状態が変わり内部キューに入る前に全てのイベントを処理するフィルタを設定する

構文

void SDL_SetEventFilter(SDL_EventFilter filter, void* userdata)

引数

filterイベント発生時に呼ばれる関数 (詳細を参照すること)
userdatafilterへ渡されるポインタ

サンプルコード

#include "SDL.h"


// まず警告: これはバカげたやり方である. しかし, イベントフィルタが
// どのように働くかを示している. 実際の場合は, メインループで
// SDL_PollEventから得たイベントをただ処理すればよい. 一般的に, イベ
// ントフィルタを使おうと思ったときは, 立ち止まり, 原点に帰ってそれ
// がよい方法かよく考えるべきである.


// この関数をSDL_SetEventFilterに渡す. ユーザがキーボードのスペース
// バーを押したとき, `userdata`ポインタが示す値を切り替える. これは
// 青色をあらわしていて, 255と0の間の値である. メインプログラムはス
// ペースバーを押すたびにこの値の色でウィンドウをクリアする.
static int SDLCALL my_event_filter(void *userdata, SDL_Event * event)
{
    if ((event->type == SDL_KEYDOWN) && (event->key.keysym.sym == SDLK_SPACE)) {
        Uint8 *blue = (Uint8 *) userdata;
        if (*blue == 0) {
            *blue = 255;
        } else {
            *blue = 0;
        }
    }
    return 1;  // イベントをキューに追加する場合は1を戻す
}

int main(int argc, char **argv)
{
    Uint8 blue = 0;
    int quit = 0;

    // 単にウィンドウを生成して黒色でクリアする.
    // 実際の場合はエラーをチェックすること!
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window *window = SDL_CreateWindow("Hello SDL", SDL_WINDOWPOS_UNDEFINED,
                                          SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);
    SDL_RenderPresent(renderer);

    // イベントフィルタを設定する...
    SDL_SetEventFilter(my_event_filter, &blue);

    // イベントループを無限に実行する. 全てのイベントはここに到達する前に
    // my_event_filter関数を通過する. フレームごとにウィンドウを`blue`に設定さ
    // れた色で塗りつぶす. その値のアドレスはuserdataでフィルタ関数に渡され,
    // そこで変えられる.
    while (!quit) {
        SDL_Event e;
        while (SDL_PollEvent(&e)) {
            if (e.type == SDL_QUIT) {
                quit = 1;
            }
        }

        SDL_SetRenderDrawColor(renderer, 0, 0, blue, 255);
        SDL_RenderClear(renderer);
        SDL_RenderPresent(renderer);
    }

    SDL_Quit();
    return 0;
}

詳細

filterの関数プロトタイプは

int YourEventFilter(void* userdata, SDL_Event* event)

YourEventFilterは任意の関数名で, パラメータは次の通りである.

userdataSDL_SetEventFilter()で設定したuserdata
eventコールバックを引き起こしたイベント

filterが1を戻したとき, イベントは内部キューに追加される. 0を戻したとき, イベントはキューから削除されるが内部状態は更新される. これにより受信したイベントを動的にフィルタで選択できる.

注意: 別スレッドで使用する場合, イベントフィルタ関数で行うことには細心の注意を払うこと!

割り込み(例えばCTRL-C)で発生した終了イベントは, アプリケーションには次のイベントポーリングで届けられる.

SDL_QuitEventイベントを扱う場合, 注意すべきことがある. この場合, イベントフィルタはウィンドウマネージャがアプリケーションウィンドウを閉じようとしたときのみ呼ばれる. もしイベントフィルタが1を戻すとウィンドウは閉じる. それ以外を戻すと可能ならば開いたままにする.

メモ: 無効化されたイベントはイベントフィルタ関数には届かない. SDL_EventState()を参照すること.

メモ: フィルタするのではなく単にイベントを調査したいのであれば, 代わりにSDL_AddEventWatch()を使うべきである.

メモ: コールバックはユーザのSDL_PushEvent()で発生させたイベントでも呼ばれる. しかし, SDL_PeepEvents()で発生したイベントの場合は呼ばれない.

バージョン

SDL 2.0.0以降

関連項目(関数)

SDL_AddEventWatch
SDL_EventState
SDL_GetEventFilter
SDL_PeepEvents
SDL_PushEvent

SDL Wikiへのリンク

SDL_SetEventFilter - SDL Wiki