UniRxのシンプルなサンプルの取扱説明書
前(購読の停止)
後(ObservableWWW.Get ダウンロード)
完了の通知(OnCompleted)
今回は機能というか概念の紹介
RxにはOnCompletedというもう値がプッシュされないことを示す機能があります。
例えばFirst()メソッドなんかはその典型で1回でも値が流れたらそれでもう値はプッシュされません。
こんな風にもう値がプッシュされない状態になったらそのことを通知することにしています。(OnCompletedと言います)
なんでこんなものがあるのかというと、この通知を利用するメソッドがあるからとかなわけですが、そのへんの話はおいておいて今回はOnCompletedの動作をTakeを使ってみていきます。
前準備
いつものようにOnCompletedというGameObjectにOnCompletedSampleというスクリプトを貼り付けています。
100Frame後に色が変わる
今回は100Frameの間は右に移動し続けて、最後に色が青に変わって停止するGameObjectを作ります。
コードはこちら
using UnityEngine;
using System.Collections;
using UniRx;
using UniRx.Triggers;
public class OnCompletedSample : Base
{
// Use this for initialization
void Start () {
gameObject.transform.position = new Vector2(0, 1f);
//100Frameだけ右に行くそれが終わったらもうプッシュされる値がないのでOnCompleteに行って青くなる
this.UpdateAsObservable()
.Take(100).Subscribe(
_ => { Move(0.01f, 0); }, //プッシュされた時は右へ移動
//全て終わったら色を青に
() => { GetComponent<SpriteRenderer>().color = Color.blue; });
}
}
Take(100)で最初の100回だけ右に移動させているのはUniRxのシンプルなサンプル その3(FirstとTake)と変わりません。
変わっているのはSubscribeに第二引数が追加されています。実はSubscribeにはいくつかのオーバーロードがあります。その内の一つの以下のオーバーロードを使っています。
Subscribe(Action onNext, Action onCompleted)
onNextは今までのやって欲しい処理と言っていた部分なので問題ないのです。
今回の主役は第二引数のonCompletedの方です。
これはもう値が来ないよという完了通知が来たら実行されます。
(内部的な話をするとこのonCompletedの呼び出しこそが完了通知そのものです。)
Take(100)は100回値がプッシュされたらもう値をプッシュすることがないので完了通知(OnCompleted)を発行します。
その完了通知をうけて今回はSpriteRendererの色を青にしています。
(ちなみに色を100Frame後に青くしたいだけならObservable.Timerおすすめです。)
実行結果
というわけで100Frame後に青くなるGameObjectの完成です。
完了通知の来ないメソッド
完了通知の来ないメソッドもあります。
例えばthis.UpdateAsObservable()はその典型です。
何故ならば、アップデートはGameObjectが生きている間起こるので原理的に終わりはありません。
Skipもそうです。あるタイミングから素通しするようになるのでその後の終わりはありません。
ただし、こいつらの前後に完了通知の来るようなメソッドを挟んでやるとOnCompletedを発行できるようになります。
今回のTakeはまさにそれで100回の後は何が何でもプッシュしないのでこれは終わりを通知できます。
前回のTakeUntilDestroyも同様にOnCompletedの発行をもって削除します。
その他OnCompletedの話
Firstは一度もonNextが呼ばれずにonCompleteが発行されると例外を起こします。
FirstOrDefaultは同様の場合一度だけデフォルト値をプッシュしてonCompletedを発行します。
この辺りはIEnumerableと同様の動きをします。
SingleなんかもそうでSingleはonCompletedが発行されるまで値をキャッシュします。
もう一度onNextが発行された場合、それは例外になりプッシュしてはいけないためです。
しかし使い道とかあるんだろうか…?