一度発火してから、一定時間以内に再発火しなかったら終了するストリーム
断続的に値が流れてくるストリームがあり、一定時間以内に値が来たら処理するが、一定時間以上値が流れて来なかったら終了する、という処理をしたいと思った。
例えばスコアを獲得する毎に値が流れてくるストリームがあるとして、これ自体は明確な終了がない。
しかし発火したタイミングで画面に表示を出したいが、表示するのは直近の1つだけにしたい。
更に表示から一定時間経過したら非表示にしたい。
というようなことをやる場合に、まぁ無理にストリームでやらなくても処理はできるのだが、スマートに書けないものか、と考えてみた。
で、こうなった。
例として、ボタン押下毎に発火するが、一定時間以上発火がなければ終了とするストリーム。
var tapStream = this.UpdateAsObservable().Where(_ => Input.GetMouseButtonDown(0)); tapStream .Select(_ => Time.frameCount) .TakeUntil(tapStream.Throttle(TimeSpan.FromSeconds(1))) .DoOnCompleted(() => Debug.Log("complete")) .RepeatUntilDestroy(this) .Subscribe(x => Debug.Log("frameCount: " + x)));
このThrottleさせたストリームを条件に使う、ってのがなかなかパッと思い浮かばなかったりするんだよなぁ。
Bufferの条件に使ったりとか、うまく使うと色々やりたいことをスマートに書けるので便利。
【追記】
上記の場合はUpdateAsObservableに対してRepeatするからいいけど、ソースがReactivePropertyだともうちょっとなんか考えないとダメっぽいな。