コールバックがある場合のコルーチンをObservable化してみる
コルーチン終了後の処理をコールバックメソッド的に書く方法が手段の一つとしてあります。
public IEnumerator CallbackCoroutine(Action<string> callback)
{
//なんかいろいろやる
yield return new WaitForSeconds(5);
callback("some methods completed");
}
こういう処理はRxがあるならFromCoroutineで書けばいいのですが、なんかのこってるときにこれをObservable化したいなーと思ったのでちょっとやってみます。
FromCoroutineだけではダメ
FromeCoroutineだけだと、コルーチンの終了をとるだけなのでコールバックの面倒は見てくれません。
Createを使う
なのでCreateを使うのがシンプルかなと思います。
CreateメソッドはobserverがSubscribeされた時の挙動を全部記述してあげるメソッドです。
observerには,コールバックに渡されるパラメータをそのまま渡したいので次のようになります。
Subjectを使ってもいいですが, その場合Hot Observableになってしまうので扱い面倒くさくなります。
public IObservable<string> ToObservable()
{
return Observable.Create<string>(observer =>
{
StartCoroutine(CallbackCoroutine(s =>
{
//コールバックに入ってきた値をそのままobserverに渡します。
observer.OnNext(s);
observer.OnCompleted();
}));
// ここではcancellation tokenを返しますが
// キャンセル機構を持っていないのでEmptyでいいでしょう
return Disposable.Empty;
});
}
まとめ
全部合わせるとこんな感じです
using System;
using System.Collections;
using UniRx;
using UnityEngine;
public class ParameterCoroutine : MonoBehaviour {
public IEnumerator CallbackCoroutine(Action<string> callback)
{
//なんかいろいろやる
yield return new WaitForSeconds(5);
callback("some methods completed");
}
public IObservable<string> ToObservable()
{
return Observable.Create<string>(observer =>
{
StartCoroutine(CallbackCoroutine(s =>
{
observer.OnNext(s);
observer.OnCompleted();
}));
return Disposable.Empty;
});
}
void Start()
{
ToObservable().Subscribe(Debug.Log);
}
}
因みにですが, もしこのObservableをUnityのメインスレッド以外で起動したい場合は, Unityの仕様に併せてSubscribeOnしてあげて下さい。
コールバックが三つも四つもある場合
知らん設計がおかしい
エラーとかはOnErrorに投げればいいよ