using System; using System.Collections.Generic; using System.Linq; namespace Wayne.Lib.StateEngine { public static class StateTransitionLookupAnalyze { #region Method: GetNextStateName /// /// /// /// /// /// /// /// /// public static string GetNextStateName(this StateMachine stateMachine, string sourceStateFactoryName, object transitionType, out HistoryType historyType, out bool fromAnyState) { if (sourceStateFactoryName != null && transitionType != null) { // Note: This routine should also work when stateMachine is null // (in this case: only look in the local lookupDictionary). foreach (StateMachine tempStateMachine in stateMachine.GetStateMachineHierarchy()) { StateLookupEntry entry; if (tempStateMachine.StateTransitionLookup.TryLookup(sourceStateFactoryName, transitionType, out entry)) { historyType = entry.HistoryType; fromAnyState = false; return entry.NextStateFactoryName; } if (tempStateMachine.StateTransitionLookup.TryLookup(AnyState.FactoryName, transitionType, out entry)) { historyType = entry.HistoryType; fromAnyState = true; return entry.NextStateFactoryName; } } } historyType = HistoryType.None; fromAnyState = false; return ""; } #endregion /// /// Returns a list of the source State names that is in the lookup table. /// /// /// Should the AnyStates be included? public static string[] GetSourceStateNameList(this StateTransitionLookup stateTransitionLookup, bool includeAnyStates) { IEnumerable result = stateTransitionLookup.LookupTable.Keys; if (!includeAnyStates) result = result.Where(x => x != AnyState.FactoryName); // If AnyState is included, remove it. return result.ToArray(); } /// /// /// /// /// public static IEnumerable GetStateMachineHierarchy(this StateMachine stateMachine) { StateMachine tempMachine = stateMachine; do { yield return tempMachine; tempMachine = tempMachine.ParentStateMachine; } while (tempMachine != null); } /// /// Returns a list of the AnyState-transition names (no duplicates). /// /// public static string[] GetAnyStateTransitionNameList(this StateMachine stateMachine) { return stateMachine.GetStateMachineHierarchy() .SelectMany(sm => sm.StateTransitionLookup .GetTransitionsForState(AnyState.FactoryName) .Keys .Select(t => Transition.GetTransitionName(t))) .Distinct() .ToArray(); } /// /// Returns a dictionary of the transitions from a state (dictionary key) to a state (dictionary value). /// /// /// /// /// public static Dictionary GetStateTransitionsDict(this StateMachine stateMachine, string sourceStateFactoryName, bool includeAnyStates) { return stateMachine.StateTransitionLookup.GetTransitionsForState(sourceStateFactoryName) .ToDictionary(x => Transition.GetTransitionName(x.Key), x => x.Value.NextStateFactoryName); } /// /// Gets a list of all transitions. /// /// /// Should the AnyState-transitions be included? /// public static TransitionInfo[] GetTransitionInfoArray(this StateMachine stateMachine, bool includeAnyStates) { return stateMachine.StateTransitionLookup.LookupTable .SelectMany(fromStatePair => fromStatePair.Value.Select(statePair => new TransitionInfo(fromStatePair.Key, Transition.GetTransitionName(statePair.Key), statePair.Value.NextStateFactoryName, statePair.Value.HistoryType))) .Where(x => includeAnyStates || x.FromStateFactoryName != AnyState.FactoryName) .ToArray(); } } }