Skip to content

ReplayFrame

1. 概要

ReplayFrame は、フレーム数に基づくウィンドウで過去の値をバッファリングし、新しい購読者に再生する ConnectableObservable を返すオペレーターです。Replay の時間ベースのウィンドウに対して、こちらはフレームカウントベースのウィンドウを使用します。Unity などのフレームベースの環境で特に有用です。

内部実装としては MulticastReplayFrameSubject<T> を渡す専用オペレーターです。各オーバーロードは、対応するコンストラクターで作成した ReplayFrameSubject<T>Multicast に渡すことと同義です。

2. シグネチャ

フレームウィンドウを指定

csharp
public static ConnectableObservable<T> ReplayFrame<T>(
    this Observable<T> source,
    int window)

指定したフレーム数のウィンドウ内の値のみをバッファリングし、新しい購読者に再生します。これは source.Multicast(new ReplayFrameSubject<T>(window)) と同義です。

window + FrameProvider を指定

csharp
public static ConnectableObservable<T> ReplayFrame<T>(
    this Observable<T> source,
    int window,
    FrameProvider frameProvider)

フレームウィンドウとカスタム FrameProvider を指定します。これは source.Multicast(new ReplayFrameSubject<T>(window, frameProvider)) と同義です。

bufferSize + window を指定

csharp
public static ConnectableObservable<T> ReplayFrame<T>(
    this Observable<T> source,
    int bufferSize,
    int window)

バッファサイズとフレームウィンドウの両方で制限します。これは source.Multicast(new ReplayFrameSubject<T>(bufferSize, window)) と同義です。

bufferSize + window + FrameProvider を指定

csharp
public static ConnectableObservable<T> ReplayFrame<T>(
    this Observable<T> source,
    int bufferSize,
    int window,
    FrameProvider frameProvider)

バッファサイズ、フレームウィンドウ、およびカスタム FrameProvider のすべてを指定する完全なオーバーロードです。これは source.Multicast(new ReplayFrameSubject<T>(bufferSize, window, frameProvider)) と同義です。

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

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

Connect() 後にソースが値を発行し始めます。新しい購読者が追加されると、指定フレーム数以内のバッファされた値が再生されます。

4. サンプルコード

csharp
// 過去 60 フレーム分の値をリプレイ
var replayedFrame = observable.ReplayFrame(window: 60);
var connection = replayedFrame.Connect();

// 後から購読しても過去 60 フレーム分の値を受け取る
replayedFrame.Subscribe(x => Console.WriteLine($"値: {x}"));

// RefCount と組み合わせて自動管理
var autoReplayFrame = observable.ReplayFrame(window: 30).RefCount();
autoReplayFrame.Subscribe(x => Console.WriteLine($"値: {x}"));

5. 補足

ReplayFrameMulticast の代表的な ReplayFrameSubject<T> 指定を簡潔に書くための API です。通常は Multicast(new ReplayFrameSubject<T>(...)) を直接書くよりも、意図が伝わりやすい ReplayFrame(...) を使用してください。