123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- #region --------------- Copyright Dresser Wayne Pignone -------------
- /*
- * $Log: /Wrk/WayneLibraries/Wrk/StateEngine/CompositeState.cs $
- *
- * 7 08-03-25 14:15 Mattias.larsson
- * Clean-up.
- *
- * 6 08-02-26 14:06 Mattias.larsson
- * Renamed stateName to factoryName.
- *
- * 5 07-08-15 15:27 roger.månsson
- * Added SetDebugLogger method.
- *
- * 4 07-08-07 8:26 Mattias.larsson
- *
- * 3 07-03-02 13:19 roger.månsson
- */
- #endregion
- #region Old file header
- /*===============================================================================
- * CompositeState
- *
- * Change history
- * When Who Comment
- * ---------- ------ ------------------------------------
- * 2006-07-17 RMa Major updates, Changed state machine and event handling.
- * 2006-05-09 RMa Implemented the dispose handling.
- * 2006-03-01 RMa FXCop updates: CreateStateMachine is not virtual anymore.
- * 2006-02-03 RMa FXCop updates: Made constuctor protected + misc.
- * 2006-01-27 RMa Removed interface Event. Use Event class instead.
- * 2006-01-05 RMa Added the internal function LookupState
- * 2005-12-14 RMa Changed so Internal_Enter is called by the state machine, so we are sure that
- * the internal stuff gets called ,if the user forgets to call base.Enter()....
- * 2005-12-09 RMa Fixed so the state entry always is sent into a composite state machine.
- * 2005-12-05 RMa This header added.
- *
- ---------------------------------------------------------------------------------*/
- #endregion
- using System;
- using System.Linq;
- using Wayne.Lib.Log;
- namespace Wayne.Lib.StateEngine
- {
- /// <summary>
- /// Composite state is an abstract class that should be overriden to
- /// create a state that within itself have a state machine with sub states.
- /// When creating the composite state, a message handling thread should be sent
- /// in to the composite state constructor. It can either be a new thread if the
- /// composite state machine should run in a separate thread , or the thread of the
- /// parent state machine if the machine should run in the same thread.
- /// </summary>
- abstract public class CompositeState : State
- {
- #region Fields
- private StateMachine stateMachine;
- private bool disposed;
- #endregion
- #region Construction
- /// <summary>
- /// Initializes a new instance of a composite state.
- /// </summary>
- protected CompositeState()
- {
- stateMachine = new CompositeStateMachine(this);
- }
- /// <summary>
- /// Destructor
- /// </summary>
- ~CompositeState()
- {
- Dispose(false);
- }
- #endregion
- #region Methods
- /// <summary>
- /// Handles an incoming event.
- /// </summary>
- /// <param name="stateEngineEvent">Event that is received.</param>
- /// <param name="transition">Perform a transaction by assigning a transition object to this ref parameter.</param>
- protected sealed override void HandleEvent(StateEngineEvent stateEngineEvent, ref Transition transition)
- {
- BeforeHandleEvent(stateEngineEvent, ref transition);
- if (!stateEngineEvent.Handled)
- stateMachine.HandleEvent(stateEngineEvent, ref transition);
- if (!stateEngineEvent.Handled)
- UnhandledEvent(stateEngineEvent, ref transition);
- }
- /// <summary>
- /// Method that can be overriden in descendant classes, so events can be handed before they are sent to the
- /// state machine.
- /// </summary>
- /// <param name="stateEngineEvent"></param>
- /// <param name="transition">Perform a transaction by assigning a transition object to this ref parameter.</param>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "1#")]
- public virtual void BeforeHandleEvent(StateEngineEvent stateEngineEvent, ref Transition transition)
- {
- }
- /// <summary>
- /// Method that can be overriden if wanting to handle events that not has been handled in the composite state machine.
- /// </summary>
- /// <param name="stateEngineEvent"></param>
- /// <param name="transition">Perform a transaction by assigning a transition object to this ref parameter.</param>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "1#")]
- public virtual void UnhandledEvent(StateEngineEvent stateEngineEvent, ref Transition transition)
- {
- }
- #endregion
- #region Internal Methods
- internal override void PerformEnter(StateEntry entry, ref Transition transition)
- {
- base.PerformEnter(entry, ref transition);
- if (!stateMachine.Initialized)
- this.Initialize();
- //If base did not result in any transition,
- if (transition == null)
- {
- stateMachine.EnterState(entry, ref transition);
- if (transition != null)
- stateMachine.HandleTransition(ref transition);
- }
- }
- internal override void PerformExit()
- {
- base.PerformExit();
- stateMachine.ExitState();
- }
- /// <summary>
- /// Initializes and creates the states of the composite state engine.
- /// </summary>
- internal void Initialize()
- {
- if (!stateMachine.Initialized)
- stateMachine.Initialize();
- }
- /// <summary>
- /// This function is used to locate a specific state in the state machine.
- ///
- /// The composite state checks first if its own FactoryName matches the name,
- /// if not it calls each created state subsequently.
- /// </summary>
- /// <param name="factoryName">The name of the state that should be looked up.</param>
- /// <returns>True if the state is or contains a state with this name.</returns>
- internal override bool LookupState(string factoryName)
- {
- if (base.LookupState(factoryName))
- return true;
- foreach (State state in StateMachine.CreatedStates)
- {
- if (state.LookupState(factoryName))
- return true;
- }
- return false;
- }
- /// <summary>
- /// Internal dispose method.
- /// </summary>
- /// <param name="disposing"></param>
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (!disposed)
- {
- disposed = true;
- if (disposing)
- stateMachine.Dispose();
- }
- }
- finally
- {
- base.Dispose(disposing);
- }
- }
- #endregion
- #region Properties
- /// <summary>
- /// Returns the state machine that is used with the Composite state.
- /// </summary>
- public StateMachine StateMachine
- {
- get { return stateMachine; }
- }
- /// <summary>
- /// Set the parent state machine for the state.
- /// </summary>
- internal override void SetParentStateMachine(StateMachine parentStateMachine)
- {
- base.SetParentStateMachine(parentStateMachine);
- this.stateMachine.ParentStateMachine = parentStateMachine;
- }
- /// <summary>
- /// Set the debug logger for the composite state, and assign it on to the state machine.
- /// </summary>
- /// <param name="debugLogger"></param>
- /// <param name="logCategory"></param>
- internal override void SetDebugLogger(IDebugLogger debugLogger, object logCategory)
- {
- base.SetDebugLogger(debugLogger, logCategory);
- this.stateMachine.SetDebugLogger(debugLogger, logCategory);
- }
- public override string Name
- {
- get { return GetType().Namespace.Split('.').LastOrDefault() ?? base.Name; }
- }
- #endregion
- }
- }
|