public ElementProjectionObservable(StoreBase <TState> store, ElementProjector <TState, T, K> projector, K elementKey, Action onEmpty) : base(onEmpty) { _store = store; _projector = projector; _elementKey = elementKey; _currentValue = projector(_store.CurrentState, elementKey); }
/// <summary> /// Send a value to all subscribers of a collection item projection, /// simulating a change to the item state. /// </summary> /// <param name="projector"> /// The projection function being simulated. The function is not called. /// </param> /// <param name="key"> /// The collection key of the item being simulated. /// </param> /// <param name="value"> /// The value to be sent to the project subscribers. /// </param> public void Publish <T, K>(ElementProjector <TState, T, K> projector, K key, T value) { if (projector == null) { throw new ArgumentNullException(nameof(projector)); } var observable = GetObservableForProjection <T>(Tuple.Create(projector, key)); observable?.PublishValue(value); }
/// <summary> /// Observe an item contained by a collection within the application state. /// </summary> /// <typeparam name="T"> /// The collection item's type. /// </typeparam> /// <typeparam name="K"> /// The collection's key or index type. /// </typeparam> /// <param name="projector"> /// The projection function. Projections are pure static functions which receive /// the current state and return a value based on that state. /// </param> /// <param name="elementKey"> /// The collection key or index value to be observed. /// </param> /// <returns> /// An <see cref="IObservable{T}"/> which can be subscribed for changes. /// </returns> public IProjectionObservable <T> ObserveElement <T, K>(ElementProjector <TState, T, K> projector, K elementKey) { if (projector == null) { throw new ArgumentNullException(nameof(projector)); } // if we've seen this projector before, reuse the observable we created for it, else create one var observableCollectionKey = Tuple.Create(projector, elementKey); var observable = GetObservableForProjection <T>(observableCollectionKey); if (observable == null) { observable = new ElementProjectionObservable <TState, T, K>(this, projector, elementKey, () => ForgetProjection(observableCollectionKey)); _observables = _observables.Add(observableCollectionKey, (IStateListener <TState>)observable); } return(observable); }
/// <summary> /// Apply a projection function to the store and return its value immediately. /// </summary> /// <typeparam name="T"> /// The projector's return type. /// </typeparam> /// <typeparam name="K"> /// The collection's key or index type. /// </typeparam> /// <param name="projector"> /// The projection function. Projections are pure static functions which receive /// the current state and return a value based on that state. /// </param> /// <param name="elementKey"> /// The collection key or index value to be observed. /// </param> /// <returns> /// The value returned by the projection function. /// </returns> public T Project <T, K>(ElementProjector <TState, T, K> projector, K elementKey) { var value = projector(CurrentState, elementKey); return(value); }