コード例 #1
0
        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);
        }
コード例 #2
0
        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()));
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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));
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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());
        }
コード例 #7
0
        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));
        }
コード例 #8
0
        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.");
        }
コード例 #9
0
ファイル: StateMachine.cs プロジェクト: stantoxt/Orleankka
        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]));
        }
コード例 #10
0
 /// <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();
 }
コード例 #11
0
        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()));
        }
コード例 #12
0
        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);
        }
コード例 #13
0
ファイル: SolidMachine.cs プロジェクト: mesh42/vpnet
        // 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);
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        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));
        }
コード例 #16
0
        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);
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        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>)));
        }
コード例 #19
0
        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));
        }
コード例 #20
0
        public static string Format(StateConfiguration stateConfiguration)
        {
            StateConfigurationWriter writer = new StateConfigurationWriter();

            stateConfiguration.PassThrough(writer);
            return(writer.ToString());
        }
コード例 #21
0
ファイル: StateMachine.cs プロジェクト: stantoxt/Orleankka
        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);
        }
コード例 #22
0
        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()));
        }
コード例 #23
0
        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);
        }
コード例 #25
0
 public PresentationWindow(IPresentationController presentationController, ResourceConfiguration resourceConfiguration, StateConfiguration stateConfiguration)
 {
     PresentationController = presentationController;
     ResourceConfiguration  = resourceConfiguration;
     StateConfiguration     = stateConfiguration;
     InitializeSettings();
     InitializeComponent();
     InitializeContexts();
 }
コード例 #26
0
        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()));
        }
コード例 #27
0
        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()));
        }
コード例 #28
0
        public BlobStateStore(
            StateConfiguration configuration,
            ILogger <BlobStateStore> logger)
        {
            _logger = logger;
            var blobClient = new BlobServiceClient(configuration.BlobConnectionString);

            _containerClient = blobClient.GetBlobContainerClient(configuration.BlobContainerName);
        }
コード例 #29
0
            // 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]);
            }
コード例 #30
0
        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)));
        }