using System; using System.Collections; using System.Threading; using UnityEngine; #if !UniRxLibrary using ObservableUnity = UniRx.Observable; #endif namespace UniRx { public static partial class AsyncOperationExtensions { /// /// If you needs return value, use AsAsyncOperationObservable instead. /// public static IObservable AsObservable(this AsyncOperation asyncOperation, IProgress progress = null) { return ObservableUnity.FromCoroutine((observer, cancellation) => AsObservableCore(asyncOperation, observer, progress, cancellation)); } // T: where T : AsyncOperation is ambigious with IObservable.AsObservable public static IObservable AsAsyncOperationObservable(this T asyncOperation, IProgress progress = null) where T : AsyncOperation { return ObservableUnity.FromCoroutine((observer, cancellation) => AsObservableCore(asyncOperation, observer, progress, cancellation)); } static IEnumerator AsObservableCore(T asyncOperation, IObserver observer, IProgress reportProgress, CancellationToken cancel) where T : AsyncOperation { if (reportProgress != null) { while (!asyncOperation.isDone && !cancel.IsCancellationRequested) { try { reportProgress.Report(asyncOperation.progress); } catch (Exception ex) { observer.OnError(ex); yield break; } yield return null; } } else { if (!asyncOperation.isDone) { yield return asyncOperation; } } if (cancel.IsCancellationRequested) yield break; if (reportProgress != null) { try { reportProgress.Report(asyncOperation.progress); } catch (Exception ex) { observer.OnError(ex); yield break; } } observer.OnNext(asyncOperation); observer.OnCompleted(); } } }