Exemple #1
0
        // public class DoorContext : Context<StateRoot, DoorContext>

        private void WriteClass(StateType state)
        {
            if (state.Type.HasFlag(StateType.TypeFlags.TOP) == true)
            {
                string contextClassName       = GetContextClassName(state);
                string contextParentClassName = GetContextParentClassName(state);

                string stateClassName = GetStateClassName(state);
                // class DoorContext
                CodeTypeDeclaration contextCode = new CodeTypeDeclaration(contextClassName);

                // doc
                contextCode.Comments.Add(new CodeCommentStatement(contextClassName));

                // public
                contextCode.Attributes = MemberAttributes.Public;

                // Context<StateTop, DoorContext> or ContextAsync<StateTop, DoorContext>
                contextCode.BaseTypes.Add(new CodeTypeReference(GetContextBaseClassName(state),
                                                                new CodeTypeReference[] { new CodeTypeReference(stateClassName),
                                                                                          new CodeTypeReference(contextParentClassName) }));

                foreach (KeyValuePair <string, string> kvp in Model.EventInterfaceMap)
                {
                    string interfaceName = kvp.Key;
                    contextCode.BaseTypes.Add(new CodeTypeReference(interfaceName));
                }

                CodeNamespace.Types.Add(contextCode);

                WriteFields(contextCode);
                WriteFieldsParallel(contextCode, state);
                WriteFieldsTimer(contextCode, state);
                WriteConstructor(contextCode, state);
                WriteEvents(contextCode, state);

                WriteMethodSetState(contextCode, state);
                WriteMethodEnterInitialState(contextCode, state);
                WriteMethodLeaveCurrentState(contextCode, state);
                WriteMethodEnterHistoryState(contextCode, state);

                WriteInitializeTimers(contextCode, state);
                WriteTimersStartStop(contextCode, state);
                WriteProperties(contextCode);
                WritePropertiesParallel(contextCode, state);
            }

            if (state.parallel != null)
            {
                foreach (StateType stateOrthogonal in state.parallel.state)
                {
                    WriteClass(stateOrthogonal);
                }
            }

            if (state.state != null)
            {
                foreach (StateType stateChild in state.state)
                {
                    WriteClass(stateChild);
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Set the current state given its name
        ///public override void SetState(string stateName)
        ///{
        ///    if ((stateName == "Running"))
        ///    {
        ///        this.SetInitialState(PersistenceParallelRunningState.Instance);
        ///        this.ContextParallel = this.PersistenceParallelRunningParallel;
        ///        this.ContextParallel.ActiveState = 2;
        ///        return;
        ///    }
        ///    if ((stateName == "End"))
        ///    {
        ///        this.SetInitialState(PersistenceParallelEndState.Instance);
        ///        return;
        ///    }
        ///    throw new System.ArgumentException();
        ///}
        /// </summary>
        /// <param name="state"></param>
        /// <param name="contextCode"></param>
        /// <summary>

        private void WriteMethodSetState(CodeTypeDeclaration contextCode, StateType state)
        {
            CodeMemberMethod setStateMethod = new CodeMemberMethod();

            contextCode.Members.Add(setStateMethod);
            setStateMethod.Comments.Add(new CodeCommentStatement("Set the current state given its name"));
            setStateMethod.Name       = "SetState";
            setStateMethod.Attributes = MemberAttributes.Public | MemberAttributes.Override;
            string stateNameVar = "stateName";

            setStateMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference("System.String"), stateNameVar));

            foreach (StateType subState in state.ChildList)
            {
                var codeBinaryOperatorExpression = new CodeBinaryOperatorExpression(
                    new CodeVariableReferenceExpression(stateNameVar),
                    CodeBinaryOperatorType.IdentityEquality,
                    new CodePrimitiveExpression(subState.name));

                var conditionalStatement = new CodeConditionStatement(codeBinaryOperatorExpression);

                // PersistenceOnState.Instance
                string subStateClassName = GetStateClassName(subState);
                var    stateDotInstance  = new CodeFieldReferenceExpression(new CodeVariableReferenceExpression(subStateClassName), "Instance");

                // SetInitialState(PersistenceOnState.Instance);
                CodeMethodInvokeExpression setInitialStateInvoke = new CodeMethodInvokeExpression(
                    new CodeThisReferenceExpression(),
                    "SetInitialState",
                    stateDotInstance);
                conditionalStatement.TrueStatements.Add(setInitialStateInvoke);

                if (subState.Type.HasFlag(StateType.TypeFlags.PARALLEL) == true)
                {
                    //this.ContextParallel = this.PersistenceParallelRunningParallel;
                    var contextParallelVar      = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "ContextParallel");
                    var parallelVar             = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), GetParallelClassName(subState));
                    var statementAssignParallel = new CodeAssignStatement(contextParallelVar, parallelVar);
                    conditionalStatement.TrueStatements.Add(statementAssignParallel);

                    // this.ContextParallel.ActiveState;
                    var parallelRunningDotActiveState = new CodeFieldReferenceExpression(contextParallelVar, "ActiveState");

                    // this.ContextParallel.ActiveState = 2;
                    CodeStatement parallelRunningActiveStateSet = new CodeAssignStatement(parallelRunningDotActiveState,
                                                                                          new CodePrimitiveExpression(subState.parallel.state.Length));

                    conditionalStatement.TrueStatements.Add(parallelRunningActiveStateSet);
                }

                conditionalStatement.TrueStatements.Add(new CodeMethodReturnStatement());
                setStateMethod.Statements.Add(conditionalStatement);
            }

            var statetementThrow = new CodeThrowExceptionStatement(
                new CodeObjectCreateExpression(
                    new CodeTypeReference(typeof(System.ArgumentException)),
                    new CodeExpression[] { }));

            setStateMethod.Statements.Add(statetementThrow);
        }
