/// <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); }
public static ILifetimeManager ToLifetime(this Task t) { var lt = new Lifetime(); t.ContinueWith((t2) => lt.Dispose(), TaskScheduler.FromCurrentSynchronizationContext()); return(lt); }
/// <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); }
public static ILifetimeManager ToLifetime(this Task t) { var lt = new Lifetime(); t.Finally((t2) => lt.Dispose()); return(lt); }
/// <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); }
/// <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); }
public static Lifetime CreateChildLifetime(this ILifetime lt) { var ret = new Lifetime(); lt.OnDisposed(() => { if (ret.IsExpired == false) { ret.Dispose(); } }); return(ret); }
public Lifetime GetPropertyValueLifetime(string propertyName) { Lifetime ret = new Lifetime(); IDisposable sub = null; sub = SubscribeUnmanaged(propertyName, () => { sub.Dispose(); ret.Dispose(); }); return(ret); }
/// <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); }
/// <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); }
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); }