目次 - API(機能別) - タイマ - SDL_AddTimer

# SDL_AddTimer

指定のミリ秒が経過した後に別スレッドのコールバック関数を呼ぶように設定する

## 構文

`SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void* param)`

## 引数

interval | callbackを呼ぶまでの時間(ミリ秒)
callback | 指定のintervalが経過した後に呼ばれる関数
param | callbackに渡されるポインタ

## 戻り値

成功のときタイマID, 失敗のとき0を戻す. SDL_GetError()を呼んで詳細を知ることができる.

## サンプルコード

``

    /* タイマを開始する; 下のコールバックは時間が経過すると実行される */

    Uint32 delay = (33 / 10) * 10;  /* 10ミリ秒単位で切り捨てる */
    SDL_TimerID my_timer_id = SDL_AddTimer(delay, my_callbackfunc, my_callback_param);

    ...

    Uint32 my_callbackfunc(Uint32 interval, void *param)
    {
        SDL_Event event;
        SDL_UserEvent userevent;

        /* この例では, コールバックでSDL_USEREVENTイベントをキューに入れている.
        このコールバック関数は一定の周期で再び呼ばれる */

        userevent.type = SDL_USEREVENT;
        userevent.code = 0;
        userevent.data1 = NULL;
        userevent.data2 = NULL;

        event.type = SDL_USEREVENT;
        event.user = userevent;

        SDL_PushEvent(&event);
        return(interval);
    }

userevent.data1に実行する関数のアドレス, userevent.data2にその引数を与え, イベントループでそれを扱うと, SDLのマルチスレッドの問題を避けられる.
``

    /* 上のコードと同じ */
    Uint32 my_callbackfunc(Uint32 interval, void *param)
    {
        SDL_Event event;
        SDL_UserEvent userevent;

        /* この例では, コールバックでSDL_USEREVENTイベントをキューに入れている.
        このコールバック関数は一定の周期で再び呼ばれる */

        userevent.type = SDL_USEREVENT;
        userevent.code = 0;
        userevent.data1 = &my_function;
        userevent.data2 = param;

        event.type = SDL_USEREVENT;
        event.user = userevent;

        SDL_PushEvent(&event);
        return(interval);
    }

    /* イベントループ */
    SDL_Event event;
    while (SDL_PollEvent (&event))
    {
        switch(event.type)
        {
            case SDL_USEREVENT: {
                /* タイマでこの関数を呼びたいところだが, マルチスレッドの問題のためできない */
                void (*p) (void*) = event.user.data1;
                p(event.user.data2);
                break;
            }
            /* ... */
        }
    }

## 詳細

この関数を使う場合, SDL_Init()にSDL_INIT_TIMERを渡している必要がある.

コールバック関数には, 第1引数に現在のタイマ間隔が, 第2引数にユーザがSDL_AddTimer()で設定したパラメータが渡される. コールバック関数は次のタイマ間隔を戻す必要がある. 0を戻すとタイマはキャンセルされる.

コールバック関数は別スレッドで実行される. メインスレッドでタイマコールバックを処理する方法が必要ならばサンプルコードを参照すること.

タイマはコールバックを実行するのにかかった時間を考慮している. 例えば, コールバックの実行に250ミリ秒かかり, 1000(ミリ秒)を戻すと, タイマは次の呼び出しまで750ミリ秒しか待たない.

間隔はOSスケジューリングで不正確になりうる. コールバック内で不正確さを補正する必要がある場合, SDL_GetTicks()またはSDL_GetPerformanceCounter()を使って現在の時刻に注目する必要がある.

## バージョン

SDL 2.0.0以降

## 関連項目(関数)

SDL_RemoveTimer

## SDL Wikiへのリンク

SDL_AddTimer - SDL Wiki