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

# SDL_SetEventFilter

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

## 構文

`void SDL_SetEventFilter(SDL_EventFilter filter, void* userdata)`

## 引数

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

## サンプルコード

`

    #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は任意の関数名で, パラメータは次の通りである.

userdata | SDL_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