/// <summary> /// Listens for when a property is changed and ensures that the subscription is properly disposed when the system disposes or when the component disposes. /// </summary> /// <typeparam name="TComponentType"></typeparam> /// <typeparam name="TPropertyType"></typeparam> /// <param name="system">This system to install this listner on, it will get disposed with this one.</param> /// <param name="select">A selector for the property observable on TComponentType that you wish to listen for.</param> /// <param name="handler">The method that is invoked when the property changes.</param> /// <param name="getImmediateValue">The lambda method for retreiving the primtive value, if this is not null, it will immedietly invoke the handler with this value.</param> /// <param name="onlyWhenChanged">Only invoke the method when the value actually changes rather than when it is set.</param> public static void PropertyChanged <TComponentType, TPropertyType>(this IEcsSystem system, Func <TComponentType, IObservable <TPropertyType> > select, Action <TComponentType, TPropertyType> handler, Func <TComponentType, TPropertyType> getImmediateValue = null, bool onlyWhenChanged = false) where TComponentType : class, IEcsComponent { if (onlyWhenChanged) { system.OnComponentCreated <TComponentType>().DistinctUntilChanged().Subscribe(_ => { select(_).Subscribe(v => handler(_, v)).DisposeWith(_).DisposeWith(system); if (getImmediateValue != null) { handler(_, getImmediateValue(_)); } }).DisposeWith(system); } else { system.OnComponentCreated <TComponentType>().Subscribe(_ => { select(_).Subscribe(v => handler(_, v)).DisposeWith(_).DisposeWith(system); if (getImmediateValue != null) { handler(_, getImmediateValue(_)); } }).DisposeWith(system); } }
/// <summary> /// Listens for when a property is changed and ensures that the subscription is properly disposed when the system disposes or when the component disposes. /// </summary> /// <typeparam name="TComponentType"></typeparam> /// <typeparam name="TPropertyType"></typeparam> /// <param name="system">This system to install this listner on, it will get disposed with this one.</param> /// <param name="select">A selector for the property observable on TComponentType that you wish to listen for.</param> /// <param name="handler">The method that is invoked when the property changes.</param> /// <param name="getImmediateValue">The lambda method for retreiving the primtive value, if this is not null, it will immedietly invoke the handler with this value.</param> /// <param name="onlyWhenChanged">Only invoke the method when the value actually changes rather than when it is set.</param> public static void PropertyChangedEvent <TComponentType, TPropertyType>(this IEcsSystem system, Func <TComponentType, IObservable <PropertyChangedEvent <TPropertyType> > > select, Action <TComponentType, PropertyChangedEvent <TPropertyType> > handler, Func <TComponentType, TPropertyType> getImmediateValue = null, bool onlyWhenChanged = false) where TComponentType : class, IEcsComponent { if (onlyWhenChanged) { system.OnComponentCreated <TComponentType>().Subscribe(_ => { select(_).Where(p => !Equals(p.PreviousValue, p.CurrentValue)).Subscribe(v => handler(_, v)).DisposeWith(_).DisposeWith(system); if (getImmediateValue != null) { handler(_, new PropertyChangedEvent <TPropertyType>() { CurrentValue = getImmediateValue(_) }); } }).DisposeWith(system); } else { system.OnComponentCreated <TComponentType>().Subscribe(_ => { select(_).Subscribe(v => handler(_, v)).DisposeWith(_).DisposeWith(system); if (getImmediateValue != null) { handler(_, new PropertyChangedEvent <TPropertyType>() { CurrentValue = getImmediateValue(_) }); } }).DisposeWith(system); } }
/// <summary> /// Listens for when a property is changed and ensures that the subscription is properly disposed when the system disposes or when the component disposes. /// </summary> /// <typeparam name="TComponentType"></typeparam> /// <typeparam name="TPropertyType"></typeparam> /// <param name="system">This system to install this listner on, it will get disposed with this one.</param> /// <param name="select">A selector for the property observable on TComponentType that you wish to listen for.</param> /// <param name="handler">The method that is invoked when the property changes.</param> /// <param name="getImmediateValue">The lambda method for retreiving the primtive value, if this is not null, it will immedietly invoke the handler with this value.</param> /// <param name="onlyWhenChanged">Only invoke the method when the value actually changes rather than when it is set.</param> public static void PropertyChangedEvent <TComponentType, TPropertyType>(this IEcsSystem system, Func <TComponentType, IObservable <PropertyChangedEvent <TPropertyType> > > select, Action <TComponentType, PropertyChangedEvent <TPropertyType> > handler, Func <TComponentType, TPropertyType> getImmediateValue = null, bool onlyWhenChanged = false) where TComponentType : class, IEcsComponent { if (onlyWhenChanged) { system.OnComponentCreated <TComponentType>().Subscribe(_ => { select(_).Subscribe(v => { // the next line crashes unity: //!Equals(v.PreviousValue, v.CurrentValue)) //That is why we got some nastiness here if (!v.Comparer.Equals(v.PreviousValue, v.CurrentValue)) { handler(_, v); } }).DisposeWith(_).DisposeWith(system); if (getImmediateValue != null) { handler(_, new PropertyChangedEvent <TPropertyType>() { CurrentValue = getImmediateValue(_) }); } }).DisposeWith(system); } else { system.OnComponentCreated <TComponentType>().Subscribe(_ => { select(_).Subscribe(v => handler(_, v)).DisposeWith(_).DisposeWith(system); if (getImmediateValue != null) { handler(_, new PropertyChangedEvent <TPropertyType>() { CurrentValue = getImmediateValue(_) }); } }).DisposeWith(system); } }
/// <summary> /// Listens for when a Reactive Collection's item has been removed, and ensures that the subscription properly disposed when the system disposes or when the component disposes. /// </summary> /// <typeparam name="TComponentType"></typeparam> /// <typeparam name="TPropertyType"></typeparam> /// <param name="system">This system to install this listner on, it will get disposed with this one.</param> /// <param name="select">The ReactiveCollection selector.</param> /// <param name="handler">The method that is invoked when an item is added to the collection</param> public static void CollectionItemRemoved <TComponentType, TPropertyType>(this IEcsSystem system, Func <TComponentType, ReactiveCollection <TPropertyType> > select, Action <TComponentType, TPropertyType> handler) where TComponentType : class, IEcsComponent { system.OnComponentCreated <TComponentType>().Subscribe(_ => { select(_).ObserveRemove().Subscribe(v => handler(_, v.Value)).DisposeWith(_).DisposeWith(system); }).DisposeWith(system); }
/// <summary> /// Listens for when a Reactive Collection's item has been added, and ensures that the subscription properly disposed when the system disposes or when the component disposes. /// </summary> /// <typeparam name="TComponentType"></typeparam> /// <typeparam name="TPropertyType"></typeparam> /// <param name="system">This system to install this listner on, it will get disposed with this one.</param> /// <param name="select">The ReactiveCollection selector.</param> /// <param name="handler">The method that is invoked when an item is added to the collection</param> /// <param name="immediate">Should the handler be invoked for every item that is currently in the list?</param> public static void CollectionItemAdded <TComponentType, TPropertyType>(this IEcsSystem system, Func <TComponentType, ReactiveCollection <TPropertyType> > select, Action <TComponentType, TPropertyType> handler, bool immediate = false) where TComponentType : class, IEcsComponent { system.OnComponentCreated <TComponentType>().Subscribe(_ => { select(_).ObserveAdd().Subscribe(v => handler(_, v.Value)).DisposeWith(_).DisposeWith(system); if (immediate) { foreach (var item in select(_)) { handler(_, item); } } }).DisposeWith(system); }