Beispiel #1
0
 public void CreateTrigger(StateMachine sm)
 {
     if (null != Condition)
     {
         var trigger = new Trigger(Event, Condition);
         trigger.AddEffects(Effects);
         sm.AddTrigger(trigger);
     }
     else if(Effects.Any())
     {
         var trigger = new Trigger(Event, new AnyCondition());
         trigger.AddEffects(Effects);
         sm.AddTrigger(trigger);
     }
 }
Beispiel #2
0
        private void ValidateTrigger(Trigger trigger)
        {
            var tset = trigger.Transitions;
            foreach (var v in tset.Variables)
            {
                var branches = new List<IGate>();
                foreach(var t in tset.GetTransitions(v))
                {
                    var c = t.PreCondition;

                    // preconditions must not intersect
                    foreach(var b in branches)
                    {
                        var sum = Gate.ComposeAND(c, b);
                        if(!(sum is FalseGate))
                        {
                        }
                    }

                    branches.Add(c);
                }
            }

            var tlist = new List<Trigger>();
        }
Beispiel #3
0
        /// <summary>
        /// Adds a trigger to the state machine.
        /// </summary>
        /// <param name="trigger">The trigger object to add.</param>
        public void AddTrigger(Trigger trigger)
        {
            var e = trigger.Event;

            SetModify();

            try
            {
                TraceDependencies("add trigger '{0}' ...", trigger.Name);

                // ValidateTrigger(trigger);

                var tlist = new List<ProductTrigger>();

                // examinate the precondition ...
                var precondition = trigger.PreCondition;

                if (precondition.Type == GateType.Fixed)
                {
                    // constant
                    if (precondition is FalseGate)
                    {
                        Trace("SMG033: warning: trigger '{0}' precondition is never met.", trigger);
                    }
                    else if (precondition is TrueGate)
                    {
                        Trace("SMG034: warning: trigger '{0}' precondition is always true.", trigger);
                        tlist.Add(new ProductTrigger(trigger));
                    }
                }
                else if (precondition.Type == GateType.OR)
                {
                    // OR combination, split into multiple simple triggers
                    var inputs = precondition.GetInputs();
                    TraceDependencies("split trigger [{0}] into its branches ...", inputs.ToSeparatorList());

                    // analyze conditions
                    // TraceDependencies("{0}", trigger.Transitions.ToDebugString());

                    // split into multiple triggers
                    foreach (var product in inputs)
                    {
                        // extract the transition subset for the guard condition
                        var tset = new TransitionSet(trigger.Transitions, product);
                        TraceDependencies("  transition set of branch [{0}]: {1}", product, tset.ToDebugString());

                        var pre = ReplaceVariableCondition(tset, product, false);
                        var post = ReplaceVariableCondition(tset, product, true);

                        TraceDependencies("  branch conditions [{0} => {1}].", pre, post);

                        // add branch trigger
                        tlist.Add(new ProductTrigger(trigger, tset, pre, post));
                    }
                }
                else
                {
                    // add original trigger
                    tlist.Add(new ProductTrigger(trigger));
                }

                // process resulting triggers
                foreach (var t1 in tlist)
                {
                    TraceDependencies("product trigger {0} ...", t1);
                    TraceDependencies("  conditions [{0}, {1}] ...", t1.PreCondition, t1.PostCondition);
                    TraceDependencies("  transitions {0}", trigger.Transitions.ToDebugString());

                    t1.Qualify();

                    // check if any existing trigger is conflicting
                    foreach (var existingtrigger in e.Triggers)
                    {
                        // the new trigger precondition must not intersect any existing precondition
                        var product = Gate.ComposeAND(existingtrigger.PreCondition, t1.PreCondition);
                        product = ReplaceTransitionVariables(existingtrigger.Transitions, product, false);
                        if (!product.IsFalse())
                        {
                            throw new CompilerException(ErrorCode.AmbigousPreCondition, "ambigous transition conditions [" +
                                existingtrigger.PreCondition + ", " + t1.PreCondition + "].");
                        }
                    }

                    e.Triggers.Add(t1);
                }
            }
            catch(CompilerException ex)
            {
                AddError(ex);
            }
        }
Beispiel #4
0
 internal void AddTrigger(Trigger t)
 {
     _triggers.Add(t);
 }
Beispiel #5
0
 /// <summary>
 /// Creates a trigger based on another trigger, with new conditions.
 /// </summary>
 /// <param name="parent">The original trigger.</param>
 /// <param name="tset">The corresponding transition set.</param>
 /// <param name="pre">The precondition for the new trigger.</param>
 /// <param name="post">The postcondition for the new trigger.</param>
 protected Trigger(Trigger parent, TransitionSet tset, IGate pre, IGate post)
     : base(tset, pre, post)
 {
     Event = parent.Event;
     AddEffects(parent.Effects);
 }
