Beispiel #1
0
        ///// <summary>
        ///// RunStateMachine is the heart of the engine that runs the finite state machine. It is executed in a
        ///// separate thread that is started when you <see cref="Start(FiniteState)"/> the state machine.
        ///// All events that have been queued by <see cref="RaiseEvent(FiniteStateEvent)"/>, are processed here.
        ///// The method runs in an infinite loop that only exits when <see cref="Stop()"/> is called.
        ///// When it has processed all of the events in the queue, it will sleep until it is pulsed
        ///// by either <see cref="RaiseEvent(FiniteStateEvent)"/> or <see cref="Stop()"/>
        ///// </summary>
        //public void RunStateMachine()
        //{
        //    string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
        //    if (log.IsDebugEnabled)
        //        log.Debug($"{methodName}: enter");
        //
        //    try
        //    {
        //        while (!stopRequested)
        //        {
        //            HandlePendingEvents();
        //            if (!stopRequested)
        //            {
        //                lock (locker)
        //                {
        //                    if (log.IsDebugEnabled)
        //                        log.Debug($"{methodName}: Putting to sleep the state machine thread.");
        //
        //                    Monitor.Wait(locker); // Nothing to do, so go to sleep until we are pulsed by RaiseEvent or Stop
        //
        //                    if (log.IsDebugEnabled)
        //                        log.Debug($"{methodName}: Just woke up :-)");
        //                }
        //            }
        //        }
        //    }
        //    catch(Exception e)
        //    {
        //        log.Error($"{e.Message}");
        //        //OnExceptionAction?.Invoke(e);
        //    }
        //    finally
        //    {
        //        if (log.IsDebugEnabled)
        //            log.Debug($"{methodName}: exit");
        //    }
        //}
        //

        /// <summary>
        /// This function is called during the first call to RaiseEvent() in Start() because at that point,
        /// we are not handling a previous event. From then on, every event handler raises an event.
        /// </summary>
        public void HandlePendingEvents()
        {
            string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;

            if (log.IsDebugEnabled)
            {
                log.Debug($"{methodName}: enter");
            }

            try
            {
                while (PendingEvents.Count > 0)
                {
                    if (log.IsDebugEnabled)
                    {
                        log.Debug($"{methodName}: PendingEvents.Count={PendingEvents.Count}");
                    }
                    FiniteStateEvent ev = null;
                    lock (PendingEvents)
                    {
                        ev = PendingEvents.Dequeue();
                    }
                    if (CurrentState.Transitions.TryGetValue(ev.Name, out FiniteStateTransition transition))
                    {
                        if (log.IsDebugEnabled)
                        {
                            log.Debug($"{methodName}: transition {CurrentState.Name} -> {ev.Name} ->{transition.ToState.Name}");
                        }
                        SetCurrentState(transition.ToState);
                        if (log.IsDebugEnabled)
                        {
                            log.Debug($"{methodName}: before invoke, PendingEvents.Count={PendingEvents.Count}");
                        }
                        CurrentState.OnEnterAction?.Invoke();
                        if (log.IsDebugEnabled)
                        {
                            log.Debug($"{methodName}: after invoke, PendingEvents.Count={PendingEvents.Count}");
                        }
                    }
                    else
                    {
                        throw new ArgumentException($"Failed to find a transition for event '{ev.Name}' from state '{CurrentState.Name}'.");
                    }
                }
            }
            finally
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug($"{methodName}: exit");
                }
            }
        }
Beispiel #2
0
 protected void Dequeue()
 {
     PendingEvents.Dequeue();
 }