using System; using System.Linq; using UnityEditor; namespace Unity.Play.Publisher.Editor { /// /// Defines the structure of a method that can be called when an action is dispatched /// /// The action to dispatch /// public delegate object Dispatcher(object action); /// /// Defines the structure of a method that can be called when the State reducer /// /// /// /// /// public delegate State Reducer(State previousState, object action); /// /// Defines the structure of a method that can be called in order to alter the state of the application /// /// /// /// public delegate Func Middleware(Store store); /// /// Defines the structure of a method that can be called when the state of an object changes /// /// /// public delegate void StateChangedHandler(State action); /// /// Manages the communication between all the application components /// /// public class Store { /// /// Delegate that reacts on state change /// public StateChangedHandler stateChanged; State _state; readonly Dispatcher _dispatcher; readonly Reducer _reducer; /// /// Initializes and returns an instance of Store /// /// /// /// public Store( Reducer reducer, State initialState = default(State), params Middleware[] middlewares) { this._reducer = reducer; this._dispatcher = this.ApplyMiddlewares(middlewares); this._state = initialState; } /// /// Dispatches an action /// /// /// Returns an object affected by the action public object Dispatch(object action) { return this._dispatcher(action); } /// /// The state /// public State state { get { return this._state; } } Dispatcher ApplyMiddlewares(params Middleware[] middlewares) { return middlewares.Reverse().Aggregate, Dispatcher>(this.InnerDispatch, (current, middleware) => middleware(this)(current)); } object InnerDispatch(object action) { this._state = this._reducer(this._state, action); if (this.stateChanged != null) { this.stateChanged(this._state); } return action; } } }