Explorar el Código

added tests for deletion and associations

sampieters hace 1 año
padre
commit
6e5491d154
Se han modificado 50 ficheros con 3441 adiciones y 375 borrados
  1. 9 3
      sccd/runtime/DEVS_statecharts_core.py
  2. 4 0
      tests/BrokenDeletion/PyDEVS/log.txt
  3. 20 0
      tests/BrokenDeletion/PyDEVS/runner.py
  4. 189 0
      tests/BrokenDeletion/PyDEVS/target.py
  5. 8 0
      tests/BrokenDeletion/Python/log.txt
  6. 16 0
      tests/BrokenDeletion/Python/runner.py
  7. 178 0
      tests/BrokenDeletion/Python/target.py
  8. 76 0
      tests/BrokenDeletion/sccd.xml
  9. 58 2
      tests/Test10/sccd.xml
  10. 3 135
      tests/Test11/Python/target.py
  11. 2 58
      tests/Test11/sccd.xml
  12. 1 1
      tests/Test12/PyDEVS/runner.py
  13. 8 62
      tests/Test12/PyDEVS/target.py
  14. 8 62
      tests/Test12/Python/target.py
  15. 7 52
      tests/Test12/sccd.xml
  16. 4 0
      tests/Test13/PyDEVS/log.txt
  17. 20 0
      tests/Test13/PyDEVS/runner.py
  18. 221 0
      tests/Test13/PyDEVS/target.py
  19. 8 0
      tests/Test13/Python/log.txt
  20. 16 0
      tests/Test13/Python/runner.py
  21. 188 0
      tests/Test13/Python/target.py
  22. 77 0
      tests/Test13/sccd.xml
  23. 4 0
      tests/Test14/PyDEVS/log.txt
  24. 20 0
      tests/Test14/PyDEVS/runner.py
  25. 224 0
      tests/Test14/PyDEVS/target.py
  26. 8 0
      tests/Test14/Python/log.txt
  27. 16 0
      tests/Test14/Python/runner.py
  28. 191 0
      tests/Test14/Python/target.py
  29. 78 0
      tests/Test14/sccd.xml
  30. 4 0
      tests/Test15/PyDEVS/log.txt
  31. 20 0
      tests/Test15/PyDEVS/runner.py
  32. 224 0
      tests/Test15/PyDEVS/target.py
  33. 8 0
      tests/Test15/Python/log.txt
  34. 16 0
      tests/Test15/Python/runner.py
  35. 191 0
      tests/Test15/Python/target.py
  36. 79 0
      tests/Test15/sccd.xml
  37. 4 0
      tests/Test22/PyDEVS/log.txt
  38. 20 0
      tests/Test22/PyDEVS/runner.py
  39. 243 0
      tests/Test22/PyDEVS/target.py
  40. 8 0
      tests/Test22/Python/log.txt
  41. 16 0
      tests/Test22/Python/runner.py
  42. 210 0
      tests/Test22/Python/target.py
  43. 99 0
      tests/Test22/sccd.xml
  44. 4 0
      tests/Test23/PyDEVS/log.txt
  45. 20 0
      tests/Test23/PyDEVS/runner.py
  46. 243 0
      tests/Test23/PyDEVS/target.py
  47. 8 0
      tests/Test23/Python/log.txt
  48. 16 0
      tests/Test23/Python/runner.py
  49. 233 0
      tests/Test23/Python/target.py
  50. 113 0
      tests/Test23/sccd.xml

+ 9 - 3
sccd/runtime/DEVS_statecharts_core.py

@@ -611,8 +611,8 @@ class RuntimeClassBase(object):
             if state.enter:
                 state.enter()
         if self.eventless_states:
-            print("")
             pass
+            # TODO: Check (untill now no problems)
             #self.controller.object_manager.eventless.add(self)
 
 class BigStepState(object):
@@ -994,6 +994,7 @@ class ObjectManagerBase(AtomicDEVS):
                 association = current["instance"].associations[name]
                 if (index >= 0 ):
                     try:
