Пример #1
0
        protected override void CacheMetadata(NativeActivityMetadata metadata)
        {
            //clean up
            this.internalStates.Clear();
            this.internalStateFuncs.Clear();
            this.internalTransitions.Clear();

            StateMachineHelper.ProcessChildStates(metadata, this.States, this.internalStates, this.internalStateFuncs);

            if (this.Entry != null)
            {
                metadata.AddChild(this.Entry);
            }
            if (this.Exit != null)
            {
                metadata.AddChild(this.Exit);
            }

            ProcessTransitions(metadata);

            metadata.AddArgument(new RuntimeArgument("ToState", this.ToState.ArgumentType, ArgumentDirection.In));
            metadata.AddArgument(new RuntimeArgument("EventManager", this.EventManager.ArgumentType, ArgumentDirection.In));

            metadata.AddImplementationVariable(this.currentRunningTriggers);
            metadata.AddImplementationVariable(this.hasRunningChildState);
            metadata.AddImplementationVariable(this.isExiting);
            metadata.AddImplementationVariable(this.evaluateConditionBookmark);
            metadata.AddImplementationVariable(this.completeStateBookmark);
        }
Пример #2
0
        void OnChildStateComplete(NativeActivityContext context, ActivityInstance instance, string targetStateId)
        {
            InternalState completedState = (InternalState)instance.Activity;

            this.hasRunningChildState.Set(context, false);
            //When child state is completed, current state become the deepest child state.
            this.EventManager.Get(context).CompleteDeepestChildBookmark = this.completeStateBookmark.Get(context);
            switch (instance.State)
            {
            case ActivityInstanceState.Closed:
                Debug.Assert(!completedState.IsFinal, "Final state is only on root level.");

                if (StateMachineHelper.IsAncestor(this.StateId, targetStateId))
                {
                    ScheduleChildState(context, targetStateId);
                }
                else
                {
                    //The target state does not belong to this state or the target state equals this state.
                    //In this case, this state should be completed.
                    PrepareForExit(context, targetStateId);
                }
                break;

            case ActivityInstanceState.Canceled:
                if (this.currentRunningTriggers.Get(context) == 0)
                {
                    ScheduleExit(context);
                }
                break;
            }
        }
Пример #3
0
        void ScheduleChildState(NativeActivityContext context, string id)
        {
            int index = StateMachineHelper.GetChildStateIndex(this.StateId, id);

            Debug.Assert(index >= 0 && index < this.internalStateFuncs.Count);
            context.ScheduleFunc <string, StateMachineEventManager, string>(this.internalStateFuncs[index],
                                                                            id, this.EventManager.Get(context), this.onChildStateComplete);
            this.hasRunningChildState.Set(context, true);
        }
Пример #4
0
 void OnStateComplete(NativeActivityContext context, ActivityInstance completedInstance, string result)
 {
     if (StateMachineHelper.IsAncestor(rootId, result))
     {
         int index = StateMachineHelper.GetChildStateIndex(rootId, result);
         context.ScheduleFunc <string, StateMachineEventManager, string>(this.internalStateFuncs[index], result,
                                                                         this.eventManager.Get(context), onStateComplete);
     }
 }
Пример #5
0
        protected override void Execute(NativeActivityContext context)
        {
            //We view the duration before moving to initial state is on transition.
            StateMachineEventManager localEventManager = this.eventManager.Get(context);

            localEventManager.OnTransition = true;
            int index = StateMachineHelper.GetChildStateIndex(rootId, this.InitialState.StateId);

            context.ScheduleFunc <string, StateMachineEventManager, string>(this.internalStateFuncs[index], this.InitialState.StateId,
                                                                            localEventManager, onStateComplete);
        }
