FindAndEvaluateTriggerRepresentationAsync <TState, TTrigger>(TTrigger trigger, RawAwaitableStateMachineBase <TState, TTrigger> machine, bool raiseInvalidTriggers = true) { var triggerRep = AwaitableStateConfigurationHelper.FindTriggerRepresentation(trigger, machine.CurrentStateRepresentation); if (triggerRep == null) { if (raiseInvalidTriggers) { machine.RaiseInvalidTrigger(trigger); } return(null); } if (AwaitableStateConfigurationHelper.CheckFlag(triggerRep.AwaitableTransitionFlags, AwaitableTransitionFlag.TriggerPredicateReturnsTask)) { var predicate = (Func <Task <bool> >)triggerRep.ConditionalTriggerPredicate; if (predicate != null) { if (!await predicate()) { if (raiseInvalidTriggers) { machine.RaiseInvalidTrigger(trigger); } return(null); } } } else { var predicate = (Func <bool>)triggerRep.ConditionalTriggerPredicate; if (predicate != null) { if (!predicate()) { if (raiseInvalidTriggers) { machine.RaiseInvalidTrigger(trigger); } return(null); } } } // Handle ignored trigger if (triggerRep.NextStateRepresentationWrapper == null) { return(null); } return(triggerRep); }
internal static async Task FireCoreAsync <TState, TTrigger>(TTrigger trigger, RawAwaitableStateMachineBase <TState, TTrigger> machine, bool raiseInvalidStateOrTrigger = true) { var currentStateRepresentation = machine.CurrentStateRepresentation; var triggerRep = await AwaitableDiagnosticsHelper.FindAndEvaluateTriggerRepresentationAsync(trigger, machine, raiseInvalidStateOrTrigger); if (triggerRep == null) { return; } // Catch invalid paramters before execution. Action <Transition <TState, TTrigger> > triggerAction = null; Func <Transition <TState, TTrigger>, Task> triggerFunc = null; if (AwaitableStateConfigurationHelper.CheckFlag(triggerRep.AwaitableTransitionFlags, AwaitableTransitionFlag.TriggerActionReturnsTask)) { try { triggerFunc = (Func <Transition <TState, TTrigger>, Task>)triggerRep.OnTriggerAction; } catch (InvalidCastException) { if (raiseInvalidStateOrTrigger) { machine.RaiseInvalidTrigger(trigger); } return; } } else { try { triggerAction = (Action <Transition <TState, TTrigger> >)triggerRep.OnTriggerAction; } catch (InvalidCastException) { if (raiseInvalidStateOrTrigger) { machine.RaiseInvalidTrigger(trigger); } return; } } AwaitableStateRepresentation <TState, TTrigger> nextStateRep = null; if (AwaitableStateConfigurationHelper.CheckFlag(triggerRep.AwaitableTransitionFlags, AwaitableTransitionFlag.DynamicState)) { var dynamicState = await AwaitableDiagnosticsHelper.GetValidatedDynamicTransition <TState, TTrigger>(triggerRep); if (dynamicState == null) { return; } var state = dynamicState.Value.ResultingState; nextStateRep = AwaitableStateConfigurationHelper.FindStateRepresentation(state, machine.Representations); if (nextStateRep == null) { if (raiseInvalidStateOrTrigger) { machine.RaiseInvalidState(state); } return; } } else { nextStateRep = (AwaitableStateRepresentation <TState, TTrigger>)triggerRep.NextStateRepresentationWrapper; } var transition = new Transition <TState, TTrigger>(currentStateRepresentation.State, nextStateRep.State); machine.RaiseTransitionStarted(nextStateRep.State); // Current exit if ( AwaitableStateConfigurationHelper.CheckFlag( currentStateRepresentation.AwaitableTransitionFlags, AwaitableTransitionFlag.ExitReturnsTask)) { var exit = (Func <Transition <TState, TTrigger>, Task>)currentStateRepresentation.OnExitAction; if (exit != null) { await exit(transition); } } else { var exit = (Action <Transition <TState, TTrigger> >)currentStateRepresentation.OnExitAction; exit?.Invoke(transition); } // Trigger entry if (triggerAction != null) { triggerAction(transition); } else if (triggerFunc != null) { await triggerFunc(transition); } // Next entry if ( AwaitableStateConfigurationHelper.CheckFlag( nextStateRep.AwaitableTransitionFlags, AwaitableTransitionFlag.EntryReturnsTask)) { var entry = (Func <Transition <TState, TTrigger>, Task>)nextStateRep.OnEntryAction; if (entry != null) { await entry(transition); } } else { var entry = (Action <Transition <TState, TTrigger> >)nextStateRep.OnEntryAction; entry?.Invoke(transition); } var pastState = machine.CurrentState; machine.CurrentStateRepresentation = nextStateRep; machine.RaiseTransitionExecuted(pastState); }