瀏覽代碼

added a create_and_start event to cd

Simon Van Mierlo 7 年之前
父節點
當前提交
fec138e395

+ 154 - 0
examples/my-tests/python/create_and_start.py

@@ -0,0 +1,154 @@
+"""
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
+
+Model name:   sourcechildbug
+
+"""
+
+from sccd.runtime.statecharts_core import *
+
+# package "sourcechildbug"
+
+class A(RuntimeClassBase):
+    def __init__(self, controller):
+        RuntimeClassBase.__init__(self, controller)
+        
+        self.semantics.big_step_maximality = StatechartSemantics.TakeMany
+        self.semantics.internal_event_lifeline = StatechartSemantics.Queue
+        self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
+        self.semantics.priority = StatechartSemantics.SourceParent
+        self.semantics.concurrency = StatechartSemantics.Single
+        
+        # build Statechart structure
+        self.build_statechart_structure()
+        
+        # call user defined constructor
+        A.user_defined_constructor(self)
+    
+    def user_defined_constructor(self):
+        pass
+    
+    def user_defined_destructor(self):
+        pass
+    
+    
+    # builds Statechart structure
+    def build_statechart_structure(self):
+        
+        # state <root>
+        self.states[""] = State(0, "", self)
+        
+        # state /running
+        self.states["/running"] = State(1, "/running", self)
+        self.states["/running"].setEnter(self._running_enter)
+        
+        # state /created
+        self.states["/created"] = State(2, "/created", self)
+        
+        # state /stopped
+        self.states["/stopped"] = State(3, "/stopped", self)
+        
+        # add children
+        self.states[""].addChild(self.states["/running"])
+        self.states[""].addChild(self.states["/created"])
+        self.states[""].addChild(self.states["/stopped"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/running"]
+        
+        # transition /running
+        _running_0 = Transition(self, self.states["/running"], [self.states["/created"]])
+        _running_0.setAction(self._running_0_exec)
+        _running_0.setTrigger(Event("instance_created", None))
+        self.states["/running"].addTransition(_running_0)
+        
+        # transition /created
+        _created_0 = Transition(self, self.states["/created"], [self.states["/stopped"]])
+        _created_0.setAction(self._created_0_exec)
+        _created_0.setTrigger(Event("instance_started", None))
+        self.states["/created"].addTransition(_created_0)
+    
+    def _running_enter(self):
+        self.big_step.outputEventOM(Event("create_and_start_instance", None, [self, 'to_B']))
+    
+    def _running_0_exec(self, parameters):
+        association_name = parameters[0]
+        print 'A got instance_created [%s]' % association_name
+    
+    def _created_0_exec(self, parameters):
+        association_name = parameters[0]
+        print 'A got instance_started [%s]' % association_name
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/running"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class B(RuntimeClassBase):
+    def __init__(self, controller):
+        RuntimeClassBase.__init__(self, controller)
+        
+        self.semantics.big_step_maximality = StatechartSemantics.TakeMany
+        self.semantics.internal_event_lifeline = StatechartSemantics.Queue
+        self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
+        self.semantics.priority = StatechartSemantics.SourceParent
+        self.semantics.concurrency = StatechartSemantics.Single
+        
+        # build Statechart structure
+        self.build_statechart_structure()
+        
+        # call user defined constructor
+        B.user_defined_constructor(self)
+    
+    def user_defined_constructor(self):
+        pass
+    
+    def user_defined_destructor(self):
+        pass
+    
+    
+    # builds Statechart structure
+    def build_statechart_structure(self):
+        
+        # state <root>
+        self.states[""] = State(0, "", self)
+        
+        # state /running
+        self.states["/running"] = State(1, "/running", self)
+        self.states["/running"].setEnter(self._running_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/running"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/running"]
+    
+    def _running_enter(self):
+        print 'B instance created!'
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/running"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class ObjectManager(ObjectManagerBase):
+    def __init__(self, controller):
+        ObjectManagerBase.__init__(self, controller)
+    
+    def instantiate(self, class_name, construct_params):
+        if class_name == "A":
+            instance = A(self.controller)
+            instance.associations = {}
+            instance.associations["to_B"] = Association("B", 0, 1)
+        elif class_name == "B":
+            instance = B(self.controller)
+            instance.associations = {}
+        else:
+            raise Exception("Cannot instantiate class " + class_name)
+        return instance
+
+class Controller(ThreadsControllerBase):
+    def __init__(self, keep_running = None, behind_schedule_callback = None):
+        if keep_running == None: keep_running = True
+        if behind_schedule_callback == None: behind_schedule_callback = None
+        ThreadsControllerBase.__init__(self, ObjectManager(self), keep_running, behind_schedule_callback)
+        self.addInputPort("input")
+        self.object_manager.createInstance("A", [])

+ 44 - 0
examples/my-tests/python/create_and_start.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<diagram name="sourcechildbug">
+    <inport name="input" />
+    <class name="A" default="true">
+        <relationships>
+            <association name="to_B" class="B" min="0" max="1" />
+        </relationships>
+        <scxml initial="running">
+            <state id="running">
+                <onentry>
+                    <raise event="create_and_start_instance" scope="cd">                        
+                        <parameter expr="'to_B'"/>
+                    </raise>
+                </onentry>
+                <transition target="../created" event="instance_created">
+                    <parameter name="association_name" />
+                    <script>
+                        print 'A got instance_created [%s]' % association_name
+                    </script>
+                </transition>
+            </state>
+            <state id="created">
+                <transition target="../stopped" event="instance_started">
+                    <parameter name="association_name" />
+                    <script>
+                        print 'A got instance_started [%s]' % association_name
+                    </script>
+                </transition>
+            </state>
+            <state id="stopped" />
+        </scxml>
+    </class>
+    <class name="B">
+        <scxml initial="running">
+            <state id="running">
+                <onentry>
+                    <script>
+                        print 'B instance created!'
+                    </script>
+                </onentry>
+            </state>
+        </scxml>
+    </class>
+</diagram>

+ 3 - 0
examples/my-tests/python/runner_create_and_start.py

@@ -0,0 +1,3 @@
+import create_and_start
+controller = create_and_start.Controller(False)
+controller.start()

+ 9 - 1
src/python_sccd/python_sccd_runtime/statecharts_core.py

@@ -125,7 +125,8 @@ class ObjectManagerBase(object):
                          "associate_instance": self.handleAssociateEvent,
                          "disassociate_instance": self.handleDisassociateEvent,
                          "start_instance": self.handleStartInstanceEvent,
-                         "delete_instance": self.handleDeleteInstanceEvent}
+                         "delete_instance": self.handleDeleteInstanceEvent,
+                         "create_and_start_instance": self.handleCreateAndStartEvent}
         self.lock = threading.Condition()
         
     def addEvent(self, event, time_offset = 0):
@@ -235,8 +236,15 @@ class ObjectManagerBase(object):
             if p:
                 p.addInstance(source)
             source.addEvent(Event("instance_created", None, [association_name+"["+str(index)+"]"]))
+            return [source, association_name+"["+str(index)+"]"]
         else:
             source.addEvent(Event("instance_creation_error", None, [association_name]))
+            return []
+
+    def handleCreateAndStartEvent(self, parameters):
+        params = self.handleCreateEvent(parameters)
+        if params:
+            self.handleStartInstanceEvent(params)
 
     def handleDeleteInstanceEvent(self, parameters):
         if len(parameters) < 2: