Skip to content

TimeoutFrame

1. 概要

TimeoutFrame は、Timeout のフレームベース版です。ソースシーケンスから前回の値(または購読開始)以降、指定したフレーム数以内に新しい値が届かなかった場合に TimeoutException でシーケンスを完了させます。

Unity などのゲームエンジン環境で、フレーム単位のタイムアウト監視を行いたい場合に使用します。

2. シグネチャ

フレーム数によるタイムアウト

csharp
public static Observable<T> TimeoutFrame<T>(
    this Observable<T> source,
    int frameCount)

前回の値(または購読開始)から frameCount フレーム以内に次の値が届かなかった場合、TimeoutException で完了します。

csharp
source.TimeoutFrame(60)

フレーム数 + FrameProvider によるタイムアウト

csharp
public static Observable<T> TimeoutFrame<T>(
    this Observable<T> source,
    int frameCount,
    FrameProvider frameProvider)

FrameProvider を指定してフレームカウントの実装を差し替えられます。

csharp
source.TimeoutFrame(60, fakeFrameProvider)

overload の使い分け

overload使う場面
int frameCountUnity などでデフォルトのフレームプロバイダーを使う場合
int frameCount, FrameProviderテスト時や独自のフレームプロバイダーを使いたい場合

3. マーブルダイアグラム

TimeoutFrame のマーブルダイアグラム

各値が発行されるたびにフレームカウンターがリセットされます。指定フレーム数以内に値が届かなかった場合、TimeoutException でシーケンスが完了します。

4. サンプルコード

csharp
using R3;

// Unity で 120 フレーム以内にプレイヤー入力がなければタイムアウト
playerInputObservable
    .TimeoutFrame(120)
    .Subscribe(
        input => ProcessInput(input),
        error =>
        {
            if (error is TimeoutException)
            {
                ShowIdleWarning();
            }
        });

// FakeFrameProvider を使ったテスト
var fakeFrames = new FakeFrameProvider();
Exception? caughtError = null;

var subject = new Subject<int>();
subject
    .TimeoutFrame(10, fakeFrames)
    .Subscribe(
        x => { },
        error => caughtError = error);

subject.OnNext(1);
fakeFrames.Advance(5);
subject.OnNext(2);  // カウンターリセット
fakeFrames.Advance(10);
// caughtError は TimeoutException

5. 補足

Timeout との違い

項目TimeoutTimeoutFrame
時間単位実時間(TimeSpanフレーム数(int
プロバイダーTimeProviderFrameProvider
主な用途一般的な .NET アプリケーションUnity などのゲームエンジン

動作の仕組みは Timeout と同一で、時間の計測単位がフレームに変わるだけです。