using System; using Chernobyl.Collections.Generic; namespace Chernobyl.StateMachine { /// /// An interface for a state machine /// (http://en.wikipedia.org/wiki/Finite-state_machine). This interface /// defines both a state and a state machine in one type; this allows for /// states to have sub-states which also have sub-states and so on and so /// forth. Types implement this interface when they want to make it aware /// that they have a state or can be a state of another state machine. /// public interface IState : ILinkedEnumerable { /// /// This event is raised when this state has become the active state. /// This can happen if this instances' has been /// set and the has had /// its set to this instance. It can also /// happen if this instance has decided to activate itself. This event /// will only be raised once when the state has become active. It will not be /// invoked a second time unless it is deactivated first. /// event EventHandler Entered; /// /// This event is raised when this state is no longer an active state. /// This can happen if this instances' has /// been set and the has /// had its set to this instance. It can also /// happen if this instance has decided to deactivate itself. This event /// will only be raised once when the state has been deactivated. It will /// not be raised a second time unless it was previously in an active /// state. /// event EventHandler Left; /// /// The that this is a /// sub-state of or null if this is not sub-state /// of another state. When set this property will set the incoming /// instances property /// to this instance (unless the value set is null of course). If this /// property is set to null (or in other words, this state is /// deactivated), two things will occur: (1) the event /// will be raised and (2), immediately prior to raising the /// event, this state will deactivate its child state /// (or sub-state) which will deactivate its child states and so and so /// forth. Deactivating sub-states is done prior to invoking the /// event so that sub-states will be deactivated from /// the lowest sub-state to the highest sub-state. For example, in a /// state machine setup like so: state1 -> state2 -> state3 -> state4 /// If state2 was deactivated, then state4 would be deactivated first /// (i.e., its event would be raised first), /// then state3, and finally state2. /// IState ParentState { get; set; } /// /// The currently active sub-state of this or null /// if this doesn't currently have an active /// sub-state. When set this property will set the incoming /// instances property /// to this instance (unless the value set is null, in which case, the /// this instances /// is set to null). /// IState ChildState { get; set; } } /// /// An interface used to "mark" an type as being an /// or a state used during the initial /// configuration of the application. This is the first state to be applied. /// public interface IConfigurationState : IState { } /// /// An interface used to "mark" an type as being an /// or a state that is applied immediately after /// the configuration state (see ) when /// it is now safe to load content and handle other tasks that are dependent /// on a fully configured Chernobyl. /// public interface ILoadingState : IState { } /// /// An interface used to "mark" an type as being an /// or a state used when the application is /// started and running. This state is applied immediately after the loading /// state (see ). /// public interface IRunningState : IState { } }