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

SDL_SetEventFilter

内部イベントキューに追加する前に全てのイベントを処理するフィルタを設定する

ヘッダ

SDL3/SDL_events.h

構文

void SDL_SetEventFilter(SDL_EventFilter filter, void *userdata);

引数

SDL_EventFilterfilterイベント発生時に呼ばれる関数
void *userdatafilterへ渡されるポインタ

詳細

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

注意: 別スレッドで実行されている可能性があるため, イベントフィルタで行うことには細心の注意を払うこと. SDL_EVENT_WINDOW_EXPOSEDを扱う場合は例外で, OSがメインスレッドに送ることを保証しているため, このイベントでウィンドウの再描画を行うことができる.

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

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

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

スレッドセーフ

この関数はスレッドセーフである.

バージョン

SDL 3.2.0以降

サンプルコード

#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>

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


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

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

    // 単にウィンドウを生成して黒色でクリアする.
    // 実際の場合はエラーをチェックすること!
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window *window = SDL_CreateWindow("Hello SDL", 640, 480, 0);
    SDL_Renderer *renderer = SDL_CreateRenderer(window, NULL);
    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_EVENT_QUIT) {
                quit = 1;
            }
        }

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

    SDL_Quit();
    return 0;
}

関連項目

SDL Wikiへのリンク

SDL_SetEventFilter - SDL Wiki