示例#1
0
        /// <summary>
        /// Creates a new lifetime that will end when any of the given
        /// lifetimes ends
        /// </summary>
        /// <param name="others">the lifetimes to use to generate this new lifetime</param>
        /// <returns>a new lifetime that will end when any of the given
        /// lifetimes ends</returns>
        public static Lifetime EarliestOf(IEnumerable <ILifetimeManager> others)
        {
            Lifetime ret   = new Lifetime();
            var      count = 0;

            foreach (var other in others)
            {
                if (other != null)
                {
                    count++;
                    other.OnDisposed(() =>
                    {
                        if (ret.IsExpired == false)
                        {
                            ret.Dispose();
                        }
                    });
                }
            }
            if (count == 0)
            {
                ret.Dispose();
            }
            return(ret);
        }
示例#2
0
        public static ILifetimeManager ToLifetime(this Task t)
        {
            var lt = new Lifetime();

            t.ContinueWith((t2) => lt.Dispose(), TaskScheduler.FromCurrentSynchronizationContext());
            return(lt);
        }
示例#3
0
        /// <summary>
        /// Converts this promise to a lifetime
        /// </summary>
        /// <returns>a lifetime that ends when this promise resolves</returns>
        public Lifetime ToLifetime()
        {
            var ret = new Lifetime();

            this.Finally(p => ret.Dispose());
            return(ret);
        }
示例#4
0
        public static ILifetimeManager ToLifetime(this Task t)
        {
            var lt = new Lifetime();

            t.Finally((t2) => lt.Dispose());
            return(lt);
        }
示例#5
0
        /// <summary>
        /// Subscribes to the given event for at most one notification
        /// </summary>
        /// <param name="route">the event to subscribe to</param>
        /// <param name="handler">the event handler</param>
        public void RegisterOnce(string route, Action <RoutedEvent <T> > handler)
        {
            var routeLifetime = new Lifetime();

            GetOrAddRoutedEvent(route).SubscribeForLifetime((t) =>
            {
                handler(t);
                routes.Remove(route);
                routeLifetime.Dispose();
            }, routeLifetime);
        }
示例#6
0
        /// <summary>
        /// Creates a new lifetime that may be disposed earlier, but will be disposed when this
        /// lifetime ends
        /// </summary>
        /// <returns></returns>
        public Lifetime CreateChildLifetime()
        {
            var ret = new Lifetime();

            _manager.OnDisposed(() =>
            {
                if (ret.IsExpired == false)
                {
                    ret.Dispose();
                }
            });
            return(ret);
        }
示例#7
0
        public static Lifetime CreateChildLifetime(this ILifetime lt)
        {
            var ret = new Lifetime();

            lt.OnDisposed(() =>
            {
                if (ret.IsExpired == false)
                {
                    ret.Dispose();
                }
            });
            return(ret);
        }
示例#8
0
        public Lifetime GetPropertyValueLifetime(string propertyName)
        {
            Lifetime    ret = new Lifetime();
            IDisposable sub = null;

            sub = SubscribeUnmanaged(propertyName, () =>
            {
                sub.Dispose();
                ret.Dispose();
            });

            return(ret);
        }
示例#9
0
        /// <summary>
        /// Creates a new lifetime that will end when any of the given
        /// lifetimes ends
        /// </summary>
        /// <param name="others">the lifetimes to use to generate this new lifetime</param>
        /// <returns>a new lifetime that will end when any of the given
        /// lifetimes ends</returns>
        public static Lifetime EarliestOf(IEnumerable <ILifetimeManager> others)
        {
            Lifetime ret = new Lifetime();

            foreach (var other in others)
            {
                other.OnDisposed(() =>
                {
                    if (ret.IsExpired == false)
                    {
                        ret.Dispose();
                    }
                });
            }
            return(ret);
        }
示例#10
0
        /// <summary>
        /// Creates a new lifetime that will end when all of the given lifetimes end
        /// </summary>
        /// <param name="others">the lifetimes to use to generate this new lifetime</param>
        /// <returns>a new lifetime that will end when all of the given lifetimes end</returns>
        public static Lifetime WhenAll(params ILifetimeManager[] others)
        {
            var togo = others.Length;
            var ret  = new Lifetime();

            foreach (var lifetime in others)
            {
                lifetime.OnDisposed(() =>
                {
                    if (Interlocked.Decrement(ref togo) == 0)
                    {
                        ret.Dispose();
                    }
                });
            }

            return(ret);
        }
示例#11
0
        private IDisposable DeepSubscribeInternal(string path, Action handler, Lifetime rootLifetime = null)
        {
            rootLifetime = rootLifetime ?? new Lifetime();
            var observableRoot = DeepObservableRoot ?? this;
            IObservableObject currentObservable = observableRoot;
            var pathExpression = ObjectPathExpression.Parse(path);
            List <IObjectPathElement> currentPath = new List <IObjectPathElement>();

            var anyChangeLifetime = new Lifetime();

            for (int i = 0; i < pathExpression.Elements.Count; i++)
            {
                var propertyElement = pathExpression.Elements[i] as PropertyPathElement;
                if (propertyElement == null)
                {
                    throw new NotSupportedException("Indexers are not supported for deep observability");
                }

                currentPath.Add(propertyElement);

                ObjectPathExpression.TraceNode eval;

                if (i == pathExpression.Elements.Count - 1 && propertyElement.PropertyName == ObservableObject.AnyProperty)
                {
                    eval = new ObjectPathExpression.TraceNode()
                    {
                        Value = null
                    };
                }
                else
                {
                    eval = new ObjectPathExpression(currentPath).EvaluateAndTraceInfo(observableRoot).Last();
                    if (i != pathExpression.Elements.Count - 1 && (eval.MemberInfo as PropertyInfo).PropertyType.GetInterfaces().Contains(typeof(IObservableObject)) == false)
                    {
                        throw new NotSupportedException($"element {eval.MemberInfo.Name} is not observable");
                    }
                }

                currentObservable.SubscribeForLifetime(propertyElement.PropertyName, () =>
                {
                    handler();
                    if (anyChangeLifetime.IsExpired == false)
                    {
                        anyChangeLifetime.Dispose();
                    }

                    if (rootLifetime.IsExpired == false)
                    {
                        DeepSubscribeInternal(path, handler, rootLifetime);
                    }
                }, EarliestOf(anyChangeLifetime, rootLifetime));

                currentObservable = eval.Value as IObservableObject;

                if (currentObservable == null)
                {
                    break;
                }
            }

            return(rootLifetime);
        }