diff --git a/src/FsmUtil.cs b/src/FsmUtil.cs index 3d4215e..db65e0e 100644 --- a/src/FsmUtil.cs +++ b/src/FsmUtil.cs @@ -115,6 +115,35 @@ private static TVal[] GetItemsFromArray(TVal[] origArray, Func [PublicAPI] public static FsmState? GetState(this Fsm fsm, string stateName) => GetItemFromArray(fsm.States, x => x.Name == stateName); + /// + /// Gets a state in a PlayMakerFSM, throwing an exception if it is not found. + /// + /// The fsm + /// The name of the state + /// The found state. + [PublicAPI] + public static FsmState MustGetState(this PlayMakerFSM fsm, string stateName) + { + var s = fsm.GetState(stateName); + if (s == null) + { + throw new InvalidOperationException($"State {stateName} not found in FSM {fsm.FsmName}"); + } + return s; + } + + /// + [PublicAPI] + public static FsmState MustGetState(this Fsm fsm, string stateName) + { + var s = fsm.GetState(stateName); + if (s == null) + { + throw new InvalidOperationException($"State {stateName} not found in FSM {fsm.Name}"); + } + return s; + } + /// /// Gets a transition in a PlayMakerFSM. /// @@ -123,11 +152,11 @@ private static TVal[] GetItemsFromArray(TVal[] origArray, Func /// The name of the event /// The found transition, null if none are found [PublicAPI] - public static FsmTransition? GetTransition(this PlayMakerFSM fsm, string stateName, string eventName) => fsm.GetState(stateName)!.GetTransition(eventName); + public static FsmTransition? GetTransition(this PlayMakerFSM fsm, string stateName, string eventName) => fsm.MustGetState(stateName).GetTransition(eventName); /// [PublicAPI] - public static FsmTransition? GetTransition(this Fsm fsm, string stateName, string eventName) => fsm.GetState(stateName)!.GetTransition(eventName); + public static FsmTransition? GetTransition(this Fsm fsm, string stateName, string eventName) => fsm.MustGetState(stateName).GetTransition(eventName); /// /// The state @@ -157,11 +186,11 @@ private static TVal[] GetItemsFromArray(TVal[] origArray, Func /// The index of the action /// The action, null if it can't be found [PublicAPI] - public static TAction? GetAction(this PlayMakerFSM fsm, string stateName, int index) where TAction : FsmStateAction => fsm.GetState(stateName)!.GetAction(index); + public static TAction? GetAction(this PlayMakerFSM fsm, string stateName, int index) where TAction : FsmStateAction => fsm.MustGetState(stateName).GetAction(index); /// [PublicAPI] - public static TAction? GetAction(this Fsm fsm, string stateName, int index) where TAction : FsmStateAction => fsm.GetState(stateName)!.GetAction(index); + public static TAction? GetAction(this Fsm fsm, string stateName, int index) where TAction : FsmStateAction => fsm.MustGetState(stateName).GetAction(index); /// /// The state @@ -171,11 +200,11 @@ private static TVal[] GetItemsFromArray(TVal[] origArray, Func /// [PublicAPI] - public static FsmStateAction? GetStateAction(this PlayMakerFSM fsm, string stateName, int index) => fsm.GetState(stateName)!.GetStateAction(index); + public static FsmStateAction? GetStateAction(this PlayMakerFSM fsm, string stateName, int index) => fsm.MustGetState(stateName).GetStateAction(index); /// [PublicAPI] - public static FsmStateAction? GetStateAction(this Fsm fsm, string stateName, int index) => fsm.GetState(stateName)!.GetStateAction(index); + public static FsmStateAction? GetStateAction(this Fsm fsm, string stateName, int index) => fsm.MustGetState(stateName).GetStateAction(index); /// [PublicAPI] @@ -189,11 +218,11 @@ private static TVal[] GetItemsFromArray(TVal[] origArray, Func /// The name of the state /// An array of actions [PublicAPI] - public static TAction[] GetActionsOfType(this PlayMakerFSM fsm, string stateName) where TAction : FsmStateAction => fsm.GetState(stateName)!.GetActionsOfType(); + public static TAction[] GetActionsOfType(this PlayMakerFSM fsm, string stateName) where TAction : FsmStateAction => fsm.MustGetState(stateName).GetActionsOfType(); /// [PublicAPI] - public static TAction[] GetActionsOfType(this Fsm fsm, string stateName) where TAction : FsmStateAction => fsm.GetState(stateName)!.GetActionsOfType(); + public static TAction[] GetActionsOfType(this Fsm fsm, string stateName) where TAction : FsmStateAction => fsm.MustGetState(stateName).GetActionsOfType(); /// /// The state @@ -207,26 +236,18 @@ private static TVal[] GetItemsFromArray(TVal[] origArray, Func /// The fsm /// The name of the state to get the actions from [PublicAPI] - public static TAction? GetFirstActionOfType(this PlayMakerFSM fsm, string stateName) where TAction : FsmStateAction => fsm.GetState(stateName)!.GetFirstActionOfType(); + public static TAction? GetFirstActionOfType(this PlayMakerFSM fsm, string stateName) where TAction : FsmStateAction => fsm.MustGetState(stateName).GetFirstActionOfType(); /// [PublicAPI] - public static TAction? GetFirstActionOfType(this Fsm fsm, string stateName) where TAction : FsmStateAction => fsm.GetState(stateName)!.GetFirstActionOfType(); + public static TAction? GetFirstActionOfType(this Fsm fsm, string stateName) where TAction : FsmStateAction => fsm.MustGetState(stateName).GetFirstActionOfType(); /// /// The fsm state [PublicAPI] public static TAction? GetFirstActionOfType(this FsmState state) where TAction : FsmStateAction { - int firstActionIndex = -1; - for (int i = 0; i < state.Actions.Length; i++) - { - if (state.Actions[i] is TAction) - { - firstActionIndex = i; - break; - } - } + int firstActionIndex = state.IndexFirstActionOfType(); if (firstActionIndex == -1) return null; @@ -240,26 +261,18 @@ private static TVal[] GetItemsFromArray(TVal[] origArray, Func /// The fsm /// The name of the state to get the actions from [PublicAPI] - public static TAction? GetLastActionOfType(this PlayMakerFSM fsm, string stateName) where TAction : FsmStateAction => fsm.GetState(stateName)!.GetLastActionOfType(); + public static TAction? GetLastActionOfType(this PlayMakerFSM fsm, string stateName) where TAction : FsmStateAction => fsm.MustGetState(stateName).GetLastActionOfType(); /// [PublicAPI] - public static TAction? GetLastActionOfType(this Fsm fsm, string stateName) where TAction : FsmStateAction => fsm.GetState(stateName)!.GetLastActionOfType(); + public static TAction? GetLastActionOfType(this Fsm fsm, string stateName) where TAction : FsmStateAction => fsm.MustGetState(stateName).GetLastActionOfType(); /// /// The fsm state [PublicAPI] public static TAction? GetLastActionOfType(this FsmState state) where TAction : FsmStateAction { - int lastActionIndex = -1; - for (int i = state.Actions.Length - 1; i >= 0; i--) - { - if (state.Actions[i] is TAction) - { - lastActionIndex = i; - break; - } - } + int lastActionIndex = state.IndexLastActionOfType(); if (lastActionIndex == -1) return null; @@ -268,6 +281,70 @@ private static TVal[] GetItemsFromArray(TVal[] origArray, Func #endregion Get + #region Index + + /// + /// Finds the index of the first action in a state that matches the predicate. + /// + /// The state + /// The predicate that each action is matched against + /// The index of the matched action, or -1 if it was not found. + [PublicAPI] + public static int IndexFirstActionMatching(this FsmState state, Func predicate) + { + int n = state.actions.Length; + for (int i = 0; i < n; i++) + { + if (predicate(state.actions[i])) + { + return i; + } + } + return -1; + } + + /// + /// Finds the index of the last action in a state that matches the predicate. + /// + /// The state + /// The predicate that each action is matched against + /// The index of the matched action, or -1 if it was not found. + [PublicAPI] + public static int IndexLastActionMatching(this FsmState state, Func predicate) + { + int n = state.actions.Length; + for (int i = n - 1; i >= 0; i--) + { + if (predicate(state.actions[i])) + { + return i; + } + } + return -1; + } + + /// + /// Finds the index of the first action in a state that is of type . + /// + /// The state + /// The type of action to look for + /// The index of the found action, or -1 if it was not found. + [PublicAPI] + public static int IndexFirstActionOfType(this FsmState state) + => state.IndexFirstActionMatching(act => act is T); + + /// + /// Finds the index of the last action in a state that is of type . + /// + /// The state + /// The type of action to look for + /// The index of the found action, or -1 if it was not found. + [PublicAPI] + public static int IndexLastActionOfType(this FsmState state) + => state.IndexLastActionMatching(act => act is T); + + #endregion Index + #region Add private static TVal[] AddItemToArray(TVal[] origArray, TVal value) @@ -348,11 +425,11 @@ public static FsmState CopyState(this Fsm fsm, string fromState, string toState) /// The name of the new state /// The event of the transition [PublicAPI] - public static FsmEvent AddTransition(this PlayMakerFSM fsm, string stateName, string eventName, string toState) => fsm.GetState(stateName)!.AddTransition(eventName, toState); + public static FsmEvent AddTransition(this PlayMakerFSM fsm, string stateName, string eventName, string toState) => fsm.MustGetState(stateName).AddTransition(eventName, toState); /// [PublicAPI] - public static FsmEvent AddTransition(this Fsm fsm, string stateName, string eventName, string toState) => fsm.GetState(stateName)!.AddTransition(eventName, toState); + public static FsmEvent AddTransition(this Fsm fsm, string stateName, string eventName, string toState) => fsm.MustGetState(stateName).AddTransition(eventName, toState); /// /// The state from which the transition starts @@ -404,11 +481,11 @@ public static FsmEvent AddGlobalTransition(this Fsm fsm, string globalEventName, /// The name of the state in which the action is added /// The action [PublicAPI] - public static void AddAction(this PlayMakerFSM fsm, string stateName, FsmStateAction action) => fsm.GetState(stateName)!.AddAction(action); + public static void AddAction(this PlayMakerFSM fsm, string stateName, FsmStateAction action) => fsm.MustGetState(stateName).AddAction(action); /// [PublicAPI] - public static void AddAction(this Fsm fsm, string stateName, FsmStateAction action) => fsm.GetState(stateName)!.AddAction(action); + public static void AddAction(this Fsm fsm, string stateName, FsmStateAction action) => fsm.MustGetState(stateName).AddAction(action); /// /// The fsm state @@ -428,11 +505,11 @@ public static void AddAction(this FsmState state, FsmStateAction action) /// The name of the state in which the action is added /// The actions [PublicAPI] - public static void AddActions(this PlayMakerFSM fsm, string stateName, params FsmStateAction[] actions) => fsm.GetState(stateName)!.AddActions(actions); + public static void AddActions(this PlayMakerFSM fsm, string stateName, params FsmStateAction[] actions) => fsm.MustGetState(stateName).AddActions(actions); /// [PublicAPI] - public static void AddActions(this Fsm fsm, string stateName, params FsmStateAction[] actions) => fsm.GetState(stateName)!.AddActions(actions); + public static void AddActions(this Fsm fsm, string stateName, params FsmStateAction[] actions) => fsm.MustGetState(stateName).AddActions(actions); /// /// The fsm state @@ -453,11 +530,11 @@ public static void AddActions(this FsmState state, params FsmStateAction[] actio /// The name of the state in which the method is added /// The method that will be invoked with the action as the parameter [PublicAPI] - public static void AddMethod(this PlayMakerFSM fsm, string stateName, Action method) => fsm.GetState(stateName)!.AddMethod(method); + public static void AddMethod(this PlayMakerFSM fsm, string stateName, Action method) => fsm.MustGetState(stateName).AddMethod(method); /// [PublicAPI] - public static void AddMethod(this Fsm fsm, string stateName, Action method) => fsm.GetState(stateName)!.AddMethod(method); + public static void AddMethod(this Fsm fsm, string stateName, Action method) => fsm.MustGetState(stateName).AddMethod(method); /// /// The fsm state @@ -478,11 +555,11 @@ public static void AddMethod(this FsmState state, Action method) /// The method that will be invoked /// If true, execute the function repeatedly on every update frame [PublicAPI] - public static void AddMethod(this PlayMakerFSM fsm, string stateName, Action method, bool everyFrame = false) => fsm.GetState(stateName)!.AddMethod(method, everyFrame); + public static void AddMethod(this PlayMakerFSM fsm, string stateName, Action method, bool everyFrame = false) => fsm.MustGetState(stateName).AddMethod(method, everyFrame); /// [PublicAPI] - public static void AddMethod(this Fsm fsm, string stateName, Action method, bool everyFrame = false) => fsm.GetState(stateName)!.AddMethod(method, everyFrame); + public static void AddMethod(this Fsm fsm, string stateName, Action method, bool everyFrame = false) => fsm.MustGetState(stateName).AddMethod(method, everyFrame); /// /// The fsm state @@ -491,10 +568,10 @@ public static void AddMethod(this FsmState state, Action method) [PublicAPI] public static void AddMethod(this FsmState state, Action method, bool everyFrame = false) { - LambdaAction action = new() + LambdaAction action = new() { Method = method, - EveryFrame = everyFrame, + EveryFrame = everyFrame, }; state.AddAction(action); } @@ -506,11 +583,11 @@ public static void AddMethod(this FsmState state, Action method, bool everyFrame /// The name of the state in which the method is added /// The method that will be invoked with the finish action as the parameter [PublicAPI] - public static void AddLambdaMethod(this PlayMakerFSM fsm, string stateName, Action method) => fsm.GetState(stateName)!.AddLambdaMethod(method); + public static void AddLambdaMethod(this PlayMakerFSM fsm, string stateName, Action method) => fsm.MustGetState(stateName).AddLambdaMethod(method); /// [PublicAPI] - public static void AddLambdaMethod(this Fsm fsm, string stateName, Action method) => fsm.GetState(stateName)!.AddLambdaMethod(method); + public static void AddLambdaMethod(this Fsm fsm, string stateName, Action method) => fsm.MustGetState(stateName).AddLambdaMethod(method); /// /// The fsm state @@ -558,19 +635,19 @@ private static TVal[] InsertItemIntoArray(TVal[] origArray, TVal value, in /// The index to place the action in /// bool that indicates whether the insertion was successful [PublicAPI] - public static void InsertAction(this PlayMakerFSM fsm, string stateName, FsmStateAction action, int index) => fsm.GetState(stateName)!.InsertAction(index, action); + public static void InsertAction(this PlayMakerFSM fsm, string stateName, FsmStateAction action, int index) => fsm.MustGetState(stateName).InsertAction(index, action); /// [PublicAPI] - public static void InsertAction(this PlayMakerFSM fsm, string stateName, int index, FsmStateAction action) => fsm.GetState(stateName)!.InsertAction(index, action); + public static void InsertAction(this PlayMakerFSM fsm, string stateName, int index, FsmStateAction action) => fsm.MustGetState(stateName).InsertAction(index, action); /// [PublicAPI] - public static void InsertAction(this Fsm fsm, string stateName, FsmStateAction action, int index) => fsm.GetState(stateName)!.InsertAction(index, action); + public static void InsertAction(this Fsm fsm, string stateName, FsmStateAction action, int index) => fsm.MustGetState(stateName).InsertAction(index, action); /// [PublicAPI] - public static void InsertAction(this Fsm fsm, string stateName, int index, FsmStateAction action) => fsm.GetState(stateName)!.InsertAction(index, action); + public static void InsertAction(this Fsm fsm, string stateName, int index, FsmStateAction action) => fsm.MustGetState(stateName).InsertAction(index, action); /// /// The fsm state @@ -598,11 +675,11 @@ public static void InsertAction(this FsmState state, int index, FsmStateAction a /// The index to place the actions in /// bool that indicates whether the insertion was successful [PublicAPI] - public static void InsertActions(this PlayMakerFSM fsm, string stateName, int index, params FsmStateAction[] actions) => fsm.GetState(stateName)!.InsertActions(index, actions); + public static void InsertActions(this PlayMakerFSM fsm, string stateName, int index, params FsmStateAction[] actions) => fsm.MustGetState(stateName).InsertActions(index, actions); /// [PublicAPI] - public static void InsertActions(this Fsm fsm, string stateName, int index, params FsmStateAction[] actions) => fsm.GetState(stateName)!.InsertActions(index, actions); + public static void InsertActions(this Fsm fsm, string stateName, int index, params FsmStateAction[] actions) => fsm.MustGetState(stateName).InsertActions(index, actions); /// /// The fsm state @@ -628,19 +705,19 @@ public static void InsertActions(this FsmState state, int index, params FsmState /// The index to place the action in /// bool that indicates whether the insertion was successful [PublicAPI] - public static void InsertMethod(this PlayMakerFSM fsm, string stateName, Action method, int index) => fsm.GetState(stateName)!.InsertMethod(index, method); + public static void InsertMethod(this PlayMakerFSM fsm, string stateName, Action method, int index) => fsm.MustGetState(stateName).InsertMethod(index, method); /// [PublicAPI] - public static void InsertMethod(this PlayMakerFSM fsm, string stateName, int index, Action method) => fsm.GetState(stateName)!.InsertMethod(index, method); + public static void InsertMethod(this PlayMakerFSM fsm, string stateName, int index, Action method) => fsm.MustGetState(stateName).InsertMethod(index, method); /// [PublicAPI] - public static void InsertMethod(this Fsm fsm, string stateName, Action method, int index) => fsm.GetState(stateName)!.InsertMethod(index, method); + public static void InsertMethod(this Fsm fsm, string stateName, Action method, int index) => fsm.MustGetState(stateName).InsertMethod(index, method); /// [PublicAPI] - public static void InsertMethod(this Fsm fsm, string stateName, int index, Action method) => fsm.GetState(stateName)!.InsertMethod(index, method); + public static void InsertMethod(this Fsm fsm, string stateName, int index, Action method) => fsm.MustGetState(stateName).InsertMethod(index, method); /// /// The fsm state @@ -669,19 +746,19 @@ public static void InsertMethod(this FsmState state, int index, ActionWhether to execute 'method' on every update frame /// bool that indicates whether the insertion was successful [PublicAPI] - public static void InsertMethod(this PlayMakerFSM fsm, string stateName, Action method, int index, bool everyFrame = false) => fsm.GetState(stateName)!.InsertMethod(index, method, everyFrame); + public static void InsertMethod(this PlayMakerFSM fsm, string stateName, Action method, int index, bool everyFrame = false) => fsm.MustGetState(stateName).InsertMethod(index, method, everyFrame); /// [PublicAPI] - public static void InsertMethod(this PlayMakerFSM fsm, string stateName, int index, Action method, bool everyFrame = false) => fsm.GetState(stateName)!.InsertMethod(index, method, everyFrame); + public static void InsertMethod(this PlayMakerFSM fsm, string stateName, int index, Action method, bool everyFrame = false) => fsm.MustGetState(stateName).InsertMethod(index, method, everyFrame); /// [PublicAPI] - public static void InsertMethod(this Fsm fsm, string stateName, Action method, int index, bool everyFrame = false) => fsm.GetState(stateName)!.InsertMethod(index, method, everyFrame); + public static void InsertMethod(this Fsm fsm, string stateName, Action method, int index, bool everyFrame = false) => fsm.MustGetState(stateName).InsertMethod(index, method, everyFrame); /// [PublicAPI] - public static void InsertMethod(this Fsm fsm, string stateName, int index, Action method, bool everyFrame = false) => fsm.GetState(stateName)!.InsertMethod(index, method, everyFrame); + public static void InsertMethod(this Fsm fsm, string stateName, int index, Action method, bool everyFrame = false) => fsm.MustGetState(stateName).InsertMethod(index, method, everyFrame); /// /// The fsm state @@ -713,19 +790,19 @@ public static void InsertMethod(this FsmState state, int index, Action method, b /// The index to place the action in /// bool that indicates whether the insertion was successful [PublicAPI] - public static void InsertLambdaMethod(this PlayMakerFSM fsm, string stateName, Action method, int index) => fsm.GetState(stateName)!.InsertLambdaMethod(index, method); + public static void InsertLambdaMethod(this PlayMakerFSM fsm, string stateName, Action method, int index) => fsm.MustGetState(stateName).InsertLambdaMethod(index, method); /// [PublicAPI] - public static void InsertLambdaMethod(this PlayMakerFSM fsm, string stateName, int index, Action method) => fsm.GetState(stateName)!.InsertLambdaMethod(index, method); + public static void InsertLambdaMethod(this PlayMakerFSM fsm, string stateName, int index, Action method) => fsm.MustGetState(stateName).InsertLambdaMethod(index, method); /// [PublicAPI] - public static void InsertLambdaMethod(this Fsm fsm, string stateName, Action method, int index) => fsm.GetState(stateName)!.InsertLambdaMethod(index, method); + public static void InsertLambdaMethod(this Fsm fsm, string stateName, Action method, int index) => fsm.MustGetState(stateName).InsertLambdaMethod(index, method); /// [PublicAPI] - public static void InsertLambdaMethod(this Fsm fsm, string stateName, int index, Action method) => fsm.GetState(stateName)!.InsertLambdaMethod(index, method); + public static void InsertLambdaMethod(this Fsm fsm, string stateName, int index, Action method) => fsm.MustGetState(stateName).InsertLambdaMethod(index, method); /// /// The fsm state @@ -859,19 +936,19 @@ public static void InsertActionAfter(this FsmStateAction action, FsmStateAction /// The action /// The index of the action [PublicAPI] - public static void ReplaceAction(this PlayMakerFSM fsm, string stateName, FsmStateAction action, int index) => fsm.GetState(stateName)!.ReplaceAction(index, action); + public static void ReplaceAction(this PlayMakerFSM fsm, string stateName, FsmStateAction action, int index) => fsm.MustGetState(stateName).ReplaceAction(index, action); /// [PublicAPI] - public static void ReplaceAction(this PlayMakerFSM fsm, string stateName, int index, FsmStateAction action) => fsm.GetState(stateName)!.ReplaceAction(index, action); + public static void ReplaceAction(this PlayMakerFSM fsm, string stateName, int index, FsmStateAction action) => fsm.MustGetState(stateName).ReplaceAction(index, action); /// [PublicAPI] - public static void ReplaceAction(this Fsm fsm, string stateName, FsmStateAction action, int index) => fsm.GetState(stateName)!.ReplaceAction(index, action); + public static void ReplaceAction(this Fsm fsm, string stateName, FsmStateAction action, int index) => fsm.MustGetState(stateName).ReplaceAction(index, action); /// [PublicAPI] - public static void ReplaceAction(this Fsm fsm, string stateName, int index, FsmStateAction action) => fsm.GetState(stateName)!.ReplaceAction(index, action); + public static void ReplaceAction(this Fsm fsm, string stateName, int index, FsmStateAction action) => fsm.MustGetState(stateName).ReplaceAction(index, action); /// /// The state in which the action is replaced @@ -895,11 +972,11 @@ public static void ReplaceAction(this FsmState state, int index, FsmStateAction /// The name of the state in which the actions are to be replaced /// The new actions of the state [PublicAPI] - public static void ReplaceAllActions(this PlayMakerFSM fsm, string stateName, params FsmStateAction[] actions) => fsm.GetState(stateName)!.ReplaceAllActions(actions); + public static void ReplaceAllActions(this PlayMakerFSM fsm, string stateName, params FsmStateAction[] actions) => fsm.MustGetState(stateName).ReplaceAllActions(actions); /// [PublicAPI] - public static void ReplaceAllActions(this Fsm fsm, string stateName, params FsmStateAction[] actions) => fsm.GetState(stateName)!.ReplaceAllActions(actions); + public static void ReplaceAllActions(this Fsm fsm, string stateName, params FsmStateAction[] actions) => fsm.MustGetState(stateName).ReplaceAllActions(actions); /// /// The fsm state @@ -912,81 +989,81 @@ public static void ReplaceAllActions(this FsmState state, params FsmStateAction[ { action.Init(state); } - } - - /// - /// Replace all actions of type with new actions. - /// - /// The type of actions to replace. - /// The state containing actions to replace. - /// Function used to generate the new actions. - [PublicAPI] - public static void ReplaceActionsOfType(this FsmState state, Func newActionGenerator) - where T : FsmStateAction - { - for (int i = 0; i < state.actions.Length; i++) - { - if (state.Actions[i] is T typedAction) - { - state.ReplaceAction(i, newActionGenerator(typedAction)); - } - } - } - - /// - /// Replace the first action of type with a new action. - /// - /// The type of the action to replace. - /// The state holding the actions. - /// The new action. - [PublicAPI] - public static void ReplaceFirstActionOfType(this FsmState state, FsmStateAction newAction) where T : FsmStateAction - { - int foundIndex = -2; - - for (int i = 0; i < state.actions.Length; i++) - { - if (state.actions[i] is T) - { - foundIndex = i; - break; - } - } - - if (foundIndex == -2) - { - return; - } - - state.ReplaceAction(newAction, foundIndex); - } - - /// - /// Replace the last action of type with a new action. - /// - /// The type of the action to replace. - /// The state holding the actions. - /// The new action. - [PublicAPI] - public static void ReplaceLastActionOfType(this FsmState state, FsmStateAction newAction) where T : FsmStateAction - { - int foundIndex = -2; - - for (int i = state.actions.Length - 1; i >= 0; i--) - { - if (state.actions[i] is T) - { - foundIndex = i; - break; - } - } - - if (foundIndex == -2) - { - return; - } - - state.ReplaceAction(newAction, foundIndex); + } + + /// + /// Replace all actions of type with new actions. + /// + /// The type of actions to replace. + /// The state containing actions to replace. + /// Function used to generate the new actions. + [PublicAPI] + public static void ReplaceActionsOfType(this FsmState state, Func newActionGenerator) + where T : FsmStateAction + { + for (int i = 0; i < state.actions.Length; i++) + { + if (state.Actions[i] is T typedAction) + { + state.ReplaceAction(i, newActionGenerator(typedAction)); + } + } + } + + /// + /// Replace the first action of type with a new action. + /// + /// The type of the action to replace. + /// The state holding the actions. + /// The new action. + [PublicAPI] + public static void ReplaceFirstActionOfType(this FsmState state, FsmStateAction newAction) where T : FsmStateAction + { + int foundIndex = -2; + + for (int i = 0; i < state.actions.Length; i++) + { + if (state.actions[i] is T) + { + foundIndex = i; + break; + } + } + + if (foundIndex == -2) + { + return; + } + + state.ReplaceAction(newAction, foundIndex); + } + + /// + /// Replace the last action of type with a new action. + /// + /// The type of the action to replace. + /// The state holding the actions. + /// The new action. + [PublicAPI] + public static void ReplaceLastActionOfType(this FsmState state, FsmStateAction newAction) where T : FsmStateAction + { + int foundIndex = -2; + + for (int i = state.actions.Length - 1; i >= 0; i--) + { + if (state.actions[i] is T) + { + foundIndex = i; + break; + } + } + + if (foundIndex == -2) + { + return; + } + + state.ReplaceAction(newAction, foundIndex); } #endregion Replace @@ -1002,11 +1079,11 @@ public static void ReplaceLastActionOfType(this FsmState state, FsmStateActio /// The new endpoint of the transition /// bool that indicates whether the change was successful [PublicAPI] - public static bool ChangeTransition(this PlayMakerFSM fsm, string stateName, string eventName, string toState) => fsm.GetState(stateName)!.ChangeTransition(eventName, toState); + public static bool ChangeTransition(this PlayMakerFSM fsm, string stateName, string eventName, string toState) => fsm.MustGetState(stateName).ChangeTransition(eventName, toState); /// [PublicAPI] - public static bool ChangeTransition(this Fsm fsm, string stateName, string eventName, string toState) => fsm.GetState(stateName)!.ChangeTransition(eventName, toState); + public static bool ChangeTransition(this Fsm fsm, string stateName, string eventName, string toState) => fsm.MustGetState(stateName).ChangeTransition(eventName, toState); /// /// The fsm state @@ -1102,11 +1179,11 @@ private static TVal[] RemoveItemsFromArray(TVal[] origArray, FuncThe name of the state from which the transition starts /// The event of the transition [PublicAPI] - public static void RemoveTransition(this PlayMakerFSM fsm, string stateName, string eventName) => fsm.GetState(stateName)!.RemoveTransition(eventName); + public static void RemoveTransition(this PlayMakerFSM fsm, string stateName, string eventName) => fsm.MustGetState(stateName).RemoveTransition(eventName); /// [PublicAPI] - public static void RemoveTransition(this Fsm fsm, string stateName, string eventName) => fsm.GetState(stateName)!.RemoveTransition(eventName); + public static void RemoveTransition(this Fsm fsm, string stateName, string eventName) => fsm.MustGetState(stateName).RemoveTransition(eventName); /// /// The fsm state @@ -1156,11 +1233,11 @@ public static void RemoveTransitionsTo(this Fsm fsm, string toState) /// The name of the state from which the transition starts /// The target of the transition [PublicAPI] - public static void RemoveTransitionsTo(this PlayMakerFSM fsm, string stateName, string toState) => fsm.GetState(stateName)!.RemoveTransitionsTo(toState); + public static void RemoveTransitionsTo(this PlayMakerFSM fsm, string stateName, string toState) => fsm.MustGetState(stateName).RemoveTransitionsTo(toState); /// [PublicAPI] - public static void RemoveTransitionsTo(this Fsm fsm, string stateName, string toState) => fsm.GetState(stateName)!.RemoveTransitionsTo(toState); + public static void RemoveTransitionsTo(this Fsm fsm, string stateName, string toState) => fsm.MustGetState(stateName).RemoveTransitionsTo(toState); /// /// The fsm state @@ -1174,11 +1251,11 @@ public static void RemoveTransitionsTo(this Fsm fsm, string toState) /// The fsm /// The name of the state from which the transition starts [PublicAPI] - public static void RemoveTransitions(this PlayMakerFSM fsm, string stateName) => fsm.GetState(stateName)!.RemoveTransitions(); + public static void RemoveTransitions(this PlayMakerFSM fsm, string stateName) => fsm.MustGetState(stateName).RemoveTransitions(); /// [PublicAPI] - public static void RemoveTransitions(this Fsm fsm, string stateName) => fsm.GetState(stateName)!.RemoveTransitions(); + public static void RemoveTransitions(this Fsm fsm, string stateName) => fsm.MustGetState(stateName).RemoveTransitions(); /// /// The fsm state @@ -1193,11 +1270,11 @@ public static void RemoveTransitionsTo(this Fsm fsm, string toState) /// The name of the state with the action /// The index of the action [PublicAPI] - public static bool RemoveAction(this PlayMakerFSM fsm, string stateName, int index) => fsm.GetState(stateName)!.RemoveAction(index); + public static bool RemoveAction(this PlayMakerFSM fsm, string stateName, int index) => fsm.MustGetState(stateName).RemoveAction(index); /// [PublicAPI] - public static bool RemoveAction(this Fsm fsm, string stateName, int index) => fsm.GetState(stateName)!.RemoveAction(index); + public static bool RemoveAction(this Fsm fsm, string stateName, int index) => fsm.MustGetState(stateName).RemoveAction(index); /// /// The fsm state @@ -1251,11 +1328,11 @@ public static void RemoveActionsOfType(this Fsm fsm) /// The fsm /// The name of the state to remove the actions from [PublicAPI] - public static void RemoveActionsOfType(this PlayMakerFSM fsm, string stateName) => fsm.GetState(stateName)!.RemoveActionsOfType(); + public static void RemoveActionsOfType(this PlayMakerFSM fsm, string stateName) => fsm.MustGetState(stateName).RemoveActionsOfType(); /// [PublicAPI] - public static void RemoveActionsOfType(this Fsm fsm, string stateName) => fsm.GetState(stateName)!.RemoveActionsOfType(); + public static void RemoveActionsOfType(this Fsm fsm, string stateName) => fsm.MustGetState(stateName).RemoveActionsOfType(); /// /// The fsm state @@ -1269,32 +1346,39 @@ public static void RemoveActionsOfType(this Fsm fsm) /// The fsm /// The name of the state to remove the actions from [PublicAPI] - public static void RemoveFirstActionOfType(this PlayMakerFSM fsm, string stateName) => fsm.GetState(stateName)!.RemoveFirstActionOfType(); + public static void RemoveFirstActionOfType(this PlayMakerFSM fsm, string stateName) => fsm.MustGetState(stateName).RemoveFirstActionOfType(); /// [PublicAPI] - public static void RemoveFirstActionOfType(this Fsm fsm, string stateName) => fsm.GetState(stateName)!.RemoveFirstActionOfType(); + public static void RemoveFirstActionOfType(this Fsm fsm, string stateName) => fsm.MustGetState(stateName).RemoveFirstActionOfType(); /// /// The fsm state [PublicAPI] public static void RemoveFirstActionOfType(this FsmState state) { - int firstActionIndex = -1; - for (int i = 0; i < state.Actions.Length; i++) - { - if (state.Actions[i] is TAction) - { - firstActionIndex = i; - break; - } - } + int firstActionIndex = state.IndexFirstActionOfType(); if (firstActionIndex == -1) return; state.RemoveAction(firstActionIndex); } + /// + /// Removes the first action in a state that matches the predicate. + /// + /// The state + /// The predicate that each action is matched against + [PublicAPI] + public static void RemoveFirstActionMatching(this FsmState state, Func predicate) + { + int i = state.IndexFirstActionMatching(predicate); + if (i != -1) + { + state.RemoveAction(i); + } + } + /// /// Removes last action of a given type in an FsmState. /// @@ -1302,32 +1386,39 @@ public static void RemoveFirstActionOfType(this FsmState state) /// The fsm /// The name of the state to remove the actions from [PublicAPI] - public static void RemoveLastActionOfType(this PlayMakerFSM fsm, string stateName) => fsm.GetState(stateName)!.RemoveLastActionOfType(); + public static void RemoveLastActionOfType(this PlayMakerFSM fsm, string stateName) => fsm.MustGetState(stateName).RemoveLastActionOfType(); /// [PublicAPI] - public static void RemoveLastActionOfType(this Fsm fsm, string stateName) => fsm.GetState(stateName)!.RemoveLastActionOfType(); + public static void RemoveLastActionOfType(this Fsm fsm, string stateName) => fsm.MustGetState(stateName).RemoveLastActionOfType(); /// /// The fsm state [PublicAPI] public static void RemoveLastActionOfType(this FsmState state) { - int lastActionIndex = -1; - for (int i = state.Actions.Length - 1; i >= 0; i--) - { - if (state.Actions[i] is TAction) - { - lastActionIndex = i; - break; - } - } + int lastActionIndex = state.IndexLastActionOfType(); if (lastActionIndex == -1) return; state.RemoveAction(lastActionIndex); } + /// + /// Removes the last action in a state that matches the predicate. + /// + /// The state + /// The predicate that each action is matched against + [PublicAPI] + public static void RemoveLastActionMatching(this FsmState state, Func predicate) + { + int i = state.IndexLastActionMatching(predicate); + if (i != -1) + { + state.RemoveAction(i); + } + } + #endregion Remove #region Disable @@ -1341,11 +1432,11 @@ public static void RemoveLastActionOfType(this FsmState state) /// The index of the action /// bool that indicates whether the disabling was successful [PublicAPI] - public static bool DisableAction(this PlayMakerFSM fsm, string stateName, int index) => fsm.GetState(stateName)!.DisableAction(index); + public static bool DisableAction(this PlayMakerFSM fsm, string stateName, int index) => fsm.MustGetState(stateName).DisableAction(index); /// [PublicAPI] - public static bool DisableAction(this Fsm fsm, string stateName, int index) => fsm.GetState(stateName)!.DisableAction(index); + public static bool DisableAction(this Fsm fsm, string stateName, int index) => fsm.MustGetState(stateName).DisableAction(index); /// /// The fsm state @@ -1370,11 +1461,11 @@ public static bool DisableAction(this FsmState state, int index) /// The indices of the action /// bool that indicates whether all the disablings were successful [PublicAPI] - public static bool DisableActions(this PlayMakerFSM fsm, string stateName, params int[] indices) => fsm.GetState(stateName)!.DisableActions(indices); + public static bool DisableActions(this PlayMakerFSM fsm, string stateName, params int[] indices) => fsm.MustGetState(stateName).DisableActions(indices); /// [PublicAPI] - public static bool DisableActions(this Fsm fsm, string stateName, params int[] indices) => fsm.GetState(stateName)!.DisableActions(indices); + public static bool DisableActions(this Fsm fsm, string stateName, params int[] indices) => fsm.MustGetState(stateName).DisableActions(indices); /// /// The fsm state @@ -1415,11 +1506,11 @@ public static void DisableActionsOfType(this Fsm fsm) /// The fsm /// The name of the state to disable the actions from [PublicAPI] - public static void DisableActionsOfType(this PlayMakerFSM fsm, string stateName) => fsm.GetState(stateName)!.DisableActionsOfType(); + public static void DisableActionsOfType(this PlayMakerFSM fsm, string stateName) => fsm.MustGetState(stateName).DisableActionsOfType(); /// [PublicAPI] - public static void DisableActionsOfType(this Fsm fsm, string stateName) => fsm.GetState(stateName)!.DisableActionsOfType(); + public static void DisableActionsOfType(this Fsm fsm, string stateName) => fsm.MustGetState(stateName).DisableActionsOfType(); /// /// The fsm state