private void TraceStateChange(StateMachine stateMachine, StateConfiguration stateConfigurationFrom, StateConfiguration stateConfigurationTo, Transition transition) { string info = DateTime.Now.ToString("HH:mm:ss.fff") + " ActiveState=\"" + stateConfigurationTo.ToString() + "\"" + " Transition=" + ((transition != null) ? "\"" + transition.Name + "\"" : "Startup/Finish"); Debug.Print(info); Display.WriteLine(info); }
public static StateConfiguration <TState, TTrigger> OnExit <TState, TTrigger>( this StateConfiguration <TState, TTrigger> config, Action action) { Contract.Requires <ArgumentNullException>(action != null, nameof(action)); return(config.OnExit(t => action())); }
public async Task ExecuteExitActionAsync_does_not_execute_if_cancelled() { var sale = new Sale(saleId: 96) { State = SaleState.ChangeDue }; var transitionResult = new StateTransitionResult <SaleState, SaleEvent>(SaleEvent.Pay , SaleState.Open , SaleState.Open , SaleState.ChangeDue , "lastTransitionName"); var stateMachine = new StateMachine <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState); var openState = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.Open, stateMachine); var openExitActionFired = false; openState.AddExitAction((sale1, _) => { openExitActionFired = true; return(Task.CompletedTask); }); using (var cancelSource = new CancellationTokenSource()) { var parameters = new ExecutionParameters <Sale, SaleEvent>(SaleEvent.Pay, sale, cancelSource.Token); cancelSource.Cancel(); await openState.ExecuteExitActionAsync(parameters, transitionResult); } Assert.False(openExitActionFired); }
public void AddDynamicTransitionWRequest_throws_ArgumentNullException_if_Function_null() { var stateMachine = new StateMachine <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState); var sut = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine); Assert.Throws <ArgumentNullException>(() => sut.AddDynamicTransition <string>(SaleEvent.AddItem, function: null)); }
public async Task ExecuteEntryActionAsync_executes_for_super_state() { var entryActionCalled = false; var stateMachine = new StateMachine <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState); var openConfig = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.Open, stateMachine); openConfig.AddEntryAction((sale1, _) => { entryActionCalled = true; return(Task.CompletedTask); }); var changeDueConfig = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine); changeDueConfig.MakeSubStateOf(openConfig); var sale = new Sale(saleId: 96) { State = SaleState.ChangeDue }; var parameters = new ExecutionParameters <Sale, SaleEvent>(SaleEvent.Pay, sale); var transitionResult = new StateTransitionResult <SaleState, SaleEvent>(SaleEvent.Pay , SaleState.Open , SaleState.Complete , SaleState.ChangeDue , "lastTransitionName"); await changeDueConfig.ExecuteEntryActionAsync(parameters, transitionResult); Assert.True(entryActionCalled); }
private static IEnumerable <Microstep> ComputeMicrosteps( IEnumerable <Transition> transitions, object context, StateConfiguration stateConfiguration, IEvent @event) { var enabled = transitions.Where(transition => transition.IsEnabled(context, @event.Data)); var result = enabled.SelectMany(transition => transition.Targets.Select(target => { var test = (transition.Source, target).LeastCommonAncestor(); var lcca = test.Value; var lastBeforeLeastCompoundCommonAncestor = transition.Source.OneBeneath(lcca); var isChildTransition = target.GetParents().Contains(transition.Source); var exited = isChildTransition ? transition.Source.GetDescendants().Where(stateConfiguration.Contains).Reverse() : lastBeforeLeastCompoundCommonAncestor.Append(lastBeforeLeastCompoundCommonAncestor.GetDescendants()).Where(stateConfiguration.Contains).Reverse(); var entered = target .Append(target.AncestorsUntil(isChildTransition ? lastBeforeLeastCompoundCommonAncestor : lcca)) .Reverse(); return(new Microstep(@event, transition, entered, exited)); })); return(result.ToList()); }
public void AddAutoForwardTransitionWRequest_throws_ArgumentNullException_if_Condition_null() { var stateMachine = new StateMachine <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState); var sut = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine); Assert.Throws <ArgumentNullException>(() => sut.AddAutoForwardTransition <string>(SaleEvent.Pay, SaleState.Complete, condition: null)); }
public void Finish_WithTransitionInExitAction_NotExecuted() { const string StateA = "StateA"; const string StateA1A = "StateA1A"; const string Transi1 = "Transi1"; const string Event1 = "Event1"; bool transitionExecuted = false; StateMachineTemplate t = new StateMachineTemplate(); t.Region(StateA, false); t.State(StateA, null, (s, ev, args) => s.SendTriggerEvent(Event1)); t.Region(StateA1A, false); t.State(StateA1A); t.Transition(Transi1, new string[] { StateA1A }, new string[] { StateA1A }, Event1, null, (s, ev, args) => transitionExecuted = true); t.EndState(); t.EndRegion(); t.EndState(); t.EndRegion(); Assert.That(t.StateConfigurationMax, Is.EqualTo(2), "StateConfigurationMax wrong"); Assert.That(t.ConcurrencyDegree, Is.EqualTo(1), "ConcurrencyDegree wrong"); StateMachine stateMachine = t.CreateStateMachine(this); stateMachine.Startup(); stateMachine.Finish(); StateConfiguration nirvana = t.CreateStateConfiguration(new string[] { }); Assert.That(stateMachine.ActiveStateConfiguration.ToString(), Is.EqualTo(nirvana.ToString()), "Active state not as expected."); Assert.That(transitionExecuted, Is.EqualTo(false), "Unintended transition during finish executed."); }
void Build(StateConfiguration state, IDictionary <string, State> states, ICollection <string> chain) { if (chain.Contains(state.Name)) { throw new InvalidOperationException("Cycle detected: " + string.Join(" -> ", chain) + $" !-> {state.Name}"); } if (states.ContainsKey(state.Name)) { return; } if (state.Super == null) { states.Add(state.Name, new State(state.Name, state.Behavior)); return; } if (!configuration.TryGetValue(state.Super, out var super)) { throw new InvalidOperationException($"Super '{state.Super}' specified for state '{state.Name}' hasn't been configured"); } chain.Add(state.Name); // recurse Build(super, states, chain); // now get fully configured super states.Add(state.Name, new State(state.Name, state.Behavior, states[state.Super])); }
/// <summary> /// Assign the state configuration reference. /// </summary> public void OnEnable() { m_StateConfiguration = target as StateConfiguration; m_StateConfiguration.hideFlags = HideFlags.None; EditorUtility.SetDirty(m_StateConfiguration); AssetDatabase.SaveAssets(); }
public static StateConfiguration <TState, TTrigger> OnExit <TState, TTrigger>( this StateConfiguration <TState, TTrigger> config, Action action) { Contract.NotNull(action != null, nameof(action)); return(config.OnExit(t => action())); }
private static IEnumerable <Transition> SelectTransitions <TContext>( Model.ExecutableStatechart <TContext> statechart, object context, StateConfiguration stateConfiguration, IEvent @event) where TContext : IContext <TContext> { Option <Transition> FirstMatchingTransition(ParsedStatenode node) => node.GetTransitions() .Where(transition => @event.Equals(transition.Event)) .FirstOrDefault(transition => transition.IsEnabled(context, @event.Data)).ToOption(); return(statechart .GetActiveStatenodes(stateConfiguration) .OrderByDescending(statenode => statenode.Depth) .Aggregate( (excluded: Enumerable.Empty <ParsedStatenode>(), transitions: Enumerable.Empty <Transition>()), (tuple, current) => tuple.excluded.Contains(current) ? tuple : FirstMatchingTransition(current).Match( transition => ( excluded: tuple.excluded.Concat(current.GetParents()), transitions: transition.IsForbidden ? tuple.transitions : tuple.transitions.Append(transition)), () => tuple)) .transitions); }
// Public methods /// <summary> /// Defines a state that should be configured. /// </summary> /// <typeparam name="TState"></typeparam> /// <returns></returns> public StateConfiguration State <TState>() where TState : ISolidState { var type = typeof(TState); // Does the state have a parameterless constructor? Otherwise a state resolver is required HandleResolverRequired(type); // Does a configuration for this state exist already? StateConfiguration configuration; if (_stateConfigurations.ContainsKey(typeof(TState))) { configuration = _stateConfigurations[typeof(TState)]; } else { configuration = new StateConfiguration(type, this); // If this is the first state that is added, it becomes the initial state if (_stateConfigurations.Count == 0) { _initialState = configuration; } _stateConfigurations.Add(type, configuration); } return(configuration); }
public async Task ExecuteReentryActionAsync_executes_ReentryAction() { var sale = new Sale(saleId: 96) { State = SaleState.Open }; var transitionResult = new StateTransitionResult <SaleState, SaleEvent>(SaleEvent.AddItem , SaleState.Open , SaleState.Open , SaleState.Open , "lastTransitionName"); var stateMachine = new StateMachine <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState); var openState = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.Open, stateMachine); var changeDueState = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine); changeDueState.AddSuperstate(openState); var changeDueEntryActionFromOpenFired = false; changeDueState.AddReentryAction((sale1, _) => { changeDueEntryActionFromOpenFired = true; return(Task.CompletedTask); }); var parameters = new ExecutionParameters <Sale, SaleEvent>(SaleEvent.Pay, sale); await changeDueState.ExecuteReentryActionAsync(parameters, transitionResult); Assert.True(changeDueEntryActionFromOpenFired); }
public void AddEntryAction_throws_ArgumentNullException_if_Action_null() { var stateMachine = new StateMachine <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState); var sut = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine); Assert.Throws <ArgumentNullException>(() => sut.AddEntryAction(action: null)); }
public void FireTrigger_executes_superState_if_currentState_not_successful() { var sale = new Sale(saleID: 96) { State = SaleState.ChangeDue }; var stateMachine = new StateMachine <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState); var openState = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.Open, stateMachine); var openStatePayTriggerFired = false; openState .AddTriggerAction(SaleEvent.Pay, sale1 => { openStatePayTriggerFired = true; }) .AddTransition(SaleEvent.Pay, SaleState.Complete, name: "openStatePay"); var changeDueState = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine); changeDueState.AddSuperstate(openState); var parameters = new ExecutionParameters <Sale, SaleEvent>(SaleEvent.Pay, sale); var result = changeDueState.FireTrigger(parameters); Assert.True(openStatePayTriggerFired); Assert.True(result.WasTransitioned); Assert.Equal(SaleState.Complete, sale.State); Assert.Equal(SaleState.Complete, result.CurrentState); Assert.Equal(SaleState.ChangeDue, result.PreviousState); Assert.Equal(SaleState.ChangeDue, result.StartingState); Assert.Equal("openStatePay", result.LastTransitionName); }
public void ExecuteAutoTransition_executes_AutoTransition_without_previous_state() { var sale = new Sale(saleID: 96) { State = SaleState.ChangeDue }; var transitionResult = new StateTransitionResult <SaleState, SaleEvent>(SaleEvent.ChangeGiven , SaleState.Open , SaleState.ChangeDue , SaleState.ChangeDue , "lastTransitionName"); var stateMachine = new StateMachine <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState); var sut = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine); sut.AddAutoForwardTransition(SaleEvent.ChangeGiven, SaleState.Complete, sale1 => true); var parameters = new ExecutionParameters <Sale, SaleEvent>(SaleEvent.ChangeGiven, sale); var autoTransitionResult = sut.ExecuteAutoTransition(parameters, transitionResult); Assert.True(autoTransitionResult.WasTransitioned); Assert.Equal(SaleState.Complete, sale.State); Assert.Equal(SaleState.Complete, autoTransitionResult.CurrentState); Assert.Equal(SaleState.ChangeDue, autoTransitionResult.PreviousState); Assert.Equal(SaleState.Open, autoTransitionResult.StartingState); }
public void AddAutoFallbackTransitionWRequestPreviousState_throws_ArgumentNullException_if_Condition_null() { var stateMachine = new StateMachine <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState); var sut = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine); Assert.Throws <ArgumentNullException>(() => sut.AddAutoFallbackTransition(SaleEvent.Pay, SaleState.Open, condition: (null as Func <Sale, string, bool>))); }
public void AddAutoFallbackTransitionWPreviousState_throws_ArgumentNullException_if_Condition_null() { var stateMachine = new StateMachine <Sale, SaleState, SaleEvent>(sale => sale.State, (sale, newState) => sale.State = newState); var sut = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.ChangeDue, stateMachine); Assert.Throws <ArgumentNullException>(() => sut.AddAutoFallbackTransition(SaleEvent.Pay, SaleState.Complete, condition: null, previousState: SaleState.Open)); }
public static string Format(StateConfiguration stateConfiguration) { StateConfigurationWriter writer = new StateConfigurationWriter(); stateConfiguration.PassThrough(writer); return(writer.ToString()); }
public StateMachine State(Receive behavior, Receive[] trait, Func <Receive, Receive> extend = null) { Requires.NotNull(behavior, nameof(behavior)); Requires.NotNull(trait, nameof(trait)); lastSuper = Add(behavior.Method.Name, behavior, null, extend, trait); return(this); }
public static StateConfiguration <TState, TTrigger> PermitReentry <TState, TTrigger>( this StateConfiguration <TState, TTrigger> config, TTrigger trigger, Action onTriggerAction) { Contract.NotNull(onTriggerAction != null, nameof(onTriggerAction)); return(config.PermitReentry(trigger, t => onTriggerAction())); }
public void IsInState_returns_True_if_in_given_state() { var stateMachine = new StateMachine <Sale, SaleState, SaleEvent>(sale1 => sale1.State, (sale1, newState) => sale1.State = newState); var openState = new StateConfiguration <Sale, SaleState, SaleEvent>(SaleState.Open, stateMachine); Assert.True(openState.IsInState(SaleState.Open)); Assert.False(openState.IsInState(SaleState.Complete)); }
public TableStateStore( StateConfiguration configuration) { var storageAccount = CloudStorageAccount.Parse(configuration.TableConnectionString); var tableClient = storageAccount.CreateCloudTableClient(); _table = tableClient.GetTableReference(configuration.TableName); }
public PresentationWindow(IPresentationController presentationController, ResourceConfiguration resourceConfiguration, StateConfiguration stateConfiguration) { PresentationController = presentationController; ResourceConfiguration = resourceConfiguration; StateConfiguration = stateConfiguration; InitializeSettings(); InitializeComponent(); InitializeContexts(); }
public static StateConfiguration <TState, TTrigger> Permit <TState, TTrigger>( this StateConfiguration <TState, TTrigger> config, TTrigger trigger, TState resultingState, Action onTriggerAction) { Contract.NotNull(onTriggerAction != null, nameof(onTriggerAction)); return(config.Permit(trigger, resultingState, t => onTriggerAction())); }
public static StateConfiguration <TState, TTrigger> PermitIf <TState, TTrigger>( StateConfiguration <TState, TTrigger> config, Func <bool> predicate, TTrigger trigger, TState resultingState, Action onTriggerAction) { Contract.NotNull(onTriggerAction != null, nameof(onTriggerAction)); return(config.PermitIf(predicate, trigger, resultingState, t => onTriggerAction())); }
public BlobStateStore( StateConfiguration configuration, ILogger <BlobStateStore> logger) { _logger = logger; var blobClient = new BlobServiceClient(configuration.BlobConnectionString); _containerClient = blobClient.GetBlobContainerClient(configuration.BlobContainerName); }
// Methods public StateConfiguration GoesTo <TTargetState>() where TTargetState : ISolidState { _targetState = _owningStateConfiguration.OwningMachine.State <TTargetState>(); // Return the correct StateConfiguration var machine = _owningStateConfiguration.OwningMachine; return(machine._stateConfigurations[_owningStateConfiguration.StateType]); }
public static StateConfiguration <TState, TTrigger> PermitReentry <TArgument, TState, TTrigger>( this StateConfiguration <TState, TTrigger> config, ParameterizedTrigger <TTrigger, TArgument> trigger, Action <TArgument> onTriggerAction) { Contract.NotNull(onTriggerAction != null, nameof(onTriggerAction)); return(config.PermitReentry(trigger, (t, a) => onTriggerAction(a))); }