/// <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."); } }
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); }