From d552c1b3af1c30d3b39aa9e7611313ab0d249009 Mon Sep 17 00:00:00 2001 From: Andrew McKaskill Date: Fri, 31 May 2024 11:48:17 +0100 Subject: [PATCH] feat: Expose unmet guard conditions Add a method to return list of non-permissible triggers from the current state, along with the descriptions of the un-met guard conditions. --- src/Stateless/StateMachine.cs | 11 +++++++++++ src/Stateless/StateRepresentation.cs | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/Stateless/StateMachine.cs b/src/Stateless/StateMachine.cs index a28c5f48..b683bfd2 100644 --- a/src/Stateless/StateMachine.cs +++ b/src/Stateless/StateMachine.cs @@ -147,6 +147,17 @@ public IEnumerable> GetDetailedPermittedTrigger .Select(trigger => new TriggerDetails(trigger, _triggerConfiguration)); } + /// + /// Gets any triggers for the current state that are not permissible, and the descriptions + /// of the unmet trigger conditions associated with them. + /// + /// + /// + public IEnumerable> GetTriggersWithUnmetConditions(params object[] args) + { + return CurrentRepresentation.GetTriggersWithUnmetGuardConditions(args); + } + StateRepresentation CurrentRepresentation { get diff --git a/src/Stateless/StateRepresentation.cs b/src/Stateless/StateRepresentation.cs index 6c306553..2d8c762e 100644 --- a/src/Stateless/StateRepresentation.cs +++ b/src/Stateless/StateRepresentation.cs @@ -330,6 +330,26 @@ public IEnumerable GetPermittedTriggers(params object[] args) return result; } + public IEnumerable> GetTriggersWithUnmetGuardConditions(params object[] args) + { + List> unmetConditions = new List>(); + + var behaviours = TriggerBehaviours.Values.SelectMany(x => x); + foreach (var triggerBehaviour in behaviours) + { + if (triggerBehaviour.GuardConditionsMet(args)) + continue; + + var conditions = triggerBehaviour.UnmetGuardConditions(args); + unmetConditions.Add(new Tuple(triggerBehaviour.Trigger, conditions.ToArray())); + } + + if (Superstate != null) + unmetConditions.AddRange(Superstate.GetTriggersWithUnmetGuardConditions(args)); + + return unmetConditions; + } + internal void SetInitialTransition(TState state) { InitialTransitionTarget = state;