/// <summary>
        /// Restore the state of this state machine from a previously-created string (from calling the <see cref="Serialize()"/> method).
        /// </summary>
        /// <param name="serialized">String created by <see cref="Serialize()"/></param>
        public void Deserialize(string serialized)
        {
            this.Reset();

            var childState         = this.serializer.Deserialize(this, serialized);
            var intermediateStates = new List <TState>();

            for (TState state = childState; state != null; state = state.ParentStateMachine.ParentState)
            {
                intermediateStates.Add(state);
            }

            ChildStateMachine <TState> stateMachine = this;

            foreach (var state in intermediateStates.AsEnumerable().Reverse())
            {
                // We should never hit this
                Trace.Assert(stateMachine != null, $"Unable to deserialize from \"{serialized}\": the previous state has no child state machine. This should not happen");

                // This will throw if the state doesn't belong to the state machine
                stateMachine.SetCurrentState(state);

                stateMachine = state.ChildStateMachine;
            }

            // Did we run out of identifiers?
            // We need to check this to avoid internal inconsistency
            if (stateMachine != null)
            {
                throw new StateMachineSerializationException($"Unable to deserialize from \"{serialized}\": a parent state has the child state machine {stateMachine}, but no information is present in the serialized string saying what its state should be. Make sure you're deserializing into exactly the same state machine as created the serialized string.");
            }
        }
Esempio n. 2
0
 internal void Initialize(string name, ChildStateMachine <TState> parentStateMachine)
 {
     this.isInitialized = true;
     // If they've subclassed this and set Name themselves, then provided 'null' in CreateState,
     // don't override what they set
     if (!String.IsNullOrWhiteSpace(name))
     {
         this.Name = name;
     }
     this.ParentStateMachine = parentStateMachine;
 }
        private void EnterChildStateMachine(ChildStateMachine <TState> childStateMachine, TState from, IEvent @event, bool isInnerTransition, object eventData, EventFireMethod eventFireMethod)
        {
            childStateMachine.SetCurrentState(childStateMachine.InitialState);

            this.EnterState(new StateHandlerInfo <TState>(from, childStateMachine.InitialState, @event, isInnerTransition, eventData, eventFireMethod));

            if (childStateMachine.InitialState.ChildStateMachine != null)
            {
                this.EnterChildStateMachine(childStateMachine.InitialState.ChildStateMachine, from, @event, isInnerTransition, eventData, eventFireMethod);
            }
        }
        private void ExitChildStateMachine(ChildStateMachine <TState> childStateMachine, TState to, IEvent @event, bool isInnerTransition, object eventData, EventFireMethod eventFireMethod)
        {
            if (childStateMachine.CurrentState != null && childStateMachine.CurrentState.ChildStateMachine != null)
            {
                this.ExitChildStateMachine(childStateMachine.CurrentState.ChildStateMachine, to, @event, isInnerTransition, eventData, eventFireMethod);
            }

            this.ExitState(new StateHandlerInfo <TState>(childStateMachine.CurrentState, to, @event, isInnerTransition, eventData, eventFireMethod));

            childStateMachine.SetCurrentState(null);
        }
Esempio n. 5
0
        private static IEnumerable <TState> StateIterator(ChildStateMachine <TState> stateMachine)
        {
            // Depth-first recursive iteration of all states

            // State machine is not fully initialised
            if (stateMachine.InitialState == null)
            {
                throw new StateMachineSerializationException($"Unable to serialize state machine {stateMachine} as it is not fully initialised (it has no initial state).");
            }

            foreach (var state in stateMachine.States)
            {
                yield return(state);

                if (state.ChildStateMachine != null)
                {
                    foreach (var subState in StateIterator(state.ChildStateMachine))
                    {
                        yield return(subState);
                    }
                }
            }
        }
Esempio n. 6
0
 internal State(string name, ChildStateMachine parentStateMachine)
 {
     this.ParentStateMachine = parentStateMachine;
     this.innerState         = new StateInner <State>(name, parentStateMachine.InnerStateMachine.Kernel);
 }
Esempio n. 7
0
 internal State(string name, TStateData data, ChildStateMachine <TStateData> parentStateMachine)
 {
     this.Data = data;
     this.ParentStateMachine = parentStateMachine;
     this.innerState         = new StateInner <State <TStateData> >(name, parentStateMachine.InnerStateMachine.Kernel);
 }