コード例 #1
0
        static IEnumerator PublishPocoValueChanged <TSource, TProperty>(WeakReference sourceReference, Func <TSource, TProperty> propertySelector, FrameCountType frameCountType, IObserver <TProperty> observer, CancellationToken cancellationToken)
        {
            var comparer = UnityEqualityComparer.GetDefault <TProperty>();

            var isFirst          = true;
            var currentValue     = default(TProperty);
            var prevValue        = default(TProperty);
            var yieldInstruction = frameCountType.GetYieldInstruction();

            while (!cancellationToken.IsCancellationRequested)
            {
                var target = sourceReference.Target;
                if (target != null)
                {
                    try
                    {
                        currentValue = propertySelector((TSource)target);
                    }
                    catch (Exception ex)
                    {
                        observer.OnError(ex);
                        yield break;
                    }
                    finally
                    {
                        target = null; // remove reference(must need!)
                    }
                }
                else
                {
                    observer.OnCompleted();
                    yield break;
                }


                if (isFirst || !comparer.Equals(currentValue, prevValue))
                {
                    isFirst = false;
                    observer.OnNext(currentValue);
                    prevValue = currentValue;
                }

                yield return(yieldInstruction);
            }
        }
コード例 #2
0
        static IEnumerator PublishUnityObjectValueChanged <TSource, TProperty>(UnityEngine.Object unityObject, Func <TSource, TProperty> propertySelector, FrameCountType frameCountType, IObserver <TProperty> observer, CancellationToken cancellationToken)
        {
            var comparer = UnityEqualityComparer.GetDefault <TProperty>();

            var isFirst          = true;
            var currentValue     = default(TProperty);
            var prevValue        = default(TProperty);
            var yieldInstruction = frameCountType.GetYieldInstruction();

            var source = (TSource)(object)unityObject;

            while (!cancellationToken.IsCancellationRequested)
            {
                if (unityObject != null)
                {
                    try
                    {
                        currentValue = propertySelector(source);
                    }
                    catch (Exception ex)
                    {
                        observer.OnError(ex);
                        yield break;
                    }
                }
                else
                {
                    observer.OnCompleted();
                    yield break;
                }

                if (isFirst || !comparer.Equals(currentValue, prevValue))
                {
                    isFirst = false;
                    observer.OnNext(currentValue);
                    prevValue = currentValue;
                }

                yield return(yieldInstruction);
            }
        }
コード例 #3
0
        /// <summary>
        /// Publish target property when value is changed. If source is destroyed/destructed, publish OnCompleted.
        /// </summary>
        /// <param name="fastDestroyCheck">If true and target is UnityObject, use destroyed check by additional component. It is faster check for lifecycle but needs initial cost.</param>
        public static 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>();
            }

            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, fastDestroyCheck);
                    }
                    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));
            }
        }
コード例 #4
0
 /// <summary>
 /// Publish target property when value is changed. If source is destroyed/destructed, publish OnCompleted.
 /// </summary>
 /// <param name="fastDestroyCheck">If true and target is UnityObject, use destroyed check by additional component. It is faster check for lifecycle but needs initial cost.</param>
 public static IObservable <TProperty> ObserveEveryValueChanged <TSource, TProperty>(this TSource source, Func <TSource, TProperty> propertySelector, FrameCountType frameCountType = FrameCountType.Update, bool fastDestroyCheck = false)
     where TSource : class
 {
     return(ObserveEveryValueChanged(source, propertySelector, frameCountType, UnityEqualityComparer.GetDefault <TProperty>(), fastDestroyCheck));
 }
コード例 #5
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));
        }