Пример #6
0
        /// <summary>
        /// Do validation and if validation is successful, create internal representations for states and transitions.
        /// </summary>
        protected override void CacheMetadata(NativeActivityMetadata metadata)
        {
            //cleanup
            this.internalStateFuncs.Clear();
            this.internalStates.Clear();

            //clear Ids and Flags via transitions
            this.PassNumber++;
            TraverseViaTransitions(ClearState, ClearTransition);
            //clear Ids and Flags via children
            this.PassNumber++;
            TraverseViaChildren(ClearStates, null, ClearTransitions, false);

            //Mark via children and do some check
            this.PassNumber++;
            TraverseViaChildren(MarkStatesViaChildren,
                                delegate(State state) { StateCannotHaveMultipleParents(metadata, state); }, null, false);

            this.PassNumber++;
            //Mark via transition
            TraverseViaTransitions(delegate(State state) { MarkStateViaTransition(metadata, state); }, null);

            //Do validation via children
            //need not check the violation of state which is not reached
            this.PassNumber++;
            TraverseViaChildren(delegate(Collection <State> states) { ValidateStates(metadata, states); }, null,
                                delegate(State state) { ValidateTransitions(metadata, state); }, true);

            //Validate the root state machine itself
            ValidateStateMachine(metadata);

            if (!metadata.HasViolations)
            {
                StateMachineHelper.ProcessChildStates(metadata, this.States, this.internalStates, this.internalStateFuncs);
            }
            metadata.AddImplementationVariable(this.eventManager);
            foreach (Variable variable in this.Variables)
            {
                metadata.AddVariable(variable);
            }
        }
Пример #7
0
        static void ValidateTransitions(NativeActivityMetadata metadata, State currentState)
        {
            Collection <Transition> transitions = currentState.Transitions;
            HashSet <Activity>      conditionalTransitionTriggers = new HashSet <Activity>();
            Dictionary <Activity, List <Transition> > unconditionalTransitionMapping = new Dictionary <Activity, List <Transition> >();

            foreach (Transition transition in transitions)
            {
                if (transition.Source != null)
                {
                    metadata.AddValidationError(string.Format(CultureInfo.CurrentCulture, SR.TransitionCannotBeAddedTwice, transition.DisplayName, currentState.DisplayName, transition.Source.DisplayName));
                    continue;
                }
                else
                {
                    transition.Source = currentState;
                }

                if (transition.To == null)
                {
                    metadata.AddValidationError(string.Format(CultureInfo.CurrentCulture, SR.TransitionTargetCannotBeNull, transition.DisplayName, currentState.DisplayName));
                }
                else
                {
                    if (transition.To.States.Count > 0)
                    {
                        metadata.AddValidationError(string.Format(CultureInfo.CurrentCulture, SR.TargetStateMustBeSimpleState, transition.To.DisplayName, transition.DisplayName));
                    }

                    if (StateMachineHelper.IsAncestor(currentState.StateId, transition.To.StateId))
                    {
                        metadata.AddValidationError(string.Format(CultureInfo.CurrentCulture, SR.AncestorCannotHaveTransitionToDescendant, currentState.DisplayName, transition.DisplayName, transition.To.DisplayName));
                    }
                }

                if (transition.Trigger != null)
                {
                    if (transition.Condition == null)
                    {
                        if (!unconditionalTransitionMapping.ContainsKey(transition.Trigger))
                        {
                            unconditionalTransitionMapping.Add(transition.Trigger, new List <Transition>());
                        }
                        unconditionalTransitionMapping[transition.Trigger].Add(transition);
                    }
                    else
                    {
                        conditionalTransitionTriggers.Add(transition.Trigger);
                    }
                }
                else
                {
                    metadata.AddValidationError(string.Format(CultureInfo.CurrentCulture, SR.TriggerCannotBeNull, transition.DisplayName, currentState.DisplayName));
                }
            }
            foreach (KeyValuePair <Activity, List <Transition> > unconditionalTransitions in unconditionalTransitionMapping)
            {
                if (conditionalTransitionTriggers.Contains(unconditionalTransitions.Key) || unconditionalTransitions.Value.Count > 1)
                {
                    foreach (Transition transition in unconditionalTransitions.Value)
                    {
                        metadata.AddValidationError(string.Format(CultureInfo.CurrentCulture, SR.UnconditionalTransitionShouldnotShareTriggersWithOthers, transition.DisplayName,
                                                                  currentState.DisplayName, transition.Trigger.DisplayName));
                    }
                }
                ;
            }
        }