+                        check = association.instances[index]
                         nexts.append({
                             "to_class": association.to_class,
                             "instance": index,
@@ -1076,7 +1077,11 @@ class ObjectManagerBase(AtomicDEVS):
                     i.user_defined_destructor()
                     i.stop()
                 self.instances = {key: value for key, value in self.instances.items() if key not in input[2].parameters[1]}
-                ev = Event("instance_deleted", None, input[2].parameters[1], input[2].instance)
+
+                #if not isinstance(input[2].parameters[1], list):
+                    
+
+                ev = Event("instance_deleted", None, [input[2].parameters[0]], input[2].instance)
                 self.to_send.append((input[1], input[0], ev))
             elif input[2].name == "instance_created":
                 instance = self.instances[input[2].instance]
@@ -1101,7 +1106,8 @@ class ObjectManagerBase(AtomicDEVS):
                 instance = self.instances[input[2].instance]
                 for association in instance.associations.items():
                     if association[1].to_class == input[0]:
-                        for index in input[2].parameters:
+                        for assoc in input[2].parameters:
+                            index = self.processAssociationReference(assoc)[0][1]
                             association[1].removeInstance(index)
                 instance.addEvent(input[2])
             else:

+ 4 - 0
tests/BrokenDeletion/PyDEVS/log.txt

@@ -0,0 +1,4 @@
+0.00s - Debugger warning: It seems that frozen modules are being used, which may
+0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
+0.00s - to python to disable frozen modules.
+0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.

+ 20 - 0
tests/BrokenDeletion/PyDEVS/runner.py

@@ -0,0 +1,20 @@
+import target as target
+from sccd.runtime.DEVS_loop import DEVSSimulator
+from sccd.runtime.statecharts_core import Event
+
+class OutputListener:
+	def add(self, events):
+		for event in events:
+			if event.port == "ui":
+				print(event.name, ", received on:", event.parameters[0], "seconds, parameters:", event.parameters[1:])
+				
+
+if __name__ == '__main__':
+	controller = target.Controller(name="controller")
+	refs = {"ui": controller.in_ui}
+	sim = DEVSSimulator(controller, refs)
+
+	listener = OutputListener()
+	sim.setListenPorts(controller.out_ui, listener.add)
+	sim.simulate()
+

+ 189 - 0
tests/BrokenDeletion/PyDEVS/target.py

@@ -0,0 +1,189 @@
+"""
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration) and Sam Pieters (DEVS)
+
+Model author: Sam Pieters
+Model name:   Create and Delete an Instance (other than the MainApp)
+Model description:
+Test 12: Check if an instance can be deleted after the creation, the instance is not started yet.
+"""
+
+from sccd.runtime.DEVS_statecharts_core import *
+
+# package "Create and Delete an Instance (other than the MainApp)"
+
+class MainAppInstance(RuntimeClassBase):
+    def __init__(self, atomdevs):
+        RuntimeClassBase.__init__(self, atomdevs)
+        self.associations = {}
+        self.associations["linkA"] = Association("A", 0, -1)
+        
+        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
+        MainAppInstance.user_defined_constructor(self)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
+    
+    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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("instance_created", None))
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state2"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("instance_deleted", None))
+        self.states["/state2"].addTransition(_state2_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state1_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, association_name]))
+    
+    def _state2_0_exec(self, parameters):
+        deleted_links = parameters[0]
+        self.big_step.outputEvent(Event("instance_deleted_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class MainApp(ObjectManagerBase):
+    def __init__(self, name):
+        ObjectManagerBase.__init__(self, name)
+        self.input = self.addInPort("input")
+        self.output = self.addOutPort("ui")
+        self.outputs["linkA"] = self.addOutPort("linkA")
+        self.instances[self.next_instance] = MainAppInstance(self)
+        self.next_instance = self.next_instance + 1
+    
+    def constructObject(self, parameters):
+        new_instance = MainAppInstance(self)
+        return new_instance
+
+class AInstance(RuntimeClassBase):
+    def __init__(self, atomdevs):
+        RuntimeClassBase.__init__(self, atomdevs)
+        self.associations = {}
+        
+        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
+        AInstance.user_defined_constructor(self)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
+    
+    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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+    
+    def _state1_enter(self):
+        self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class A(ObjectManagerBase):
+    def __init__(self, name):
+        ObjectManagerBase.__init__(self, name)
+        self.input = self.addInPort("input")
+        self.output = self.addOutPort("ui")
+    
+    def constructObject(self, parameters):
+        new_instance = AInstance(self)
+        return new_instance
+
+class ObjectManagerState:
+    def __init__(self):
+        self.to_send = [("MainApp", "MainApp", Event("start_instance", None, ["MainApp[0]"], 0))]
+
+class ObjectManager(TheObjectManager):
+    def __init__(self, name):
+        TheObjectManager.__init__(self, name)
+        self.State = ObjectManagerState()
+        self.input = self.addInPort("input")
+        self.output["MainApp"] = self.addOutPort()
+        self.output["A"] = self.addOutPort()
+
+class Controller(CoupledDEVS):
+    def __init__(self, name):
+        CoupledDEVS.__init__(self, name)
+        self.in_ui = self.addInPort("ui")
+        Ports.addInputPort("ui")
+        self.out_ui = self.addOutPort("ui")
+        Ports.addOutputPort("ui")
+        self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
+        self.atomic0 = self.addSubModel(MainApp("MainApp"))
+        self.atomic1 = self.addSubModel(A("A"))
+        self.connectPorts(self.atomic0.obj_manager_out, self.objectmanager.input)
+        self.connectPorts(self.objectmanager.output["MainApp"], self.atomic0.obj_manager_in)
+        self.connectPorts(self.atomic0.outputs["linkA"], self.atomic1.input)
+        self.connectPorts(self.atomic1.obj_manager_out, self.objectmanager.input)
+        self.connectPorts(self.objectmanager.output["A"], self.atomic1.obj_manager_in)
+        self.connectPorts(self.atomic0.output, self.out_ui)
+        self.connectPorts(self.atomic1.output, self.out_ui)

+ 8 - 0
tests/BrokenDeletion/Python/log.txt

@@ -0,0 +1,8 @@
+instance_created_succesfully , received on: 0.00 seconds, parameters: ['linkA[0]']
+statechart_started_succesfully , received on: 0.00 seconds, parameters: []
+constructor_initialized_succesfully , received on: 0.00 seconds, parameters: []
+instance_started_succesfully , received on: 0.00 seconds, parameters: ['linkA[0]']
+0.00s - Debugger warning: It seems that frozen modules are being used, which may
+0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
+0.00s - to python to disable frozen modules.
+0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.

+ 16 - 0
tests/BrokenDeletion/Python/runner.py

@@ -0,0 +1,16 @@
+import target as target
+from sccd.runtime.statecharts_core import Event
+import threading
+
+class OutputListener:
+	def add(self, event):
+		if event.port == "ui":
+			print(event.name, ", received on:", event.parameters[0], "seconds, parameters:", event.parameters[1:])
+				
+
+if __name__ == '__main__':
+	controller = target.Controller()
+	controller.keep_running = False
+	controller.addMyOwnOutputListener(OutputListener())
+	controller.setVerbose(None)
+	controller.start()

+ 178 - 0
tests/BrokenDeletion/Python/target.py

@@ -0,0 +1,178 @@
+"""
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
+
+Model author: Sam Pieters
+Model name:   Create and Delete Multiple Instances of the same type (other than the MainApp)
+Model description:
+Test 13: Check if multiple instances can be deleted after the creation, the instance is not started yet.
+"""
+
+from sccd.runtime.statecharts_core import *
+
+# package "Create and Delete Multiple Instances of the same type (other than the MainApp)"
+
+class MainApp(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
+        MainApp.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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        self.states["/state2"].setEnter(self._state2_enter)
+        
+        # state /state3
+        self.states["/state3"] = State(3, "/state3", self)
+        self.states["/state3"].setEnter(self._state3_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].addChild(self.states["/state3"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("instance_created", None))
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state3"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("instance_created", None))
+        self.states["/state2"].addTransition(_state2_0)
+        
+        # transition /state3
+        _state3_0 = Transition(self, self.states["/state3"], [self.states["/state3"]])
+        _state3_0.setAction(self._state3_0_exec)
+        _state3_0.setTrigger(Event("instance_deleted", None))
+        self.states["/state3"].addTransition(_state3_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state2_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state3_enter(self):
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, 'linkA[1]']))
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, 'linkA[0]']))
+    
+    def _state1_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+    
+    def _state2_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+    
+    def _state3_0_exec(self, parameters):
+        deleted_links = parameters[0]
+        self.big_step.outputEvent(Event("instance_deleted_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+    
+    def _state1_enter(self):
+        self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].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 == "MainApp":
+            instance = MainApp(self.controller)
+            instance.associations = {}
+            instance.associations["linkA"] = Association("A", 0, -1)
+        elif class_name == "A":
+            instance = A(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("ui")
+        self.addOutputPort("ui")
+        self.object_manager.createInstance("MainApp", [])

+ 76 - 0
tests/BrokenDeletion/sccd.xml

@@ -0,0 +1,76 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="Create and Delete Multiple Instances of the same type (other than the MainApp)">
+    <description>
+        # TODO: This is broken in python SCCD, check in PyDEVS
+        Test 13: Check if multiple instances can be deleted after the creation, the instance is not started yet.
+    </description>
+    <inport name="ui"/>
+    <outport name="ui"/>
+    <class name="MainApp" default="true">
+        <relationships>
+            <association name="linkA" class="A" />
+        </relationships>
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise scope="cd" event="create_instance">
+                        <parameter expr='"linkA"' />
+                        <parameter expr='"A"' />
+                    </raise>
+                </onentry>
+                <transition event='instance_created' target='../state2'>
+                    <parameter name="association_name" type="string"/>
+                    <raise port="ui" event="instance_created_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state2">
+                <onentry>
+                    <raise scope="cd" event="create_instance">
+                        <parameter expr='"linkA"' />
+                        <parameter expr='"A"' />
+                    </raise>
+                </onentry>
+                <transition event='instance_created' target='../state3'>
+                    <parameter name="association_name" type="string"/>
+                    <raise port="ui" event="instance_created_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state3">
+                <onentry>
+                    <raise scope="cd" event="delete_instance">
+                        <parameter expr="'linkA[1]'" />
+                    </raise>
+                    <raise scope="cd" event="delete_instance">
+                        <parameter expr="'linkA[0]'" />
+                    </raise>
+                </onentry>
+
+                <transition event='instance_deleted' target='.'>
+                    <parameter name="deleted_links" type="string"/>
+                    <raise port="ui" event="instance_deleted_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="deleted_links" />
+                    </raise>
+                </transition>
+            </state>
+        </scxml>
+    </class>
+
+    <class name="A">
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise port="ui" event="not_possible">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                </onentry>
+            </state>
+        </scxml>
+    </class>
+</diagram>

+ 58 - 2
tests/Test10/sccd.xml

@@ -1,7 +1,8 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="Multiple Files">
+<diagram author="Sam Pieters" name="Create and Start Instance Of Multiple Classes">
     <description>
-        Test 11: Check if multiple files can run a model
+        TODO
+        Test 10: Check if an instance of multiple classes are created and started successfully
     </description>
     <inport name="ui"/>
     <outport name="ui"/>
@@ -12,6 +13,61 @@
         </relationships>
         <scxml initial="state1">
             <state id="state1">
+                <onentry>
+                    <raise scope="cd" event="create_instance">
+                        <parameter expr='"linkA"' />
+                        <parameter expr='"A"' />
+                    </raise>
+                </onentry>
+                <transition event='instance_created' target='../state2'>
+                    <parameter name="association_name" type="string"/>
+                    <raise port="ui" event="instance_created_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                    <raise scope="cd" event="start_instance">
+                        <parameter expr="association_name" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state2">
+                <transition event='instance_started' target='.'>
+                    <parameter name="association_name" type="string"/>
+                    <raise port="ui" event="instance_started_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                </transition>
+            </state>
+        </scxml>
+    </class>
+
+    <class name="A">
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise port="ui" event="statechart_started_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                    <raise port="ui" event="constructor_initialized_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                </onentry>
+            </state>
+        </scxml>
+    </class>
+
+    <class name="B">
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise port="ui" event="statechart_started_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                    <raise port="ui" event="constructor_initialized_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                </onentry>
             </state>
         </scxml>
     </class>

+ 3 - 135
tests/Test11/Python/target.py

@@ -2,15 +2,14 @@
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
 Model author: Sam Pieters
-Model name:   Create and Start Instance Of Multiple Classes
+Model name:   Multiple Files
 Model description:
-TODO
-        Test 10: Check if an instance of multiple classes are created and started successfully
+Test 11: Check if multiple files can run a model
 """
 
 from sccd.runtime.statecharts_core import *
 
-# package "Create and Start Instance Of Multiple Classes"
+# package "Multiple Files"
 
 class MainApp(RuntimeClassBase):
     def __init__(self, controller):
@@ -44,137 +43,12 @@ class MainApp(RuntimeClassBase):
         
         # state /state1
         self.states["/state1"] = State(1, "/state1", self)
-        self.states["/state1"].setEnter(self._state1_enter)
-        
-        # state /state2
-        self.states["/state2"] = State(2, "/state2", self)
-        
-        # add children
-        self.states[""].addChild(self.states["/state1"])
-        self.states[""].addChild(self.states["/state2"])
-        self.states[""].fixTree()
-        self.states[""].default_state = self.states["/state1"]
-        
-        # transition /state1
-        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
-        _state1_0.setAction(self._state1_0_exec)
-        _state1_0.setTrigger(Event("instance_created", None))
-        self.states["/state1"].addTransition(_state1_0)
-        
-        # transition /state2
-        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state2"]])
-        _state2_0.setAction(self._state2_0_exec)
-        _state2_0.setTrigger(Event("instance_started", None))
-        self.states["/state2"].addTransition(_state2_0)
-    
-    def _state1_enter(self):
-        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
-    
-    def _state1_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
-        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
-    
-    def _state2_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEvent(Event("instance_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
-    
-    def initializeStatechart(self):
-        # enter default state
-        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
-        RuntimeClassBase.initializeStatechart(self)
-
-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 /state1
-        self.states["/state1"] = State(1, "/state1", self)
-        self.states["/state1"].setEnter(self._state1_enter)
-        
-        # add children
-        self.states[""].addChild(self.states["/state1"])
-        self.states[""].fixTree()
-        self.states[""].default_state = self.states["/state1"]
-    
-    def _state1_enter(self):
-        self.big_step.outputEvent(Event("statechart_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
-        self.big_step.outputEvent(Event("constructor_initialized_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
-    
-    def initializeStatechart(self):
-        # enter default state
-        self.default_targets = self.states["/state1"].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 /state1
-        self.states["/state1"] = State(1, "/state1", self)
-        self.states["/state1"].setEnter(self._state1_enter)
         
         # add children
         self.states[""].addChild(self.states["/state1"])
         self.states[""].fixTree()
         self.states[""].default_state = self.states["/state1"]
     
-    def _state1_enter(self):
-        self.big_step.outputEvent(Event("statechart_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
-        self.big_step.outputEvent(Event("constructor_initialized_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
-    
     def initializeStatechart(self):
         # enter default state
         self.default_targets = self.states["/state1"].getEffectiveTargetStates()
@@ -190,12 +64,6 @@ class ObjectManager(ObjectManagerBase):
             instance.associations = {}
             instance.associations["linkA"] = Association("A", 0, -1)
             instance.associations["linkB"] = Association("B", 0, -1)
-        elif class_name == "A":
-            instance = A(self.controller)
-            instance.associations = {}
-        elif class_name == "B":
-            instance = B(self.controller)
-            instance.associations = {}
         else:
             raise Exception("Cannot instantiate class " + class_name)
         return instance

+ 2 - 58
tests/Test11/sccd.xml

@@ -1,8 +1,7 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="Create and Start Instance Of Multiple Classes">
+<diagram author="Sam Pieters" name="Multiple Files">
     <description>
-        TODO
-        Test 10: Check if an instance of multiple classes are created and started successfully
+        Test 11: Check if multiple files can run a model
     </description>
     <inport name="ui"/>
     <outport name="ui"/>
@@ -13,61 +12,6 @@
         </relationships>
         <scxml initial="state1">
             <state id="state1">
-                <onentry>
-                    <raise scope="cd" event="create_instance">
-                        <parameter expr='"linkA"' />
-                        <parameter expr='"A"' />
-                    </raise>
-                </onentry>
-                <transition event='instance_created' target='../state2'>
-                    <parameter name="association_name" type="string"/>
-                    <raise port="ui" event="instance_created_succesfully">
-                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
-                        <parameter expr="association_name" />
-                    </raise>
-                    <raise scope="cd" event="start_instance">
-                        <parameter expr="association_name" />
-                    </raise>
-                </transition>
-            </state>
-            <state id="state2">
-                <transition event='instance_started' target='.'>
-                    <parameter name="association_name" type="string"/>
-                    <raise port="ui" event="instance_started_succesfully">
-                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
-                        <parameter expr="association_name" />
-                    </raise>
-                </transition>
-            </state>
-        </scxml>
-    </class>
-
-    <class name="A">
-        <scxml initial="state1">
-            <state id="state1">
-                <onentry>
-                    <raise port="ui" event="statechart_started_succesfully">
-                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
-                    </raise>
-                    <raise port="ui" event="constructor_initialized_succesfully">
-                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
-                    </raise>
-                </onentry>
-            </state>
-        </scxml>
-    </class>
-
-    <class name="B">
-        <scxml initial="state1">
-            <state id="state1">
-                <onentry>
-                    <raise port="ui" event="statechart_started_succesfully">
-                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
-                    </raise>
-                    <raise port="ui" event="constructor_initialized_succesfully">
-                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
-                    </raise>
-                </onentry>
             </state>
         </scxml>
     </class>

+ 1 - 1
tests/Test12/PyDEVS/runner.py

@@ -1,4 +1,4 @@
-import tests.Test12.PyDEVS.target as target
+import target as target
 from sccd.runtime.DEVS_loop import DEVSSimulator
 from sccd.runtime.statecharts_core import Event
 

+ 8 - 62
tests/Test12/PyDEVS/target.py

@@ -2,14 +2,14 @@
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration) and Sam Pieters (DEVS)
 
 Model author: Sam Pieters
-Model name:   Dissasociate an instance
+Model name:   Create and Delete an Instance (other than the MainApp)
 Model description:
-Test 12: Dissasociate an instance
+Test 12: Check if an instance can be deleted after the creation, the instance is not started yet.
 """
 
 from sccd.runtime.DEVS_statecharts_core import *
 
-# package "Dissasociate an instance"
+# package "Create and Delete an Instance (other than the MainApp)"
 
 class MainAppInstance(RuntimeClassBase):
     def __init__(self, atomdevs):
@@ -32,7 +32,7 @@ class MainAppInstance(RuntimeClassBase):
         atomdevs.addInPort(port_name)
     
     def user_defined_constructor(self):
-        self.association_name = None
+        pass
     
     def user_defined_destructor(self):
         pass
@@ -51,19 +51,9 @@ class MainAppInstance(RuntimeClassBase):
         # state /state2
         self.states["/state2"] = State(2, "/state2", self)
         
-        # state /state3
-        self.states["/state3"] = State(3, "/state3", self)
-        self.states["/state3"].setEnter(self._state3_enter)
-        
-        # state /state4
-        self.states["/state4"] = State(4, "/state4", self)
-        self.states["/state4"].setEnter(self._state4_enter)
-        
         # add children
         self.states[""].addChild(self.states["/state1"])
         self.states[""].addChild(self.states["/state2"])
-        self.states[""].addChild(self.states["/state3"])
-        self.states[""].addChild(self.states["/state4"])
         self.states[""].fixTree()
         self.states[""].default_state = self.states["/state1"]
         
@@ -74,40 +64,22 @@ class MainAppInstance(RuntimeClassBase):
         self.states["/state1"].addTransition(_state1_0)
         
         # transition /state2
-        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state3"]])
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state2"]])
         _state2_0.setAction(self._state2_0_exec)
-        _state2_0.setTrigger(Event("instance_started", None))
+        _state2_0.setTrigger(Event("instance_deleted", None))
         self.states["/state2"].addTransition(_state2_0)
-        
-        # transition /state3
-        _state3_0 = Transition(self, self.states["/state3"], [self.states["/state4"]])
-        _state3_0.setAction(self._state3_0_exec)
-        _state3_0.setTrigger(Event("instance_disassociated", None))
-        self.states["/state3"].addTransition(_state3_0)
     
     def _state1_enter(self):
         self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
     
-    def _state3_enter(self):
-        self.big_step.outputEventOM(Event("disassociate_instance", None, [self, "linkA"]))
-    
-    def _state4_enter(self):
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.association_name, Event("sanity_check", None, [])]))
-    
     def _state1_0_exec(self, parameters):
         association_name = parameters[0]
