Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

コールバックがあるコルーチンをObservable化してみる

More than 1 year has passed since last update.

コールバックがある場合のコルーチンを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に投げればいいよ

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away