示例#1
0
 // marker for CatchIgnore and Catch avoid iOS AOT problem.
 public static IObservable <TSource> CatchIgnore <TSource>(Exception ex)
 {
     return(Observable.Empty <TSource>());
 }
        /// <summary>
        /// Publish target property when value is changed. If source is destroyed/destructed, publish OnCompleted.
        /// </summary>
        public static IObservable <TProperty> ObserveEveryValueChanged <TSource, TProperty>(this TSource source, Func <TSource, TProperty> propertySelector, FrameCountType frameCountType, IEqualityComparer <TProperty> comparer)
            where TSource : class
        {
            if (source == null)
            {
                return(Observable.Empty <TProperty>());
            }
            if (comparer == null)
            {
                comparer = UnityEqualityComparer.GetDefault <TProperty>();
            }

            var unityObject   = source as UnityEngine.Object;
            var isUnityObject = source is UnityEngine.Object;

            if (isUnityObject && unityObject == null)
            {
                return(Observable.Empty <TProperty>());
            }

            // MicroCoroutine does not publish value immediately, so publish value on subscribe.
            if (isUnityObject)
            {
                return(ObservableUnity.FromMicroCoroutine <TProperty>((observer, cancellationToken) =>
                {
                    if (unityObject != null)
                    {
                        var firstValue = default(TProperty);
                        try
                        {
                            firstValue = propertySelector((TSource)(object)unityObject);
                        }
                        catch (Exception ex)
                        {
                            observer.OnError(ex);
                            return EmptyEnumerator();
                        }

                        observer.OnNext(firstValue);
                        return PublishUnityObjectValueChanged(unityObject, firstValue, propertySelector, comparer, observer, cancellationToken);
                    }
                    else
                    {
                        observer.OnCompleted();
                        return EmptyEnumerator();
                    }
                }, frameCountType));
            }
            else
            {
                var reference = new WeakReference(source);
                source = null;

                return(ObservableUnity.FromMicroCoroutine <TProperty>((observer, cancellationToken) =>
                {
                    var target = reference.Target;
                    if (target != null)
                    {
                        var firstValue = default(TProperty);
                        try
                        {
                            firstValue = propertySelector((TSource)target);
                        }
                        catch (Exception ex)
                        {
                            observer.OnError(ex);
                            return EmptyEnumerator();
                        }
                        finally
                        {
                            target = null;
                        }

                        observer.OnNext(firstValue);
                        return PublishPocoValueChanged(reference, firstValue, propertySelector, comparer, observer, cancellationToken);
                    }
                    else
                    {
                        observer.OnCompleted();
                        return EmptyEnumerator();
                    }
                }, frameCountType));
            }
        }
