Skip to content

ChunkFrame

1. 概要

ChunkFrame はソース Observable の要素をフレーム単位でバッファリングし、配列 T[] として発行する演算子です。Chunk の時間ベース版がリアルタイム時間(TimeSpan)を使うのに対し、ChunkFrame はフレームカウントを使います。ゲームループや UI フレーム単位での処理に適しています。

空の配列は発行されません。

2. シグネチャ

フレーム単位 — ChunkFrame()

csharp
public static Observable<T[]> ChunkFrame<T>(this Observable<T> source)

毎フレーム(1 フレームごと)にバッファを区切り、蓄積された要素を配列として発行します。

csharp
source.ChunkFrame()

フレーム数指定 — ChunkFrame(frameCount)

csharp
public static Observable<T[]> ChunkFrame<T>(this Observable<T> source, Int32 frameCount)
public static Observable<T[]> ChunkFrame<T>(this Observable<T> source, Int32 frameCount, FrameProvider frameProvider)

frameCount フレームごとにバッファを区切ります。FrameProvider を指定するとフレームカウントの実装を差し替えられます(テスト時に便利)。

csharp
source.ChunkFrame(3)

フレーム数+個数上限 — ChunkFrame(frameCount, count)

csharp
public static Observable<T[]> ChunkFrame<T>(this Observable<T> source, Int32 frameCount, Int32 count)
public static Observable<T[]> ChunkFrame<T>(this Observable<T> source, Int32 frameCount, Int32 count, FrameProvider frameProvider)

フレーム数と個数の どちらか先に到達した条件 でバッファを発行します。Chunk(timeSpan, count) のフレーム版に相当します。

csharp
source.ChunkFrame(frameCount: 3, count: 10)

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

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

フレーム境界ごとにバッファが区切られ、その区間に到着した要素がまとめて配列として発行されます。

4. サンプルコード

毎フレームバッファリング

csharp
// 1 フレームに届いた入力イベントをまとめて処理
inputEventObservable
    .ChunkFrame()
    .Subscribe(events =>
    {
        foreach (var e in events)
        {
            ProcessInput(e);
        }
    });

フレーム数指定

csharp
// 3 フレームごとにまとめて処理
source
    .ChunkFrame(3)
    .Subscribe(batch =>
    {
        Console.WriteLine($"Batch ({batch.Length} items)");
    });

フレーム数+個数上限

csharp
// 5 フレームまたは 20 個のどちらか先に到達した時点で発行
source
    .ChunkFrame(frameCount: 5, count: 20)
    .Subscribe(batch =>
    {
        UpdateUI(batch);
    });

5. 補足

  • ChunkFrameChunk のフレームベース版です。Chunk(TimeSpan) がリアルタイム時間で区切るのに対し、ChunkFrame はフレーム数で区切ります。
  • 引数なしの ChunkFrame() は毎フレーム発行するため、Chunk(TimeSpan.Zero) に近い動作ですが、フレーム境界に正確に揃う点が異なります。
  • ゲームエンジン(Unity など)でフレーム同期が重要な場合は ChunkFrame を、実時間での制御が必要な場合は Chunk(TimeSpan) を使用してください。