Skip to content

ThrottleFirstFrame

1. 概要

ThrottleFirstFrame は、ThrottleFirst のフレームベース版です。ソースシーケンスから最初に届いた値を即座に下流へ発行し、その後指定したフレーム数の間は新しい値を無視します。

Unity などのゲームエンジン環境で、フレーム単位のスロットリングを行いたい場合に使用します。

2. シグネチャ

フレーム数によるスロットリング

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

最初の値を即座に発行した後、frameCount フレームの間に届く値をすべて無視します。

csharp
source.ThrottleFirstFrame(10)

フレーム数 + FrameProvider によるスロットリング

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

FrameProvider を指定してフレームカウントの実装を差し替えられます。テスト時に FakeFrameProvider を使用してフレームを手動制御できます。

csharp
source.ThrottleFirstFrame(10, fakeFrameProvider)

overload の使い分け

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

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

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

最初の値が発行されるとフレームカウンターが開始し、指定フレーム数が経過するまでの間に届いた値はすべて無視されます。カウンターが満了すると、次に届く値が再び即座に発行されます。

4. サンプルコード

csharp
using R3;

// Unity でボタン連打防止(30 フレーム間隔)
buttonClickObservable
    .ThrottleFirstFrame(30)
    .Subscribe(_ => ExecuteAction());

// FakeFrameProvider を使ったテスト
var fakeFrames = new FakeFrameProvider();
var results = new List<int>();

Observable.Create<int>(observer =>
{
    observer.OnNext(1);
    observer.OnNext(2);
    observer.OnNext(3);
    return Disposable.Empty;
})
.ThrottleFirstFrame(5, fakeFrames)
.Subscribe(x => results.Add(x));

// results: [1] — 最初の値のみ即座に発行される

5. 補足

ThrottleFirst との違い

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

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