Example #1
0
 /// <summary>
 /// This is the default handler if there was neither a transition handler nor an event handler
 /// defined. Overriding this method allows to establish a custom error handler or a default 
 /// event handler defining a default behavior.
 /// </summary>
 /// <param name="fsmEvent"></param>
 protected internal virtual void OnFsmEventDefault(FsmEvent fsmEvent)
 {
     // error: There exists neither a transition handler nor an event handler
     if ( classInfo.hasStates )
     {
         Trace.WriteLine("FSM:" + this.GetType().Name + " Event:" + fsmEvent.GetType().Name + " not handled in state:"
                 + Enum.GetName( classInfo.stateEnumType, GetCurrentState() ) );
     }
     else
     {
         Trace.WriteLine("FSM:" + this.GetType().Name + " Event:" + fsmEvent.GetType().Name + " not handled");
     }
 }
Example #2
0
 /// <summary>
 /// Send an event to this FSM. The event will be forwarded to the processor.
 /// It is not called directly but in the context of the processor thread.
 /// </summary>
 /// <param name="ev"></param>
 public void PushEvent( FsmEvent ev )
 {
     FsmProcessor.PushEvent( ev, this );
 }
Example #3
0
        /// <summary>
        /// This is the core event dispatching of the FSM. The FSM looks up the
        /// curent state and calls the state and transition handlers if they are 
        /// defined.
        /// Override is possible but not recommended.
        /// </summary>
        /// <param name="fsmEvent"></param>
        protected internal virtual void OnFsmEvent(FsmEvent fsmEvent)
        {
            Debug.Assert( classInfo != null );
            if ( classInfo.hasStates )
            {
                Int32 currState = GetCurrentState();
                // execute transition
                StateInfo stateInfo1 = classInfo.stateInfoArray[currState];
                Debug.Assert( stateInfo1 != null );
                MethodInfo methInfoTransition = (MethodInfo)stateInfo1.transitions[fsmEvent.GetType()];
                if ( methInfoTransition != null )
                {
                    // first execute exit method
                    if ( stateInfo1.exitMethod != null )
                    {
                        stateInfo1.exitMethod.Invoke(this, new Object[] {fsmEvent});
                        // it is not allowed to change state in State Exit Handler!
                        Debug.Assert( currState == GetCurrentState() );
                    }

                    // now execute transition method
                    methInfoTransition.Invoke(this, new Object[] {fsmEvent} );
                    // on return, FSM has probably a new state

                    int newState = GetCurrentState();
                    if ( newState != currState )
                    {
                        // Transition to other state
                        StateInfo stateInfo2 = classInfo.stateInfoArray[newState];
                        Debug.Assert( stateInfo2 != null );

                        // Execute Entry state handler of new state
                        if ( stateInfo2.entryMethod != null )
                        {
                            stateInfo2.entryMethod.Invoke(this, new Object[] {fsmEvent,
                                                 Enum.ToObject(classInfo.stateEnumType,currState)});
                            // it is not allowed to change state in State Entry Handler!
                            Debug.Assert( newState == GetCurrentState() );
                        }
                    }
                    else
                    { // It is the same state --> transition loop
                        if ( stateInfo1.entryMethod != null )
                        {
                            stateInfo1.entryMethod.Invoke(this, new Object[] {fsmEvent,
                                    Enum.ToObject(classInfo.stateEnumType,currState)});
                            // it is not allowed to change state in State Entry Handler!
                            Debug.Assert( currState == GetCurrentState() );
                        }
                    }
                }
                else
                {
                    // There is no transition for this event in current state.
                    if ( stateInfo1.defaultTransitionMethod != null )
                    {
                        stateInfo1.defaultTransitionMethod.Invoke(this, new Object[] {fsmEvent} );
                    }
                    else
                    {
                        // Try to find an event handler
                        MethodInfo methInfoEvHnd = (MethodInfo)classInfo.eventHandlers[fsmEvent.GetType()];
                        if ( methInfoEvHnd != null )
                        {
                            methInfoEvHnd.Invoke(this, new Object[] {fsmEvent} );
                        }
                        else
                        {
                            // Call default handler
                            OnFsmEventDefault(fsmEvent);
                        }
                    }
                }
            }
            else
            {
                // FSM has no states. Therefore event handlers are the only handlers to check.
                MethodInfo methodInfo = (MethodInfo)classInfo.eventHandlers[fsmEvent.GetType()];
                if ( methodInfo != null )
                {
                    methodInfo.Invoke(this, new Object[] {fsmEvent} );
                }
                else
                {
                    // error: No matching event handler available
                    Trace.WriteLine("FSM:" + this.GetType().Name + " Event:" + fsmEvent.GetType().Name + " no event handler found");
                }
            }
        }
 /// <summary>
 /// Push event on an FSM using this processor 
 /// </summary>
 /// <param name="fsmEvent">event to push</param>
 /// <param name="fsm">target FSM</param>
 public void PushEvent( FsmEvent fsmEvent, Fsm fsm )
 {
     lock(this)
     {
         fsmEvent.Fsm = fsm;
         jobQueue.Enqueue(fsmEvent);
         Monitor.Pulse(this);
     }
 }