internal async Task FireInternalAsync(TTrigger trigger) { var triggerRep = AwaitableStateConfigurationHelper <TState, TTrigger> .FindTriggerRepresentation(trigger, CurrentStateRepresentation); if (triggerRep == null) { HandleInvalidTrigger(trigger); return; } if (CheckFlag(triggerRep.TransitionFlags, AwaitableStateTransitionFlag.TriggerPredicateReturnsTask)) { var predicate = (Func <Task <bool> >)triggerRep.ConditionalTriggerPredicate; if (predicate != null) { if (!await predicate()) { HandleInvalidTrigger(trigger); return; } } } else { var predicate = (Func <bool>)triggerRep.ConditionalTriggerPredicate; if (predicate != null) { if (!predicate()) { HandleInvalidTrigger(trigger); return; } } } // Handle ignored trigger if (triggerRep.NextStateRepresentation == null) { return; } // Catch invalid paramters before execution. Action triggerAction = null; Func <Task> triggerFunc = null; if (CheckFlag(triggerRep.TransitionFlags, AwaitableStateTransitionFlag.TriggerActionReturnsTask)) { try { triggerFunc = (Func <Task>)triggerRep.OnTriggerAction; } catch (InvalidCastException) { InvalidTriggerParameterException <TTrigger> .Throw(trigger); return; } } else { try { triggerAction = (Action)triggerRep.OnTriggerAction; } catch (InvalidCastException) { InvalidTriggerParameterException <TTrigger> .Throw(trigger); return; } } // Current exit if (CheckFlag(CurrentStateRepresentation.TransitionFlags, AwaitableStateTransitionFlag.ExitReturnsTask)) { var exit = (Func <Task>)CurrentStateRepresentation.OnExitAction; if (exit != null) { await exit(); } } else { var exit = (Action)CurrentStateRepresentation.OnExitAction; if (exit != null) { exit(); } } // Trigger entry if (triggerAction != null) { triggerAction(); } else if (triggerFunc != null) { await triggerFunc(); } // Next state entry var nextStateRep = triggerRep.NextStateRepresentation; if (CheckFlag(nextStateRep.TransitionFlags, AwaitableStateTransitionFlag.EntryReturnsTask)) { var entry = (Func <Task>)nextStateRep.OnEntryAction; if (entry != null) { await entry(); } } else { var entry = (Action)nextStateRep.OnEntryAction; if (entry != null) { entry(); } } // Set states var previousState = CurrentStateRepresentation.State; CurrentStateRepresentation = nextStateRep; // Raise event var sc = StateChanged; if (sc != null) { sc.Invoke(previousState, CurrentStateRepresentation.State); } }
public async Task FireAsync <TArgument>(ParameterizedTrigger <TTrigger, TArgument> parameterizedTrigger, TArgument argument) { if (isRunning) { throw new InvalidOperationException("State cannot be changed while in transition"); } if (IsEnabled) { isRunning = true; var trigger = parameterizedTrigger.Trigger; var triggerRep = AwaitableStateConfigurationHelper <TState, TTrigger> .FindTriggerRepresentation(trigger, currentStateRepresentation); if (triggerRep == null) { HandleInvalidTrigger(trigger); return; } if (CheckFlag(triggerRep.TransitionFlags, AwaitableStateTransitionFlag.TriggerPredicateReturnsTask)) { var predicate = (Func <Task <bool> >)triggerRep.ConditionalTriggerPredicate; if (predicate != null) { if (!await predicate()) { HandleInvalidTrigger(trigger); return; } } } else { var predicate = (Func <bool>)triggerRep.ConditionalTriggerPredicate; if (predicate != null) { if (!predicate()) { HandleInvalidTrigger(trigger); return; } } } // Handle ignored trigger if (triggerRep.NextStateRepresentation == null) { return; } // Catch invalid paramters before execution. Action <TArgument> triggerAction = null; Func <TArgument, Task> triggerFunc = null; if (CheckFlag(triggerRep.TransitionFlags, AwaitableStateTransitionFlag.TriggerActionReturnsTask)) { try { triggerFunc = (Func <TArgument, Task>)triggerRep.OnTriggerAction; } catch (InvalidCastException) { InvalidTriggerParameterException <TTrigger> .Throw(trigger); return; } } else { try { triggerAction = (Action <TArgument>)triggerRep.OnTriggerAction; } catch (InvalidCastException) { InvalidTriggerParameterException <TTrigger> .Throw(trigger); return; } } // Current exit if (CheckFlag(currentStateRepresentation.TransitionFlags, AwaitableStateTransitionFlag.ExitReturnsTask)) { var exit = (Func <Task>)currentStateRepresentation.OnExitAction; if (exit != null) { await exit(); } } else { var exit = (Action)currentStateRepresentation.OnExitAction; if (exit != null) { exit(); } } // Trigger entry if (triggerAction != null) { triggerAction(argument); } else if (triggerFunc != null) { await triggerFunc(argument); } // Next state entry var nextStateRep = triggerRep.NextStateRepresentation; if (CheckFlag(nextStateRep.TransitionFlags, AwaitableStateTransitionFlag.EntryReturnsTask)) { var entry = (Func <Task>)nextStateRep.OnEntryAction; if (entry != null) { await entry(); } } else { var entry = (Action)nextStateRep.OnEntryAction; if (entry != null) { entry(); } } // Set states var previousState = currentStateRepresentation.State; currentStateRepresentation = nextStateRep; // Raise event var sc = StateChanged; if (sc != null) { sc(previousState, currentStateRepresentation.State); } isRunning = false; } }