private void TransitionDownToTargetState( QState targetState, ArrayList statesTargetToLCA, int indexFirstStateToEnter, TransitionChainRecorder recorder) { // we enter the states in the passed in array in reverse order for (int stateIndex = indexFirstStateToEnter; stateIndex >= 0; stateIndex--) { Trigger((QState)statesTargetToLCA[stateIndex], QSignals.Entry, recorder); } m_MyState = targetState; // At last we are ready to initialize the target state. // If the specified target state handles init then the effective // target state is deeper than the target state specified in // the transition. while (Trigger(targetState, QSignals.Init, recorder) == null) { // Initial transition must be one level deep Debug.Assert(targetState == GetSuperState(m_MyState)); targetState = m_MyState; Trigger(targetState, QSignals.Entry, recorder); } if (recorder != null) { // We always make sure that the last entry in the recorder represents the entry to the target state. EnsureLastTransistionStepIsEntryIntoTargetState(targetState, recorder); Debug.Assert(recorder.GetRecordedTransitionChain().Length > 0); } }
private void TransitionToSynchronized(QState targetState, ref TransitionChain transitionChain) { //The entire method had been embedded within [MethodImpl(MethodImplOptions.Synchronized)], //which is not available in .NET Core, and so a lock is used instead... lock (this) { if (transitionChain != null) { // We encountered a race condition. The first (non-synchronized) check indicated that the transition chain // is null. However, a second threat beat us in getting into this synchronized method and populated // the transition chain in the meantime. We can execute the regular method again now. TransitionTo(targetState, ref transitionChain); } else { // The transition chain is not initialized yet, we need to dynamically retrieve // the required transition steps and record them so that we can subsequently simply // play them back. TransitionChainRecorder recorder = new TransitionChainRecorder(); TransitionFromSourceToTarget(targetState.GetMethodInfo(), recorder); // We pass the recorded transition steps back to the caller: transitionChain = recorder.GetRecordedTransitionChain(); } } }
private void EnsureLastTransistionStepIsEntryIntoTargetState( QState targetState, TransitionChainRecorder recorder) { if (recorder.GetRecordedTransitionChain().Length == 0) { // Nothing recorded so far RecordEntryIntoTargetState(targetState, recorder); return; } else { // We need to test whether the last recorded transition step is the entry into the target state TransitionChain transitionChain = recorder.GetRecordedTransitionChain(); TransitionStep lastTransitionStep = transitionChain[transitionChain.Length - 1]; if (lastTransitionStep.State != targetState || lastTransitionStep.QSignal != QSignals.Entry) { RecordEntryIntoTargetState(targetState, recorder); return; } } }
private void TransitionToSynchronized(QState targetState, ref TransitionChain transitionChain) { if (transitionChain != null) { // We encountered a race condition. The first (non-synchronized) check indicated that the transition chain // is null. However, a second threat beat us in getting into this synchronized method and populated // the transition chain in the meantime. We can execute the regular method again now. TransitionTo(targetState, ref transitionChain); } else { // The transition chain is not initialized yet, we need to dynamically retrieve // the required transition steps and record them so that we can subsequently simply // play them back. TransitionChainRecorder recorder = new TransitionChainRecorder(); TransitionFromSourceToTarget(targetState, recorder); // We pass the recorded transition steps back to the caller: transitionChain = recorder.GetRecordedTransitionChain(); } }
private void TransitionToSynchronized(QState targetState, ref TransitionChain transitionChain) { if (transitionChain != null) { // We encountered a race condition. The first (non-synchronized) check indicated that the transition chain // is null. However, a second threat beat us in getting into this synchronized method and populated // the transition chain in the meantime. We can execute the regular method again now. TransitionTo(targetState, ref transitionChain); } else { // The transition chain is not initialized yet, we need to dynamically retrieve // the required transition steps and record them so that we can subsequently simply // play them back. TransitionChainRecorder recorder = new TransitionChainRecorder(); TransitionFromSourceToTarget(targetState.Method, recorder); // We pass the recorded transition steps back to the caller: transitionChain = recorder.GetRecordedTransitionChain(); } }
private void TransitionDownToTargetState( MethodInfo targetStateMethod, ArrayList statesTargetToLCA, int indexFirstStateToEnter, TransitionChainRecorder recorder) { // we enter the states in the passed in array in reverse order for (int stateIndex = indexFirstStateToEnter; stateIndex >= 0; stateIndex--) { Trigger((MethodInfo)statesTargetToLCA[stateIndex], QSignals.Entry, recorder); } m_MyStateMethod = targetStateMethod; // At last we are ready to initialize the target state. // If the specified target state handles init then the effective // target state is deeper than the target state specified in // the transition. while (Trigger(targetStateMethod, QSignals.Init, recorder) == null) { // Initial transition must be one level deep Debug.Assert(targetStateMethod == GetSuperStateMethod(m_MyStateMethod)); targetStateMethod = m_MyStateMethod; Trigger(targetStateMethod, QSignals.Entry, recorder); } if (recorder != null) { // We always make sure that the last entry in the recorder represents the entry to the target state. EnsureLastTransistionStepIsEntryIntoTargetState(targetStateMethod, recorder); Debug.Assert(recorder.GetRecordedTransitionChain().Length > 0); } }
private void EnsureLastTransistionStepIsEntryIntoTargetState( MethodInfo targetStateMethod, TransitionChainRecorder recorder) { if (recorder.GetRecordedTransitionChain().Length == 0) { // Nothing recorded so far RecordEntryIntoTargetState(targetStateMethod, recorder); return; } else { // We need to test whether the last recorded transition step is the entry into the target state TransitionChain transitionChain = recorder.GetRecordedTransitionChain(); TransitionStep lastTransitionStep = transitionChain[transitionChain.Length - 1]; if (lastTransitionStep.StateMethod != targetStateMethod || lastTransitionStep.QSignal != QSignals.Entry) { RecordEntryIntoTargetState(targetStateMethod, recorder); return; } } }