Exemple #3
0
        /// <summary>
        /// Fill the state parent and Type, add the state to the map state.
        /// This is a recursive function.
        /// </summary>
        /// <param name="state"></param>
        /// <param name="stateParent"></param>
        private void FillState(StateType state, StateType stateParent, StateType stateParallel)
        {
            if (stateMap.ContainsKey(state.name) == true)
            {
                ts.TraceEvent(TraceEventType.Error, 1, "FillState:  {0} already exist", state.name);
            }
            else
            {
                stateMap.Add(state.name, state);
            }

            state.Parent        = stateParent;
            state.StateParallel = stateParallel;



            ts.TraceEvent(TraceEventType.Verbose, 1, "FillState:  {0}", state.name);

            if (state.kindSpecified == true)
            {
                switch (state.kind)
                {
                case StateKindType.final:
                    state.Type = state.Type | StateType.TypeFlags.FINAL;
                    break;

                case StateKindType.history:
                    state.Type = state.Type | StateType.TypeFlags.HISTORY;
                    break;

                default:
                    //Should not happen
                    break;
                }
            }

            StateType stateTop = GetStateTop(state);

            if ((stateParent != null) && (state.Type.HasFlag(StateType.TypeFlags.HISTORY) == false))
            {
                stateTop.ChildAdd(state);
            }

            if (state.parallel != null)
            {
                // Parallel region
                state.Type = state.Type | StateType.TypeFlags.PARALLEL | StateType.TypeFlags.LEAF;

                stateTop.ParallelList.Add(state);

                if (state.parallel.state != null)
                {
                    foreach (StateType stateOrthogonal in state.parallel.state)
                    {
                        FillState(stateOrthogonal, null, state);
                    }
                }
            }
            else if (state.state == null)
            {
                // No child
                state.Type = state.Type | StateType.TypeFlags.LEAF;
            }
            else
            {
                // Childs
                state.Type = state.Type | StateType.TypeFlags.COMPOSITE;

                if (state.HasChildHistory())
                {
                    state.Type = state.Type | StateType.TypeFlags.HAS_HISTORY;
                }

                if (stateParent == null)
                {
                    state.Type = state.Type | StateType.TypeFlags.TOP;
                    //For top states in a parallel state machines, set the flag to HAS_HISTORY, it saves the current state upon OnExit
                    if ((state.StateParallel != null) && state.StateParallel.HasParentStateHistory())
                    {
                        state.Type = state.Type | StateType.TypeFlags.HAS_HISTORY;
                    }
                }

                if ((state.kindSpecified == true) && (state.kind == StateKindType.final))
                {
                    // TODO  ERROR Composite state cannot have error or final atttribute
                }

                foreach (StateType stateChild in state.state)
                {
                    FillState(stateChild, state, stateParallel);
                }
            }
        }
