この記事ではUniRxで、Observable.Timer()
などのように元から用意されているファクトリメソッドを使わず、
自分自身で処理を定義してObservableを作る方法をまとめました。
- 最もちゃんとやるならIObservableを実装
- 手軽さと自由度が高いObservable.Create
- イベントからObservableを作るObservable.FromEvent
- コルーチンからObservableを作るObservable.FromCoroutine
- 処理をサブスレッド化するObservable.ToAsyncとObservable.Start
- 関連
Unity2019.2.6
最もちゃんとやるならIObservableを実装
独自のObservableを作るうえで最もちゃんと実装する方法はIObservableを実装する方法です。
using UniRx; using System; public class Example : IObservable<Unit> { public IDisposable Subscribe(IObserver<Unit> observer) { // 色んな処理を書く return Disposable.Empty; } }
ただこの方法は一々クラスを作らなければならないし、
なによりきちんとした設計でObservableを作るのは大変です。
なのでこの記事ではこの方法には深くは触れないことにします。
手軽さと自由度が高いObservable.Create
Observableのファクトリメソッドに、Observable.Create()
というものがあります。
これを使うとある程度複雑なObservableも手軽に作ることができます。
Observable.Create<Unit>(observer => { // 任意のタイミングで通知する observer.OnNext(Unit.Default); observer.OnCompleted(); observer.OnError(new Exception()); return Disposable.Empty; });
またこのファクトリメソッドはDisposableを返却するため、
このDisposableに破棄時の処理を書けばCompleteやError、Cancelした時の処理を記述することができます。
Observable.Create<Unit>(observer => { return Disposable.Create(() => { // Complete時 / Error時 / Cancel時に呼ばれる Debug.Log("Disposed"); }); });
イベントからObservableを作るObservable.FromEvent
Observable.FromEvent()
を使うとクリックイベントなどのイベントからObservableを作れます。
Action someAction = null;
Observable.FromEvent(h => someAction += h, h => someAction -= h);
上記の例では、これでsomeActionがInvokeされた際にストリームに値が流れてきます。
コルーチンからObservableを作るObservable.FromCoroutine
コルーチンをObservableに変換するにはObservable.FromCoroutine()
を使います。
下記のように書くとコルーチンが終了した時にOnCompleteが呼ばれるストリームが作られます。
public void Start() { Observable.FromCoroutine(ExampleCoroutine); } IEnumerator ExampleCoroutine() { yield return new WaitForSeconds(1); }
値の通知を行うにはIObservableを引数に取るコルーチンを定義します。
public void Start() { Observable.FromCoroutine<Unit>(observer => ExampleCoroutine(observer)); } IEnumerator ExampleCoroutine(IObserver<Unit> observer) { yield return new WaitForSeconds(1); observer.OnNext(Unit.Default); }
またこのようにコルーチンをObservable化すると、例外処理が書きやすくなるので便利です。
処理をサブスレッド化するObservable.ToAsyncとObservable.Start
Observable.ToAsync()
を使うと引数に指定した処理をサブスレッドで処理します。
Invoke()を呼んだ時点から処理を開始します。
Observable.ToAsync(() => {}).Invoke();
またObservable.Start()
を使うとObservable.ToAsync()
のあとすぐInvoke()したのと同じ効果が得られます。
Observable.Start(() => {});
これらの使い方については下記の記事に詳しく記載していますので必要に応じて参照してください。