Exemplo n.º 1
0
        public async Task CompositeRuntimeState_WithoutCancellationAndEventTransitions_ExecutesAllSubStates()
        {
            var tracker = new TestTracker();

            var tcs2 = new TaskCompletionSource <object>();

            var state1 = new SimpleRuntimeState(
                "state1",
                tracker.StateEnterAction,
                tracker.StateExecutionAction,
                tracker.StateExitAction,
                tracker.StateCanceledAction);

            var state2 = new SimpleRuntimeState(
                "state2",
                tracker.StateEnterAction,
                async s =>
            {
                await tracker.StateExecutionAction(s);
                tcs2.SetResult(null);
            },
                tracker.StateExitAction,
                tracker.StateCanceledAction);

            var state3 = new SimpleRuntimeState(
                "state3",
                tracker.StateEnterAction,
                tracker.StateExecutionAction,
                tracker.StateExitAction,
                tracker.StateCanceledAction);

            var compositeState = new CompositeRuntimeState(
                "composite",
                tracker.StateEnterAction,
                tracker.StateExitAction,
                tracker.StateCanceledAction,
                new RuntimeTransition("T1", state1, tracker.TransitionAction, null));

            state1.AddEventTransition("E1", new RuntimeTransition("T2", state2, tracker.TransitionAction, null));
            state2.AddEventTransition("E2", new RuntimeTransition("T3", state3, tracker.TransitionAction, null));

            var task = compositeState.ExecuteAsync(CancellationToken.None);

            Assert.False(task.IsCompleted);

            var handled = await compositeState.PublishEventAsync("E1");

            Assert.True(handled);
            Assert.False(task.IsCompleted);

            await tcs2.Task;

            handled = await compositeState.PublishEventAsync("E2");

            Assert.True(handled);

            await task;

            Assert.Equal(">composite;@composite->state1;>state1;*state1;!state1;@state1->state2;>state2;*state2;!state2;@state2->state3;>state3;*state3;<state3;<composite;", tracker.ToString());
        }
Exemplo n.º 2
0
        public static RuntimeStateBase BuildRuntimeState(this StateBase state, IEnumerable <RuntimeStateBase> runtimeStates)
        {
            if (state == null)
            {
                throw new ArgumentNullException(nameof(state));
            }

            var validation = state.Validate();

            if (validation.Any())
            {
                throw new ValidationException(validation);
            }

            switch (state)
            {
            case IfElseState ifElseState:
                return(new IfElseRuntimeState(
                           ifElseState.Name,
                           ifElseState.OnEnterAction,
                           ifElseState.OnExitAction,
                           ifElseState.OnCanceledAction,
                           BuildRuntimeTransition(ifElseState.ElseTransition, runtimeStates),
                           BuildRuntimeTransition(ifElseState.TrueTransition, runtimeStates),
                           ifElseState.Predicate));

            case ChoiceStateBase switchState when TryBuildSwitch(switchState, runtimeStates, out var runtimeState):
                return(runtimeState);

            case SimpleState simpleState:
                return(new SimpleRuntimeState(
                           simpleState.Name,
                           simpleState.OnEnterAction,
                           simpleState.OnExecuteAction,
                           simpleState.OnExitAction,
                           simpleState.OnCanceledAction));

            case CompositeState compositeState:
                var subStates             = compositeState.SubStates.Select(s => BuildRuntimeState(s)).ToList();
                var compositeRuntimeState = new CompositeRuntimeState(
                    compositeState.Name,
                    compositeState.OnEnterAction,
                    compositeState.OnExitAction,
                    compositeState.OnCanceledAction,
                    BuildRuntimeTransition(compositeState.InitialTransition, subStates));
                foreach (var pair in compositeState.Transitions)
                {
                    foreach (var transition in pair.Value)
                    {
                        compositeRuntimeState.AddEventTransition(pair.Key, BuildRuntimeTransition(transition, subStates));
                    }
                }

                return(compositeRuntimeState);

            case ParallelState parallelState when parallelState.Mode == ParallelModes.All:
                return(new ParallelAllRuntimeState(
                           parallelState.Name,
                           parallelState.OnEnterAction,
                           parallelState.OnExitAction,
                           parallelState.OnCanceledAction,
                           parallelState.Regions.Select(r => BuildRuntimeState(r))));

            case ParallelState parallelState when parallelState.Mode == ParallelModes.Any:
                return(new ParallelAnyRuntimeState(
                           parallelState.Name,
                           parallelState.OnEnterAction,
                           parallelState.OnExitAction,
                           parallelState.OnCanceledAction,
                           parallelState.Regions.Select(r => BuildRuntimeState(r))));

            default:
                throw new ArgumentOutOfRangeException(nameof(state), $"Invalid state type: {state.GetType().FullName}");
            }
        }