Exemple #4
0
        //
        //public DoorContext(Door door) : base(contextParent)
        //public DoorContext(Door door, DoorContextParent contextParent) : base(contextParent)
        //public MicrowaveContext(Microwave microwave)
        //{
        //    Name = "MicrowaveContext";
        //    this._microwave = microwave;
        //    this.InitializeTimers();
        //    this._parallelOperating = new MicrowaveContextOperatingParallel(microwave, this);
        //    this.SetInitialState(MicrowaveInitialState.Instance);
        //}
        private void WriteConstructor(CodeTypeDeclaration contextCode, StateType state)
        {
            CodeConstructor ctor = new CodeConstructor();

            ctor.Attributes = MemberAttributes.Public;
            ctor.Comments.Add(new CodeCommentStatement("Constructor"));
            ObjectType[] objects = Model.settings.@object;

            string contextClassName       = GetContextClassName(state);
            string contextParentClassName = GetContextParentClassName(state);

            foreach (ObjectType obj in Model.settings.@object)
            {
                ctor.Parameters.Add(new CodeParameterDeclarationExpression(obj.@class, obj.instance));
            }

            if (Model.IsRoot(state) == false)
            {
                ctor.Parameters.Add(new CodeParameterDeclarationExpression(contextParentClassName, "contextParent"));
                ctor.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("contextParent"));
            }

            // Name = "DoorContext";
            ctor.Statements.Add(
                new CodeAssignStatement(new CodeVariableReferenceExpression("Name"),
                                        new CodePrimitiveExpression(contextClassName)));

            // this._door = door;
            foreach (ObjectType obj in Model.settings.@object)
            {
                ctor.Statements.Add(
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(
                            new CodeThisReferenceExpression(),
                            GetObjectFieldName(obj.instance)),
                        new CodeVariableReferenceExpression(obj.instance)));
            }

            WriteParallelNew(ctor, state);

            // this.InitializeTimers()
            if ((Model.GetTimersAll().Count != 0) && (Model.IsRoot(state) == true))
            {
                CodeMethodInvokeExpression initializeTimersMethod = new CodeMethodInvokeExpression(
                    new CodeThisReferenceExpression(),
                    "InitializeTimers");
                ctor.Statements.Add(initializeTimersMethod);
            }

            // Get the initial state
            string stateInitialClassName = GetStateClassName(GetStateInitial(state));

            // SetInitialState(StateIdle.Instance);
            CodeMethodInvokeExpression setInitialStateInvoke = new CodeMethodInvokeExpression(
                new CodeThisReferenceExpression(),
                "SetInitialState");

            setInitialStateInvoke.Parameters.Add(new CodeFieldReferenceExpression(new CodeVariableReferenceExpression(stateInitialClassName), "Instance"));

            ctor.Statements.Add(setInitialStateInvoke);

            contextCode.Members.Add(ctor);
        }
Exemple #5
0
        /// <summary>
        /// Returns the context depth between the state and the next state.
        /// </summary>
        /// <param name="state">The current state.</param>
        /// <param name="stateNext">The next state.</param>
        /// <returns></returns>
        public int ContextDepth(StateType state, StateType stateNext)
        {
            int depth = 0;

            return(ContextDepth(state, stateNext, depth));
        }
Exemple #6
0
 /// <summary>
 /// Is this state the root state
 /// </summary>
 /// <param name="state"></param>
 /// <returns></returns>
 public bool IsRoot(StateType state)
 {
     return(state.Type.HasFlag(StateType.TypeFlags.ROOT));
 }
 /// <summary>
 /// Get the state class name: DoorXxxState
 /// </summary>
 /// <param name="state"></param>
 /// <returns></returns>
 protected string GetStateClassName(StateType state)
 {
     return(Model.settings.name + state.name + "State");
 }
Exemple #8
0
 /// <summary>
 /// Add a state to the state map.
 /// </summary>
 /// <param name="state"></param>
 public void AddState(StateType state)
 {
     stateMap[state.name] = state;
 }
        // If next state is final, invoke:
        // context.OnEnd();
        // or
        // context.ContextParent.OnEnd();
        protected void WriteContextOnEnd(CodeStatementCollection statements, StateType state, StateType stateNext)
        {
            //Special case when the next state is a final state.
            if ((stateNext != null) && (stateNext.Type.HasFlag(StateType.TypeFlags.FINAL)))
            {
                statements.Add(new CodeCommentStatement("Notify the end of this state machine."));

                // context or context.ContextParent or context.ContextParent.ContextParent .... depending where is stateNext compared to state.
                var contextExpression = GetContextParentExpression(state, stateNext);

                // context.OnEnd();
                CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression(
                    contextExpression,
                    "OnEnd");
                statements.Add(methodInvoke);
            }
        }
        //}
        // StateMachineHelper.ProcessTransitionBegin<DoorContext, DoorContext, StateTop>(context, StateNext.Instance);
        // or
        // StateMachineHelper.ProcessTransitionEnd<DoorContext, DoorContext, StateTop>(context, StateNext.Instance);
        protected void WriteProcessTransition(CodeStatementCollection statements, StateType state, string nextStateName, string suffix)
        {
            CodeExpression[] paramsRef;

            StateType stateNext = Model.GetStateType(nextStateName);

            string stateTopClassName;
            string contextClassName;
            string contextParentClassName;
            // context or context.ContextParent or context.ContextParent.ContextParent .... depending where is stateNext compared to state.
            var contextExpression = GetContextParentExpression(state, stateNext);

            if (stateNext == null)
            {
                //Internal transition
                paramsRef = new CodeExpression[] {
                    contextExpression,
                    new CodePrimitiveExpression(null)
                };

                stateTopClassName      = GetStateClassName(Model.GetStateTop(state));
                contextClassName       = GetContextClassName(state);
                contextParentClassName = GetContextParentClassName(state);
            }
            else
            {
                CodeExpression nextStateExpression;

                if (stateNext.Type.HasFlag(StateType.TypeFlags.HISTORY))
                {
                    // context.StateHistory
                    nextStateExpression = new CodeFieldReferenceExpression(
                        new CodeVariableReferenceExpression(Model.settings.context.instance),
                        "StateHistory");
                }
                else
                {
                    StateType stateLeaf = Model.GetStateLeaf(stateNext);
                    // NextState.Instance
                    nextStateExpression = new CodeFieldReferenceExpression(
                        new CodeVariableReferenceExpression(GetStateClassName(stateLeaf)),
                        "Instance");
                }

                stateTopClassName      = GetStateClassName(Model.GetStateTop(stateNext));
                contextClassName       = GetContextClassName(stateNext);
                contextParentClassName = GetContextParentClassName(stateNext);
                paramsRef = new CodeExpression[] {
                    contextExpression,
                    nextStateExpression
                };
            }

            // param StateRunning.Instance
            var onMethodInvoke = new CodeMethodInvokeExpression(
                new CodeMethodReferenceExpression(
                    new CodeVariableReferenceExpression("StateMachineHelper"),
                    "ProcessTransition" + suffix,
                    new CodeTypeReference[] {
                new CodeTypeReference(contextClassName),
                new CodeTypeReference(contextParentClassName),
                new CodeTypeReference((stateTopClassName))
            }),
                paramsRef);

            statements.Add(onMethodInvoke);
        }
 protected string GetParallelFieldName(StateType state)
 {
     return("_parallel" + state.name);
 }
 protected string GetParallelLocalVariableName(StateType state)
 {
     return("parallel" + state.name);
 }
 protected string GetParallelClassName(StateType state)
 {
     return(Model.settings.name + state.name + "Parallel");
 }