Beispiel #6
0
 /// <summary>
 /// Creates a trigger based on another trigger, with new conditions.
 /// </summary>
 /// <param name="parent">The original trigger.</param>
 /// <param name="tset">The corresponding transition set.</param>
 /// <param name="pre">The precondition for the new trigger.</param>
 /// <param name="post">The postcondition for the new trigger.</param>
 internal ProductTrigger(Trigger parent, TransitionSet tset, IGate pre, IGate post)
     : base(parent, tset, pre, post)
 {
 }
Beispiel #7
0
 public ProductTrigger(Trigger parent)
     : base(parent, parent.Transitions, parent.PreCondition, parent.PostCondition)
 {
 }
Beispiel #8
0
        public void SMG_05_01_CodeGeneration()
        {
            var cc = new StateMachineCompiler();
            cc.CompileString(ReadEmbeddedScript("CodeGeneration.smg"));

            cc.GenerateCode();
            Assert.AreEqual(2, cc.SM.Events.Count());

            var u = cc.SM.AddEvent("u");
            var trigger = new Trigger(u, cc.EvaluateCondition("s(b => a)"));
            trigger.AddEffects(new[] { new CallEffect(cc.SM, "m") });
            cc.SM.AddTrigger(trigger);

            Assert.IsFalse(cc.SM.IsPrepared);

            cc.Parameters.IsProcessEventPublic = true;

            cc.GenerateCode();

            Assert.IsTrue(cc.SM.IsPrepared);
            Assert.AreEqual(3, cc.SM.Events.Count());

            Trace("output:\n{0}", cc.Output);

            var csharp = new CSharpCodeProvider();
            var options = new CompilerParameters();

            var result = csharp.CompileAssemblyFromSource(options, cc.Output);

            if (result.Errors.Count > 0)
            {
                foreach (var e in result.Errors)
                {
                    Trace("{0}", e);
                }

                Assert.Fail("generated code failed to compile.");
            }

            var dll = result.CompiledAssembly;
            var type = dll.GetType("CodeGeneration");
            var eventtype = dll.GetType("EventCode");
            var events = Enum.GetValues(eventtype);

            var x = Activator.CreateInstance(type);

            var tostatestring = type.GetMethod("ToStateString");
            Trace("initial state [{0}].", tostatestring.Invoke(x, new object[0]));

            var processevent = type.GetMethod("ProcessEvent");
            var sendevent = events.GetValue(0);
            Trace("sending event '{0}' ...", sendevent);
            processevent.Invoke(x, new object[] { sendevent });

            var statestring = tostatestring.Invoke(x, new object[0]).ToString();
            Trace("state after [{0}].", statestring);

            Assert.AreEqual("s(b) t(b) f(0)", statestring);

            sendevent = events.GetValue(1);
            Trace("sending event '{0}' ...", sendevent);
            processevent.Invoke(x, new object[] { sendevent });

            statestring = tostatestring.Invoke(x, new object[0]).ToString();
            Trace("state after [{0}].", statestring);

            Assert.AreEqual("s(b) t(a) f(1)", statestring);
        }
Beispiel #9
0
        public void SMG_03_StateCondition()
        {
            TraceFlags.ShowDepencencyAnalysis = true;

            var sm = new StateMachine();
            var stype = new SimpleStateType("State");
            stype.AddStateNames(new[] { "A", "B", "C" });
            var s = sm.AddVariable("s", stype);
            var t = sm.AddVariable("t", stype);

            var c = new StateCondition(s);
            c.SetPreStates("A,B");
            c.SetPostStates("C");

            var e1 = sm.AddEvent("e1");

            var trigger = new Trigger(e1, c);
            sm.AddTrigger(trigger);

            var gc1 = new StateCondition(s);
            gc1.SetPreStates("A");
            // gc1.SetPostStates("C");
            sm.AddGuard(gc1, GuardType.LEAVE, "g1");

            var gc2 = new StateCondition(s);
            gc2.SetPreStates("C");
            sm.AddGuard(gc2, GuardType.ENTER, "g2");

            {
                var c1 = new StateCondition(t);
                c1.SetPreStates("A");

                var c2 = new StateCondition(s);
                c2.SetPreStates("A");
            }

            sm.Calculate();

            // sm.Dump();

            var e = sm.Events.First();
            Assert.AreEqual("e1", e.Name);
            Assert.AreEqual(2, e.Triggers.Count);

            var t1 = e.Triggers[0];
            var t2 = e.Triggers[1];

            Assert.AreEqual(2, t1.Guards.Count);
            Assert.AreEqual(1, t2.Guards.Count);

            Assert.IsTrue(t1.Guards.Any(g => g.Name == "g1"));
            Assert.IsTrue(t1.Guards.Any(g => g.Name == "g2"));
            Assert.IsTrue(t2.Guards.Any(g => g.Name == "g2"));
        }