実務で使っているUnityの便利モジュール・実装パターン3選 - Technology of DeNA で紹介されている Using
が便利そうだったんですが、使ってみようとしたらいまいち使いにくかった 1 ので、使えるものを用意しました。
結論としては、 Rx.NET の Observable.Using
がほぼそのまま使えました。
Observable.Using.cs
using System;
namespace UniRx
{
public static partial class Observable
{
// https://github.com/Reactive-Extensions/Rx.NET/blob/371c83c621562a2259580a03f0cb5bf8680ea720/Rx.NET/Source/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Creation.cs#L417-L441
public static IObservable<TSource> Using<TSource, TResource>(
Func<TResource> resourceFactory,
Func<TResource, IObservable<TSource>> observableFactory)
where TResource : IDisposable
{
return Observable.Create<TSource> (observer =>
{
var source = default(IObservable<TSource>);
var disposable = Disposable.Empty;
try
{
var resource = resourceFactory();
if (resource != null)
{
disposable = resource;
}
source = observableFactory(resource);
}
catch (Exception exception)
{
return new CompositeDisposable(Throw<TSource>(exception).Subscribe(observer), disposable);
}
return new CompositeDisposable(source.Subscribe(observer), disposable);
});
}
}
}
これを Assets/Plugins/ の下に置くと、元の UniRx の Observable
に .Using
が生えます。
使用例:
Observable.Using(() => new UnityWebRequest(), request =>
{
// いろいろ設定…。
request.url = "URL";
return request.Send().AsObservable().Select(_ => request.responseCode);
})
.Subscribe(code => Debug.Log(code));
Rx.NET の NO_PERF
条件コンパイルの NO_PERF
の時のコードを今回使ったんですが、この NO_PERF
は Rx 1.1 の頃のパフォーマンス改善前のコードのようです。
http://stackoverflow.com/a/22691962
Observable.Using
を使うようなタイミングなら UniRx のパフォーマンスはあんまり気にしなくて大丈夫かと思います。
-
元の
Using
ではnew
したUnityWebRequest
がobservableFactory
に渡されないので、そこが使いにくいです。 ↩