-        self.association_name = association_name
         self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
-        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, association_name]))
     
     def _state2_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEvent(Event("instance_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("link_check", None, [association_name])]))
-    
-    def _state3_0_exec(self, parameters):
         deleted_links = parameters[0]
-        self.big_step.outputEvent(Event("instance_disassociated_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+        self.big_step.outputEvent(Event("instance_deleted_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
     
     def initializeStatechart(self):
         # enter default state
@@ -163,38 +135,12 @@ class AInstance(RuntimeClassBase):
         self.states["/state1"] = State(1, "/state1", self)
         self.states["/state1"].setEnter(self._state1_enter)
         
-        # state /state2
-        self.states["/state2"] = State(2, "/state2", self)
-        
         # add children
         self.states[""].addChild(self.states["/state1"])
-        self.states[""].addChild(self.states["/state2"])
         self.states[""].fixTree()
         self.states[""].default_state = self.states["/state1"]
-        
-        # transition /state1
-        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
-        _state1_0.setTrigger(None)
-        self.states["/state1"].addTransition(_state1_0)
-        
-        # transition /state2
-        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state2"]])
-        _state2_0.setAction(self._state2_0_exec)
-        _state2_0.setTrigger(Event("link_check", None))
-        self.states["/state2"].addTransition(_state2_0)
-        _state2_1 = Transition(self, self.states["/state2"], [self.states["/state2"]])
-        _state2_1.setAction(self._state2_1_exec)
-        _state2_1.setTrigger(Event("sanity_check", None))
-        self.states["/state2"].addTransition(_state2_1)
     
     def _state1_enter(self):
-        self.big_step.outputEvent(Event("statechart_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
-    
-    def _state2_0_exec(self, parameters):
-        link_name = parameters[0]
-        self.big_step.outputEvent(Event("instance_linked_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), link_name]))
-    
-    def _state2_1_exec(self, parameters):
         self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
     
     def initializeStatechart(self):

+ 8 - 62
tests/Test12/Python/target.py

@@ -2,14 +2,14 @@
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
 Model author: Sam Pieters
-Model name:   Dissasociate an instance
+Model name:   Create and Delete an Instance (other than the MainApp)
 Model description:
-Test 12: Dissasociate an instance
+Test 12: Check if an instance can be deleted after the creation, the instance is not started yet.
 """
 
 from sccd.runtime.statecharts_core import *
 
-# package "Dissasociate an instance"
+# package "Create and Delete an Instance (other than the MainApp)"
 
 class MainApp(RuntimeClassBase):
     def __init__(self, controller):
@@ -29,7 +29,7 @@ class MainApp(RuntimeClassBase):
         MainApp.user_defined_constructor(self)
     
     def user_defined_constructor(self):
-        self.association_name = None
+        pass
     
     def user_defined_destructor(self):
         pass
@@ -48,19 +48,9 @@ class MainApp(RuntimeClassBase):
         # state /state2
         self.states["/state2"] = State(2, "/state2", self)
         
-        # state /state3
-        self.states["/state3"] = State(3, "/state3", self)
-        self.states["/state3"].setEnter(self._state3_enter)
-        
-        # state /state4
-        self.states["/state4"] = State(4, "/state4", self)
-        self.states["/state4"].setEnter(self._state4_enter)
-        
         # add children
         self.states[""].addChild(self.states["/state1"])
         self.states[""].addChild(self.states["/state2"])
-        self.states[""].addChild(self.states["/state3"])
-        self.states[""].addChild(self.states["/state4"])
         self.states[""].fixTree()
         self.states[""].default_state = self.states["/state1"]
         
@@ -71,40 +61,22 @@ class MainApp(RuntimeClassBase):
         self.states["/state1"].addTransition(_state1_0)
         
         # transition /state2
-        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state3"]])
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state2"]])
         _state2_0.setAction(self._state2_0_exec)
-        _state2_0.setTrigger(Event("instance_started", None))
+        _state2_0.setTrigger(Event("instance_deleted", None))
         self.states["/state2"].addTransition(_state2_0)
-        
-        # transition /state3
-        _state3_0 = Transition(self, self.states["/state3"], [self.states["/state4"]])
-        _state3_0.setAction(self._state3_0_exec)
-        _state3_0.setTrigger(Event("instance_disassociated", None))
-        self.states["/state3"].addTransition(_state3_0)
     
     def _state1_enter(self):
         self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
     
-    def _state3_enter(self):
-        self.big_step.outputEventOM(Event("disassociate_instance", None, [self, "linkA"]))
-    
-    def _state4_enter(self):
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.association_name, Event("sanity_check", None, [])]))
-    
     def _state1_0_exec(self, parameters):
         association_name = parameters[0]
-        self.association_name = association_name
         self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
-        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, association_name]))
     
     def _state2_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEvent(Event("instance_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("link_check", None, [association_name])]))
-    
-    def _state3_0_exec(self, parameters):
         deleted_links = parameters[0]
-        self.big_step.outputEvent(Event("instance_disassociated_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+        self.big_step.outputEvent(Event("instance_deleted_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
     
     def initializeStatechart(self):
         # enter default state
@@ -145,38 +117,12 @@ class A(RuntimeClassBase):
         self.states["/state1"] = State(1, "/state1", self)
         self.states["/state1"].setEnter(self._state1_enter)
         
-        # state /state2
-        self.states["/state2"] = State(2, "/state2", self)
-        
         # add children
         self.states[""].addChild(self.states["/state1"])
-        self.states[""].addChild(self.states["/state2"])
         self.states[""].fixTree()
         self.states[""].default_state = self.states["/state1"]
-        
-        # transition /state1
-        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
-        _state1_0.setTrigger(None)
-        self.states["/state1"].addTransition(_state1_0)
-        
-        # transition /state2
-        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state2"]])
-        _state2_0.setAction(self._state2_0_exec)
-        _state2_0.setTrigger(Event("link_check", None))
-        self.states["/state2"].addTransition(_state2_0)
-        _state2_1 = Transition(self, self.states["/state2"], [self.states["/state2"]])
-        _state2_1.setAction(self._state2_1_exec)
-        _state2_1.setTrigger(Event("sanity_check", None))
-        self.states["/state2"].addTransition(_state2_1)
     
     def _state1_enter(self):
-        self.big_step.outputEvent(Event("statechart_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
-    
-    def _state2_0_exec(self, parameters):
-        link_name = parameters[0]
-        self.big_step.outputEvent(Event("instance_linked_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), link_name]))
-    
-    def _state2_1_exec(self, parameters):
         self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
     
     def initializeStatechart(self):

+ 7 - 52
tests/Test12/sccd.xml

@@ -1,7 +1,7 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="Dissasociate an instance">
+<diagram author="Sam Pieters" name="Create and Delete an Instance (other than the MainApp)">
     <description>
-        Test 12: Dissasociate an instance
+        Test 12: Check if an instance can be deleted after the creation, the instance is not started yet.
     </description>
     <inport name="ui"/>
     <outport name="ui"/>
@@ -9,11 +9,6 @@
         <relationships>
             <association name="linkA" class="A" />
         </relationships>
-        <constructor>
-            <body>
-                self.association_name = None
-            </body>
-        </constructor>
         <scxml initial="state1">
             <state id="state1">
                 <onentry>
@@ -24,49 +19,24 @@
                 </onentry>
                 <transition event='instance_created' target='../state2'>
                     <parameter name="association_name" type="string"/>
-                    <script>
-                        self.association_name = association_name
-                    </script>
                     <raise port="ui" event="instance_created_succesfully">
                         <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
                         <parameter expr="association_name" />
                     </raise>
-                    <raise scope="cd" event="start_instance">
+                    <raise scope="cd" event="delete_instance">
                         <parameter expr="association_name" />
                     </raise>
                 </transition>
             </state>
             <state id="state2">
-                <transition event='instance_started' target='../state3'>
-                    <parameter name="association_name" type="string"/>
-                    <raise port="ui" event="instance_started_succesfully">
-                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
-                        <parameter expr="association_name" />
-                    </raise>
-                    <raise scope="narrow" event="link_check" target="association_name">
-                        <parameter expr="association_name" />
-                    </raise>
-                </transition>
-            </state>
-            <state id="state3">
-                <onentry>
-                    <raise scope="cd" event='disassociate_instance'>
-                        <parameter expr='"linkA"' />
-                    </raise>
-                </onentry>
-                <transition event='instance_disassociated' target='../state4'>
-                    <parameter name='deleted_links' />
-                    <raise port="ui" event="instance_disassociated_succesfully">
+                <transition event='instance_deleted' target='.'>
+                    <parameter name="deleted_links" type="string"/>
+                    <raise port="ui" event="instance_deleted_succesfully">
                         <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
                         <parameter expr="deleted_links" />
                     </raise>
                 </transition>
             </state>
-            <state id="state4">
-                <onentry>
-                    <raise scope="narrow" event="sanity_check" target="self.association_name" />
-                </onentry>
-            </state>
         </scxml>
     </class>
 
@@ -74,25 +44,10 @@
         <scxml initial="state1">
             <state id="state1">
                 <onentry>
-                    <raise port="ui" event="statechart_started_succesfully">
-                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
-                    </raise>
-                </onentry>
-                <transition target="../state2" />
-            </state>
-            <state id="state2">
-                <transition event="link_check" target=".">
-                    <parameter name='link_name' />
-                    <raise port="ui" event="instance_linked_succesfully">
-                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
-                        <parameter expr="link_name" />
-                    </raise>
-                </transition>
-                <transition event="sanity_check" target=".">
                     <raise port="ui" event="not_possible">
                         <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
                     </raise>
-                </transition>
+                </onentry>
             </state>
         </scxml>
     </class>

+ 4 - 0
tests/Test13/PyDEVS/log.txt

@@ -0,0 +1,4 @@
+0.00s - Debugger warning: It seems that frozen modules are being used, which may
+0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
+0.00s - to python to disable frozen modules.
+0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.

+ 20 - 0
tests/Test13/PyDEVS/runner.py

@@ -0,0 +1,20 @@
+import target as target
+from sccd.runtime.DEVS_loop import DEVSSimulator
+from sccd.runtime.statecharts_core import Event
+
+class OutputListener:
+	def add(self, events):
+		for event in events:
+			if event.port == "ui":
+				print(event.name, ", received on:", event.parameters[0], "seconds, parameters:", event.parameters[1:])
+				
+
+if __name__ == '__main__':
+	controller = target.Controller(name="controller")
+	refs = {"ui": controller.in_ui}
+	sim = DEVSSimulator(controller, refs)
+
+	listener = OutputListener()
+	sim.setListenPorts(controller.out_ui, listener.add)
+	sim.simulate()
+

+ 221 - 0
tests/Test13/PyDEVS/target.py

@@ -0,0 +1,221 @@
+"""
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration) and Sam Pieters (DEVS)
+
+Model author: Sam Pieters
+Model name:   Create and Delete Multiple Instances of the same type (other than the MainApp)
+Model description:
+# TODO: This is broken in python SCCD, check in PyDEVS
+        Test 13: Check if multiple instances can be deleted after the creation, the instance is not started yet.
+"""
+
+from sccd.runtime.DEVS_statecharts_core import *
+
+# package "Create and Delete Multiple Instances of the same type (other than the MainApp)"
+
+class MainAppInstance(RuntimeClassBase):
+    def __init__(self, atomdevs):
+        RuntimeClassBase.__init__(self, atomdevs)
+        self.associations = {}
+        self.associations["linkA"] = Association("A", 0, -1)
+        
+        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
+        MainAppInstance.user_defined_constructor(self)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
+    
+    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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        self.states["/state2"].setEnter(self._state2_enter)
+        
+        # state /state3
+        self.states["/state3"] = State(3, "/state3", self)
+        self.states["/state3"].setEnter(self._state3_enter)
+        
+        # state /state4
+        self.states["/state4"] = State(4, "/state4", self)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].addChild(self.states["/state3"])
+        self.states[""].addChild(self.states["/state4"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("instance_created", None))
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state3"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("instance_created", None))
+        self.states["/state2"].addTransition(_state2_0)
+        
+        # transition /state3
+        _state3_0 = Transition(self, self.states["/state3"], [self.states["/state4"]])
+        _state3_0.setTrigger(None)
+        self.states["/state3"].addTransition(_state3_0)
+        
+        # transition /state4
+        _state4_0 = Transition(self, self.states["/state4"], [self.states["/state4"]])
+        _state4_0.setAction(self._state4_0_exec)
+        _state4_0.setTrigger(Event("instance_deleted", None))
+        self.states["/state4"].addTransition(_state4_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state2_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state3_enter(self):
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, 'linkA[1]']))
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, 'linkA[0]']))
+    
+    def _state1_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+    
+    def _state2_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+    
+    def _state4_0_exec(self, parameters):
+        deleted_links = parameters[0]
+        self.big_step.outputEvent(Event("instance_deleted_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class MainApp(ObjectManagerBase):
+    def __init__(self, name):
+        ObjectManagerBase.__init__(self, name)
+        self.input = self.addInPort("input")
+        self.output = self.addOutPort("ui")
+        self.outputs["linkA"] = self.addOutPort("linkA")
+        self.instances[self.next_instance] = MainAppInstance(self)
+        self.next_instance = self.next_instance + 1
+    
+    def constructObject(self, parameters):
+        new_instance = MainAppInstance(self)
+        return new_instance
+
+class AInstance(RuntimeClassBase):
+    def __init__(self, atomdevs):
+        RuntimeClassBase.__init__(self, atomdevs)
+        self.associations = {}
+        
+        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
+        AInstance.user_defined_constructor(self)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
+    
+    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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+    
+    def _state1_enter(self):
+        self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class A(ObjectManagerBase):
+    def __init__(self, name):
+        ObjectManagerBase.__init__(self, name)
+        self.input = self.addInPort("input")
+        self.output = self.addOutPort("ui")
+    
+    def constructObject(self, parameters):
+        new_instance = AInstance(self)
+        return new_instance
+
+class ObjectManagerState:
+    def __init__(self):
+        self.to_send = [("MainApp", "MainApp", Event("start_instance", None, ["MainApp[0]"], 0))]
+
+class ObjectManager(TheObjectManager):
+    def __init__(self, name):
+        TheObjectManager.__init__(self, name)
+        self.State = ObjectManagerState()
+        self.input = self.addInPort("input")
+        self.output["MainApp"] = self.addOutPort()
+        self.output["A"] = self.addOutPort()
+
+class Controller(CoupledDEVS):
+    def __init__(self, name):
+        CoupledDEVS.__init__(self, name)
+        self.in_ui = self.addInPort("ui")
+        Ports.addInputPort("ui")
+        self.out_ui = self.addOutPort("ui")
+        Ports.addOutputPort("ui")
+        self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
+        self.atomic0 = self.addSubModel(MainApp("MainApp"))
+        self.atomic1 = self.addSubModel(A("A"))
+        self.connectPorts(self.atomic0.obj_manager_out, self.objectmanager.input)
+        self.connectPorts(self.objectmanager.output["MainApp"], self.atomic0.obj_manager_in)
+        self.connectPorts(self.atomic0.outputs["linkA"], self.atomic1.input)
+        self.connectPorts(self.atomic1.obj_manager_out, self.objectmanager.input)
+        self.connectPorts(self.objectmanager.output["A"], self.atomic1.obj_manager_in)
+        self.connectPorts(self.atomic0.output, self.out_ui)
+        self.connectPorts(self.atomic1.output, self.out_ui)

+ 8 - 0
tests/Test13/Python/log.txt

@@ -0,0 +1,8 @@
+instance_created_succesfully , received on: 0.00 seconds, parameters: ['linkA[0]']
+statechart_started_succesfully , received on: 0.00 seconds, parameters: []
+constructor_initialized_succesfully , received on: 0.00 seconds, parameters: []
+instance_started_succesfully , received on: 0.00 seconds, parameters: ['linkA[0]']
+0.00s - Debugger warning: It seems that frozen modules are being used, which may
+0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
+0.00s - to python to disable frozen modules.
+0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.

+ 16 - 0
tests/Test13/Python/runner.py

@@ -0,0 +1,16 @@
+import target as target
+from sccd.runtime.statecharts_core import Event
+import threading
+
+class OutputListener:
+	def add(self, event):
+		if event.port == "ui":
+			print(event.name, ", received on:", event.parameters[0], "seconds, parameters:", event.parameters[1:])
+				
+
+if __name__ == '__main__':
+	controller = target.Controller()
+	controller.keep_running = False
+	controller.addMyOwnOutputListener(OutputListener())
+	controller.setVerbose(None)
+	controller.start()

+ 188 - 0
tests/Test13/Python/target.py

@@ -0,0 +1,188 @@
+"""
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
+
+Model author: Sam Pieters
+Model name:   Create and Delete Multiple Instances of the same type (other than the MainApp)
+Model description:
+# TODO: This is broken in python SCCD, check in PyDEVS
+        Test 13: Check if multiple instances can be deleted after the creation, the instance is not started yet.
+"""
+
+from sccd.runtime.statecharts_core import *
+
+# package "Create and Delete Multiple Instances of the same type (other than the MainApp)"
+
+class MainApp(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
+        MainApp.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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        self.states["/state2"].setEnter(self._state2_enter)
+        
+        # state /state3
+        self.states["/state3"] = State(3, "/state3", self)
+        self.states["/state3"].setEnter(self._state3_enter)
+        
+        # state /state4
+        self.states["/state4"] = State(4, "/state4", self)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].addChild(self.states["/state3"])
+        self.states[""].addChild(self.states["/state4"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("instance_created", None))
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state3"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("instance_created", None))
+        self.states["/state2"].addTransition(_state2_0)
+        
+        # transition /state3
+        _state3_0 = Transition(self, self.states["/state3"], [self.states["/state4"]])
+        _state3_0.setTrigger(None)
+        self.states["/state3"].addTransition(_state3_0)
+        
+        # transition /state4
+        _state4_0 = Transition(self, self.states["/state4"], [self.states["/state4"]])
+        _state4_0.setAction(self._state4_0_exec)
+        _state4_0.setTrigger(Event("instance_deleted", None))
+        self.states["/state4"].addTransition(_state4_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state2_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state3_enter(self):
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, 'linkA[1]']))
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, 'linkA[0]']))
+    
+    def _state1_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+    
+    def _state2_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+    
+    def _state4_0_exec(self, parameters):
+        deleted_links = parameters[0]
+        self.big_step.outputEvent(Event("instance_deleted_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+    
+    def _state1_enter(self):
+        self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].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 == "MainApp":
+            instance = MainApp(self.controller)
+            instance.associations = {}
+            instance.associations["linkA"] = Association("A", 0, -1)
+        elif class_name == "A":
+            instance = A(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("ui")
+        self.addOutputPort("ui")
+        self.object_manager.createInstance("MainApp", [])

+ 77 - 0
tests/Test13/sccd.xml

@@ -0,0 +1,77 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="Create and Delete Multiple Instances of the same type (other than the MainApp)">
+    <description>
+        Test 13: Check if multiple instances can be deleted after the creation, the instance is not started yet.
+    </description>
+    <inport name="ui"/>
+    <outport name="ui"/>
+    <class name="MainApp" default="true">
+        <relationships>
+            <association name="linkA" class="A" />
+        </relationships>
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise scope="cd" event="create_instance">
+                        <parameter expr='"linkA"' />
+                        <parameter expr='"A"' />
+                    </raise>
+                </onentry>
+                <transition event='instance_created' target='../state2'>
+                    <parameter name="association_name" type="string"/>
+                    <raise port="ui" event="instance_created_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state2">
+                <onentry>
+                    <raise scope="cd" event="create_instance">
+                        <parameter expr='"linkA"' />
+                        <parameter expr='"A"' />
+                    </raise>
+                </onentry>
+                <transition event='instance_created' target='../state3'>
+                    <parameter name="association_name" type="string"/>
+                    <raise port="ui" event="instance_created_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state3">
+                <onentry>
+                    <raise scope="cd" event="delete_instance">
+                        <parameter expr="'linkA[1]'" />
+                    </raise>
+                    <raise scope="cd" event="delete_instance">
+                        <parameter expr="'linkA[0]'" />
+                    </raise>
+                </onentry>
+                <transition target="../state4"/>
+            </state>
+            <state id="state4">
+                <transition event='instance_deleted' target='.'>
+                    <parameter name="deleted_links" type="string"/>
+                    <raise port="ui" event="instance_deleted_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="deleted_links" />
+                    </raise>
+                </transition>
+            </state>
+        </scxml>
+    </class>
+
+    <class name="A">
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise port="ui" event="not_possible">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                </onentry>
+            </state>
+        </scxml>
+    </class>
+</diagram>

+ 4 - 0
tests/Test14/PyDEVS/log.txt

@@ -0,0 +1,4 @@
+0.00s - Debugger warning: It seems that frozen modules are being used, which may
+0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
+0.00s - to python to disable frozen modules.
+0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.

+ 20 - 0
tests/Test14/PyDEVS/runner.py

@@ -0,0 +1,20 @@
+import target as target
+from sccd.runtime.DEVS_loop import DEVSSimulator
+from sccd.runtime.statecharts_core import Event
+
+class OutputListener:
+	def add(self, events):
+		for event in events:
+			if event.port == "ui":
+				print(event.name, ", received on:", event.parameters[0], "seconds, parameters:", event.parameters[1:])
+				
+
+if __name__ == '__main__':
+	controller = target.Controller(name="controller")
+	refs = {"ui": controller.in_ui}
+	sim = DEVSSimulator(controller, refs)
+
+	listener = OutputListener()
+	sim.setListenPorts(controller.out_ui, listener.add)
+	sim.simulate()
+

+ 224 - 0
tests/Test14/PyDEVS/target.py

@@ -0,0 +1,224 @@
+"""
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration) and Sam Pieters (DEVS)
+
+Model author: Sam Pieters
+Model name:   Create and Delete A Running Instance (other than the MainApp)
+Model description:
+Test 14: Check if multiple running instances can be deleted after the creation.
+"""
+
+from sccd.runtime.DEVS_statecharts_core import *
+
+# package "Create and Delete A Running Instance (other than the MainApp)"
+
+class MainAppInstance(RuntimeClassBase):
+    def __init__(self, atomdevs):
+        RuntimeClassBase.__init__(self, atomdevs)
+        self.associations = {}
+        self.associations["linkA"] = Association("A", 0, -1)
+        
+        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
+        MainAppInstance.user_defined_constructor(self)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
+    
+    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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        
+        # state /state3
+        self.states["/state3"] = State(3, "/state3", self)
+        self.states["/state3"].setEnter(self._state3_enter)
+        
+        # state /state4
+        self.states["/state4"] = State(4, "/state4", self)
+        self.states["/state4"].setEnter(self._state4_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].addChild(self.states["/state3"])
+        self.states[""].addChild(self.states["/state4"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("instance_created", None))
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state3"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("instance_started", None))
+        self.states["/state2"].addTransition(_state2_0)
+        
+        # transition /state3
+        _state3_0 = Transition(self, self.states["/state3"], [self.states["/state4"]])
+        _state3_0.setAction(self._state3_0_exec)
+        _state3_0.setTrigger(Event("instance_deleted", None))
+        self.states["/state3"].addTransition(_state3_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state3_enter(self):
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, 'linkA[0]']))
+    
+    def _state4_enter(self):
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'linkA[0]', Event("sanity_check", None, [])]))
+    
+    def _state1_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
+    
+    def _state2_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+    
+    def _state3_0_exec(self, parameters):
+        deleted_links = parameters[0]
+        self.big_step.outputEvent(Event("instance_deleted_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class MainApp(ObjectManagerBase):
+    def __init__(self, name):
+        ObjectManagerBase.__init__(self, name)
+        self.input = self.addInPort("input")
+        self.output = self.addOutPort("ui")
+        self.outputs["linkA"] = self.addOutPort("linkA")
+        self.instances[self.next_instance] = MainAppInstance(self)
+        self.next_instance = self.next_instance + 1
+    
+    def constructObject(self, parameters):
+        new_instance = MainAppInstance(self)
+        return new_instance
+
+class AInstance(RuntimeClassBase):
+    def __init__(self, atomdevs):
+        RuntimeClassBase.__init__(self, atomdevs)
+        self.associations = {}
+        
+        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
+        AInstance.user_defined_constructor(self)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
+    
+    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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state1"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("sanity_check", None))
+        self.states["/state1"].addTransition(_state1_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEvent(Event("statechart_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def _state1_0_exec(self, parameters):
+        self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class A(ObjectManagerBase):
+    def __init__(self, name):
+        ObjectManagerBase.__init__(self, name)
+        self.input = self.addInPort("input")
+        self.output = self.addOutPort("ui")
+    
+    def constructObject(self, parameters):
+        new_instance = AInstance(self)
+        return new_instance
+
+class ObjectManagerState:
+    def __init__(self):
+        self.to_send = [("MainApp", "MainApp", Event("start_instance", None, ["MainApp[0]"], 0))]
+
+class ObjectManager(TheObjectManager):
+    def __init__(self, name):
+        TheObjectManager.__init__(self, name)
+        self.State = ObjectManagerState()
+        self.input = self.addInPort("input")
+        self.output["MainApp"] = self.addOutPort()
+        self.output["A"] = self.addOutPort()
+
+class Controller(CoupledDEVS):
+    def __init__(self, name):
+        CoupledDEVS.__init__(self, name)
+        self.in_ui = self.addInPort("ui")
+        Ports.addInputPort("ui")
+        self.out_ui = self.addOutPort("ui")
+        Ports.addOutputPort("ui")
+        self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
+        self.atomic0 = self.addSubModel(MainApp("MainApp"))
+        self.atomic1 = self.addSubModel(A("A"))
+        self.connectPorts(self.atomic0.obj_manager_out, self.objectmanager.input)
+        self.connectPorts(self.objectmanager.output["MainApp"], self.atomic0.obj_manager_in)
+        self.connectPorts(self.atomic0.outputs["linkA"], self.atomic1.input)
+        self.connectPorts(self.atomic1.obj_manager_out, self.objectmanager.input)
+        self.connectPorts(self.objectmanager.output["A"], self.atomic1.obj_manager_in)
+        self.connectPorts(self.atomic0.output, self.out_ui)
+        self.connectPorts(self.atomic1.output, self.out_ui)

+ 8 - 0
tests/Test14/Python/log.txt

@@ -0,0 +1,8 @@
+instance_created_succesfully , received on: 0.00 seconds, parameters: ['linkA[0]']
+statechart_started_succesfully , received on: 0.00 seconds, parameters: []
+constructor_initialized_succesfully , received on: 0.00 seconds, parameters: []
+instance_started_succesfully , received on: 0.00 seconds, parameters: ['linkA[0]']
+0.00s - Debugger warning: It seems that frozen modules are being used, which may
+0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
+0.00s - to python to disable frozen modules.
+0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.

+ 16 - 0
tests/Test14/Python/runner.py

@@ -0,0 +1,16 @@
+import target as target
+from sccd.runtime.statecharts_core import Event
+import threading
+
+class OutputListener:
+	def add(self, event):
+		if event.port == "ui":
+			print(event.name, ", received on:", event.parameters[0], "seconds, parameters:", event.parameters[1:])
+				
+
+if __name__ == '__main__':
+	controller = target.Controller()
+	controller.keep_running = False
+	controller.addMyOwnOutputListener(OutputListener())
+	controller.setVerbose(None)
+	controller.start()

+ 191 - 0
tests/Test14/Python/target.py

@@ -0,0 +1,191 @@
+"""
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
+
+Model author: Sam Pieters
+Model name:   Create and Delete A Running Instance (other than the MainApp)
+Model description:
+Test 14: Check if multiple running instances can be deleted after the creation.
+"""
+
+from sccd.runtime.statecharts_core import *
+
+# package "Create and Delete A Running Instance (other than the MainApp)"
+
+class MainApp(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
+        MainApp.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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        
+        # state /state3
+        self.states["/state3"] = State(3, "/state3", self)
+        self.states["/state3"].setEnter(self._state3_enter)
+        
+        # state /state4
+        self.states["/state4"] = State(4, "/state4", self)
+        self.states["/state4"].setEnter(self._state4_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].addChild(self.states["/state3"])
+        self.states[""].addChild(self.states["/state4"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("instance_created", None))
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state3"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("instance_started", None))
+        self.states["/state2"].addTransition(_state2_0)
+        
+        # transition /state3
+        _state3_0 = Transition(self, self.states["/state3"], [self.states["/state4"]])
+        _state3_0.setAction(self._state3_0_exec)
+        _state3_0.setTrigger(Event("instance_deleted", None))
+        self.states["/state3"].addTransition(_state3_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state3_enter(self):
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, 'linkA[0]']))
+    
+    def _state4_enter(self):
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'linkA[0]', Event("sanity_check", None, [])]))
+    
+    def _state1_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
+    
+    def _state2_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+    
+    def _state3_0_exec(self, parameters):
+        deleted_links = parameters[0]
+        self.big_step.outputEvent(Event("instance_deleted_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state1"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("sanity_check", None))
+        self.states["/state1"].addTransition(_state1_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEvent(Event("statechart_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def _state1_0_exec(self, parameters):
+        self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].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 == "MainApp":
+            instance = MainApp(self.controller)
+            instance.associations = {}
+            instance.associations["linkA"] = Association("A", 0, -1)
+        elif class_name == "A":
+            instance = A(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("ui")
+        self.addOutputPort("ui")
+        self.object_manager.createInstance("MainApp", [])

+ 78 - 0
tests/Test14/sccd.xml

@@ -0,0 +1,78 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="Create and Delete A Running Instance (other than the MainApp)">
+    <description>
+        Test 14: Check if a running instance can be deleted after the creation.
+    </description>
+    <inport name="ui"/>
+    <outport name="ui"/>
+    <class name="MainApp" default="true">
+        <relationships>
+            <association name="linkA" class="A" />
+        </relationships>
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise scope="cd" event="create_instance">
+                        <parameter expr='"linkA"' />
+                        <parameter expr='"A"' />
+                    </raise>
+                </onentry>
+                <transition event='instance_created' target='../state2'>
+                    <parameter name="association_name" type="string"/>
+                    <raise port="ui" event="instance_created_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                    <raise scope="cd" event="start_instance">
+                        <parameter expr='association_name' />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state2">
+                <transition event='instance_started' target='../state3'>
+                    <parameter name="association_name" type="string"/>
+                    <raise port="ui" event="instance_started_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state3">
+                <onentry>
+                    <raise scope="cd" event="delete_instance">
+                        <parameter expr="'linkA[0]'" />
+                    </raise>
+                </onentry>
+                <transition event='instance_deleted' target='../state4'>
+                    <parameter name="deleted_links" type="string"/>
+                    <raise port="ui" event="instance_deleted_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="deleted_links" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state4">
+                <onentry>
+                    <raise scope="narrow" event="sanity_check" target="'linkA[0]'" />
+                </onentry>
+            </state>
+        </scxml>
+    </class>
+
+    <class name="A">
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise port="ui" event="statechart_started_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                </onentry>
+                <transition event="sanity_check" target=".">
+                    <raise port="ui" event="not_possible">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                </transition>
+            </state>
+        </scxml>
+    </class>
+</diagram>

+ 4 - 0
tests/Test15/PyDEVS/log.txt

@@ -0,0 +1,4 @@
+0.00s - Debugger warning: It seems that frozen modules are being used, which may
+0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
+0.00s - to python to disable frozen modules.
+0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.

+ 20 - 0
tests/Test15/PyDEVS/runner.py

@@ -0,0 +1,20 @@
+import target as target
+from sccd.runtime.DEVS_loop import DEVSSimulator
+from sccd.runtime.statecharts_core import Event
+
+class OutputListener:
+	def add(self, events):
+		for event in events:
+			if event.port == "ui":
+				print(event.name, ", received on:", event.parameters[0], "seconds, parameters:", event.parameters[1:])
+				
+
+if __name__ == '__main__':
+	controller = target.Controller(name="controller")
+	refs = {"ui": controller.in_ui}
+	sim = DEVSSimulator(controller, refs)
+
+	listener = OutputListener()
+	sim.setListenPorts(controller.out_ui, listener.add)
+	sim.simulate()
+

+ 224 - 0
tests/Test15/PyDEVS/target.py

@@ -0,0 +1,224 @@
+"""
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration) and Sam Pieters (DEVS)
+
+Model author: Sam Pieters
+Model name:   Create and Delete A Running Instance (other than the MainApp)
+Model description:
+Test 14: Check if multiple running instances can be deleted after the creation.
+"""
+
+from sccd.runtime.DEVS_statecharts_core import *
+
+# package "Create and Delete A Running Instance (other than the MainApp)"
+
+class MainAppInstance(RuntimeClassBase):
+    def __init__(self, atomdevs):
+        RuntimeClassBase.__init__(self, atomdevs)
+        self.associations = {}
+        self.associations["linkA"] = Association("A", 0, -1)
+        
+        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
+        MainAppInstance.user_defined_constructor(self)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
+    
+    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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        
+        # state /state3
+        self.states["/state3"] = State(3, "/state3", self)
+        self.states["/state3"].setEnter(self._state3_enter)
+        
+        # state /state4
+        self.states["/state4"] = State(4, "/state4", self)
+        self.states["/state4"].setEnter(self._state4_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].addChild(self.states["/state3"])
+        self.states[""].addChild(self.states["/state4"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("instance_created", None))
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state3"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("instance_started", None))
+        self.states["/state2"].addTransition(_state2_0)
+        
+        # transition /state3
+        _state3_0 = Transition(self, self.states["/state3"], [self.states["/state4"]])
+        _state3_0.setAction(self._state3_0_exec)
+        _state3_0.setTrigger(Event("instance_deleted", None))
+        self.states["/state3"].addTransition(_state3_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state3_enter(self):
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, 'linkA[0]']))
+    
+    def _state4_enter(self):
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'linkA[0]', Event("sanity_check", None, [])]))
+    
+    def _state1_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
+    
+    def _state2_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+    
+    def _state3_0_exec(self, parameters):
+        deleted_links = parameters[0]
+        self.big_step.outputEvent(Event("instance_deleted_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class MainApp(ObjectManagerBase):
+    def __init__(self, name):
+        ObjectManagerBase.__init__(self, name)
+        self.input = self.addInPort("input")
+        self.output = self.addOutPort("ui")
+        self.outputs["linkA"] = self.addOutPort("linkA")
+        self.instances[self.next_instance] = MainAppInstance(self)
+        self.next_instance = self.next_instance + 1
+    
+    def constructObject(self, parameters):
+        new_instance = MainAppInstance(self)
+        return new_instance
+
+class AInstance(RuntimeClassBase):
+    def __init__(self, atomdevs):
+        RuntimeClassBase.__init__(self, atomdevs)
+        self.associations = {}
+        
+        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
+        AInstance.user_defined_constructor(self)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
+    
+    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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state1"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("sanity_check", None))
+        self.states["/state1"].addTransition(_state1_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEvent(Event("statechart_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def _state1_0_exec(self, parameters):
+        self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class A(ObjectManagerBase):
+    def __init__(self, name):
+        ObjectManagerBase.__init__(self, name)
+        self.input = self.addInPort("input")
+        self.output = self.addOutPort("ui")
+    
+    def constructObject(self, parameters):
+        new_instance = AInstance(self)
+        return new_instance
+
+class ObjectManagerState:
+    def __init__(self):
+        self.to_send = [("MainApp", "MainApp", Event("start_instance", None, ["MainApp[0]"], 0))]
+
+class ObjectManager(TheObjectManager):
+    def __init__(self, name):
+        TheObjectManager.__init__(self, name)
+        self.State = ObjectManagerState()
+        self.input = self.addInPort("input")
+        self.output["MainApp"] = self.addOutPort()
+        self.output["A"] = self.addOutPort()
+
+class Controller(CoupledDEVS):
+    def __init__(self, name):
+        CoupledDEVS.__init__(self, name)
+        self.in_ui = self.addInPort("ui")
+        Ports.addInputPort("ui")
+        self.out_ui = self.addOutPort("ui")
+        Ports.addOutputPort("ui")
+        self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
+        self.atomic0 = self.addSubModel(MainApp("MainApp"))
+        self.atomic1 = self.addSubModel(A("A"))
+        self.connectPorts(self.atomic0.obj_manager_out, self.objectmanager.input)
+        self.connectPorts(self.objectmanager.output["MainApp"], self.atomic0.obj_manager_in)
+        self.connectPorts(self.atomic0.outputs["linkA"], self.atomic1.input)
+        self.connectPorts(self.atomic1.obj_manager_out, self.objectmanager.input)
+        self.connectPorts(self.objectmanager.output["A"], self.atomic1.obj_manager_in)
+        self.connectPorts(self.atomic0.output, self.out_ui)
+        self.connectPorts(self.atomic1.output, self.out_ui)

+ 8 - 0
tests/Test15/Python/log.txt

@@ -0,0 +1,8 @@
+instance_created_succesfully , received on: 0.00 seconds, parameters: ['linkA[0]']
+statechart_started_succesfully , received on: 0.00 seconds, parameters: []
+constructor_initialized_succesfully , received on: 0.00 seconds, parameters: []
+instance_started_succesfully , received on: 0.00 seconds, parameters: ['linkA[0]']
+0.00s - Debugger warning: It seems that frozen modules are being used, which may
+0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
+0.00s - to python to disable frozen modules.
+0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.

+ 16 - 0
tests/Test15/Python/runner.py

@@ -0,0 +1,16 @@
+import target as target
+from sccd.runtime.statecharts_core import Event
+import threading
+
+class OutputListener:
+	def add(self, event):
+		if event.port == "ui":
+			print(event.name, ", received on:", event.parameters[0], "seconds, parameters:", event.parameters[1:])
+				
+
+if __name__ == '__main__':
+	controller = target.Controller()
+	controller.keep_running = False
+	controller.addMyOwnOutputListener(OutputListener())
+	controller.setVerbose(None)
+	controller.start()

+ 191 - 0
tests/Test15/Python/target.py

@@ -0,0 +1,191 @@
+"""
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
+
+Model author: Sam Pieters
+Model name:   Create and Delete A Running Instance (other than the MainApp)
+Model description:
+Test 14: Check if multiple running instances can be deleted after the creation.
+"""
+
+from sccd.runtime.statecharts_core import *
+
+# package "Create and Delete A Running Instance (other than the MainApp)"
+
+class MainApp(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
+        MainApp.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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        
+        # state /state3
+        self.states["/state3"] = State(3, "/state3", self)
+        self.states["/state3"].setEnter(self._state3_enter)
+        
+        # state /state4
+        self.states["/state4"] = State(4, "/state4", self)
+        self.states["/state4"].setEnter(self._state4_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].addChild(self.states["/state3"])
+        self.states[""].addChild(self.states["/state4"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("instance_created", None))
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state3"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("instance_started", None))
+        self.states["/state2"].addTransition(_state2_0)
+        
+        # transition /state3
+        _state3_0 = Transition(self, self.states["/state3"], [self.states["/state4"]])
+        _state3_0.setAction(self._state3_0_exec)
+        _state3_0.setTrigger(Event("instance_deleted", None))
+        self.states["/state3"].addTransition(_state3_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state3_enter(self):
+        self.big_step.outputEventOM(Event("delete_instance", None, [self, 'linkA[0]']))
+    
+    def _state4_enter(self):
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'linkA[0]', Event("sanity_check", None, [])]))
+    
+    def _state1_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
+    
+    def _state2_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+    
+    def _state3_0_exec(self, parameters):
+        deleted_links = parameters[0]
+        self.big_step.outputEvent(Event("instance_deleted_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state1"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("sanity_check", None))
+        self.states["/state1"].addTransition(_state1_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEvent(Event("statechart_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def _state1_0_exec(self, parameters):
+        self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].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 == "MainApp":
+            instance = MainApp(self.controller)
+            instance.associations = {}
+            instance.associations["linkA"] = Association("A", 0, -1)
+        elif class_name == "A":
+            instance = A(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("ui")
+        self.addOutputPort("ui")
+        self.object_manager.createInstance("MainApp", [])

+ 79 - 0
tests/Test15/sccd.xml

@@ -0,0 +1,79 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="Create and Delete Multiple Running Instance (other than the MainApp)">
+    <description>
+        # TODO: Still need to do this
+        Test 15: Check if multiple running instances can be deleted after the creation.
+    </description>
+    <inport name="ui"/>
+    <outport name="ui"/>
+    <class name="MainApp" default="true">
+        <relationships>
+            <association name="linkA" class="A" />
+        </relationships>
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise scope="cd" event="create_instance">
+                        <parameter expr='"linkA"' />
+                        <parameter expr='"A"' />
+                    </raise>
+                </onentry>
+                <transition event='instance_created' target='../state2'>
+                    <parameter name="association_name" type="string"/>
+                    <raise port="ui" event="instance_created_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                    <raise scope="cd" event="start_instance">
+                        <parameter expr='association_name' />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state2">
+                <transition event='instance_started' target='../state3'>
+                    <parameter name="association_name" type="string"/>
+                    <raise port="ui" event="instance_started_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state3">
+                <onentry>
+                    <raise scope="cd" event="delete_instance">
+                        <parameter expr="'linkA[0]'" />
+                    </raise>
+                </onentry>
+                <transition event='instance_deleted' target='../state4'>
+                    <parameter name="deleted_links" type="string"/>
+                    <raise port="ui" event="instance_deleted_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="deleted_links" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state4">
+                <onentry>
+                    <raise scope="narrow" event="sanity_check" target="'linkA[0]'" />
+                </onentry>
+            </state>
+        </scxml>
+    </class>
+
+    <class name="A">
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise port="ui" event="statechart_started_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                </onentry>
+                <transition event="sanity_check" target=".">
+                    <raise port="ui" event="not_possible">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                </transition>
+            </state>
+        </scxml>
+    </class>
+</diagram>

+ 4 - 0
tests/Test22/PyDEVS/log.txt

@@ -0,0 +1,4 @@
+0.00s - Debugger warning: It seems that frozen modules are being used, which may
+0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
+0.00s - to python to disable frozen modules.
+0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.

+ 20 - 0
tests/Test22/PyDEVS/runner.py

@@ -0,0 +1,20 @@
+import target as target
+from sccd.runtime.DEVS_loop import DEVSSimulator
+from sccd.runtime.statecharts_core import Event
+
+class OutputListener:
+	def add(self, events):
+		for event in events:
+			if event.port == "ui":
+				print(event.name, ", received on:", event.parameters[0], "seconds, parameters:", event.parameters[1:])
+				
+
+if __name__ == '__main__':
+	controller = target.Controller(name="controller")
+	refs = {"ui": controller.in_ui}
+	sim = DEVSSimulator(controller, refs)
+
+	listener = OutputListener()
+	sim.setListenPorts(controller.out_ui, listener.add)
+	sim.simulate()
+

+ 243 - 0
tests/Test22/PyDEVS/target.py

@@ -0,0 +1,243 @@
+"""
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration) and Sam Pieters (DEVS)
+
+Model author: Sam Pieters
+Model name:   Dissasociate an instance
+Model description:
+Test 12: Dissasociate an instance
+"""
+
+from sccd.runtime.DEVS_statecharts_core import *
+
+# package "Dissasociate an instance"
+
+class MainAppInstance(RuntimeClassBase):
+    def __init__(self, atomdevs):
+        RuntimeClassBase.__init__(self, atomdevs)
+        self.associations = {}
+        self.associations["linkA"] = Association("A", 0, -1)
+        
+        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
+        MainAppInstance.user_defined_constructor(self)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
+    
+    def user_defined_constructor(self):
+        self.association_name = None
+    
+    def user_defined_destructor(self):
+        pass
+    
+    
+    # builds Statechart structure
+    def build_statechart_structure(self):
+        
+        # state <root>
+        self.states[""] = State(0, "", self)
+        
+        # state /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        
+        # state /state3
+        self.states["/state3"] = State(3, "/state3", self)
+        self.states["/state3"].setEnter(self._state3_enter)
+        
+        # state /state4
+        self.states["/state4"] = State(4, "/state4", self)
+        self.states["/state4"].setEnter(self._state4_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].addChild(self.states["/state3"])
+        self.states[""].addChild(self.states["/state4"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("instance_created", None))
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state3"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("instance_started", None))
+        self.states["/state2"].addTransition(_state2_0)
+        
+        # transition /state3
+        _state3_0 = Transition(self, self.states["/state3"], [self.states["/state4"]])
+        _state3_0.setAction(self._state3_0_exec)
+        _state3_0.setTrigger(Event("instance_disassociated", None))
+        self.states["/state3"].addTransition(_state3_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state3_enter(self):
+        self.big_step.outputEventOM(Event("disassociate_instance", None, [self, "linkA"]))
+    
+    def _state4_enter(self):
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.association_name, Event("sanity_check", None, [])]))
+    
+    def _state1_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.association_name = association_name
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
+    
+    def _state2_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("link_check", None, [association_name])]))
+    
+    def _state3_0_exec(self, parameters):
+        deleted_links = parameters[0]
+        self.big_step.outputEvent(Event("instance_disassociated_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class MainApp(ObjectManagerBase):
+    def __init__(self, name):
+        ObjectManagerBase.__init__(self, name)
+        self.input = self.addInPort("input")
+        self.output = self.addOutPort("ui")
+        self.outputs["linkA"] = self.addOutPort("linkA")
+        self.instances[self.next_instance] = MainAppInstance(self)
+        self.next_instance = self.next_instance + 1
+    
+    def constructObject(self, parameters):
+        new_instance = MainAppInstance(self)
+        return new_instance
+
+class AInstance(RuntimeClassBase):
+    def __init__(self, atomdevs):
+        RuntimeClassBase.__init__(self, atomdevs)
+        self.associations = {}
+        
+        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
+        AInstance.user_defined_constructor(self)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
+    
+    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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setTrigger(None)
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state2"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("link_check", None))
+        self.states["/state2"].addTransition(_state2_0)
+        _state2_1 = Transition(self, self.states["/state2"], [self.states["/state2"]])
+        _state2_1.setAction(self._state2_1_exec)
+        _state2_1.setTrigger(Event("sanity_check", None))
+        self.states["/state2"].addTransition(_state2_1)
+    
+    def _state1_enter(self):
+        self.big_step.outputEvent(Event("statechart_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def _state2_0_exec(self, parameters):
+        link_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_linked_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), link_name]))
+    
+    def _state2_1_exec(self, parameters):
+        self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class A(ObjectManagerBase):
+    def __init__(self, name):
+        ObjectManagerBase.__init__(self, name)
+        self.input = self.addInPort("input")
+        self.output = self.addOutPort("ui")
+    
+    def constructObject(self, parameters):
+        new_instance = AInstance(self)
+        return new_instance
+
+class ObjectManagerState:
+    def __init__(self):
+        self.to_send = [("MainApp", "MainApp", Event("start_instance", None, ["MainApp[0]"], 0))]
+
+class ObjectManager(TheObjectManager):
+    def __init__(self, name):
+        TheObjectManager.__init__(self, name)
+        self.State = ObjectManagerState()
+        self.input = self.addInPort("input")
+        self.output["MainApp"] = self.addOutPort()
+        self.output["A"] = self.addOutPort()
+
+class Controller(CoupledDEVS):
+    def __init__(self, name):
+        CoupledDEVS.__init__(self, name)
+        self.in_ui = self.addInPort("ui")
+        Ports.addInputPort("ui")
+        self.out_ui = self.addOutPort("ui")
+        Ports.addOutputPort("ui")
+        self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
+        self.atomic0 = self.addSubModel(MainApp("MainApp"))
+        self.atomic1 = self.addSubModel(A("A"))
+        self.connectPorts(self.atomic0.obj_manager_out, self.objectmanager.input)
+        self.connectPorts(self.objectmanager.output["MainApp"], self.atomic0.obj_manager_in)
+        self.connectPorts(self.atomic0.outputs["linkA"], self.atomic1.input)
+        self.connectPorts(self.atomic1.obj_manager_out, self.objectmanager.input)
+        self.connectPorts(self.objectmanager.output["A"], self.atomic1.obj_manager_in)
+        self.connectPorts(self.atomic0.output, self.out_ui)
+        self.connectPorts(self.atomic1.output, self.out_ui)

+ 8 - 0
tests/Test22/Python/log.txt

@@ -0,0 +1,8 @@
+instance_created_succesfully , received on: 0.00 seconds, parameters: ['linkA[0]']
+statechart_started_succesfully , received on: 0.00 seconds, parameters: []
+constructor_initialized_succesfully , received on: 0.00 seconds, parameters: []
+instance_started_succesfully , received on: 0.00 seconds, parameters: ['linkA[0]']
+0.00s - Debugger warning: It seems that frozen modules are being used, which may
+0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
+0.00s - to python to disable frozen modules.
+0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.

+ 16 - 0
tests/Test22/Python/runner.py

@@ -0,0 +1,16 @@
+import target as target
+from sccd.runtime.statecharts_core import Event
+import threading
+
+class OutputListener:
+	def add(self, event):
+		if event.port == "ui":
+			print(event.name, ", received on:", event.parameters[0], "seconds, parameters:", event.parameters[1:])
+				
+
+if __name__ == '__main__':
+	controller = target.Controller()
+	controller.keep_running = False
+	controller.addMyOwnOutputListener(OutputListener())
+	controller.setVerbose(None)
+	controller.start()

+ 210 - 0
tests/Test22/Python/target.py

@@ -0,0 +1,210 @@
+"""
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
+
+Model author: Sam Pieters
+Model name:   Dissasociate an instance
+Model description:
+Test 12: Dissasociate an instance
+"""
+
+from sccd.runtime.statecharts_core import *
+
+# package "Dissasociate an instance"
+
+class MainApp(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
+        MainApp.user_defined_constructor(self)
+    
+    def user_defined_constructor(self):
+        self.association_name = None
+    
+    def user_defined_destructor(self):
+        pass
+    
+    
+    # builds Statechart structure
+    def build_statechart_structure(self):
+        
+        # state <root>
+        self.states[""] = State(0, "", self)
+        
+        # state /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        
+        # state /state3
+        self.states["/state3"] = State(3, "/state3", self)
+        self.states["/state3"].setEnter(self._state3_enter)
+        
+        # state /state4
+        self.states["/state4"] = State(4, "/state4", self)
+        self.states["/state4"].setEnter(self._state4_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].addChild(self.states["/state3"])
+        self.states[""].addChild(self.states["/state4"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("instance_created", None))
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state3"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("instance_started", None))
+        self.states["/state2"].addTransition(_state2_0)
+        
+        # transition /state3
+        _state3_0 = Transition(self, self.states["/state3"], [self.states["/state4"]])
+        _state3_0.setAction(self._state3_0_exec)
+        _state3_0.setTrigger(Event("instance_disassociated", None))
+        self.states["/state3"].addTransition(_state3_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state3_enter(self):
+        self.big_step.outputEventOM(Event("disassociate_instance", None, [self, "linkA"]))
+    
+    def _state4_enter(self):
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.association_name, Event("sanity_check", None, [])]))
+    
+    def _state1_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.association_name = association_name
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
+    
+    def _state2_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("link_check", None, [association_name])]))
+    
+    def _state3_0_exec(self, parameters):
+        deleted_links = parameters[0]
+        self.big_step.outputEvent(Event("instance_disassociated_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setTrigger(None)
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state2"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("link_check", None))
+        self.states["/state2"].addTransition(_state2_0)
+        _state2_1 = Transition(self, self.states["/state2"], [self.states["/state2"]])
+        _state2_1.setAction(self._state2_1_exec)
+        _state2_1.setTrigger(Event("sanity_check", None))
+        self.states["/state2"].addTransition(_state2_1)
+    
+    def _state1_enter(self):
+        self.big_step.outputEvent(Event("statechart_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def _state2_0_exec(self, parameters):
+        link_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_linked_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), link_name]))
+    
+    def _state2_1_exec(self, parameters):
+        self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].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 == "MainApp":
+            instance = MainApp(self.controller)
+            instance.associations = {}
+            instance.associations["linkA"] = Association("A", 0, -1)
+        elif class_name == "A":
+            instance = A(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("ui")
+        self.addOutputPort("ui")
+        self.object_manager.createInstance("MainApp", [])

+ 99 - 0
tests/Test22/sccd.xml

@@ -0,0 +1,99 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="Dissasociate an instance">
+    <description>
+        Test 12: Dissasociate an instance
+    </description>
+    <inport name="ui"/>
+    <outport name="ui"/>
+    <class name="MainApp" default="true">
+        <relationships>
+            <association name="linkA" class="A" />
+        </relationships>
+        <constructor>
+            <body>
+                self.association_name = None
+            </body>
+        </constructor>
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise scope="cd" event="create_instance">
+                        <parameter expr='"linkA"' />
+                        <parameter expr='"A"' />
+                    </raise>
+                </onentry>
+                <transition event='instance_created' target='../state2'>
+                    <parameter name="association_name" type="string"/>
+                    <script>
+                        self.association_name = association_name
+                    </script>
+                    <raise port="ui" event="instance_created_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                    <raise scope="cd" event="start_instance">
+                        <parameter expr="association_name" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state2">
+                <transition event='instance_started' target='../state3'>
+                    <parameter name="association_name" type="string"/>
+                    <raise port="ui" event="instance_started_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                    <raise scope="narrow" event="link_check" target="association_name">
+                        <parameter expr="association_name" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state3">
+                <onentry>
+                    <raise scope="cd" event='disassociate_instance'>
+                        <parameter expr='"linkA"' />
+                    </raise>
+                </onentry>
+                <transition event='instance_disassociated' target='../state4'>
+                    <parameter name='deleted_links' />
+                    <raise port="ui" event="instance_disassociated_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="deleted_links" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state4">
+                <onentry>
+                    <raise scope="narrow" event="sanity_check" target="self.association_name" />
+                </onentry>
+            </state>
+        </scxml>
+    </class>
+
+    <class name="A">
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise port="ui" event="statechart_started_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                </onentry>
+                <transition target="../state2" />
+            </state>
+            <state id="state2">
+                <transition event="link_check" target=".">
+                    <parameter name='link_name' />
+                    <raise port="ui" event="instance_linked_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="link_name" />
+                    </raise>
+                </transition>
+                <transition event="sanity_check" target=".">
+                    <raise port="ui" event="not_possible">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                </transition>
+            </state>
+        </scxml>
+    </class>
+</diagram>

+ 4 - 0
tests/Test23/PyDEVS/log.txt

@@ -0,0 +1,4 @@
+0.00s - Debugger warning: It seems that frozen modules are being used, which may
+0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
+0.00s - to python to disable frozen modules.
+0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.

+ 20 - 0
tests/Test23/PyDEVS/runner.py

@@ -0,0 +1,20 @@
+import target as target
+from sccd.runtime.DEVS_loop import DEVSSimulator
+from sccd.runtime.statecharts_core import Event
+
+class OutputListener:
+	def add(self, events):
+		for event in events:
+			if event.port == "ui":
+				print(event.name, ", received on:", event.parameters[0], "seconds, parameters:", event.parameters[1:])
+				
+
+if __name__ == '__main__':
+	controller = target.Controller(name="controller")
+	refs = {"ui": controller.in_ui}
+	sim = DEVSSimulator(controller, refs)
+
+	listener = OutputListener()
+	sim.setListenPorts(controller.out_ui, listener.add)
+	sim.simulate()
+

+ 243 - 0
tests/Test23/PyDEVS/target.py

@@ -0,0 +1,243 @@
+"""
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration) and Sam Pieters (DEVS)
+
+Model author: Sam Pieters
+Model name:   Dissasociate an instance
+Model description:
+Test 12: Dissasociate an instance
+"""
+
+from sccd.runtime.DEVS_statecharts_core import *
+
+# package "Dissasociate an instance"
+
+class MainAppInstance(RuntimeClassBase):
+    def __init__(self, atomdevs):
+        RuntimeClassBase.__init__(self, atomdevs)
+        self.associations = {}
+        self.associations["linkA"] = Association("A", 0, -1)
+        
+        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
+        MainAppInstance.user_defined_constructor(self)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
+    
+    def user_defined_constructor(self):
+        self.association_name = None
+    
+    def user_defined_destructor(self):
+        pass
+    
+    
+    # builds Statechart structure
+    def build_statechart_structure(self):
+        
+        # state <root>
+        self.states[""] = State(0, "", self)
+        
+        # state /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        
+        # state /state3
+        self.states["/state3"] = State(3, "/state3", self)
+        self.states["/state3"].setEnter(self._state3_enter)
+        
+        # state /state4
+        self.states["/state4"] = State(4, "/state4", self)
+        self.states["/state4"].setEnter(self._state4_enter)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].addChild(self.states["/state3"])
+        self.states[""].addChild(self.states["/state4"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("instance_created", None))
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state3"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("instance_started", None))
+        self.states["/state2"].addTransition(_state2_0)
+        
+        # transition /state3
+        _state3_0 = Transition(self, self.states["/state3"], [self.states["/state4"]])
+        _state3_0.setAction(self._state3_0_exec)
+        _state3_0.setTrigger(Event("instance_disassociated", None))
+        self.states["/state3"].addTransition(_state3_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state3_enter(self):
+        self.big_step.outputEventOM(Event("disassociate_instance", None, [self, "linkA"]))
+    
+    def _state4_enter(self):
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.association_name, Event("sanity_check", None, [])]))
+    
+    def _state1_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.association_name = association_name
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
+    
+    def _state2_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("link_check", None, [association_name])]))
+    
+    def _state3_0_exec(self, parameters):
+        deleted_links = parameters[0]
+        self.big_step.outputEvent(Event("instance_disassociated_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class MainApp(ObjectManagerBase):
+    def __init__(self, name):
+        ObjectManagerBase.__init__(self, name)
+        self.input = self.addInPort("input")
+        self.output = self.addOutPort("ui")
+        self.outputs["linkA"] = self.addOutPort("linkA")
+        self.instances[self.next_instance] = MainAppInstance(self)
+        self.next_instance = self.next_instance + 1
+    
+    def constructObject(self, parameters):
+        new_instance = MainAppInstance(self)
+        return new_instance
+
+class AInstance(RuntimeClassBase):
+    def __init__(self, atomdevs):
+        RuntimeClassBase.__init__(self, atomdevs)
+        self.associations = {}
+        
+        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
+        AInstance.user_defined_constructor(self)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
+    
+    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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setTrigger(None)
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state2"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("link_check", None))
+        self.states["/state2"].addTransition(_state2_0)
+        _state2_1 = Transition(self, self.states["/state2"], [self.states["/state2"]])
+        _state2_1.setAction(self._state2_1_exec)
+        _state2_1.setTrigger(Event("sanity_check", None))
+        self.states["/state2"].addTransition(_state2_1)
+    
+    def _state1_enter(self):
+        self.big_step.outputEvent(Event("statechart_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def _state2_0_exec(self, parameters):
+        link_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_linked_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), link_name]))
+    
+    def _state2_1_exec(self, parameters):
+        self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+class A(ObjectManagerBase):
+    def __init__(self, name):
+        ObjectManagerBase.__init__(self, name)
+        self.input = self.addInPort("input")
+        self.output = self.addOutPort("ui")
+    
+    def constructObject(self, parameters):
+        new_instance = AInstance(self)
+        return new_instance
+
+class ObjectManagerState:
+    def __init__(self):
+        self.to_send = [("MainApp", "MainApp", Event("start_instance", None, ["MainApp[0]"], 0))]
+
+class ObjectManager(TheObjectManager):
+    def __init__(self, name):
+        TheObjectManager.__init__(self, name)
+        self.State = ObjectManagerState()
+        self.input = self.addInPort("input")
+        self.output["MainApp"] = self.addOutPort()
+        self.output["A"] = self.addOutPort()
+
+class Controller(CoupledDEVS):
+    def __init__(self, name):
+        CoupledDEVS.__init__(self, name)
+        self.in_ui = self.addInPort("ui")
+        Ports.addInputPort("ui")
+        self.out_ui = self.addOutPort("ui")
+        Ports.addOutputPort("ui")
+        self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
+        self.atomic0 = self.addSubModel(MainApp("MainApp"))
+        self.atomic1 = self.addSubModel(A("A"))
+        self.connectPorts(self.atomic0.obj_manager_out, self.objectmanager.input)
+        self.connectPorts(self.objectmanager.output["MainApp"], self.atomic0.obj_manager_in)
+        self.connectPorts(self.atomic0.outputs["linkA"], self.atomic1.input)
+        self.connectPorts(self.atomic1.obj_manager_out, self.objectmanager.input)
+        self.connectPorts(self.objectmanager.output["A"], self.atomic1.obj_manager_in)
+        self.connectPorts(self.atomic0.output, self.out_ui)
+        self.connectPorts(self.atomic1.output, self.out_ui)

+ 8 - 0
tests/Test23/Python/log.txt

@@ -0,0 +1,8 @@
+instance_created_succesfully , received on: 0.00 seconds, parameters: ['linkA[0]']
+statechart_started_succesfully , received on: 0.00 seconds, parameters: []
+constructor_initialized_succesfully , received on: 0.00 seconds, parameters: []
+instance_started_succesfully , received on: 0.00 seconds, parameters: ['linkA[0]']
+0.00s - Debugger warning: It seems that frozen modules are being used, which may
+0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
+0.00s - to python to disable frozen modules.
+0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.

+ 16 - 0
tests/Test23/Python/runner.py

@@ -0,0 +1,16 @@
+import target as target
+from sccd.runtime.statecharts_core import Event
+import threading
+
+class OutputListener:
+	def add(self, event):
+		if event.port == "ui":
+			print(event.name, ", received on:", event.parameters[0], "seconds, parameters:", event.parameters[1:])
+				
+
+if __name__ == '__main__':
+	controller = target.Controller()
+	controller.keep_running = False
+	controller.addMyOwnOutputListener(OutputListener())
+	controller.setVerbose(None)
+	controller.start()

+ 233 - 0
tests/Test23/Python/target.py

@@ -0,0 +1,233 @@
+"""
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
+
+Model author: Sam Pieters
+Model name:   Dissasociate and associate an instance
+Model description:
+Test 13: Dissasociate an instance and then associate an instance again
+"""
+
+from sccd.runtime.statecharts_core import *
+
+# package "Dissasociate and associate an instance"
+
+class MainApp(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
+        MainApp.user_defined_constructor(self)
+    
+    def user_defined_constructor(self):
+        self.association_name = None
+    
+    def user_defined_destructor(self):
+        pass
+    
+    
+    # builds Statechart structure
+    def build_statechart_structure(self):
+        
+        # state <root>
+        self.states[""] = State(0, "", self)
+        
+        # state /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        
+        # state /state3
+        self.states["/state3"] = State(3, "/state3", self)
+        self.states["/state3"].setEnter(self._state3_enter)
+        
+        # state /state4
+        self.states["/state4"] = State(4, "/state4", self)
+        self.states["/state4"].setEnter(self._state4_enter)
+        
+        # state /state5
+        self.states["/state5"] = State(5, "/state5", self)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].addChild(self.states["/state3"])
+        self.states[""].addChild(self.states["/state4"])
+        self.states[""].addChild(self.states["/state5"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setAction(self._state1_0_exec)
+        _state1_0.setTrigger(Event("instance_created", None))
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state3"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("instance_started", None))
+        self.states["/state2"].addTransition(_state2_0)
+        
+        # transition /state3
+        _state3_0 = Transition(self, self.states["/state3"], [self.states["/state4"]])
+        _state3_0.setAction(self._state3_0_exec)
+        _state3_0.setTrigger(Event("instance_disassociated", None))
+        self.states["/state3"].addTransition(_state3_0)
+        
+        # transition /state4
+        _state4_0 = Transition(self, self.states["/state4"], [self.states["/state5"]])
+        _state4_0.setAction(self._state4_0_exec)
+        _state4_0.setTrigger(None)
+        self.states["/state4"].addTransition(_state4_0)
+        
+        # transition /state5
+        _state5_0 = Transition(self, self.states["/state5"], [self.states["/state5"]])
+        _state5_0.setAction(self._state5_0_exec)
+        _state5_0.setTrigger(Event("instance_associated", None))
+        self.states["/state5"].addTransition(_state5_0)
+    
+    def _state1_enter(self):
+        self.big_step.outputEventOM(Event("create_instance", None, [self, "linkA", "A"]))
+    
+    def _state3_enter(self):
+        self.big_step.outputEventOM(Event("disassociate_instance", None, [self, "linkA"]))
+    
+    def _state4_enter(self):
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, self.association_name, Event("sanity_check", None, [])]))
+    
+    def _state1_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.association_name = association_name
+        self.big_step.outputEvent(Event("instance_created_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
+    
+    def _state2_0_exec(self, parameters):
+        association_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), association_name]))
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("link_check", None, [association_name])]))
+    
+    def _state3_0_exec(self, parameters):
+        deleted_links = parameters[0]
+        self.big_step.outputEvent(Event("instance_disassociated_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), deleted_links]))
+    
+    def _state4_0_exec(self, parameters):
+        self.big_step.outputEventOM(Event("associate_instance", None, [self, self.association_name, "linkA"]))
+    
+    def _state5_0_exec(self, parameters):
+        created_links = parameters[0]
+        self.big_step.outputEventOM(Event("narrow_cast", None, [self, created_links, Event("sanity_check", None, [])]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].getEffectiveTargetStates()
+        RuntimeClassBase.initializeStatechart(self)
+
+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 /state1
+        self.states["/state1"] = State(1, "/state1", self)
+        self.states["/state1"].setEnter(self._state1_enter)
+        
+        # state /state2
+        self.states["/state2"] = State(2, "/state2", self)
+        
+        # add children
+        self.states[""].addChild(self.states["/state1"])
+        self.states[""].addChild(self.states["/state2"])
+        self.states[""].fixTree()
+        self.states[""].default_state = self.states["/state1"]
+        
+        # transition /state1
+        _state1_0 = Transition(self, self.states["/state1"], [self.states["/state2"]])
+        _state1_0.setTrigger(None)
+        self.states["/state1"].addTransition(_state1_0)
+        
+        # transition /state2
+        _state2_0 = Transition(self, self.states["/state2"], [self.states["/state2"]])
+        _state2_0.setAction(self._state2_0_exec)
+        _state2_0.setTrigger(Event("link_check", None))
+        self.states["/state2"].addTransition(_state2_0)
+        _state2_1 = Transition(self, self.states["/state2"], [self.states["/state2"]])
+        _state2_1.setAction(self._state2_1_exec)
+        _state2_1.setTrigger(Event("sanity_check", None))
+        self.states["/state2"].addTransition(_state2_1)
+    
+    def _state1_enter(self):
+        self.big_step.outputEvent(Event("statechart_started_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def _state2_0_exec(self, parameters):
+        link_name = parameters[0]
+        self.big_step.outputEvent(Event("instance_linked_succesfully", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0)), link_name]))
+    
+    def _state2_1_exec(self, parameters):
+        self.big_step.outputEvent(Event("not_possible", self.getOutPortName("ui"), [str('%.2f' % (self.getSimulatedTime() / 1000.0))]))
+    
+    def initializeStatechart(self):
+        # enter default state
+        self.default_targets = self.states["/state1"].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 == "MainApp":
+            instance = MainApp(self.controller)
+            instance.associations = {}
+            instance.associations["linkA"] = Association("A", 0, -1)
+        elif class_name == "A":
+            instance = A(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("ui")
+        self.addOutputPort("ui")
+        self.object_manager.createInstance("MainApp", [])

+ 113 - 0
tests/Test23/sccd.xml

@@ -0,0 +1,113 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="Dissasociate and associate an instance">
+    <description>
+        TODO: Does not work as I think it does
+        Test 13: Dissasociate an instance and then associate an instance again
+    </description>
+    <inport name="ui"/>
+    <outport name="ui"/>
+    <class name="MainApp" default="true">
+        <relationships>
+            <association name="linkA" class="A" />
+        </relationships>
+        <constructor>
+            <body>
+                self.association_name = None
+            </body>
+        </constructor>
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise scope="cd" event="create_instance">
+                        <parameter expr='"linkA"' />
+                        <parameter expr='"A"' />
+                    </raise>
+                </onentry>
+                <transition event='instance_created' target='../state2'>
+                    <parameter name="association_name" type="string"/>
+                    <script>
+                        self.association_name = association_name
+                    </script>
+                    <raise port="ui" event="instance_created_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                    <raise scope="cd" event="start_instance">
+                        <parameter expr="association_name" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state2">
+                <transition event='instance_started' target='../state3'>
+                    <parameter name="association_name" type="string"/>
+                    <raise port="ui" event="instance_started_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="association_name" />
+                    </raise>
+                    <raise scope="narrow" event="link_check" target="association_name">
+                        <parameter expr="association_name" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state3">
+                <onentry>
+                    <raise scope="cd" event='disassociate_instance'>
+                        <parameter expr='"linkA"' />
+                    </raise>
+                </onentry>
+                <transition event='instance_disassociated' target='../state4'>
+                    <parameter name='deleted_links' />
+                    <raise port="ui" event="instance_disassociated_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="deleted_links" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state4">
+                <onentry>
+                    <raise scope="narrow" event="sanity_check" target="self.association_name" />
+                </onentry>
+                <transition target='../state5'>
+                    <raise scope="cd" event='associate_instance'>
+                        <parameter expr='self.association_name' />
+                        <parameter expr='"linkA"' />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state5">
+                <transition event='instance_associated' target='.'>
+                    <parameter name='created_links' />
+                    <raise scope="narrow" event="sanity_check" target="created_links" />
+                </transition>
+
+            </state>
+        </scxml>
+    </class>
+
+    <class name="A">
+        <scxml initial="state1">
+            <state id="state1">
+                <onentry>
+                    <raise port="ui" event="statechart_started_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                </onentry>
+                <transition target="../state2" />
+            </state>
+            <state id="state2">
+                <transition event="link_check" target=".">
+                    <parameter name='link_name' />
+                    <raise port="ui" event="instance_linked_succesfully">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                        <parameter expr="link_name" />
+                    </raise>
+                </transition>
+                <transition event="sanity_check" target=".">
+                    <raise port="ui" event="not_possible">
+                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    </raise>
+                </transition>
+            </state>
+        </scxml>
+    </class>
+</diagram>