StateTransitionLookupAnalyze.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace Wayne.Lib.StateEngine
  5. {
  6. public static class StateTransitionLookupAnalyze
  7. {
  8. #region Method: GetNextStateName
  9. /// <summary>
  10. ///
  11. /// </summary>
  12. /// <param name="stateMachine"></param>
  13. /// <param name="sourceStateFactoryName"></param>
  14. /// <param name="transitionType"></param>
  15. /// <param name="historyType"></param>
  16. /// <param name="fromAnyState"></param>
  17. /// <returns></returns>
  18. public static string GetNextStateName(this StateMachine stateMachine, string sourceStateFactoryName, object transitionType, out HistoryType historyType, out bool fromAnyState)
  19. {
  20. if (sourceStateFactoryName != null && transitionType != null)
  21. {
  22. // Note: This routine should also work when stateMachine is null
  23. // (in this case: only look in the local lookupDictionary).
  24. foreach (StateMachine tempStateMachine in stateMachine.GetStateMachineHierarchy())
  25. {
  26. StateLookupEntry entry;
  27. if (tempStateMachine.StateTransitionLookup.TryLookup(sourceStateFactoryName, transitionType, out entry))
  28. {
  29. historyType = entry.HistoryType;
  30. fromAnyState = false;
  31. return entry.NextStateFactoryName;
  32. }
  33. if (tempStateMachine.StateTransitionLookup.TryLookup(AnyState.FactoryName, transitionType, out entry))
  34. {
  35. historyType = entry.HistoryType;
  36. fromAnyState = true;
  37. return entry.NextStateFactoryName;
  38. }
  39. }
  40. }
  41. historyType = HistoryType.None;
  42. fromAnyState = false;
  43. return "";
  44. }
  45. #endregion
  46. /// <summary>
  47. /// Returns a list of the source State names that is in the lookup table.
  48. /// </summary>
  49. /// <param name="stateTransitionLookup"></param>
  50. /// <param name="includeAnyStates">Should the AnyStates be included?</param>
  51. public static string[] GetSourceStateNameList(this StateTransitionLookup stateTransitionLookup, bool includeAnyStates)
  52. {
  53. IEnumerable<string> result = stateTransitionLookup.LookupTable.Keys;
  54. if (!includeAnyStates)
  55. result = result.Where(x => x != AnyState.FactoryName); // If AnyState is included, remove it.
  56. return result.ToArray();
  57. }
  58. /// <summary>
  59. ///
  60. /// </summary>
  61. /// <param name="stateMachine"></param>
  62. /// <returns></returns>
  63. public static IEnumerable<StateMachine> GetStateMachineHierarchy(this StateMachine stateMachine)
  64. {
  65. StateMachine tempMachine = stateMachine;
  66. do
  67. {
  68. yield return tempMachine;
  69. tempMachine = tempMachine.ParentStateMachine;
  70. } while (tempMachine != null);
  71. }
  72. /// <summary>
  73. /// Returns a list of the AnyState-transition names (no duplicates).
  74. /// </summary>
  75. /// <returns></returns>
  76. public static string[] GetAnyStateTransitionNameList(this StateMachine stateMachine)
  77. {
  78. return stateMachine.GetStateMachineHierarchy()
  79. .SelectMany(sm => sm.StateTransitionLookup
  80. .GetTransitionsForState(AnyState.FactoryName)
  81. .Keys
  82. .Select(t => Transition.GetTransitionName(t)))
  83. .Distinct()
  84. .ToArray();
  85. }
  86. /// <summary>
  87. /// Returns a dictionary of the transitions from a state (dictionary key) to a state (dictionary value).
  88. /// </summary>
  89. /// <param name="stateMachine"></param>
  90. /// <param name="sourceStateFactoryName"></param>
  91. /// <param name="includeAnyStates"></param>
  92. /// <returns></returns>
  93. public static Dictionary<string, string> GetStateTransitionsDict(this StateMachine stateMachine, string sourceStateFactoryName, bool includeAnyStates)
  94. {
  95. return stateMachine.StateTransitionLookup.GetTransitionsForState(sourceStateFactoryName)
  96. .ToDictionary(x => Transition.GetTransitionName(x.Key), x => x.Value.NextStateFactoryName);
  97. }
  98. /// <summary>
  99. /// Gets a list of all transitions.
  100. /// </summary>
  101. /// <param name="stateMachine"></param>
  102. /// <param name="includeAnyStates">Should the AnyState-transitions be included?</param>
  103. /// <returns></returns>
  104. public static TransitionInfo[] GetTransitionInfoArray(this StateMachine stateMachine, bool includeAnyStates)
  105. {
  106. return stateMachine.StateTransitionLookup.LookupTable
  107. .SelectMany(fromStatePair => fromStatePair.Value.Select(statePair =>
  108. new TransitionInfo(fromStatePair.Key,
  109. Transition.GetTransitionName(statePair.Key),
  110. statePair.Value.NextStateFactoryName,
  111. statePair.Value.HistoryType)))
  112. .Where(x => includeAnyStates || x.FromStateFactoryName != AnyState.FactoryName)
  113. .ToArray();
  114. }
  115. }
  116. }