示例#3
0
        private static IObservable <T> Tween <T>(Func <OperatableBase <T> > start, Func <OperatableBase <T> > finish, Func <float> duration, EaseType easeType, LoopType loopType, Action onCompleteTween) where T : struct
        {
            T startValue  = default(T);
            T finishValue = default(T);

            onCompleteTween = onCompleteTween ?? (() => { });
            Func <IObserver <T>, IDisposable> returnStartValue = (observer) =>
            {
                observer.OnNext(startValue);
                return(null);
            };
            Func <IObserver <T>, IDisposable> returnFinishValue = (observer) =>
            {
                observer.OnNext(finishValue);
                return(null);
            };
            IObservable <T> stream = Observable.Empty <TweenInformation <T> >()
                                     // Repeat() のために、毎回初期値を生成
                                     .StartWith(() => new TweenInformation <T>(Time.time, start(), finish(), duration(), easeType, out startValue, out finishValue))
                                     // Update のストリームに変換
                                     .SelectMany(information => Observable.EveryUpdate().Do(_ => information.Time = Time.time - information.StartTime).Select(_ => information))
                                     // Tween 時間が処理時間よりも小さい間流し続ける
                                     .TakeWhile(information => information.Time <= information.Duration)
                                     // 実際の Easing 処理実行
                                     .Select(information => Easing(information.Time, information.Start, (information.Finish - information.Start), information.Duration, information.EaseType).Value)
                                     // 最終フレームの値を確実に流すために OnCompleted が来たら値を一つ流すストリームに繋ぐ
                                     // 1回分の Tween が終わったらコールバックを呼ぶ
                                     .Concat(Observable.Create(returnFinishValue).Take(1).Do(_ => onCompleteTween()));

            switch (loopType)
            {
            case LoopType.None:
                // Do nothing.
                break;

            case LoopType.Repeat:
                stream = stream.Repeat();
                break;

            case LoopType.PingPong:
                stream = stream
                         .Concat(
                    Observable.Empty <TweenInformation <T> >()
                    // Repeat() のために、毎回初期値を生成
                    .StartWith(() => new TweenInformation <T>(Time.time, start(), finish(), duration(), easeType, out startValue, out finishValue))
                    // Update のストリームに変換
                    .SelectMany(information => Observable.EveryUpdate().Do(_ => information.Time = Time.time - information.StartTime).Select(_ => information))
                    // Tween 時間が処理時間よりも小さい間流し続ける
                    .TakeWhile(information => information.Time <= information.Duration)
                    // start と finish を入れ替えて、実際の Easing 処理実行
                    .Select(information => Easing(information.Time, information.Finish, (information.Start - information.Finish), information.Duration, information.EaseType).Value)
                    // 最終フレームの値を確実に流すために OnCompleted が来たら最終値を一つ流すストリームに繋ぐ
                    // 1回分の Tween が終わったらコールバックを呼ぶ
                    .Concat(Observable.Create(returnStartValue).Take(1).Do(_ => onCompleteTween()))
                    )
                         .Repeat();
                break;

            case LoopType.Mirror:
                stream = stream
                         .Concat(
                    Observable.Empty <TweenInformation <T> >()
                    // Repeat() のために、毎回初期値を生成
                    .StartWith(() => new TweenInformation <T>(Time.time, start(), finish(), duration(), easeType, out startValue, out finishValue))
                    // Update のストリームに変換
                    .SelectMany(information => Observable.EveryUpdate().Do(_ => information.Time = Time.time - information.StartTime).Select(_ => information))
                    // Tween 時間が処理時間よりも小さい間流し続ける
                    .TakeWhile(information => information.Time <= information.Duration)
                    // start と finish を入れ替えて、実際の Easing 処理実行
                    .Select(information => Easing(information.Time, information.Finish, (information.Start - information.Finish), information.Duration, MirrorEaseTypeMap[information.EaseType]).Value)
                    // 最終フレームの値を確実に流すために OnCompleted が来たら最終値を一つ流すストリームに繋ぐ
                    // 1回分の Tween が終わったらコールバックを呼ぶ
                    .Concat(Observable.Create(returnStartValue).Take(1).Do(_ => onCompleteTween()))
                    )
                         .Repeat();
                break;
            }

            return(stream);
        }
示例#4
0
        public static UniRx.IObservable <TProperty> ObserveEveryValueChanged <TSource, TProperty>(this TSource source, Func <TSource, TProperty> propertySelector, FrameCountType frameCountType, IEqualityComparer <TProperty> comparer, bool fastDestroyCheck) where TSource : class
        {
            if (source == null)
            {
                return(Observable.Empty <TProperty>());
            }
            if (comparer == null)
            {
                comparer = UnityEqualityComparer.GetDefault <TProperty>();
            }
            UnityEngine.Object unityObject = source as UnityEngine.Object;
            bool flag = source is UnityEngine.Object;

            if (flag && unityObject == null)
            {
                return(Observable.Empty <TProperty>());
            }
            if (flag)
            {
                return(Observable.FromMicroCoroutine(delegate(UniRx.IObserver <TProperty> observer, CancellationToken cancellationToken)
                {
                    if (unityObject != null)
                    {
                        TProperty val2 = default(TProperty);
                        try
                        {
                            val2 = propertySelector((TSource)(object)unityObject);
                        }
                        catch (Exception error2)
                        {
                            observer.OnError(error2);
                            return EmptyEnumerator();
                        }
                        observer.OnNext(val2);
                        return PublishUnityObjectValueChanged(unityObject, val2, propertySelector, comparer, observer, cancellationToken, fastDestroyCheck);
                    }
                    observer.OnCompleted();
                    return EmptyEnumerator();
                }, frameCountType));
            }
            WeakReference reference = new WeakReference(source);

            source = (TSource)null;
            return(Observable.FromMicroCoroutine(delegate(UniRx.IObserver <TProperty> observer, CancellationToken cancellationToken)
            {
                object target = reference.Target;
                if (target != null)
                {
                    TProperty val = default(TProperty);
                    try
                    {
                        val = propertySelector((TSource)target);
                    }
                    catch (Exception error)
                    {
                        observer.OnError(error);
                        return EmptyEnumerator();
                    }
                    finally
                    {
                        target = null;
                    }
                    observer.OnNext(val);
                    return PublishPocoValueChanged(reference, val, propertySelector, comparer, observer, cancellationToken);
                }
                observer.OnCompleted();
                return EmptyEnumerator();
            }, frameCountType));
        }
        /// <summary>Catch exception and return Observable.Empty.</summary>
        public static IObservable <TSource> CatchIgnore <TSource>(this IObservable <TSource> source)
        {
            var result = source.Catch <TSource, Exception>(ex => Observable.Empty <TSource>());

            return(result);
        }