Procházet zdrojové kódy

Cleanup of tests (renaming, indexing, adding tests)

sampieters před 1 rokem
rodič
revize
5a842e14a3
100 změnil soubory, kde provedl 2804 přidání a 44943 odebrání
  1. 1 0
      .gitignore
  2. 12 8
      README.md
  3. 16 27
      TraceVerifier/DEVSTesterUnit.py
  4. 50 142
      TraceVerifier/TraceChecker.py
  5. 0 23
      TraceVerifier/clear.py
  6. 140 0
      TraceVerifier/main.py
  7. 0 86
      TraceVerifier/process_tests.py
  8. 0 562
      examples/BouncingBalls/PyDEVS/log.txt
  9. 1 2
      examples/BouncingBalls/PyDEVS/runner.py
  10. 4 4
      examples/BouncingBalls/PyDEVS/target.py
  11. 0 894
      examples/BouncingBalls/PyDEVS/the_target.py
  12. 0 898
      examples/BouncingBalls/PyDEVS/thetarget.py
  13. 0 8592
      examples/BouncingBalls/PyDEVS/trace.txt
  14. 0 12
      examples/BouncingBalls/Python/output.txt
  15. 5 0
      examples/BouncingBalls/Python/runner.py
  16. 1 3
      examples/BouncingBalls/Python/target.py
  17. 0 33275
      examples/BouncingBalls/Python/trace.txt
  18. 0 4
      examples/BouncingBalls/input_trace.txt
  19. 1 3
      examples/BouncingBalls/sccd.xml
  20. 26 0
      examples/Fail1/Python/runner.py
  21. 0 0
      examples/Fail1/config.json
  22. 0 0
      examples/Fail1/expected_trace.txt
  23. 23 0
      examples/Fail1/sccd.xml
  24. 2 4
      examples/TrafficLightHistory/Python/target.py
  25. 15 16
      sccd/compiler/DEVS_generator.py
  26. 0 1
      sccd/compiler/sccdc.py
  27. 12 8
      sccd/runtime/DEVS_statecharts_core.py
  28. 11 0
      sccd/runtime/libs/DEVSutils.py
  29. 25 1
      sccd/runtime/statecharts_core.py
  30. 1 1
      tests/1.0) EventlessTransitionTest/sccd.xml
  31. 1 1
      tests/1.1) AfterTransitionTest/sccd.xml
  32. 5 3
      tests/1.10) ShallowHistoryTest/sccd.xml
  33. 5 3
      tests/1.11) DeepHistoryTest/sccd.xml
  34. 6 2
      tests/1.12) NonDeterminismTest/sccd.xml
  35. 1 1
      tests/1.2) GuardConditionTest/sccd.xml
  36. 1 1
      tests/1.3) TransitionToItselfTest/sccd.xml
  37. 2 2
      tests/1.4) ScriptTransitionTest/sccd.xml
  38. 2 2
      tests/1.5) ScriptEntryTest/sccd.xml
  39. 2 2
      tests/1.6) ScriptExitTest/sccd.xml
  40. 0 0
      tests/1.7) CompositeInitialStateTest/config.json
  41. 7 0
      tests/1.7) CompositeInitialStateTest/expected_trace.txt
  42. 3 2
      tests/1.7) CompositeStateTest/sccd.xml
  43. 3 0
      tests/1.9) ParallelStateTest/config.json
  44. 0 0
      tests/1.9) ParallelStateTest/expected_trace.txt
  45. 2 2
      tests/1.8) ParallelStateTest/sccd.xml
  46. 1 1
      tests/10.0) TrafficLightTest/input.txt
  47. 0 250
      tests/10.0) TrafficLightTest/output.txt
  48. 1 1
      tests/10.0) TrafficLightTest/sccd.xml
  49. 0 4
      tests/10.1) BouncingBallsTest/input.txt
  50. 3 0
      tests/10.1) TrafficLightHistory/config.json
  51. 43 0
      tests/10.1) TrafficLightHistory/expected_trace.txt
  52. 10 0
      tests/10.1) TrafficLightHistory/input.txt
  53. 292 0
      tests/10.1) TrafficLightHistory/sccd.xml
  54. 3 0
      tests/10.2) SimplestBouncingBallsTest/config.json
  55. 70 0
      tests/10.2) SimplestBouncingBallsTest/expected_trace.txt
  56. 4 0
      tests/10.2) SimplestBouncingBallsTest/input.txt
  57. 43 42
      tests/10.1) BouncingBallsTest/sccd.xml
  58. 3 0
      tests/10.3) OneBallBouncingBallsTest/config.json
  59. 186 0
      tests/10.3) OneBallBouncingBallsTest/expected_trace.txt
  60. 6 0
      tests/10.3) OneBallBouncingBallsTest/input.txt
  61. 484 0
      tests/10.3) OneBallBouncingBallsTest/sccd.xml
  62. 3 0
      tests/10.4) CreateExtraFieldBouncingBallsTest/config.json
  63. 597 0
      tests/10.4) CreateExtraFieldBouncingBallsTest/expected_trace.txt
  64. 7 0
      tests/10.4) CreateExtraFieldBouncingBallsTest/input.txt
  65. 484 0
      tests/10.4) CreateExtraFieldBouncingBallsTest/sccd.xml
  66. 3 3
      tests/2.0) GlobalInputTest/expected_trace.txt
  67. 2 1
      tests/2.0) GlobalInputTest/input.txt
  68. 3 3
      tests/2.0) GlobalInputTest/sccd.xml
  69. 3 0
      tests/2.1) GlobalInputCheckTest/config.json
  70. 3 0
      tests/2.1) GlobalInputCheckTest/expected_trace.txt
  71. 2 0
      tests/2.1) GlobalInputCheckTest/input.txt
  72. 16 0
      tests/2.1) GlobalInputCheckTest/sccd.xml
  73. 3 0
      tests/2.2) GlobalInputParameterTest/config.json
  74. 6 0
      tests/2.2) GlobalInputParameterTest/expected_trace.txt
  75. 1 0
      tests/2.2) GlobalInputParameterTest/input.txt
  76. 28 0
      tests/2.2) GlobalInputParameterTest/sccd.xml
  77. 0 0
      tests/2.3) GlobalOutputTest/expected_trace.txt
  78. 2 2
      tests/2.1) GlobalOutputTest/sccd.xml
  79. 0 1
      tests/2.3) TimedOutputTest/expected_trace.txt
  80. 1 0
      tests/2.4) GlobalTimedOutputTest/expected_trace.txt
  81. 17 0
      tests/2.4) GlobalTimedOutputTest/sccd.xml
  82. 1 0
      tests/2.5) GlobalTimedOutputTest/expected_trace.txt
  83. 4 7
      tests/2.3) TimedOutputTest/sccd.xml
  84. 0 5
      tests/2.5) MultipleOutputTest/expected_trace.txt
  85. 0 0
      tests/2.6) GlobalIOTest/expected_trace.txt
  86. 0 0
      tests/2.6) GlobalIOTest/input.txt
  87. 2 2
      tests/2.2) GlobalIOTest/sccd.xml
  88. 3 0
      tests/2.7) MultipleInstanceGlobalInputTest/config.json
  89. 12 0
      tests/2.7) MultipleInstanceGlobalInputTest/expected_trace.txt
  90. 1 0
      tests/2.7) MultipleInstanceGlobalInputTest/input.txt
  91. 42 0
      tests/2.7) MultipleInstanceGlobalInputTest/sccd.xml
  92. 5 0
      tests/2.8) MultipleOutputTest/expected_trace.txt
  93. 4 6
      tests/2.5) MultipleOutputTest/sccd.xml
  94. 1 1
      tests/3.0) ClassCreation/expected_trace.txt
  95. 5 9
      tests/3.0) ClassCreation/sccd.xml
  96. 3 0
      tests/3.1) ClassInitialisation/expected_trace.txt
  97. 5 9
      tests/3.1) ClassInitialization/sccd.xml
  98. 0 3
      tests/3.1) ClassInitialization/expected_trace.txt
  99. 0 6
      tests/3.10) DeleteBadFromNonParent/expected_trace.txt
  100. 0 0
      tests/3.10) DeleteGoodFromNonParent/expected_trace.txt

+ 1 - 0
.gitignore

@@ -1,5 +1,6 @@
 /tests/**/ClassicDEVS/
 /tests/**/Python/
+/PythonPreconfigTest/
 
 # Byte-compiled / optimized Python files
 __pycache__/

+ 12 - 8
README.md

@@ -65,10 +65,18 @@ If the user wants to create its own test, the user can create a new subfolder wi
 
 - An SCCDXML file which provides the model that needs to be tested.
 - An expected trace file called ```expected_trace.txt``` which consists of traces in a chronological order the tracer of the model should output them.
-- (Optional) A ```config.json``` file which provides a configuration file for the test. Up to this point the file is a json with one parameter called ```trace``` and could be three options. These options could be used together.
-    - external: check global outputs of the model
-    - internal: check internal events of the model
-    - statechart: check statechart dynamics (exit state, enter state, and transition)
+- (Optional) A ```config.json``` file which provides a configuration file for the test. If this is not given, the test framework will default to an internal configuration. The configuration file has the following parameters:
+
+    - ```model```: The SCCDXML file the model to be tested is defined in (default: ```sccd.xml```),
+    - ```input```: Text file with input events (default: ```None```),
+    - ```trace```: Option for which events need to be traced. There are three levels of tracing which can be used together for one test:
+        - ```external``` (default): check global outputs of the model.
+        - ```internal```: check internal events of the model.
+        - ```statechart```: check statechart dynamics (exit state, enter state, and transition).
+    - ```platforms```: The platforms to be tested, the parameter is either one platform or a list of multiple platforms. Current platforms that are supported:
+        - ```Python``` (default): The Python SCCD threading platform.
+        - ```ClassicDEVS``` (default): The DEVS version of SCCD.
+    - ```check_file```: A text file referring to the actual trace (default: ```expected_trace.txt```)
 
 For each test, the script will return a result in the terminal:
 - Passed: The test passed, meaning the trace of the model is the same as the expected trace.
@@ -194,9 +202,5 @@ A window can also be deleted by clicking on the close window button on the top r
 ## TODO
 - [] Create elevator balls example
 - [] Fix bug in narrow cast for testing framework
-- [] Finish README
 - [] Check paper
-- [] Ask for deadline + presentation
-- [] Check if tests are properly named
-- [] Add examples to test (bouncing balls, predefine velocity)
 - [] Send in paper, FINALLY!

+ 16 - 27
TraceVerifier/DEVSTesterUnit.py

@@ -1,7 +1,7 @@
 import re
 from pypdevs.DEVS import *
-from pypdevs.simulator import Simulator
 from sccd.runtime.DEVS_statecharts_core import Event
+from sccd.runtime.libs import DEVSutils
 from pypdevs.infinity import INFINITY
 
 def parse_event(line):
@@ -16,51 +16,40 @@ def parse_event(line):
     else:
         raise ValueError(f"Line format is incorrect: {line}")
 
-def get_port(text):
-	match = re.search(r'private_\d+_(\w+)', text)
-
-	if match:
-		result = match.group(1)
-		return result
-	else:
-		return text
-
 class TesterUnit(AtomicDEVS):
     def __init__(self, name, inputfile=None):
         AtomicDEVS.__init__(self, name)
 
+        # Open the input file and write lines to an array
         self.events = []
         if inputfile is not None:
             with open(inputfile, 'r') as file:
                 lines = file.readlines()
             self.events = [line.strip() for line in lines]
 
-        self.total_time = 0
+        self.simulated_time = 0
         self.next_event_time = 0
-
         self.to_send = []
 
     def intTransition(self):
-        self.total_time += self.next_event_time
-
+        # Update simulate time and clear the previous sended events
+        self.simulated_time += self.next_event_time
         self.to_send = []
+
         if self.events:
+            # Process events one at a time (for tracing purposes)
             event = self.events[0]
-
+            # Check if line is correct. If not halt the simulation
             space_pos = event.find(' ')
             if space_pos == -1:
                 raise ValueError("Line format is incorrect. No space found to split time and event.")
-            
-            # Extract the time and event parts
-            self.next_event_time = float(event[:space_pos]) - self.total_time
-            event_part = event[space_pos + 1:].strip()  # Strip to remove any leading/trailing whitespace
-
+            # Extract the time and event part of a line
+            self.next_event_time = float(event[:space_pos]) - self.simulated_time
+            event_part = event[space_pos + 1:].strip()
+            # Create an Event for SCCD and convert parameters to the proper format (String -> List)
             name, port, parameters = parse_event(event_part)
-            # parameters is string, convert it to list
-            parameters = eval(parameters)
-            actual_event = Event(name, port, parameters)
+            actual_event = Event(name, port, eval(parameters))
             self.to_send.append(actual_event)
-
             self.events = self.events[1:]
         else:
             self.next_event_time = INFINITY
@@ -68,11 +57,11 @@ class TesterUnit(AtomicDEVS):
     def outputFnc(self):
         to_output = {}
         for event in self.to_send:
+            # Check the corresponding port the event needs to be sended from
             for port in self.OPorts:
-                real_port = get_port(event.port)
+                real_port = DEVSutils.get_general_port(event.port)
                 if f"Test_{real_port}" == port.name:
-                    string_event = f"Event(\"{event.name}\",\"{event.port}\",{event.parameters})"
-                    to_output[port] = [string_event]
+                    to_output[port] = [event]
         return to_output
 
     def timeAdvance(self):

+ 50 - 142
TraceVerifier/TraceChecker.py

@@ -1,38 +1,23 @@
 import os
+import re
 import subprocess
 import importlib.util
-import re
-from sccd.runtime.DEVSSimulatorWrapper import DEVSSimulator
+from sccd.runtime.statecharts_core import Event
 import TraceVerifier.DEVSTesterUnit as DEVSTesterUnit
-from sccd.runtime.DEVS_statecharts_core import Event
+from sccd.runtime.DEVSSimulatorWrapper import DEVSSimulator
 
 def import_target_module(module_name, file_path):
+    # Dynamically import a target module for the runner to execute
     spec = importlib.util.spec_from_file_location(module_name, file_path)
     module = importlib.util.module_from_spec(spec)
     spec.loader.exec_module(module)
     return module
 
-def extract_pattern(log_file_path, pattern):
-    with open(log_file_path, 'r') as log_file:
-        lines = log_file.readlines()
-
-    matched_lines = [line.strip() for line in lines if re.search(pattern, line)]
-    return matched_lines
-
-def parse_event(line):
-    # Regular expression to match the desired parts of the line
-    pattern = re.compile(r'\(event name: (.*?); port: (.*?); parameters: (.*?)\)$')
-
-    match = pattern.match(line)
-    if match:
-        event_name = match.group(1)
-        port = match.group(2)
-        parameters = match.group(3)
-        return event_name, port, parameters
-    else:
-        raise ValueError(f"Line format is incorrect: {line}")
-
 class SCCDTraceChecker:
+    '''
+    Abstract class, this class defines the methods and parameters a custom trace checker 
+    needs to function in the testing framework
+    '''
     def __init__(self) -> None:
         self.config = None
         self.directory = None
@@ -43,26 +28,24 @@ class SCCDTraceChecker:
     def run(self):
         raise NotImplementedError("Run method must be implemented by the subclass")
 
-    def check(self):
+    def filter(self):
         raise NotImplementedError("Check method must be implemented by the subclass")
 
 
 class PythonSCCDTraceChecker(SCCDTraceChecker):
     def __init__(self) -> None:
         super().__init__()
-
         self.id_dict = {}
     
     def __str__(self):
         return "Python"
 
     def compile(self):
-        """
+        '''
         Convert sccd.xml to target.py for the specified tool.
-        """
+        '''
         sccd_file = os.path.join(self.directory, self.config['model'])
         output_file = os.path.join(self.directory, 'Python', 'target.py')
-
         os.makedirs(os.path.join(self.directory, 'Python'), exist_ok=True)
 
         command = [
@@ -81,22 +64,22 @@ class PythonSCCDTraceChecker(SCCDTraceChecker):
         return result.returncode
 
     def run(self):
-        python_target = os.path.join(self.directory, "Python", "target.py")
-
+        '''
+        Run the model (target.py) with a defined execution function
+        '''
         # Dynamically import the target module
+        python_target = os.path.join(self.directory, "Python", "target.py")
         target = import_target_module("target", python_target)
-
         controller = target.Controller()
         controller.keep_running = False
 
-        # Check if there is an input file
+        # Check if there is an input file for input events
         input_file = os.path.join(self.directory, self.config["input"])
         if os.path.exists(input_file):
-            # add the inputs before the simulation is started  
+            # add the inputs before the simulation is started with the correct event time 
             with open(input_file, 'r') as file:
                 lines = file.readlines()
             input_events = [line.strip() for line in lines] 
-            
             for event in input_events:
                 space_pos = event.find(' ')
                 if space_pos == -1:
@@ -106,10 +89,9 @@ class PythonSCCDTraceChecker(SCCDTraceChecker):
                 next_event_time = float(event[:space_pos]) * 1000
                 event_part = event[space_pos + 1:].strip()  # Strip to remove any leading/trailing whitespace
 
-                name, port, parameters = parse_event(event_part)
+                name, port, parameters = DEVSTesterUnit.parse_event(event_part)
                 # list is as string, convert it to actual list
                 parameters = eval(parameters)
-
                 actual_event = Event(name, port, parameters)
                 controller.addInput(actual_event, next_event_time)
 
@@ -118,60 +100,56 @@ class PythonSCCDTraceChecker(SCCDTraceChecker):
 
         # Set verbose to the log file path
         controller.setVerbose(log_file_path)
-
+        # Start the execution
         controller.start()
-
         controller.tracers.stopTracers()
     
     def extract_globalio(self, line, context):
+        # Extract global output event from the line if present
         event_pattern = re.compile(r'^\s*\\Event: \(event name:.*\)$')
         event_match = event_pattern.match(line)
         if event_match and context["time"] is not None:
             if context["context"] == "global output":
+                # Remove everything before the event string
                 event = line.strip()
-                # Remove everything before '(' in each string
                 event = event[event.index('('):]
+                # Narrow casts are also matched by regex so filter these out
                 if not "<narrow_cast>" in event:
                     return f"{context["time"]:.2f} {event}"
         return None
         
     def extract_internalio(self, line, context):
+        # Extract internal events, e.g. events sended to and from the object manager and classes
         event_pattern = re.compile(r'^\s*\\Event: \(event name:.*\)$')
         event_match = event_pattern.match(line)
 
-        if "test_narrow" in line:
-            pass
         if event_match and context["context"] is not None:
             if context["context"] == "internal input" or context["context"] == "internal output":
+                # Remove everything before the event in string
                 event = line.strip()
-                # Remove everything before '(' in each string
                 event = event[event.index('('):]
 
-                # Special for python SCCD, the first parameter is sometmies the source but the source is a memory address, give it a unique index
+                # Special for python SCCD, the first parameter is sometimes the source but the source is a memory address, give it a unique index 
+                # So that it will match DEVS and is consistent in traces. 
                 id_pattern = re.compile(
                     r'.*\(event name:.*; port:.*; parameters: \[\<[\w\.]+ object at (0x[0-9a-fA-F]+)\>.*\]'
                 )
                 id_match = id_pattern.search(event)
-
                 if id_match:
                     address = id_match.group(1)
                     if address not in self.id_dict:
                         self.id_dict[address] = len(self.id_dict)
 
-                    # Find the start and end indices of the object reference within <>
+                    # Replace the entire object reference wit a unique id
                     start_idx = event.find('<')
                     end_idx = event.find('>', start_idx) + 1
-
                     if start_idx != -1 and end_idx != -1:
-                        # Replace the entire object reference
-                        new_text = event[:start_idx] + str(self.id_dict[address]) + event[end_idx:]
-
-                    return f"{context["time"]:.2f} {new_text}"
-                
+                        event = event[:start_idx] + str(self.id_dict[address]) + event[end_idx:]
                 return f"{context["time"]:.2f} {event}"
         return None
 
     def extract_statechart(self, line, context):
+        # extract statechart statements
         if line != "\n":
             if "TRANSITION FIRED" in line:
                 context["extra_info"] = "transition"
@@ -180,14 +158,13 @@ class PythonSCCDTraceChecker(SCCDTraceChecker):
             elif "ENTER STATE" in line:
                 context["extra_info"] = "enter"
             else:
+                # Remove all unnecessary characters
                 if context["extra_info"] == "transition":
                     line = line[line.index('('):line.rfind(')')+1]
-                    line = line.replace('\n', '')
-                    line = line.replace('\t', '')  # Remove all tab character
                 else:
                     line = line[line.index('/'):]
-                    line = line.replace('\n', '')
-                    line = line.replace('\t', '')  # Remove all tab characters
+                line = line.replace('\n', '')
+                line = line.replace('\t', '')
                 return f"{context["time"]:.2f} {context['model']}: {context["extra_info"]} {line}"
         return None
 
@@ -257,10 +234,10 @@ class PythonSCCDTraceChecker(SCCDTraceChecker):
                 "extra_info": "Transition "
             }
         return context
-    
-    def extract_info(self, log_file_path, options):
-        output_events = []
 
+    def filter(self):
+        log = os.path.join(self.directory, "Python", "log.txt")
+        output_events = []
         context = {
             "time": None,
             "model": None,
@@ -268,60 +245,29 @@ class PythonSCCDTraceChecker(SCCDTraceChecker):
             "extra_info": None
         }
         
-        with open(log_file_path, 'r') as file:
+        with open(log, 'r') as file:
             lines = file.readlines()
             
             for line in lines:
                 context = self.check_state(line, context)
                 
-                if "external" in options["trace"]:
+                if "external" in self.config["trace"]:
                     io_event = self.extract_globalio(line, context)
                     if io_event is not None:
                         output_events.append(io_event)
                 
-                if "internal" in options["trace"]:
+                if "internal" in self.config["trace"]:
                     internal_event = self.extract_internalio(line, context)
                     if internal_event is not None:
                         output_events.append(internal_event)
                 
-                if "statechart" in options["trace"]:
+                if "statechart" in self.config["trace"]:
                     if context['context'] == "state":
                         statechart_event = self.extract_statechart(line, context)
                         if statechart_event is not None:
                             output_events.append(statechart_event)
-        
         return output_events
 
-    def check(self):
-        log = os.path.join(self.directory, "Python", "log.txt")
-
-        expected_log = os.path.join(self.directory, self.config["check_file"])
-
-        expected_events = []
-
-        return_code = 1
-        if os.path.exists(expected_log):
-            with open(expected_log, 'r') as file:
-                expected_events = [line.strip() for line in file.readlines()]
-
-        actual_events = self.extract_info(log, self.config)
-
-        if len(expected_events) != len(actual_events):
-            return_code = 0
-
-        elif len(expected_events) == 0 and len(actual_events) == 0:
-            return_code = 2
-        else:
-            for index, (item1, item2) in enumerate(zip(expected_events, actual_events)):
-                if item1 != item2:
-                    return_code = 0
-            
-        if return_code == 0:
-            # Write actual events to a file
-            with open(os.path.join(self.directory, "Python", "faulty_log.txt"), 'w') as file:
-                file.writelines([event + '\n' for event in actual_events])
-        return return_code
-
 
 class ClassicDevsSCCDTraceChecker(SCCDTraceChecker):
     def __init__(self) -> None:
@@ -386,10 +332,10 @@ class ClassicDevsSCCDTraceChecker(SCCDTraceChecker):
         sim = DEVSSimulator(test_model)
         sim.setRealTime(False)
         
-        # Create the full path for the log file
+        # Add the verbose tracer to add traces to .txt file
         log_file_path = os.path.join(self.directory, "ClassicDEVS", "log.txt")
-        # Set verbose to the log file path
         sim.setVerbose(log_file_path)
+        # Start the simulation correctly
         sim.setClassicDEVS()
         sim.simulate()
 
@@ -404,36 +350,26 @@ class ClassicDevsSCCDTraceChecker(SCCDTraceChecker):
         return None
         
     def extract_internalio(self, line, context):
-        if "private_2_<narrow_cast>" in line:
-            pass
         if (context["extra_info"] == "obj_manager_out" and context['transition_type'] == 'internal'):
             # Pattern to match the outermost '(event name: ...)' including a single nested '(event name: ...)'
             event_pattern = re.compile(r'\(event name:.*?(?:\(event name:.*?\))?.*?\)')
             event_match = re.search(event_pattern, line)
             if event_match and context["time"] is not None:
                 event = event_match.group(0)
-                # TODO: quick fix
+                # quick fix
                 if "event name: narrow_cast" in event:
                     event += "])"
                 return f"{context["time"]:.2f} {event}"
             
         elif (context["extra_info"] == "obj_manager_in" and context['transition_type'] == 'external') and ("<narrow_cast>" in line):
-            #event_pattern = re.compile(r'\(event name:.*\)$')
             event_pattern = r'\(event name.*?\)'
-
             event_matches = re.findall(event_pattern, line)
-
             if event_matches and context["time"] is not None:
                 if len(event_matches) > 1:
                     pass
                 # Get the last match
                 event = event_matches[-1]
                 return f"{context['time']:.2f} {event}"
-            #event_match = re.search(event_pattern, line)
-
-            #if event_match and context["time"] is not None:
-            #    event = event_match.group(0)
-            #    return f"{context["time"]:.2f} {event}"
         return None
 
     def extract_statechart(self, line, context):
@@ -497,8 +433,9 @@ class ClassicDevsSCCDTraceChecker(SCCDTraceChecker):
             context["extra_info"] = "other_port"
             
         return context
-    
-    def extract_info(self, log_file_path, options):
+
+    def filter(self):
+        log = os.path.join(self.directory, "ClassicDEVS", "log.txt")
         output_events = []
         current_time = None
 
@@ -510,7 +447,7 @@ class ClassicDevsSCCDTraceChecker(SCCDTraceChecker):
             "extra_info": None
         }
         
-        with open(log_file_path, 'r') as file:
+        with open(log, 'r') as file:
             lines = file.readlines()
             
             time_pattern = re.compile(r"__  Current Time: +([\d\.]+) +__________________________________________")
@@ -522,49 +459,20 @@ class ClassicDevsSCCDTraceChecker(SCCDTraceChecker):
 
                 context = self.check_state(line, context)
                 
-                if "external" in options["trace"]:
+                if "external" in self.config["trace"]:
                     io_event = self.extract_globalio(line, context)
                     if io_event is not None:
                         output_events.append(io_event)
                 
-                if "internal" in options["trace"]:
+                if "internal" in self.config["trace"]:
                     internal_event = self.extract_internalio(line, context)
                     if internal_event is not None:
                         output_events.append(internal_event)
                 
-                if "statechart" in options["trace"]:
+                if "statechart" in self.config["trace"]:
                     if context['context'] == "state":
                         statechart_event = self.extract_statechart(line, context)
                         if statechart_event is not None:
                             output_events.append(statechart_event)
         
-        return output_events
-
-    def check(self):
-        log = os.path.join(self.directory, "ClassicDEVS", "log.txt")
-        expected_log = os.path.join(self.directory, self.config["check_file"])
-
-        expected_events = []
-        if os.path.exists(expected_log):
-            with open(expected_log, 'r') as file:
-                expected_events = [line.strip() for line in file.readlines()]
-        
-        actual_events = self.extract_info(log, self.config)
-
-        return_code = 1
-        if len(expected_events) != len(actual_events):
-            return_code = 0
-
-        if len(expected_events) == 0 and len(actual_events) == 0:
-            return_code = 2
-
-        for index, (item1, item2) in enumerate(zip(expected_events, actual_events)):
-            if item1 != item2:
-                return_code = 0
-
-        if return_code == 0:
-            # Write actual events to a file
-            with open(os.path.join(self.directory, "ClassicDEVS", "faulty_log.txt"), 'w') as file:
-                file.writelines([event + '\n' for event in actual_events])
-
-        return return_code
+        return output_events

+ 0 - 23
TraceVerifier/clear.py

@@ -1,23 +0,0 @@
-import os
-import shutil
-
-# Path to the parent directory containing the test folders
-parent_directory = './tests'
-
-# Iterate over each folder inside the parent directory
-for folder_name in os.listdir(parent_directory):
-    folder_path = os.path.join(parent_directory, folder_name)
-    
-    # Check if the path is a directory and not a file
-    if os.path.isdir(folder_path):
-        # Delete PyDEVS folder if it exists
-        pydevs_path = os.path.join(folder_path, 'ClassicDEVS')
-        if os.path.exists(pydevs_path):
-            shutil.rmtree(pydevs_path)
-            print(f"Deleted {pydevs_path}")
-        
-        # Delete Python folder if it exists
-        python_path = os.path.join(folder_path, 'Python')
-        if os.path.exists(python_path):
-            shutil.rmtree(python_path)
-            print(f"Deleted {python_path}")

+ 140 - 0
TraceVerifier/main.py

@@ -0,0 +1,140 @@
+import os
+import re
+import json
+import shutil
+import difflib
+import argparse
+import TraceChecker
+
+# ANSI color escape codes
+RED = '\033[91m'    # Red color
+GREEN = '\033[92m'  # Green color
+YELLOW = '\033[93m' # Yellow color
+ENDC = '\033[0m'    # Reset color to default
+
+def sort_directories(test_directory):
+    # Read directory names and sort using natural sort
+    all_test_dirs = [d for d in os.listdir(test_directory) if os.path.isdir(os.path.join(test_directory, d))]
+    return sorted(all_test_dirs, key=natural_sort_key)
+
+def natural_sort_key(s):
+    # Split the string into a list of strings and numbers
+    return [int(text) if text.isdigit() else text.lower() for text in re.split(r'(\d+)', s)]
+
+if __name__ == '__main__':
+    # Create the parser to get arguments of command line
+    parser = argparse.ArgumentParser(description="Process a test folder.")
+    parser.add_argument(
+        '-i', '--input', 
+        type=str, 
+        required=True, 
+        help='Path to the test folder'
+    )
+
+    parser.add_argument(
+        '-c', '--clear', 
+        action='store_true', 
+        help='Clear the output after execution'
+    )
+
+    args = parser.parse_args()
+    source = args.input
+
+    # Define the default configuration if no configuration file is given 
+    default_config = {
+        "model": "sccd.xml",
+        "input": "input.txt",
+        "trace": "external",
+        "platforms": ["Python", "ClassicDEVS"],
+        "check_file": "expected_trace.txt"
+    }
+
+    # Add here all possible platforms (Not only the one that need to be tested but all --> resolved in config file)
+    platforms = [TraceChecker.PythonSCCDTraceChecker(), TraceChecker.ClassicDevsSCCDTraceChecker()]
+    sorted_dirs = sort_directories(source)
+    results = {str(platform): [] for platform in platforms}
+    for directory_name in sorted_dirs:
+        full_directory = os.path.join(source, directory_name)
+        if os.path.isdir(full_directory):
+            print(f"Processing {directory_name}...")
+            # Check if a user defined config exists otherwise default to the default config file
+            config_file = os.path.join(full_directory, 'config.json')
+            if os.path.exists(config_file):
+                with open(config_file, 'r') as file:
+                    config_data = json.load(file)
+                    # If an option in user config is empty, replace with default
+                    for key, value in default_config.items():
+                        if key not in config_data:
+                            config_data[key] = value
+            else:
+                # If there is no config file found in the test, give the default config file
+                config_data = default_config
+            for platform in platforms:
+                platform_name = str(platform)
+                # For each platform to be checked for the test, compile, run, and filter necessary traces
+                if platform_name in config_data['platforms']:
+                    platform.directory = full_directory
+                    platform.config = config_data
+
+                    platform.compile()
+                    platform.run()
+                    result = platform.filter()
+                    # Open the log to be compared to and write them in same format as filtered traces (list of strings)
+                    expected_log = os.path.join(full_directory, config_data["check_file"])
+                    expected_events = []
+                    if os.path.exists(expected_log):
+                        with open(expected_log, 'r') as file:
+                            expected_events = [line.strip() for line in file.readlines()]
+                    # Compare traces
+                    return_code = 1
+                    # If both traces are not the same in length, test fails
+                    if len(expected_events) != len(result):
+                        return_code = 0
+                    # If one of the trace files is empty, likely not a good option in config file
+                    if len(expected_events) == 0 and len(result) == 0:
+                        return_code = 2
+                    # Check if each line is exactly the same in both files
+                    for index, (line1, line2) in enumerate(zip(expected_events, result)):
+                        if line1 != line2:
+                            return_code = 0
+                    results[platform_name].append(return_code)
+                    # Notice the user about the test (by printing in terminal)
+                    if return_code == 0:
+                        print(f"{platform_name}: ", RED + "Failed" + ENDC)
+                        # If test fails, write the traces to a log for checking
+                        faulty_log = os.path.join(full_directory, platform_name, "faulty_log.txt")
+                        with open(faulty_log, 'w') as file:
+                            file.writelines([event + '\n' for event in result])
+                        # Use the difflib package to check on a deeper level what is different
+                        with open(expected_log, "r") as f1, open(faulty_log, "r") as f2:
+                            diff = difflib.unified_diff(f1.readlines(), f2.readlines(), fromfile=expected_log, tofile=faulty_log)
+                            for line in diff:
+                                print("\t" + line)
+                    elif return_code == 1:
+                        print(f"{platform_name}: ", GREEN + "Passed" + ENDC)
+                    else:
+                        print(f"{platform_name}: ", YELLOW + "Need more detailed testing" + ENDC)
+
+    # Print summary
+    print("\nTest Summary:")
+    for platform in platforms:
+        platform_name = str(platform)
+        print(f"\n{platform_name} Results:")
+        print(f"Passed: {GREEN}{results[platform_name].count(1)}{ENDC}")
+        print(f"Failed: {RED}{results[platform_name].count(0)}{ENDC}")
+        print(f"Warnings: {YELLOW}{results[platform_name].count(2)}{ENDC}")
+
+    # If clear option (-c) is specified, perform the clear operation
+    if args.clear:
+        print("Resetting environment...")
+        # Iterate over each folder inside the parent directory
+        for folder_name in os.listdir(source):
+            folder_path = os.path.join(source, folder_name)
+            # Check if the path is a directory and not a file
+            if os.path.isdir(folder_path):
+                for platform in platforms:
+                    platform_name = str(platform)
+                    path = os.path.join(folder_path, platform_name)
+                    if os.path.exists(path):
+                        shutil.rmtree(path)
+                        print(f"Deleted {path}")

+ 0 - 86
TraceVerifier/process_tests.py

@@ -1,86 +0,0 @@
-import os
-import re
-import json
-import TraceChecker
-
-# ANSI color escape codes
-RED = '\033[91m'    # Red color
-GREEN = '\033[92m'  # Green color
-YELLOW = '\033[93m' # Yellow color
-ENDC = '\033[0m'    # Reset color to default
-
-def sort_directories(test_directory):
-    with os.scandir(tests_directory) as entries:
-        sorted_entries = sorted(entries, key=lambda entry: entry.name)
-        sorted_items = [entry.name for entry in sorted_entries]
-    
-    # Read directory names
-    all_test_dirs = [d for d in os.listdir(tests_directory) if os.path.isdir(os.path.join(tests_directory, d))]
-    # Sort the list of directories using natural sort
-    return sorted(all_test_dirs, key=natural_sort_key)
-
-def natural_sort_key(s):
-    # Split the string into a list of strings and numbers
-    return [int(text) if text.isdigit() else text.lower() for text in re.split(r'(\d+)', s)]
-
-if __name__ == '__main__':
-    tests_directory = "./tests"
-
-    default_config = {
-        "model": "sccd.xml",
-        "input": "input.txt",
-        "trace": "external",
-        "platforms": ["Python", "ClassicDEVS"],
-        "check_file": "expected_trace.txt"
-    }
-
-    checkers = {
-        "Python": TraceChecker.PythonSCCDTraceChecker(),
-        "ClassicDEVS": TraceChecker.ClassicDevsSCCDTraceChecker()
-    }
-
-    sorted_dirs = sort_directories(tests_directory)
-    results = {checker_name: [] for checker_name in checkers}
-
-    for directory_name in sorted_dirs:
-        full_directory = os.path.join(tests_directory, directory_name)
-        if os.path.isdir(full_directory):
-            print(f"Processing {directory_name}...")
-
-            # Path to your JSON file
-            config_file = os.path.join(full_directory, 'config.json')
-            # Open and read the JSON file
-            if os.path.exists(config_file):
-                with open(config_file, 'r') as file:
-                    config_data = json.load(file)
-
-                    # Update the defined dict with any key from the default dict that is not already in the user defined dict
-                    for key, value in default_config.items():
-                        if key not in config_data:
-                            config_data[key] = value
-            else:
-                config_data = default_config
-            for checker_name, checker in checkers.items():
-                if checker_name in config_data['platforms']:
-                    checker.directory = full_directory
-                    checker.config = config_data
-
-                    checker.compile()
-                    checker.run()
-                    result = checker.check()
-                    
-                    results[checker_name].append(result)
-                    if result == 0:
-                        print(f"{checker_name}: ", RED + "Failed" + ENDC)
-                    elif result == 1:
-                        print(f"{checker_name}: ", GREEN + "Passed" + ENDC)
-                    else:
-                        print(f"{checker_name}: ", YELLOW + "Need more detailed testing" + ENDC)
-
-    # Print summary
-    print("\nTest Summary:")
-    for checker_name in checkers:
-        print(f"\n{checker_name} Results:")
-        print(f"Passed: {GREEN}{results[checker_name].count(1)}{ENDC}")
-        print(f"Failed: {RED}{results[checker_name].count(0)}{ENDC}")
-        print(f"Warnings: {YELLOW}{results[checker_name].count(2)}{ENDC}")

+ 0 - 562
examples/BouncingBalls/PyDEVS/log.txt

@@ -1,562 +0,0 @@
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	INITIAL CONDITIONS in model <controller.Ball>
-		Initial State: 
-		Next scheduled internal transition at time inf
-
-
-	INITIAL CONDITIONS in model <controller.Button>
-		Initial State: 
-		Next scheduled internal transition at time inf
-
-
-	INITIAL CONDITIONS in model <controller.Field>
-		Initial State: 
-		Next scheduled internal transition at time inf
-
-
-	INITIAL CONDITIONS in model <controller.MainApp>
-		Initial State: 
-		Next scheduled internal transition at time 0.000000
-
-
-	INITIAL CONDITIONS in model <controller.ObjectManager>
-		Initial State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: 
-			EXIT STATE in model <MainApp>
-			State: State(4) (name: /running/root/main_behaviour/initializing)
-
-			TRANSITION FIRED in model <MainApp>
-			Transition(/running/root/main_behaviour/initializing -> /running/root/main_behaviour/running)
-
-			ENTER STATE in model <MainApp>
-			State: State(5) (name: /running/root/main_behaviour/running)
-
-			EXIT STATE in model <MainApp>
-			State: State(7) (name: /running/root/cd_behaviour/waiting)
-
-			TRANSITION FIRED in model <MainApp>
-			Transition(/running/root/cd_behaviour/waiting -> /running/root/cd_behaviour/creating)
-
-			ENTER STATE in model <MainApp>
-			State: State(8) (name: /running/root/cd_behaviour/creating)
-
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-		Next scheduled internal transition at time 0.000000
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-		Next scheduled internal transition at time 0.000000
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.ObjectManager>
-		Input Port Configuration:
-			port <input>:
-				(('MainApp', 0), None, (event name: create_instance; port: None; parameters: [0, 'fields[0]']))
-		New State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Next scheduled internal transition at time 0.000000
-
-
-	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-				(('MainApp', 0), None, (event name: create_instance; port: None; parameters: [0, 'fields']))
-			port <ui>:
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.Field>
-		Input Port Configuration:
-			port <obj_manager_in>:
-				[(('MainApp', 0), ('Field', 1), (event name: create_instance; port: None; parameters: [0, 1, 'fields[0]']))]
-			port <input>:
-			port <field_ui>:
-		New State: 
-		Next scheduled internal transition at time 0.000000
-
-
-	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Output Port Configuration:
-			port <port1>:
-			port <port2>:
-				[(('MainApp', 0), ('Field', 1), (event name: create_instance; port: None; parameters: [0, 1, 'fields[0]']))]
-			port <port3>:
-			port <port4>:
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.ObjectManager>
-		Input Port Configuration:
-			port <input>:
-				(('Field', 1), ('MainApp', 0), (event name: instance_created; port: None; parameters: ['fields[0]']))
-		New State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Next scheduled internal transition at time 0.000000
-
-
-	INTERNAL TRANSITION in model <controller.Field>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-				(('Field', 1), ('MainApp', 0), (event name: instance_created; port: None; parameters: ['fields[0]']))
-			port <ui>:
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.MainApp>
-		Input Port Configuration:
-			port <obj_manager_in>:
-				[(('Field', 1), ('MainApp', 0), (event name: instance_created; port: None; parameters: ['fields[0]']))]
-			port <input>:
-		New State: 
-		Next scheduled internal transition at time 0.000000
-
-
-	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Output Port Configuration:
-			port <port1>:
-				[(('Field', 1), ('MainApp', 0), (event name: instance_created; port: None; parameters: ['fields[0]']))]
-			port <port2>:
-			port <port3>:
-			port <port4>:
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: 
-			EXIT STATE in model <MainApp>
-			State: State(8) (name: /running/root/cd_behaviour/creating)
-
-			TRANSITION FIRED in model <MainApp>
-			Transition(/running/root/cd_behaviour/creating -> /running/root/cd_behaviour/waiting)
-
-			ENTER STATE in model <MainApp>
-			State: State(7) (name: /running/root/cd_behaviour/waiting)
-
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-		Next scheduled internal transition at time 0.000000
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-		Next scheduled internal transition at time 0.000000
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.ObjectManager>
-		Input Port Configuration:
-			port <input>:
-				(('MainApp', 0), None, (event name: start_instance; port: None; parameters: [0, 'fields[0]']))
-		New State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Next scheduled internal transition at time 0.000000
-
-
-	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-				(('MainApp', 0), None, (event name: start_instance; port: None; parameters: [0, 'fields[0]']))
-			port <ui>:
-		Next scheduled internal transition at time 0.000000
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.ObjectManager>
-		Input Port Configuration:
-			port <input>:
-				(('MainApp', 0), None, (event name: narrow_cast; port: None; parameters: [0, 'fields[0]', (event name: set_association_name; port: None; parameters: ['fields[0]'])]))
-		New State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Next scheduled internal transition at time 0.000000
-
-
-	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-				(('MainApp', 0), None, (event name: narrow_cast; port: None; parameters: [0, 'fields[0]', (event name: set_association_name; port: None; parameters: ['fields[0]'])]))
-			port <ui>:
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.Field>
-		Input Port Configuration:
-			port <obj_manager_in>:
-				[(('MainApp', 0), ('Field', 1), (event name: start_instance; port: None; parameters: ['fields[0]'])), (('MainApp', 0), ('Field', 1), (event name: set_association_name; port: private_1_<narrow_cast>; parameters: ['fields[0]']))]
-			port <input>:
-			port <field_ui>:
-		New State: 
-		Next scheduled internal transition at time 0.000000
-
-
-	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Output Port Configuration:
-			port <port1>:
-			port <port2>:
-				[(('MainApp', 0), ('Field', 1), (event name: start_instance; port: None; parameters: ['fields[0]'])), (('MainApp', 0), ('Field', 1), (event name: set_association_name; port: private_1_<narrow_cast>; parameters: ['fields[0]']))]
-			port <port3>:
-			port <port4>:
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.ObjectManager>
-		Input Port Configuration:
-			port <input>:
-				(('Field', 1), ('MainApp', 0), (event name: instance_started; port: None; parameters: ['fields[0]']))
-		New State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Next scheduled internal transition at time 0.000000
-
-
-	INTERNAL TRANSITION in model <controller.Field>
-		New State: 
-			EXIT STATE in model <Field>
-			State: State(2) (name: /root/waiting)
-
-			TRANSITION FIRED in model <Field>
-			Transition(/root/waiting -> /root/creating_window)
-
-			ENTER STATE in model <Field>
-			State: State(3) (name: /root/creating_window)
-
-		Output Port Configuration:
-			port <obj_manager_out>:
-				(('Field', 1), ('MainApp', 0), (event name: instance_started; port: None; parameters: ['fields[0]']))
-			port <ui>:
-		Next scheduled internal transition at time 0.000000
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.Field>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-				(event name: create_window; port: ui; parameters: [800, 600, 'BouncingBalls', 'private_2_field_ui'])
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.MainApp>
-		Input Port Configuration:
-			port <obj_manager_in>:
-				[(('Field', 1), ('MainApp', 0), (event name: instance_started; port: None; parameters: ['fields[0]']))]
-			port <input>:
-		New State: 
-		Next scheduled internal transition at time 0.000000
-
-
-	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Output Port Configuration:
-			port <port1>:
-				[(('Field', 1), ('MainApp', 0), (event name: instance_started; port: None; parameters: ['fields[0]']))]
-			port <port2>:
-			port <port3>:
-			port <port4>:
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-		Next scheduled internal transition at time 0.000000
-
-
-__  Current Time:   0.000000 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.021034 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.Field>
-		Input Port Configuration:
-			port <obj_manager_in>:
-			port <input>:
-			port <field_ui>:
-				Event("window_created","private_2_field_ui",[0])
-		New State: 
-		Next scheduled internal transition at time 0.021034
-
-
-__  Current Time:   0.021034 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.Field>
-		New State: 
-			EXIT STATE in model <Field>
-			State: State(3) (name: /root/creating_window)
-
-			TRANSITION FIRED in model <Field>
-			Transition(/root/creating_window -> /root/creating_canvas)
-
-			ENTER STATE in model <Field>
-			State: State(4) (name: /root/creating_canvas)
-
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-		Next scheduled internal transition at time 0.021034
-
-
-__  Current Time:   0.021034 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.Field>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-				(event name: bind_event; port: ui; parameters: [0, 'WM_DELETE_WINDOW', 'window_close', 'private_2_field_ui'])
-		Next scheduled internal transition at time 0.021034
-
-
-__  Current Time:   0.021034 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.Field>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-				(event name: bind_event; port: ui; parameters: [0, '<Key>', 'key_press', 'private_2_field_ui'])
-		Next scheduled internal transition at time 0.021034
-
-
-__  Current Time:   0.021034 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.Field>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-				(event name: create_canvas; port: ui; parameters: [0, 800, 550, {'background': '#eee'}, 'private_2_field_ui'])
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.024327 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.Field>
-		Input Port Configuration:
-			port <obj_manager_in>:
-			port <input>:
-			port <field_ui>:
-				Event("canvas_created","private_2_field_ui",[1])
-		New State: 
-		Next scheduled internal transition at time 0.024327
-
-
-__  Current Time:   0.024327 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.Field>
-		New State: 
-			EXIT STATE in model <Field>
-			State: State(4) (name: /root/creating_canvas)
-
-			TRANSITION FIRED in model <Field>
-			Transition(/root/creating_canvas -> /root/creating_button)
-
-			ENTER STATE in model <Field>
-			State: State(5) (name: /root/creating_button)
-
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-		Next scheduled internal transition at time 0.024327
-
-
-__  Current Time:   0.024327 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.Field>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-				(event name: bind_event; port: ui; parameters: [1, '<Button-2>', 'right_click', 'private_2_field_ui'])
-		Next scheduled internal transition at time 0.024327
-
-
-__  Current Time:   0.024327 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.Field>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-				(event name: bind_event; port: ui; parameters: [1, '<Motion>', 'mouse_move', 'private_2_field_ui'])
-		Next scheduled internal transition at time 0.024327
-
-
-__  Current Time:   0.024327 __________________________________________ 
-
-
-	INTERNAL TRANSITION in model <controller.Field>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-			port <ui>:
-				(event name: bind_event; port: ui; parameters: [1, '<ButtonRelease>', 'mouse_release', 'private_2_field_ui'])
-		Next scheduled internal transition at time 0.024327
-
-
-__  Current Time:   0.024327 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.ObjectManager>
-		Input Port Configuration:
-			port <input>:
-				(('Field', 1), None, (event name: create_instance; port: None; parameters: [1, 'buttons[0]', 'Button', 0, 'create_new_field', 'Spawn New Window']))
-		New State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Next scheduled internal transition at time 0.024327
-
-
-	INTERNAL TRANSITION in model <controller.Field>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-				(('Field', 1), None, (event name: create_instance; port: None; parameters: [1, 'buttons', 'Button', 0, 'create_new_field', 'Spawn New Window']))
-			port <ui>:
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.024327 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.Button>
-		Input Port Configuration:
-			port <obj_manager_in>:
-				[(('Field', 1), ('Button', 2), (event name: create_instance; port: None; parameters: [1, 3, 'buttons[0]', 'Button', 0, 'create_new_field', 'Spawn New Window']))]
-			port <input>:
-			port <button_ui>:
-		New State: 
-		Next scheduled internal transition at time 0.024327
-
-
-	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Output Port Configuration:
-			port <port1>:
-			port <port2>:
-			port <port3>:
-				[(('Field', 1), ('Button', 2), (event name: create_instance; port: None; parameters: [1, 3, 'buttons[0]', 'Button', 0, 'create_new_field', 'Spawn New Window']))]
-			port <port4>:
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.024327 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.ObjectManager>
-		Input Port Configuration:
-			port <input>:
-				(('Button', 2), ('Field', 1), (event name: instance_created; port: None; parameters: ['buttons[0]']))
-		New State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Next scheduled internal transition at time 0.024327
-
-
-	INTERNAL TRANSITION in model <controller.Button>
-		New State: 
-		Output Port Configuration:
-			port <obj_manager_out>:
-				(('Button', 2), ('Field', 1), (event name: instance_created; port: None; parameters: ['buttons[0]']))
-			port <ui>:
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.024327 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.Field>
-		Input Port Configuration:
-			port <obj_manager_in>:
-				[(('Button', 2), ('Field', 1), (event name: instance_created; port: None; parameters: ['buttons[0]']))]
-			port <input>:
-			port <field_ui>:
-		New State: 
-		Next scheduled internal transition at time 0.024327
-
-
-	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <sccd.runtime.DEVS_statecharts_core.ObjectManagerState object at 0x104ab9e20>
-		Output Port Configuration:
-			port <port1>:
-			port <port2>:
-				[(('Button', 2), ('Field', 1), (event name: instance_created; port: None; parameters: ['buttons[0]']))]
-			port <port3>:
-			port <port4>:
-		Next scheduled internal transition at time inf
-

+ 1 - 2
examples/BouncingBalls/PyDEVS/runner.py

@@ -19,8 +19,7 @@ if __name__ == '__main__':
 	tkroot = tk.Tk()
 	tkroot.withdraw()
 	sim = DEVSSimulator(model)
-
-	sim.setVerbose("./examples/BouncingBalls/PyDEVS/log.txt")
+	
 	sim.setRealTimePlatformTk(tkroot)
 
 	ui = UI(tkroot, sim)

+ 4 - 4
examples/BouncingBalls/PyDEVS/target.py

@@ -31,7 +31,7 @@ class MainAppInstance(RuntimeClassBase):
         # call user defined constructor
         MainAppInstance.user_defined_constructor(self)
         port_name = addInputPort("ui", start_port_id, True)
-        atomdevs.state.port_mappings[port_name] = id
+        atomdevs.state.port_mappings[port_name] = None
         port_name = addInputPort("<narrow_cast>", start_port_id)
         atomdevs.state.port_mappings[port_name] = id
     
@@ -229,7 +229,7 @@ class FieldInstance(RuntimeClassBase):
         # call user defined constructor
         FieldInstance.user_defined_constructor(self)
         port_name = addInputPort("ui", start_port_id, True)
-        atomdevs.state.port_mappings[port_name] = id
+        atomdevs.state.port_mappings[port_name] = None
         port_name = addInputPort("<narrow_cast>", start_port_id)
         atomdevs.state.port_mappings[port_name] = id
         port_name = addInputPort("field_ui", start_port_id + 1)
@@ -498,7 +498,7 @@ class ButtonInstance(RuntimeClassBase):
         # call user defined constructor
         ButtonInstance.user_defined_constructor(self, window_id, event_name, button_text)
         port_name = addInputPort("ui", start_port_id, True)
-        atomdevs.state.port_mappings[port_name] = id
+        atomdevs.state.port_mappings[port_name] = None
         port_name = addInputPort("<narrow_cast>", start_port_id)
         atomdevs.state.port_mappings[port_name] = id
         port_name = addInputPort("button_ui", start_port_id + 1)
@@ -601,7 +601,7 @@ class BallInstance(RuntimeClassBase):
         # call user defined constructor
         BallInstance.user_defined_constructor(self, canvas_id, x, y)
         port_name = addInputPort("ui", start_port_id, True)
-        atomdevs.state.port_mappings[port_name] = id
+        atomdevs.state.port_mappings[port_name] = None
         port_name = addInputPort("<narrow_cast>", start_port_id)
         atomdevs.state.port_mappings[port_name] = id
         port_name = addInputPort("ball_ui", start_port_id + 1)

+ 0 - 894
examples/BouncingBalls/PyDEVS/the_target.py

@@ -1,894 +0,0 @@
-"""
-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:   Bouncing_Balls_DEVS_Version
-Model description:
-Tkinter frame with bouncing balls in it.
-"""
-
-from sccd.runtime.DEVS_statecharts_core import *
-from sccd.runtime.libs import ui_v2 as ui
-import random
-
-CANVAS_DIMS = (800, 550)
-
-# package "Bouncing_Balls_DEVS_Version"
-
-class MainAppInstance(RuntimeClassBase):
-    def __init__(self, atomdevs, id, start_port_id):
-        RuntimeClassBase.__init__(self, atomdevs, id)
-        self.associations = {}
-        self.associations["fields"] = Association("Field", 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 = addInputPort("<narrow_cast>", start_port_id)
-        atomdevs.addInPort(port_name)
-        atomdevs.state.port_mappings[port_name] = id
-    
-    def user_defined_constructor(self):
-        self.nr_of_fields = 0
-    
-    def user_defined_destructor(self):
-        pass
-    
-    
-    # builds Statechart structure
-    def build_statechart_structure(self):
-        
-        # state <root>
-        self.states[""] = State(0, "", self)
-        
-        # state /running
-        self.states["/running"] = State(1, "/running", self)
-        
-        # state /running/root
-        self.states["/running/root"] = ParallelState(2, "/running/root", self)
-        
-        # state /running/root/main_behaviour
-        self.states["/running/root/main_behaviour"] = State(3, "/running/root/main_behaviour", self)
-        
-        # state /running/root/main_behaviour/initializing
-        self.states["/running/root/main_behaviour/initializing"] = State(4, "/running/root/main_behaviour/initializing", self)
-        
-        # state /running/root/main_behaviour/running
-        self.states["/running/root/main_behaviour/running"] = State(5, "/running/root/main_behaviour/running", self)
-        
-        # state /running/root/cd_behaviour
-        self.states["/running/root/cd_behaviour"] = State(6, "/running/root/cd_behaviour", self)
-        
-        # state /running/root/cd_behaviour/waiting
-        self.states["/running/root/cd_behaviour/waiting"] = State(7, "/running/root/cd_behaviour/waiting", self)
-        
-        # state /running/root/cd_behaviour/creating
-        self.states["/running/root/cd_behaviour/creating"] = State(8, "/running/root/cd_behaviour/creating", self)
-        
-        # state /running/root/cd_behaviour/check_nr_of_fields
-        self.states["/running/root/cd_behaviour/check_nr_of_fields"] = State(9, "/running/root/cd_behaviour/check_nr_of_fields", self)
-        self.states["/running/root/cd_behaviour/check_nr_of_fields"].setEnter(self._running_root_cd_behaviour_check_nr_of_fields_enter)
-        self.states["/running/root/cd_behaviour/check_nr_of_fields"].setExit(self._running_root_cd_behaviour_check_nr_of_fields_exit)
-        
-        # state /running/root/cd_behaviour/stopped
-        self.states["/running/root/cd_behaviour/stopped"] = State(10, "/running/root/cd_behaviour/stopped", self)
-        
-        # state /running/stopped
-        self.states["/running/stopped"] = State(11, "/running/stopped", self)
-        
-        # add children
-        self.states[""].addChild(self.states["/running"])
-        self.states["/running"].addChild(self.states["/running/root"])
-        self.states["/running"].addChild(self.states["/running/stopped"])
-        self.states["/running/root"].addChild(self.states["/running/root/main_behaviour"])
-        self.states["/running/root"].addChild(self.states["/running/root/cd_behaviour"])
-        self.states["/running/root/main_behaviour"].addChild(self.states["/running/root/main_behaviour/initializing"])
-        self.states["/running/root/main_behaviour"].addChild(self.states["/running/root/main_behaviour/running"])
-        self.states["/running/root/cd_behaviour"].addChild(self.states["/running/root/cd_behaviour/waiting"])
-        self.states["/running/root/cd_behaviour"].addChild(self.states["/running/root/cd_behaviour/creating"])
-        self.states["/running/root/cd_behaviour"].addChild(self.states["/running/root/cd_behaviour/check_nr_of_fields"])
-        self.states["/running/root/cd_behaviour"].addChild(self.states["/running/root/cd_behaviour/stopped"])
-        self.states[""].fixTree()
-        self.states[""].default_state = self.states["/running"]
-        self.states["/running"].default_state = self.states["/running/root"]
-        self.states["/running/root/main_behaviour"].default_state = self.states["/running/root/main_behaviour/initializing"]
-        self.states["/running/root/cd_behaviour"].default_state = self.states["/running/root/cd_behaviour/waiting"]
-        
-        # transition /running/root/main_behaviour/initializing
-        _running_root_main_behaviour_initializing_0 = Transition(self, self.states["/running/root/main_behaviour/initializing"], [self.states["/running/root/main_behaviour/running"]])
-        _running_root_main_behaviour_initializing_0.setAction(self._running_root_main_behaviour_initializing_0_exec)
-        _running_root_main_behaviour_initializing_0.setTrigger(None)
-        self.states["/running/root/main_behaviour/initializing"].addTransition(_running_root_main_behaviour_initializing_0)
-        
-        # transition /running/root/main_behaviour/running
-        _running_root_main_behaviour_running_0 = Transition(self, self.states["/running/root/main_behaviour/running"], [self.states["/running/root/main_behaviour/running"]])
-        _running_root_main_behaviour_running_0.setAction(self._running_root_main_behaviour_running_0_exec)
-        _running_root_main_behaviour_running_0.setTrigger(Event("button_pressed", None))
-        _running_root_main_behaviour_running_0.setGuard(self._running_root_main_behaviour_running_0_guard)
-        self.states["/running/root/main_behaviour/running"].addTransition(_running_root_main_behaviour_running_0)
-        
-        # transition /running/root/cd_behaviour/waiting
-        _running_root_cd_behaviour_waiting_0 = Transition(self, self.states["/running/root/cd_behaviour/waiting"], [self.states["/running/root/cd_behaviour/creating"]])
-        _running_root_cd_behaviour_waiting_0.setAction(self._running_root_cd_behaviour_waiting_0_exec)
-        _running_root_cd_behaviour_waiting_0.setTrigger(Event("create_field", None))
-        self.states["/running/root/cd_behaviour/waiting"].addTransition(_running_root_cd_behaviour_waiting_0)
-        _running_root_cd_behaviour_waiting_1 = Transition(self, self.states["/running/root/cd_behaviour/waiting"], [self.states["/running/root/cd_behaviour/check_nr_of_fields"]])
-        _running_root_cd_behaviour_waiting_1.setAction(self._running_root_cd_behaviour_waiting_1_exec)
-        _running_root_cd_behaviour_waiting_1.setTrigger(Event("delete_field", None))
-        self.states["/running/root/cd_behaviour/waiting"].addTransition(_running_root_cd_behaviour_waiting_1)
-        
-        # transition /running/root/cd_behaviour/creating
-        _running_root_cd_behaviour_creating_0 = Transition(self, self.states["/running/root/cd_behaviour/creating"], [self.states["/running/root/cd_behaviour/waiting"]])
-        _running_root_cd_behaviour_creating_0.setAction(self._running_root_cd_behaviour_creating_0_exec)
-        _running_root_cd_behaviour_creating_0.setTrigger(Event("instance_created", None))
-        self.states["/running/root/cd_behaviour/creating"].addTransition(_running_root_cd_behaviour_creating_0)
-        
-        # transition /running/root/cd_behaviour/check_nr_of_fields
-        _running_root_cd_behaviour_check_nr_of_fields_0 = Transition(self, self.states["/running/root/cd_behaviour/check_nr_of_fields"], [self.states["/running/root/cd_behaviour/stopped"]])
-        _running_root_cd_behaviour_check_nr_of_fields_0.setAction(self._running_root_cd_behaviour_check_nr_of_fields_0_exec)
-        _running_root_cd_behaviour_check_nr_of_fields_0.setTrigger(Event("_0after"))
-        _running_root_cd_behaviour_check_nr_of_fields_0.setGuard(self._running_root_cd_behaviour_check_nr_of_fields_0_guard)
-        self.states["/running/root/cd_behaviour/check_nr_of_fields"].addTransition(_running_root_cd_behaviour_check_nr_of_fields_0)
-        _running_root_cd_behaviour_check_nr_of_fields_1 = Transition(self, self.states["/running/root/cd_behaviour/check_nr_of_fields"], [self.states["/running/root/cd_behaviour/waiting"]])
-        _running_root_cd_behaviour_check_nr_of_fields_1.setTrigger(None)
-        _running_root_cd_behaviour_check_nr_of_fields_1.setGuard(self._running_root_cd_behaviour_check_nr_of_fields_1_guard)
-        self.states["/running/root/cd_behaviour/check_nr_of_fields"].addTransition(_running_root_cd_behaviour_check_nr_of_fields_1)
-        
-        # transition /running/root
-        _running_root_0 = Transition(self, self.states["/running/root"], [self.states["/running/stopped"]])
-        _running_root_0.setAction(self._running_root_0_exec)
-        _running_root_0.setTrigger(Event("stop", None))
-        self.states["/running/root"].addTransition(_running_root_0)
-    
-    def _running_root_cd_behaviour_check_nr_of_fields_enter(self):
-        self.addTimer(0, 0.05)
-    
-    def _running_root_cd_behaviour_check_nr_of_fields_exit(self):
-        self.removeTimer(0)
-    
-    def _running_root_0_exec(self, parameters):
-        self.big_step.outputEvent(Event("destroy_all", self.getOutPortName("ui"), []))
-    
-    def _running_root_main_behaviour_initializing_0_exec(self, parameters):
-        self.raiseInternalEvent(Event("create_field", None, []))
-    
-    def _running_root_main_behaviour_running_0_exec(self, parameters):
-        event_name = parameters[0]
-        self.raiseInternalEvent(Event("create_field", None, []))
-    
-    def _running_root_main_behaviour_running_0_guard(self, parameters):
-        event_name = parameters[0]
-        return event_name == "create_new_field"
-    
-    def _running_root_cd_behaviour_waiting_0_exec(self, parameters):
-        self.big_step.outputEventOM(Event("create_instance", None, [self, "fields"]))
-    
-    def _running_root_cd_behaviour_waiting_1_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEventOM(Event("delete_instance", None, [self, association_name]))
-        self.nr_of_fields -= 1
-    
-    def _running_root_cd_behaviour_creating_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("set_association_name", None, [association_name])]))
-        self.nr_of_fields += 1
-    
-    def _running_root_cd_behaviour_check_nr_of_fields_0_exec(self, parameters):
-        self.raiseInternalEvent(Event("stop", None, []))
-    
-    def _running_root_cd_behaviour_check_nr_of_fields_0_guard(self, parameters):
-        return self.nr_of_fields == 0
-    
-    def _running_root_cd_behaviour_check_nr_of_fields_1_guard(self, parameters):
-        return self.nr_of_fields != 0
-    
-    def initializeStatechart(self):
-        # enter default state
-        self.default_targets = self.states["/running"].getEffectiveTargetStates()
-        RuntimeClassBase.initializeStatechart(self)
-
-class MainApp(ClassBase):
-    def __init__(self, name):
-        ClassBase.__init__(self, name)
-        self.input = self.addInPort("input")
-        self.glob_outputs["ui"] = self.addOutPort("ui")
-        self.outputs["fields"] = self.addOutPort("fields")
-        new_instance = self.constructObject(0, 0, [])
-        self.state.instances[new_instance.instance_id] = new_instance
-        self.state.next_instance = self.state.next_instance + 1
-    
-    def constructObject(self, id, start_port_id, parameters):
-        new_instance = MainAppInstance(self, id, start_port_id)
-        return new_instance
-
-class FieldInstance(RuntimeClassBase):
-    def __init__(self, atomdevs, id, start_port_id):
-        RuntimeClassBase.__init__(self, atomdevs, id)
-        self.associations = {}
-        self.associations["balls"] = Association("Ball", 0, -1)
-        self.associations["buttons"] = Association("Button", 0, -1)
-        self.associations["parent"] = Association("MainApp", 1, 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()
-        
-        # user defined attributes
-        self.window_id = None
-        self.canvas_id = None
-        
-        # call user defined constructor
-        FieldInstance.user_defined_constructor(self)
-        port_name = addInputPort("<narrow_cast>", start_port_id)
-        atomdevs.addInPort(port_name)
-        atomdevs.state.port_mappings[port_name] = id
-        port_name = addInputPort("field_ui", start_port_id)
-        atomdevs.addInPort(port_name)
-        atomdevs.state.port_mappings[port_name] = id
-        self.inports["field_ui"] = 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 /root
-        self.states["/root"] = State(1, "/root", self)
-        
-        # state /root/waiting
-        self.states["/root/waiting"] = State(2, "/root/waiting", self)
-        
-        # state /root/creating_window
-        self.states["/root/creating_window"] = State(3, "/root/creating_window", self)
-        self.states["/root/creating_window"].setEnter(self._root_creating_window_enter)
-        
-        # state /root/creating_canvas
-        self.states["/root/creating_canvas"] = State(4, "/root/creating_canvas", self)
-        self.states["/root/creating_canvas"].setEnter(self._root_creating_canvas_enter)
-        
-        # state /root/creating_button
-        self.states["/root/creating_button"] = State(5, "/root/creating_button", self)
-        self.states["/root/creating_button"].setEnter(self._root_creating_button_enter)
-        
-        # state /root/running
-        self.states["/root/running"] = ParallelState(6, "/root/running", self)
-        
-        # state /root/running/main_behaviour
-        self.states["/root/running/main_behaviour"] = State(7, "/root/running/main_behaviour", self)
-        
-        # state /root/running/main_behaviour/running
-        self.states["/root/running/main_behaviour/running"] = State(8, "/root/running/main_behaviour/running", self)
-        
-        # state /root/running/main_behaviour/creating_ball
-        self.states["/root/running/main_behaviour/creating_ball"] = State(9, "/root/running/main_behaviour/creating_ball", self)
-        
-        # state /root/running/deleting_behaviour
-        self.states["/root/running/deleting_behaviour"] = State(10, "/root/running/deleting_behaviour", self)
-        
-        # state /root/running/deleting_behaviour/running
-        self.states["/root/running/deleting_behaviour/running"] = State(11, "/root/running/deleting_behaviour/running", self)
-        
-        # state /root/running/child_behaviour
-        self.states["/root/running/child_behaviour"] = State(12, "/root/running/child_behaviour", self)
-        
-        # state /root/running/child_behaviour/listening
-        self.states["/root/running/child_behaviour/listening"] = State(13, "/root/running/child_behaviour/listening", self)
-        
-        # state /root/running/deleting_balls_behaviour
-        self.states["/root/running/deleting_balls_behaviour"] = State(14, "/root/running/deleting_balls_behaviour", self)
-        
-        # state /root/running/deleting_balls_behaviour/listening
-        self.states["/root/running/deleting_balls_behaviour/listening"] = State(15, "/root/running/deleting_balls_behaviour/listening", self)
-        
-        # state /root/deleting
-        self.states["/root/deleting"] = State(16, "/root/deleting", self)
-        
-        # state /root/deleted
-        self.states["/root/deleted"] = State(17, "/root/deleted", self)
-        
-        # add children
-        self.states[""].addChild(self.states["/root"])
-        self.states["/root"].addChild(self.states["/root/waiting"])
-        self.states["/root"].addChild(self.states["/root/creating_window"])
-        self.states["/root"].addChild(self.states["/root/creating_canvas"])
-        self.states["/root"].addChild(self.states["/root/creating_button"])
-        self.states["/root"].addChild(self.states["/root/running"])
-        self.states["/root"].addChild(self.states["/root/deleting"])
-        self.states["/root"].addChild(self.states["/root/deleted"])
-        self.states["/root/running"].addChild(self.states["/root/running/main_behaviour"])
-        self.states["/root/running"].addChild(self.states["/root/running/deleting_behaviour"])
-        self.states["/root/running"].addChild(self.states["/root/running/child_behaviour"])
-        self.states["/root/running"].addChild(self.states["/root/running/deleting_balls_behaviour"])
-        self.states["/root/running/main_behaviour"].addChild(self.states["/root/running/main_behaviour/running"])
-        self.states["/root/running/main_behaviour"].addChild(self.states["/root/running/main_behaviour/creating_ball"])
-        self.states["/root/running/deleting_behaviour"].addChild(self.states["/root/running/deleting_behaviour/running"])
-        self.states["/root/running/child_behaviour"].addChild(self.states["/root/running/child_behaviour/listening"])
-        self.states["/root/running/deleting_balls_behaviour"].addChild(self.states["/root/running/deleting_balls_behaviour/listening"])
-        self.states[""].fixTree()
-        self.states[""].default_state = self.states["/root"]
-        self.states["/root"].default_state = self.states["/root/waiting"]
-        self.states["/root/running/main_behaviour"].default_state = self.states["/root/running/main_behaviour/running"]
-        self.states["/root/running/deleting_behaviour"].default_state = self.states["/root/running/deleting_behaviour/running"]
-        self.states["/root/running/child_behaviour"].default_state = self.states["/root/running/child_behaviour/listening"]
-        self.states["/root/running/deleting_balls_behaviour"].default_state = self.states["/root/running/deleting_balls_behaviour/listening"]
-        
-        # transition /root/waiting
-        _root_waiting_0 = Transition(self, self.states["/root/waiting"], [self.states["/root/creating_window"]])
-        _root_waiting_0.setAction(self._root_waiting_0_exec)
-        _root_waiting_0.setTrigger(Event("set_association_name", None))
-        self.states["/root/waiting"].addTransition(_root_waiting_0)
-        
-        # transition /root/creating_window
-        _root_creating_window_0 = Transition(self, self.states["/root/creating_window"], [self.states["/root/creating_canvas"]])
-        _root_creating_window_0.setAction(self._root_creating_window_0_exec)
-        _root_creating_window_0.setTrigger(Event("window_created", None))
-        self.states["/root/creating_window"].addTransition(_root_creating_window_0)
-        
-        # transition /root/creating_canvas
-        _root_creating_canvas_0 = Transition(self, self.states["/root/creating_canvas"], [self.states["/root/creating_button"]])
-        _root_creating_canvas_0.setAction(self._root_creating_canvas_0_exec)
-        _root_creating_canvas_0.setTrigger(Event("canvas_created", None))
-        self.states["/root/creating_canvas"].addTransition(_root_creating_canvas_0)
-        
-        # transition /root/creating_button
-        _root_creating_button_0 = Transition(self, self.states["/root/creating_button"], [self.states["/root/running"]])
-        _root_creating_button_0.setAction(self._root_creating_button_0_exec)
-        _root_creating_button_0.setTrigger(Event("instance_created", None))
-        self.states["/root/creating_button"].addTransition(_root_creating_button_0)
-        
-        # transition /root/running/main_behaviour/running
-        _root_running_main_behaviour_running_0 = Transition(self, self.states["/root/running/main_behaviour/running"], [self.states["/root/running/main_behaviour/creating_ball"]])
-        _root_running_main_behaviour_running_0.setAction(self._root_running_main_behaviour_running_0_exec)
-        _root_running_main_behaviour_running_0.setTrigger(Event("right_click", self.getInPortName("field_ui")))
-        self.states["/root/running/main_behaviour/running"].addTransition(_root_running_main_behaviour_running_0)
-        
-        # transition /root/running/main_behaviour/creating_ball
-        _root_running_main_behaviour_creating_ball_0 = Transition(self, self.states["/root/running/main_behaviour/creating_ball"], [self.states["/root/running/main_behaviour/running"]])
-        _root_running_main_behaviour_creating_ball_0.setAction(self._root_running_main_behaviour_creating_ball_0_exec)
-        _root_running_main_behaviour_creating_ball_0.setTrigger(Event("instance_created", None))
-        self.states["/root/running/main_behaviour/creating_ball"].addTransition(_root_running_main_behaviour_creating_ball_0)
-        
-        # transition /root/running/deleting_behaviour/running
-        _root_running_deleting_behaviour_running_0 = Transition(self, self.states["/root/running/deleting_behaviour/running"], [self.states["/root/running/deleting_behaviour/running"]])
-        _root_running_deleting_behaviour_running_0.setAction(self._root_running_deleting_behaviour_running_0_exec)
-        _root_running_deleting_behaviour_running_0.setTrigger(Event("delete_ball", None))
-        self.states["/root/running/deleting_behaviour/running"].addTransition(_root_running_deleting_behaviour_running_0)
-        
-        # transition /root/running/child_behaviour/listening
-        _root_running_child_behaviour_listening_0 = Transition(self, self.states["/root/running/child_behaviour/listening"], [self.states["/root/running/child_behaviour/listening"]])
-        _root_running_child_behaviour_listening_0.setAction(self._root_running_child_behaviour_listening_0_exec)
-        _root_running_child_behaviour_listening_0.setTrigger(Event("button_pressed", None))
-        self.states["/root/running/child_behaviour/listening"].addTransition(_root_running_child_behaviour_listening_0)
-        
-        # transition /root/running/deleting_balls_behaviour/listening
-        _root_running_deleting_balls_behaviour_listening_0 = Transition(self, self.states["/root/running/deleting_balls_behaviour/listening"], [self.states["/root/running/deleting_balls_behaviour/listening"]])
-        _root_running_deleting_balls_behaviour_listening_0.setAction(self._root_running_deleting_balls_behaviour_listening_0_exec)
-        _root_running_deleting_balls_behaviour_listening_0.setTrigger(Event("key_press", self.getInPortName("field_ui")))
-        _root_running_deleting_balls_behaviour_listening_0.setGuard(self._root_running_deleting_balls_behaviour_listening_0_guard)
-        self.states["/root/running/deleting_balls_behaviour/listening"].addTransition(_root_running_deleting_balls_behaviour_listening_0)
-        
-        # transition /root/deleting
-        _root_deleting_0 = Transition(self, self.states["/root/deleting"], [self.states["/root/deleted"]])
-        _root_deleting_0.setAction(self._root_deleting_0_exec)
-        _root_deleting_0.setTrigger(None)
-        self.states["/root/deleting"].addTransition(_root_deleting_0)
-        
-        # transition /root/running
-        _root_running_0 = Transition(self, self.states["/root/running"], [self.states["/root/deleting"]])
-        _root_running_0.setAction(self._root_running_0_exec)
-        _root_running_0.setTrigger(Event("window_close", self.getInPortName("field_ui")))
-        self.states["/root/running"].addTransition(_root_running_0)
-    
-    def _root_creating_window_enter(self):
-        self.big_step.outputEvent(Event("create_window", self.getOutPortName("ui"), [800, 600, "BouncingBalls", self.inports['field_ui']]))
-    
-    def _root_creating_canvas_enter(self):
-        self.big_step.outputEvent(Event("create_canvas", self.getOutPortName("ui"), [self.window_id, CANVAS_DIMS[0], CANVAS_DIMS[1], {'background':'#eee'}, self.inports['field_ui']]))
-    
-    def _root_creating_button_enter(self):
-        self.big_step.outputEventOM(Event("create_instance", None, [self, "buttons", "Button", self.window_id, 'create_new_field', 'Spawn New Window']))
-    
-    def _root_running_0_exec(self, parameters):
-        self.big_step.outputEventOM(Event("delete_instance", None, [self, "buttons"]))
-        self.big_step.outputEventOM(Event("delete_instance", None, [self, "balls"]))
-    
-    def _root_waiting_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.association_name = association_name
-    
-    def _root_creating_window_0_exec(self, parameters):
-        window_id = parameters[0]
-        self.window_id = window_id
-        self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [window_id, ui.EVENTS.WINDOW_CLOSE, 'window_close', self.inports['field_ui']]))
-        self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [window_id, ui.EVENTS.KEY_PRESS, 'key_press', self.inports['field_ui']]))
-    
-    def _root_creating_canvas_0_exec(self, parameters):
-        canvas_id = parameters[0]
-        self.canvas_id = canvas_id
-        self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [canvas_id, ui.EVENTS.MOUSE_RIGHT_CLICK, 'right_click', self.inports['field_ui']]))
-        self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [canvas_id, ui.EVENTS.MOUSE_MOVE, 'mouse_move', self.inports['field_ui']]))
-        self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [canvas_id, ui.EVENTS.MOUSE_RELEASE, 'mouse_release', self.inports['field_ui']]))
-    
-    def _root_creating_button_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
-    
-    def _root_running_main_behaviour_running_0_exec(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        self.big_step.outputEventOM(Event("create_instance", None, [self, "balls", "Ball", self.canvas_id, x, y]))
-    
-    def _root_running_main_behaviour_creating_ball_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("set_association_name", None, [association_name])]))
-    
-    def _root_running_deleting_behaviour_running_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEventOM(Event("delete_instance", None, [self, association_name]))
-    
-    def _root_running_child_behaviour_listening_0_exec(self, parameters):
-        event_name = parameters[0]
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("button_pressed", None, [event_name])]))
-    
-    def _root_running_deleting_balls_behaviour_listening_0_exec(self, parameters):
-        key = parameters[0]
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'balls', Event("delete_self", None, [])]))
-    
-    def _root_running_deleting_balls_behaviour_listening_0_guard(self, parameters):
-        key = parameters[0]
-        return key == ui.KEYCODES.DELETE
-    
-    def _root_deleting_0_exec(self, parameters):
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("delete_field", None, [self.association_name])]))
-        self.big_step.outputEvent(Event("destroy_window", self.getOutPortName("ui"), [self.window_id]))
-    
-    def initializeStatechart(self):
-        # enter default state
-        self.default_targets = self.states["/root"].getEffectiveTargetStates()
-        RuntimeClassBase.initializeStatechart(self)
-
-class Field(ClassBase):
-    def __init__(self, name):
-        ClassBase.__init__(self, name)
-        self.input = self.addInPort("input")
-        self.glob_outputs["ui"] = self.addOutPort("ui")
-        self.outputs["balls"] = self.addOutPort("balls")
-        self.outputs["buttons"] = self.addOutPort("buttons")
-        self.outputs["parent"] = self.addOutPort("parent")
-        self.field_ui = self.addInPort("field_ui")
-    
-    def constructObject(self, id, start_port_id, parameters):
-        new_instance = FieldInstance(self, id, start_port_id)
-        return new_instance
-
-class ButtonInstance(RuntimeClassBase):
-    def __init__(self, atomdevs, id, start_port_id, window_id, event_name, button_text):
-        RuntimeClassBase.__init__(self, atomdevs, id)
-        self.associations = {}
-        self.associations["parent"] = Association("Field", 1, 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()
-        
-        # user defined attributes
-        self.window_id = None
-        self.event_name = None
-        self.button_id = None
-        
-        # call user defined constructor
-        ButtonInstance.user_defined_constructor(self, window_id, event_name, button_text)
-        port_name = addInputPort("<narrow_cast>", start_port_id)
-        atomdevs.addInPort(port_name)
-        atomdevs.state.port_mappings[port_name] = id
-        port_name = addInputPort("button_ui", start_port_id)
-        atomdevs.addInPort(port_name)
-        atomdevs.state.port_mappings[port_name] = id
-        self.inports["button_ui"] = port_name
-    
-    def user_defined_constructor(self, window_id, event_name, button_text):
-        self.window_id = window_id;
-        self.event_name = event_name;
-    
-    def user_defined_destructor(self):
-        pass
-    
-    
-    # builds Statechart structure
-    def build_statechart_structure(self):
-        
-        # state <root>
-        self.states[""] = State(0, "", self)
-        
-        # state /creating_button
-        self.states["/creating_button"] = State(1, "/creating_button", self)
-        self.states["/creating_button"].setEnter(self._creating_button_enter)
-        
-        # state /running
-        self.states["/running"] = State(2, "/running", self)
-        
-        # add children
-        self.states[""].addChild(self.states["/creating_button"])
-        self.states[""].addChild(self.states["/running"])
-        self.states[""].fixTree()
-        self.states[""].default_state = self.states["/creating_button"]
-        
-        # transition /creating_button
-        _creating_button_0 = Transition(self, self.states["/creating_button"], [self.states["/running"]])
-        _creating_button_0.setAction(self._creating_button_0_exec)
-        _creating_button_0.setTrigger(Event("button_created", None))
-        self.states["/creating_button"].addTransition(_creating_button_0)
-        
-        # transition /running
-        _running_0 = Transition(self, self.states["/running"], [self.states["/running"]])
-        _running_0.setAction(self._running_0_exec)
-        _running_0.setTrigger(Event("mouse_click", self.getInPortName("button_ui")))
-        _running_0.setGuard(self._running_0_guard)
-        self.states["/running"].addTransition(_running_0)
-    
-    def _creating_button_enter(self):
-        self.big_step.outputEvent(Event("create_button", self.getOutPortName("ui"), [self.window_id, self.event_name, self.inports['button_ui']]))
-    
-    def _creating_button_0_exec(self, parameters):
-        button_id = parameters[0]
-        self.button_id = button_id
-        self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [button_id, ui.EVENTS.MOUSE_CLICK, "mouse_click", self.inports['button_ui']]))
-    
-    def _running_0_exec(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("button_pressed", None, [self.event_name])]))
-    
-    def _running_0_guard(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        return button == ui.MOUSE_BUTTONS.LEFT
-    
-    def initializeStatechart(self):
-        # enter default state
-        self.default_targets = self.states["/creating_button"].getEffectiveTargetStates()
-        RuntimeClassBase.initializeStatechart(self)
-
-class Button(ClassBase):
-    def __init__(self, name):
-        ClassBase.__init__(self, name)
-        self.input = self.addInPort("input")
-        self.glob_outputs["ui"] = self.addOutPort("ui")
-        self.outputs["parent"] = self.addOutPort("parent")
-        self.button_ui = self.addInPort("button_ui")
-    
-    def constructObject(self, id, start_port_id, parameters):
-        new_instance = ButtonInstance(self, id, start_port_id, parameters[1], parameters[2], parameters[3])
-        return new_instance
-
-class BallInstance(RuntimeClassBase):
-    def __init__(self, atomdevs, id, start_port_id, canvas_id, x, y):
-        RuntimeClassBase.__init__(self, atomdevs, id)
-        self.associations = {}
-        self.associations["parent"] = Association("Field", 1, 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()
-        
-        # user defined attributes
-        self.canvas_id = None
-        self.pos = None
-        
-        # call user defined constructor
-        BallInstance.user_defined_constructor(self, canvas_id, x, y)
-        port_name = addInputPort("<narrow_cast>", start_port_id)
-        atomdevs.addInPort(port_name)
-        atomdevs.state.port_mappings[port_name] = id
-        port_name = addInputPort("ball_ui", start_port_id)
-        atomdevs.addInPort(port_name)
-        atomdevs.state.port_mappings[port_name] = id
-        self.inports["ball_ui"] = port_name
-    
-    def user_defined_constructor(self, canvas_id, x, y):
-        self.canvas_id = canvas_id;
-        self.r = 20.0;
-        self.vel = {'x': random.uniform(-5.0, 5.0), 'y': random.uniform(-5.0, 5.0)};
-        self.pos = {'x': x, 'y': y};
-        self.smooth = 0.6; # value between 0 and 1
-    
-    def user_defined_destructor(self):
-        pass
-    
-    
-    # builds Statechart structure
-    def build_statechart_structure(self):
-        
-        # state <root>
-        self.states[""] = State(0, "", self)
-        
-        # state /main_behaviour
-        self.states["/main_behaviour"] = State(1, "/main_behaviour", self)
-        
-        # state /main_behaviour/initializing
-        self.states["/main_behaviour/initializing"] = State(2, "/main_behaviour/initializing", self)
-        
-        # state /main_behaviour/creating_circle
-        self.states["/main_behaviour/creating_circle"] = State(3, "/main_behaviour/creating_circle", self)
-        self.states["/main_behaviour/creating_circle"].setEnter(self._main_behaviour_creating_circle_enter)
-        
-        # state /main_behaviour/bouncing
-        self.states["/main_behaviour/bouncing"] = State(4, "/main_behaviour/bouncing", self)
-        self.states["/main_behaviour/bouncing"].setEnter(self._main_behaviour_bouncing_enter)
-        self.states["/main_behaviour/bouncing"].setExit(self._main_behaviour_bouncing_exit)
-        
-        # state /main_behaviour/dragging
-        self.states["/main_behaviour/dragging"] = State(5, "/main_behaviour/dragging", self)
-        
-        # state /main_behaviour/selected
-        self.states["/main_behaviour/selected"] = State(6, "/main_behaviour/selected", self)
-        
-        # state /deleted
-        self.states["/deleted"] = State(7, "/deleted", self)
-        
-        # add children
-        self.states[""].addChild(self.states["/main_behaviour"])
-        self.states[""].addChild(self.states["/deleted"])
-        self.states["/main_behaviour"].addChild(self.states["/main_behaviour/initializing"])
-        self.states["/main_behaviour"].addChild(self.states["/main_behaviour/creating_circle"])
-        self.states["/main_behaviour"].addChild(self.states["/main_behaviour/bouncing"])
-        self.states["/main_behaviour"].addChild(self.states["/main_behaviour/dragging"])
-        self.states["/main_behaviour"].addChild(self.states["/main_behaviour/selected"])
-        self.states[""].fixTree()
-        self.states[""].default_state = self.states["/main_behaviour"]
-        self.states["/main_behaviour"].default_state = self.states["/main_behaviour/initializing"]
-        
-        # transition /main_behaviour/initializing
-        _main_behaviour_initializing_0 = Transition(self, self.states["/main_behaviour/initializing"], [self.states["/main_behaviour/creating_circle"]])
-        _main_behaviour_initializing_0.setAction(self._main_behaviour_initializing_0_exec)
-        _main_behaviour_initializing_0.setTrigger(Event("set_association_name", None))
-        self.states["/main_behaviour/initializing"].addTransition(_main_behaviour_initializing_0)
-        
-        # transition /main_behaviour/creating_circle
-        _main_behaviour_creating_circle_0 = Transition(self, self.states["/main_behaviour/creating_circle"], [self.states["/main_behaviour/bouncing"]])
-        _main_behaviour_creating_circle_0.setAction(self._main_behaviour_creating_circle_0_exec)
-        _main_behaviour_creating_circle_0.setTrigger(Event("circle_created", None))
-        self.states["/main_behaviour/creating_circle"].addTransition(_main_behaviour_creating_circle_0)
-        
-        # transition /main_behaviour/bouncing
-        _main_behaviour_bouncing_0 = Transition(self, self.states["/main_behaviour/bouncing"], [self.states["/main_behaviour/bouncing"]])
-        _main_behaviour_bouncing_0.setAction(self._main_behaviour_bouncing_0_exec)
-        _main_behaviour_bouncing_0.setTrigger(Event("_0after"))
-        self.states["/main_behaviour/bouncing"].addTransition(_main_behaviour_bouncing_0)
-        _main_behaviour_bouncing_1 = Transition(self, self.states["/main_behaviour/bouncing"], [self.states["/main_behaviour/selected"]])
-        _main_behaviour_bouncing_1.setAction(self._main_behaviour_bouncing_1_exec)
-        _main_behaviour_bouncing_1.setTrigger(Event("mouse_press", self.getInPortName("ball_ui")))
-        _main_behaviour_bouncing_1.setGuard(self._main_behaviour_bouncing_1_guard)
-        self.states["/main_behaviour/bouncing"].addTransition(_main_behaviour_bouncing_1)
-        
-        # transition /main_behaviour/dragging
-        _main_behaviour_dragging_0 = Transition(self, self.states["/main_behaviour/dragging"], [self.states["/main_behaviour/dragging"]])
-        _main_behaviour_dragging_0.setAction(self._main_behaviour_dragging_0_exec)
-        _main_behaviour_dragging_0.setTrigger(Event("mouse_move", self.getInPortName("ball_ui")))
-        self.states["/main_behaviour/dragging"].addTransition(_main_behaviour_dragging_0)
-        _main_behaviour_dragging_1 = Transition(self, self.states["/main_behaviour/dragging"], [self.states["/main_behaviour/bouncing"]])
-        _main_behaviour_dragging_1.setAction(self._main_behaviour_dragging_1_exec)
-        _main_behaviour_dragging_1.setTrigger(Event("mouse_release", self.getInPortName("ball_ui")))
-        self.states["/main_behaviour/dragging"].addTransition(_main_behaviour_dragging_1)
-        
-        # transition /main_behaviour/selected
-        _main_behaviour_selected_0 = Transition(self, self.states["/main_behaviour/selected"], [self.states["/main_behaviour/dragging"]])
-        _main_behaviour_selected_0.setAction(self._main_behaviour_selected_0_exec)
-        _main_behaviour_selected_0.setTrigger(Event("mouse_press", self.getInPortName("ball_ui")))
-        _main_behaviour_selected_0.setGuard(self._main_behaviour_selected_0_guard)
-        self.states["/main_behaviour/selected"].addTransition(_main_behaviour_selected_0)
-        _main_behaviour_selected_1 = Transition(self, self.states["/main_behaviour/selected"], [self.states["/deleted"]])
-        _main_behaviour_selected_1.setAction(self._main_behaviour_selected_1_exec)
-        _main_behaviour_selected_1.setTrigger(Event("delete_self", None))
-        self.states["/main_behaviour/selected"].addTransition(_main_behaviour_selected_1)
-    
-    def _main_behaviour_creating_circle_enter(self):
-        self.big_step.outputEvent(Event("create_circle", self.getOutPortName("ui"), [self.canvas_id, self.pos['x'], self.pos['y'], self.r, {'fill':'#000'}, self.inports['ball_ui']]))
-    
-    def _main_behaviour_bouncing_enter(self):
-        self.addTimer(0, 0.02)
-    
-    def _main_behaviour_bouncing_exit(self):
-        self.removeTimer(0)
-    
-    def _main_behaviour_initializing_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.association_name = association_name
-    
-    def _main_behaviour_creating_circle_0_exec(self, parameters):
-        canvas_id = parameters[0]
-        circle_id = parameters[1]
-        self.circle_id = circle_id
-        self.big_step.outputEvent(Event("bind_canvas_event", self.getOutPortName("ui"), [self.canvas_id, circle_id, ui.EVENTS.MOUSE_PRESS, 'mouse_press', self.inports['ball_ui']]))
-        self.big_step.outputEvent(Event("bind_canvas_event", self.getOutPortName("ui"), [self.canvas_id, circle_id, ui.EVENTS.MOUSE_MOVE, 'mouse_move', self.inports['ball_ui']]))
-        self.big_step.outputEvent(Event("bind_canvas_event", self.getOutPortName("ui"), [self.canvas_id, circle_id, ui.EVENTS.MOUSE_RELEASE, 'mouse_release', self.inports['ball_ui']]))
-    
-    def _main_behaviour_bouncing_0_exec(self, parameters):
-        # Invert velocity when colliding with canvas border:
-        if self.pos['x']-self.r <= 0 or self.pos['x']+self.r >= CANVAS_DIMS[0]:
-            self.vel['x'] = -self.vel['x'];
-        if self.pos['y']-self.r <= 0 or self.pos['y']+self.r >= CANVAS_DIMS[1]:
-            self.vel['y'] = -self.vel['y'];
-        self.big_step.outputEvent(Event("move_element", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, self.vel['x'], self.vel['y']]))
-        self.pos['x'] += self.vel['x']
-        self.pos['y'] += self.vel['y']
-    
-    def _main_behaviour_bouncing_1_exec(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, '#ff0']))
-    
-    def _main_behaviour_bouncing_1_guard(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        return button == ui.MOUSE_BUTTONS.LEFT
-    
-    def _main_behaviour_dragging_0_exec(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        # Always keep ball within canvas:
-        x = min(max(0+self.r, x), CANVAS_DIMS[0]-self.r)
-        y = min(max(0+self.r, y), CANVAS_DIMS[1]-self.r)
-        
-        dx = x - self.pos['x']
-        dy = y - self.pos['y']
-        
-        self.vel = {
-            'x': (1-self.smooth)*dx + self.smooth*self.vel['x'],
-            'y': (1-self.smooth)*dy + self.smooth*self.vel['y']
-        }
-        
-        self.pos = {'x': x, 'y': y}
-        self.big_step.outputEvent(Event("set_element_pos", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, x-self.r, y-self.r]))
-    
-    def _main_behaviour_dragging_1_exec(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, '#f00']))
-    
-    def _main_behaviour_selected_0_exec(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        self.mouse_pos = {'x':x, 'y':y};
-    
-    def _main_behaviour_selected_0_guard(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        return button == ui.MOUSE_BUTTONS.LEFT
-    
-    def _main_behaviour_selected_1_exec(self, parameters):
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("delete_ball", None, [self.association_name])]))
-        self.big_step.outputEvent(Event("destroy_element", self.getOutPortName("ui"), [self.canvas_id, self.element_id]))
-    
-    def initializeStatechart(self):
-        # enter default state
-        self.default_targets = self.states["/main_behaviour"].getEffectiveTargetStates()
-        RuntimeClassBase.initializeStatechart(self)
-
-class Ball(ClassBase):
-    def __init__(self, name):
-        ClassBase.__init__(self, name)
-        self.input = self.addInPort("input")
-        self.glob_outputs["ui"] = self.addOutPort("ui")
-        self.outputs["parent"] = self.addOutPort("parent")
-        self.ball_ui = self.addInPort("ball_ui")
-    
-    def constructObject(self, id, start_port_id, parameters):
-        new_instance = BallInstance(self, id, start_port_id, parameters[1], parameters[2], parameters[3])
-        return new_instance
-
-class Dummy(ObjectManagerState):
-    def __init__(self):
-        ObjectManagerState.__init__(self)
-    
-    def instantiate(self, class_name, construct_params):
-        instance = {}
-        instance["name"] = class_name
-        if class_name == "MainApp":
-            instance["associations"] = {}
-            instance["associations"]["fields"] = Association("Field", 0, -1)
-            self.narrow_cast_id +=  0
-        elif class_name == "Field":
-            instance["associations"] = {}
-            instance["associations"]["balls"] = Association("Ball", 0, -1)
-            instance["associations"]["buttons"] = Association("Button", 0, -1)
-            instance["associations"]["parent"] = Association("MainApp", 1, 1)
-            self.narrow_cast_id +=  1
-        elif class_name == "Button":
-            instance["associations"] = {}
-            instance["associations"]["parent"] = Association("Field", 1, 1)
-            self.narrow_cast_id +=  1
-        elif class_name == "Ball":
-            instance["associations"] = {}
-            instance["associations"]["parent"] = Association("Field", 1, 1)
-            self.narrow_cast_id +=  1
-        else:
-            raise Exception("Cannot instantiate class " + class_name)
-        return instance
-
-class ObjectManager(ObjectManagerBase):
-    def __init__(self, name):
-        ObjectManagerBase.__init__(self, name)
-        self.state = Dummy()
-        self.input = self.addInPort("input")
-        self.output["MainApp"] = self.addOutPort()
-        self.output["Field"] = self.addOutPort()
-        self.output["Button"] = self.addOutPort()
-        self.output["Ball"] = self.addOutPort()
-        self.state.createInstance("MainApp", [])
-        self.state.to_send.append((("MainApp", 0), ("MainApp", 0), Event("start_instance", None, ["MainApp[0]"])))
-
-class Controller(CoupledDEVS):
-    def __init__(self, name):
-        CoupledDEVS.__init__(self, name)
-        self.in_ui = self.addInPort("ui")
-        self.out_ui = self.addOutPort("ui")
-        self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
-        self.atomics = []
-        self.atomics.append(self.addSubModel(MainApp("MainApp")))
-        self.atomics.append(self.addSubModel(Field("Field")))
-        self.atomics.append(self.addSubModel(Button("Button")))
-        self.atomics.append(self.addSubModel(Ball("Ball")))
-        self.connectPorts(self.atomics[0].obj_manager_out, self.objectmanager.input)
-        self.connectPorts(self.objectmanager.output["MainApp"], self.atomics[0].obj_manager_in)
-        self.connectPorts(self.atomics[0].outputs["fields"], self.atomics[1].input)
-        self.connectPorts(self.atomics[1].obj_manager_out, self.objectmanager.input)
-        self.connectPorts(self.objectmanager.output["Field"], self.atomics[1].obj_manager_in)
-        self.connectPorts(self.atomics[1].outputs["balls"], self.atomics[3].input)
-        self.connectPorts(self.atomics[1].outputs["buttons"], self.atomics[2].input)
-        self.connectPorts(self.atomics[1].outputs["parent"], self.atomics[0].input)
-        self.connectPorts(self.atomics[2].obj_manager_out, self.objectmanager.input)
-        self.connectPorts(self.objectmanager.output["Button"], self.atomics[2].obj_manager_in)
-        self.connectPorts(self.atomics[2].outputs["parent"], self.atomics[1].input)
-        self.connectPorts(self.atomics[3].obj_manager_out, self.objectmanager.input)
-        self.connectPorts(self.objectmanager.output["Ball"], self.atomics[3].obj_manager_in)
-        self.connectPorts(self.atomics[3].outputs["parent"], self.atomics[1].input)
-        self.connectPorts(self.atomics[0].glob_outputs["ui"], self.out_ui)
-        self.connectPorts(self.atomics[1].glob_outputs["ui"], self.out_ui)
-        self.connectPorts(self.atomics[2].glob_outputs["ui"], self.out_ui)
-        self.connectPorts(self.atomics[3].glob_outputs["ui"], self.out_ui)
-        self.connectPorts(self.in_ui, self.atomics[0].input)
-        self.connectPorts(self.in_ui, self.atomics[1].input)
-        self.connectPorts(self.in_ui, self.atomics[2].input)
-        self.connectPorts(self.in_ui, self.atomics[3].input)

+ 0 - 898
examples/BouncingBalls/PyDEVS/thetarget.py

@@ -1,898 +0,0 @@
-"""
-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:   Bouncing_Balls_DEVS_Version
-Model description:
-Tkinter frame with bouncing balls in it.
-"""
-
-from sccd.runtime.DEVS_statecharts_core import *
-from sccd.runtime.libs import ui_v2 as ui
-import random
-
-CANVAS_DIMS = (800, 550)
-
-# package "Bouncing_Balls_DEVS_Version"
-
-class MainAppInstance(RuntimeClassBase):
-    def __init__(self, atomdevs, id, start_port_id):
-        RuntimeClassBase.__init__(self, atomdevs, id)
-        self.associations = {}
-        self.associations["fields"] = Association("Field", 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 = addInputPort("ui", start_port_id, True)
-        atomdevs.state.port_mappings[port_name] = id
-        port_name = addInputPort("<narrow_cast>", start_port_id)
-        atomdevs.state.port_mappings[port_name] = id
-    
-    def user_defined_constructor(self):
-        self.nr_of_fields = 0
-    
-    def user_defined_destructor(self):
-        pass
-    
-    
-    # builds Statechart structure
-    def build_statechart_structure(self):
-        
-        # state <root>
-        self.states[""] = State(0, "", self)
-        
-        # state /running
-        self.states["/running"] = State(1, "/running", self)
-        
-        # state /running/root
-        self.states["/running/root"] = ParallelState(2, "/running/root", self)
-        
-        # state /running/root/main_behaviour
-        self.states["/running/root/main_behaviour"] = State(3, "/running/root/main_behaviour", self)
-        
-        # state /running/root/main_behaviour/initializing
-        self.states["/running/root/main_behaviour/initializing"] = State(4, "/running/root/main_behaviour/initializing", self)
-        
-        # state /running/root/main_behaviour/running
-        self.states["/running/root/main_behaviour/running"] = State(5, "/running/root/main_behaviour/running", self)
-        
-        # state /running/root/cd_behaviour
-        self.states["/running/root/cd_behaviour"] = State(6, "/running/root/cd_behaviour", self)
-        
-        # state /running/root/cd_behaviour/waiting
-        self.states["/running/root/cd_behaviour/waiting"] = State(7, "/running/root/cd_behaviour/waiting", self)
-        
-        # state /running/root/cd_behaviour/creating
-        self.states["/running/root/cd_behaviour/creating"] = State(8, "/running/root/cd_behaviour/creating", self)
-        
-        # state /running/root/cd_behaviour/check_nr_of_fields
-        self.states["/running/root/cd_behaviour/check_nr_of_fields"] = State(9, "/running/root/cd_behaviour/check_nr_of_fields", self)
-        self.states["/running/root/cd_behaviour/check_nr_of_fields"].setEnter(self._running_root_cd_behaviour_check_nr_of_fields_enter)
-        self.states["/running/root/cd_behaviour/check_nr_of_fields"].setExit(self._running_root_cd_behaviour_check_nr_of_fields_exit)
-        
-        # state /running/root/cd_behaviour/stopped
-        self.states["/running/root/cd_behaviour/stopped"] = State(10, "/running/root/cd_behaviour/stopped", self)
-        
-        # state /running/stopped
-        self.states["/running/stopped"] = State(11, "/running/stopped", self)
-        
-        # add children
-        self.states[""].addChild(self.states["/running"])
-        self.states["/running"].addChild(self.states["/running/root"])
-        self.states["/running"].addChild(self.states["/running/stopped"])
-        self.states["/running/root"].addChild(self.states["/running/root/main_behaviour"])
-        self.states["/running/root"].addChild(self.states["/running/root/cd_behaviour"])
-        self.states["/running/root/main_behaviour"].addChild(self.states["/running/root/main_behaviour/initializing"])
-        self.states["/running/root/main_behaviour"].addChild(self.states["/running/root/main_behaviour/running"])
-        self.states["/running/root/cd_behaviour"].addChild(self.states["/running/root/cd_behaviour/waiting"])
-        self.states["/running/root/cd_behaviour"].addChild(self.states["/running/root/cd_behaviour/creating"])
-        self.states["/running/root/cd_behaviour"].addChild(self.states["/running/root/cd_behaviour/check_nr_of_fields"])
-        self.states["/running/root/cd_behaviour"].addChild(self.states["/running/root/cd_behaviour/stopped"])
-        self.states[""].fixTree()
-        self.states[""].default_state = self.states["/running"]
-        self.states["/running"].default_state = self.states["/running/root"]
-        self.states["/running/root/main_behaviour"].default_state = self.states["/running/root/main_behaviour/initializing"]
-        self.states["/running/root/cd_behaviour"].default_state = self.states["/running/root/cd_behaviour/waiting"]
-        
-        # transition /running/root/main_behaviour/initializing
-        _running_root_main_behaviour_initializing_0 = Transition(self, self.states["/running/root/main_behaviour/initializing"], [self.states["/running/root/main_behaviour/running"]])
-        _running_root_main_behaviour_initializing_0.setAction(self._running_root_main_behaviour_initializing_0_exec)
-        _running_root_main_behaviour_initializing_0.setTrigger(None)
-        self.states["/running/root/main_behaviour/initializing"].addTransition(_running_root_main_behaviour_initializing_0)
-        
-        # transition /running/root/main_behaviour/running
-        _running_root_main_behaviour_running_0 = Transition(self, self.states["/running/root/main_behaviour/running"], [self.states["/running/root/main_behaviour/running"]])
-        _running_root_main_behaviour_running_0.setAction(self._running_root_main_behaviour_running_0_exec)
-        _running_root_main_behaviour_running_0.setTrigger(Event("button_pressed", None))
-        _running_root_main_behaviour_running_0.setGuard(self._running_root_main_behaviour_running_0_guard)
-        self.states["/running/root/main_behaviour/running"].addTransition(_running_root_main_behaviour_running_0)
-        
-        # transition /running/root/cd_behaviour/waiting
-        _running_root_cd_behaviour_waiting_0 = Transition(self, self.states["/running/root/cd_behaviour/waiting"], [self.states["/running/root/cd_behaviour/creating"]])
-        _running_root_cd_behaviour_waiting_0.setAction(self._running_root_cd_behaviour_waiting_0_exec)
-        _running_root_cd_behaviour_waiting_0.setTrigger(Event("create_field", None))
-        self.states["/running/root/cd_behaviour/waiting"].addTransition(_running_root_cd_behaviour_waiting_0)
-        _running_root_cd_behaviour_waiting_1 = Transition(self, self.states["/running/root/cd_behaviour/waiting"], [self.states["/running/root/cd_behaviour/check_nr_of_fields"]])
-        _running_root_cd_behaviour_waiting_1.setAction(self._running_root_cd_behaviour_waiting_1_exec)
-        _running_root_cd_behaviour_waiting_1.setTrigger(Event("delete_field", None))
-        self.states["/running/root/cd_behaviour/waiting"].addTransition(_running_root_cd_behaviour_waiting_1)
-        
-        # transition /running/root/cd_behaviour/creating
-        _running_root_cd_behaviour_creating_0 = Transition(self, self.states["/running/root/cd_behaviour/creating"], [self.states["/running/root/cd_behaviour/waiting"]])
-        _running_root_cd_behaviour_creating_0.setAction(self._running_root_cd_behaviour_creating_0_exec)
-        _running_root_cd_behaviour_creating_0.setTrigger(Event("instance_created", None))
-        self.states["/running/root/cd_behaviour/creating"].addTransition(_running_root_cd_behaviour_creating_0)
-        
-        # transition /running/root/cd_behaviour/check_nr_of_fields
-        _running_root_cd_behaviour_check_nr_of_fields_0 = Transition(self, self.states["/running/root/cd_behaviour/check_nr_of_fields"], [self.states["/running/root/cd_behaviour/stopped"]])
-        _running_root_cd_behaviour_check_nr_of_fields_0.setAction(self._running_root_cd_behaviour_check_nr_of_fields_0_exec)
-        _running_root_cd_behaviour_check_nr_of_fields_0.setTrigger(Event("_0after"))
-        _running_root_cd_behaviour_check_nr_of_fields_0.setGuard(self._running_root_cd_behaviour_check_nr_of_fields_0_guard)
-        self.states["/running/root/cd_behaviour/check_nr_of_fields"].addTransition(_running_root_cd_behaviour_check_nr_of_fields_0)
-        _running_root_cd_behaviour_check_nr_of_fields_1 = Transition(self, self.states["/running/root/cd_behaviour/check_nr_of_fields"], [self.states["/running/root/cd_behaviour/waiting"]])
-        _running_root_cd_behaviour_check_nr_of_fields_1.setTrigger(None)
-        _running_root_cd_behaviour_check_nr_of_fields_1.setGuard(self._running_root_cd_behaviour_check_nr_of_fields_1_guard)
-        self.states["/running/root/cd_behaviour/check_nr_of_fields"].addTransition(_running_root_cd_behaviour_check_nr_of_fields_1)
-        
-        # transition /running/root
-        _running_root_0 = Transition(self, self.states["/running/root"], [self.states["/running/stopped"]])
-        _running_root_0.setAction(self._running_root_0_exec)
-        _running_root_0.setTrigger(Event("stop", None))
-        self.states["/running/root"].addTransition(_running_root_0)
-    
-    def _running_root_cd_behaviour_check_nr_of_fields_enter(self):
-        self.addTimer(0, 0.05)
-    
-    def _running_root_cd_behaviour_check_nr_of_fields_exit(self):
-        self.removeTimer(0)
-    
-    def _running_root_0_exec(self, parameters):
-        self.big_step.outputEvent(Event("destroy_all", self.getOutPortName("ui"), []))
-    
-    def _running_root_main_behaviour_initializing_0_exec(self, parameters):
-        self.raiseInternalEvent(Event("create_field", None, []))
-    
-    def _running_root_main_behaviour_running_0_exec(self, parameters):
-        event_name = parameters[0]
-        self.raiseInternalEvent(Event("create_field", None, []))
-    
-    def _running_root_main_behaviour_running_0_guard(self, parameters):
-        event_name = parameters[0]
-        return event_name == "create_new_field"
-    
-    def _running_root_cd_behaviour_waiting_0_exec(self, parameters):
-        self.big_step.outputEventOM(Event("create_instance", None, [self, "fields"]))
-    
-    def _running_root_cd_behaviour_waiting_1_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEventOM(Event("delete_instance", None, [self, association_name]))
-        self.nr_of_fields -= 1
-    
-    def _running_root_cd_behaviour_creating_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("set_association_name", None, [association_name])]))
-        self.nr_of_fields += 1
-    
-    def _running_root_cd_behaviour_check_nr_of_fields_0_exec(self, parameters):
-        self.raiseInternalEvent(Event("stop", None, []))
-    
-    def _running_root_cd_behaviour_check_nr_of_fields_0_guard(self, parameters):
-        return self.nr_of_fields == 0
-    
-    def _running_root_cd_behaviour_check_nr_of_fields_1_guard(self, parameters):
-        return self.nr_of_fields != 0
-    
-    def initializeStatechart(self):
-        # enter default state
-        self.default_targets = self.states["/running"].getEffectiveTargetStates()
-        RuntimeClassBase.initializeStatechart(self)
-
-class MainApp(ClassBase):
-    def __init__(self, name):
-        ClassBase.__init__(self, name)
-        self.input = self.addInPort("input")
-        self.glob_outputs["ui"] = self.addOutPort("ui")
-        self.outputs["fields"] = self.addOutPort("fields")
-        new_instance = self.constructObject(0, 0, [])
-        self.state.instances[new_instance.instance_id] = new_instance
-        self.state.next_instance = self.state.next_instance + 1
-    
-    def constructObject(self, id, start_port_id, parameters):
-        new_instance = MainAppInstance(self, id, start_port_id)
-        return new_instance
-
-class FieldInstance(RuntimeClassBase):
-    def __init__(self, atomdevs, id, start_port_id):
-        RuntimeClassBase.__init__(self, atomdevs, id)
-        self.associations = {}
-        self.associations["balls"] = Association("Ball", 0, -1)
-        self.associations["buttons"] = Association("Button", 0, -1)
-        self.associations["parent"] = Association("MainApp", 1, 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()
-        
-        # user defined attributes
-        self.window_id = None
-        self.canvas_id = None
-        
-        # call user defined constructor
-        FieldInstance.user_defined_constructor(self)
-        port_name = addInputPort("ui", start_port_id, True)
-        atomdevs.state.port_mappings[port_name] = id
-        port_name = addInputPort("<narrow_cast>", start_port_id)
-        atomdevs.state.port_mappings[port_name] = id
-        port_name = addInputPort("field_ui", start_port_id)
-        atomdevs.state.port_mappings[port_name] = id
-        self.inports["field_ui"] = 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 /root
-        self.states["/root"] = State(1, "/root", self)
-        
-        # state /root/waiting
-        self.states["/root/waiting"] = State(2, "/root/waiting", self)
-        
-        # state /root/creating_window
-        self.states["/root/creating_window"] = State(3, "/root/creating_window", self)
-        self.states["/root/creating_window"].setEnter(self._root_creating_window_enter)
-        
-        # state /root/creating_canvas
-        self.states["/root/creating_canvas"] = State(4, "/root/creating_canvas", self)
-        self.states["/root/creating_canvas"].setEnter(self._root_creating_canvas_enter)
-        
-        # state /root/creating_button
-        self.states["/root/creating_button"] = State(5, "/root/creating_button", self)
-        self.states["/root/creating_button"].setEnter(self._root_creating_button_enter)
-        
-        # state /root/running
-        self.states["/root/running"] = ParallelState(6, "/root/running", self)
-        
-        # state /root/running/main_behaviour
-        self.states["/root/running/main_behaviour"] = State(7, "/root/running/main_behaviour", self)
-        
-        # state /root/running/main_behaviour/running
-        self.states["/root/running/main_behaviour/running"] = State(8, "/root/running/main_behaviour/running", self)
-        
-        # state /root/running/main_behaviour/creating_ball
-        self.states["/root/running/main_behaviour/creating_ball"] = State(9, "/root/running/main_behaviour/creating_ball", self)
-        
-        # state /root/running/deleting_behaviour
-        self.states["/root/running/deleting_behaviour"] = State(10, "/root/running/deleting_behaviour", self)
-        
-        # state /root/running/deleting_behaviour/running
-        self.states["/root/running/deleting_behaviour/running"] = State(11, "/root/running/deleting_behaviour/running", self)
-        
-        # state /root/running/child_behaviour
-        self.states["/root/running/child_behaviour"] = State(12, "/root/running/child_behaviour", self)
-        
-        # state /root/running/child_behaviour/listening
-        self.states["/root/running/child_behaviour/listening"] = State(13, "/root/running/child_behaviour/listening", self)
-        
-        # state /root/running/deleting_balls_behaviour
-        self.states["/root/running/deleting_balls_behaviour"] = State(14, "/root/running/deleting_balls_behaviour", self)
-        
-        # state /root/running/deleting_balls_behaviour/listening
-        self.states["/root/running/deleting_balls_behaviour/listening"] = State(15, "/root/running/deleting_balls_behaviour/listening", self)
-        
-        # state /root/deleting
-        self.states["/root/deleting"] = State(16, "/root/deleting", self)
-        
-        # state /root/deleted
-        self.states["/root/deleted"] = State(17, "/root/deleted", self)
-        
-        # add children
-        self.states[""].addChild(self.states["/root"])
-        self.states["/root"].addChild(self.states["/root/waiting"])
-        self.states["/root"].addChild(self.states["/root/creating_window"])
-        self.states["/root"].addChild(self.states["/root/creating_canvas"])
-        self.states["/root"].addChild(self.states["/root/creating_button"])
-        self.states["/root"].addChild(self.states["/root/running"])
-        self.states["/root"].addChild(self.states["/root/deleting"])
-        self.states["/root"].addChild(self.states["/root/deleted"])
-        self.states["/root/running"].addChild(self.states["/root/running/main_behaviour"])
-        self.states["/root/running"].addChild(self.states["/root/running/deleting_behaviour"])
-        self.states["/root/running"].addChild(self.states["/root/running/child_behaviour"])
-        self.states["/root/running"].addChild(self.states["/root/running/deleting_balls_behaviour"])
-        self.states["/root/running/main_behaviour"].addChild(self.states["/root/running/main_behaviour/running"])
-        self.states["/root/running/main_behaviour"].addChild(self.states["/root/running/main_behaviour/creating_ball"])
-        self.states["/root/running/deleting_behaviour"].addChild(self.states["/root/running/deleting_behaviour/running"])
-        self.states["/root/running/child_behaviour"].addChild(self.states["/root/running/child_behaviour/listening"])
-        self.states["/root/running/deleting_balls_behaviour"].addChild(self.states["/root/running/deleting_balls_behaviour/listening"])
-        self.states[""].fixTree()
-        self.states[""].default_state = self.states["/root"]
-        self.states["/root"].default_state = self.states["/root/waiting"]
-        self.states["/root/running/main_behaviour"].default_state = self.states["/root/running/main_behaviour/running"]
-        self.states["/root/running/deleting_behaviour"].default_state = self.states["/root/running/deleting_behaviour/running"]
-        self.states["/root/running/child_behaviour"].default_state = self.states["/root/running/child_behaviour/listening"]
-        self.states["/root/running/deleting_balls_behaviour"].default_state = self.states["/root/running/deleting_balls_behaviour/listening"]
-        
-        # transition /root/waiting
-        _root_waiting_0 = Transition(self, self.states["/root/waiting"], [self.states["/root/creating_window"]])
-        _root_waiting_0.setAction(self._root_waiting_0_exec)
-        _root_waiting_0.setTrigger(Event("set_association_name", None))
-        self.states["/root/waiting"].addTransition(_root_waiting_0)
-        
-        # transition /root/creating_window
-        _root_creating_window_0 = Transition(self, self.states["/root/creating_window"], [self.states["/root/creating_canvas"]])
-        _root_creating_window_0.setAction(self._root_creating_window_0_exec)
-        _root_creating_window_0.setTrigger(Event("window_created", None))
-        self.states["/root/creating_window"].addTransition(_root_creating_window_0)
-        
-        # transition /root/creating_canvas
-        _root_creating_canvas_0 = Transition(self, self.states["/root/creating_canvas"], [self.states["/root/creating_button"]])
-        _root_creating_canvas_0.setAction(self._root_creating_canvas_0_exec)
-        _root_creating_canvas_0.setTrigger(Event("canvas_created", None))
-        self.states["/root/creating_canvas"].addTransition(_root_creating_canvas_0)
-        
-        # transition /root/creating_button
-        _root_creating_button_0 = Transition(self, self.states["/root/creating_button"], [self.states["/root/running"]])
-        _root_creating_button_0.setAction(self._root_creating_button_0_exec)
-        _root_creating_button_0.setTrigger(Event("instance_created", None))
-        self.states["/root/creating_button"].addTransition(_root_creating_button_0)
-        
-        # transition /root/running/main_behaviour/running
-        _root_running_main_behaviour_running_0 = Transition(self, self.states["/root/running/main_behaviour/running"], [self.states["/root/running/main_behaviour/creating_ball"]])
-        _root_running_main_behaviour_running_0.setAction(self._root_running_main_behaviour_running_0_exec)
-        _root_running_main_behaviour_running_0.setTrigger(Event("right_click", self.getInPortName("field_ui")))
-        self.states["/root/running/main_behaviour/running"].addTransition(_root_running_main_behaviour_running_0)
-        
-        # transition /root/running/main_behaviour/creating_ball
-        _root_running_main_behaviour_creating_ball_0 = Transition(self, self.states["/root/running/main_behaviour/creating_ball"], [self.states["/root/running/main_behaviour/running"]])
-        _root_running_main_behaviour_creating_ball_0.setAction(self._root_running_main_behaviour_creating_ball_0_exec)
-        _root_running_main_behaviour_creating_ball_0.setTrigger(Event("instance_created", None))
-        self.states["/root/running/main_behaviour/creating_ball"].addTransition(_root_running_main_behaviour_creating_ball_0)
-        
-        # transition /root/running/deleting_behaviour/running
-        _root_running_deleting_behaviour_running_0 = Transition(self, self.states["/root/running/deleting_behaviour/running"], [self.states["/root/running/deleting_behaviour/running"]])
-        _root_running_deleting_behaviour_running_0.setAction(self._root_running_deleting_behaviour_running_0_exec)
-        _root_running_deleting_behaviour_running_0.setTrigger(Event("delete_ball", None))
-        self.states["/root/running/deleting_behaviour/running"].addTransition(_root_running_deleting_behaviour_running_0)
-        
-        # transition /root/running/child_behaviour/listening
-        _root_running_child_behaviour_listening_0 = Transition(self, self.states["/root/running/child_behaviour/listening"], [self.states["/root/running/child_behaviour/listening"]])
-        _root_running_child_behaviour_listening_0.setAction(self._root_running_child_behaviour_listening_0_exec)
-        _root_running_child_behaviour_listening_0.setTrigger(Event("button_pressed", None))
-        self.states["/root/running/child_behaviour/listening"].addTransition(_root_running_child_behaviour_listening_0)
-        
-        # transition /root/running/deleting_balls_behaviour/listening
-        _root_running_deleting_balls_behaviour_listening_0 = Transition(self, self.states["/root/running/deleting_balls_behaviour/listening"], [self.states["/root/running/deleting_balls_behaviour/listening"]])
-        _root_running_deleting_balls_behaviour_listening_0.setAction(self._root_running_deleting_balls_behaviour_listening_0_exec)
-        _root_running_deleting_balls_behaviour_listening_0.setTrigger(Event("key_press", self.getInPortName("field_ui")))
-        _root_running_deleting_balls_behaviour_listening_0.setGuard(self._root_running_deleting_balls_behaviour_listening_0_guard)
-        self.states["/root/running/deleting_balls_behaviour/listening"].addTransition(_root_running_deleting_balls_behaviour_listening_0)
-        
-        # transition /root/deleting
-        _root_deleting_0 = Transition(self, self.states["/root/deleting"], [self.states["/root/deleted"]])
-        _root_deleting_0.setAction(self._root_deleting_0_exec)
-        _root_deleting_0.setTrigger(None)
-        self.states["/root/deleting"].addTransition(_root_deleting_0)
-        
-        # transition /root/running
-        _root_running_0 = Transition(self, self.states["/root/running"], [self.states["/root/deleting"]])
-        _root_running_0.setAction(self._root_running_0_exec)
-        _root_running_0.setTrigger(Event("window_close", self.getInPortName("field_ui")))
-        self.states["/root/running"].addTransition(_root_running_0)
-    
-    def _root_creating_window_enter(self):
-        self.big_step.outputEvent(Event("create_window", self.getOutPortName("ui"), [800, 600, "BouncingBalls", self.inports['field_ui']]))
-    
-    def _root_creating_canvas_enter(self):
-        self.big_step.outputEvent(Event("create_canvas", self.getOutPortName("ui"), [self.window_id, CANVAS_DIMS[0], CANVAS_DIMS[1], {'background':'#eee'}, self.inports['field_ui']]))
-    
-    def _root_creating_button_enter(self):
-        self.big_step.outputEventOM(Event("create_instance", None, [self, "buttons", "Button", self.window_id, 'create_new_field', 'Spawn New Window']))
-    
-    def _root_running_0_exec(self, parameters):
-        self.big_step.outputEventOM(Event("delete_instance", None, [self, "buttons"]))
-        self.big_step.outputEventOM(Event("delete_instance", None, [self, "balls"]))
-    
-    def _root_waiting_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.association_name = association_name
-    
-    def _root_creating_window_0_exec(self, parameters):
-        window_id = parameters[0]
-        self.window_id = window_id
-        self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [window_id, ui.EVENTS.WINDOW_CLOSE, 'window_close', self.inports['field_ui']]))
-        self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [window_id, ui.EVENTS.KEY_PRESS, 'key_press', self.inports['field_ui']]))
-    
-    def _root_creating_canvas_0_exec(self, parameters):
-        canvas_id = parameters[0]
-        self.canvas_id = canvas_id
-        self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [canvas_id, ui.EVENTS.MOUSE_RIGHT_CLICK, 'right_click', self.inports['field_ui']]))
-        self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [canvas_id, ui.EVENTS.MOUSE_MOVE, 'mouse_move', self.inports['field_ui']]))
-        self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [canvas_id, ui.EVENTS.MOUSE_RELEASE, 'mouse_release', self.inports['field_ui']]))
-    
-    def _root_creating_button_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
-    
-    def _root_running_main_behaviour_running_0_exec(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        self.big_step.outputEventOM(Event("create_instance", None, [self, "balls", "Ball", self.canvas_id, x, y]))
-    
-    def _root_running_main_behaviour_creating_ball_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("set_association_name", None, [association_name])]))
-    
-    def _root_running_deleting_behaviour_running_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.big_step.outputEventOM(Event("delete_instance", None, [self, association_name]))
-    
-    def _root_running_child_behaviour_listening_0_exec(self, parameters):
-        event_name = parameters[0]
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("button_pressed", None, [event_name])]))
-    
-    def _root_running_deleting_balls_behaviour_listening_0_exec(self, parameters):
-        key = parameters[0]
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'balls', Event("delete_self", None, [])]))
-    
-    def _root_running_deleting_balls_behaviour_listening_0_guard(self, parameters):
-        key = parameters[0]
-        return key == ui.KEYCODES.DELETE
-    
-    def _root_deleting_0_exec(self, parameters):
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("delete_field", None, [self.association_name])]))
-        self.big_step.outputEvent(Event("destroy_window", self.getOutPortName("ui"), [self.window_id]))
-    
-    def initializeStatechart(self):
-        # enter default state
-        self.default_targets = self.states["/root"].getEffectiveTargetStates()
-        RuntimeClassBase.initializeStatechart(self)
-
-class Field(ClassBase):
-    def __init__(self, name):
-        ClassBase.__init__(self, name)
-        self.input = self.addInPort("input")
-        self.glob_outputs["ui"] = self.addOutPort("ui")
-        self.outputs["balls"] = self.addOutPort("balls")
-        self.outputs["buttons"] = self.addOutPort("buttons")
-        self.outputs["parent"] = self.addOutPort("parent")
-        self.field_ui = self.addInPort("field_ui")
-    
-    def constructObject(self, id, start_port_id, parameters):
-        new_instance = FieldInstance(self, id, start_port_id)
-        return new_instance
-
-class ButtonInstance(RuntimeClassBase):
-    def __init__(self, atomdevs, id, start_port_id, window_id, event_name, button_text):
-        RuntimeClassBase.__init__(self, atomdevs, id)
-        self.associations = {}
-        self.associations["parent"] = Association("Field", 1, 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()
-        
-        # user defined attributes
-        self.window_id = None
-        self.event_name = None
-        self.button_id = None
-        
-        # call user defined constructor
-        ButtonInstance.user_defined_constructor(self, window_id, event_name, button_text)
-        port_name = addInputPort("ui", start_port_id, True)
-        atomdevs.state.port_mappings[port_name] = id
-        port_name = addInputPort("<narrow_cast>", start_port_id)
-        atomdevs.state.port_mappings[port_name] = id
-        port_name = addInputPort("button_ui", start_port_id)
-        atomdevs.state.port_mappings[port_name] = id
-        self.inports["button_ui"] = port_name
-    
-    def user_defined_constructor(self, window_id, event_name, button_text):
-        self.window_id = window_id;
-        self.event_name = event_name;
-    
-    def user_defined_destructor(self):
-        pass
-    
-    
-    # builds Statechart structure
-    def build_statechart_structure(self):
-        
-        # state <root>
-        self.states[""] = State(0, "", self)
-        
-        # state /creating_button
-        self.states["/creating_button"] = State(1, "/creating_button", self)
-        self.states["/creating_button"].setEnter(self._creating_button_enter)
-        
-        # state /running
-        self.states["/running"] = State(2, "/running", self)
-        
-        # add children
-        self.states[""].addChild(self.states["/creating_button"])
-        self.states[""].addChild(self.states["/running"])
-        self.states[""].fixTree()
-        self.states[""].default_state = self.states["/creating_button"]
-        
-        # transition /creating_button
-        _creating_button_0 = Transition(self, self.states["/creating_button"], [self.states["/running"]])
-        _creating_button_0.setAction(self._creating_button_0_exec)
-        _creating_button_0.setTrigger(Event("button_created", None))
-        self.states["/creating_button"].addTransition(_creating_button_0)
-        
-        # transition /running
-        _running_0 = Transition(self, self.states["/running"], [self.states["/running"]])
-        _running_0.setAction(self._running_0_exec)
-        _running_0.setTrigger(Event("mouse_click", self.getInPortName("button_ui")))
-        _running_0.setGuard(self._running_0_guard)
-        self.states["/running"].addTransition(_running_0)
-    
-    def _creating_button_enter(self):
-        self.big_step.outputEvent(Event("create_button", self.getOutPortName("ui"), [self.window_id, self.event_name, self.inports['button_ui']]))
-    
-    def _creating_button_0_exec(self, parameters):
-        button_id = parameters[0]
-        self.button_id = button_id
-        self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [button_id, ui.EVENTS.MOUSE_CLICK, "mouse_click", self.inports['button_ui']]))
-    
-    def _running_0_exec(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("button_pressed", None, [self.event_name])]))
-    
-    def _running_0_guard(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        return button == ui.MOUSE_BUTTONS.LEFT
-    
-    def initializeStatechart(self):
-        # enter default state
-        self.default_targets = self.states["/creating_button"].getEffectiveTargetStates()
-        RuntimeClassBase.initializeStatechart(self)
-
-class Button(ClassBase):
-    def __init__(self, name):
-        ClassBase.__init__(self, name)
-        self.input = self.addInPort("input")
-        self.glob_outputs["ui"] = self.addOutPort("ui")
-        self.outputs["parent"] = self.addOutPort("parent")
-        self.button_ui = self.addInPort("button_ui")
-    
-    def constructObject(self, id, start_port_id, parameters):
-        new_instance = ButtonInstance(self, id, start_port_id, parameters[1], parameters[2], parameters[3])
-        return new_instance
-
-class BallInstance(RuntimeClassBase):
-    def __init__(self, atomdevs, id, start_port_id, canvas_id, x, y):
-        RuntimeClassBase.__init__(self, atomdevs, id)
-        self.associations = {}
-        self.associations["parent"] = Association("Field", 1, 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()
-        
-        # user defined attributes
-        self.canvas_id = None
-        self.pos = None
-        
-        # call user defined constructor
-        BallInstance.user_defined_constructor(self, canvas_id, x, y)
-        port_name = addInputPort("ui", start_port_id, True)
-        atomdevs.state.port_mappings[port_name] = id
-        port_name = addInputPort("<narrow_cast>", start_port_id)
-        atomdevs.state.port_mappings[port_name] = id
-        port_name = addInputPort("ball_ui", start_port_id)
-        atomdevs.state.port_mappings[port_name] = id
-        self.inports["ball_ui"] = port_name
-    
-    def user_defined_constructor(self, canvas_id, x, y):
-        self.canvas_id = canvas_id;
-        self.r = 20.0;
-        self.vel = {'x': random.uniform(-5.0, 5.0), 'y': random.uniform(-5.0, 5.0)};
-        self.pos = {'x': x, 'y': y};
-        self.smooth = 0.6; # value between 0 and 1
-    
-    def user_defined_destructor(self):
-        pass
-    
-    
-    # builds Statechart structure
-    def build_statechart_structure(self):
-        
-        # state <root>
-        self.states[""] = State(0, "", self)
-        
-        # state /main_behaviour
-        self.states["/main_behaviour"] = State(1, "/main_behaviour", self)
-        
-        # state /main_behaviour/initializing
-        self.states["/main_behaviour/initializing"] = State(2, "/main_behaviour/initializing", self)
-        
-        # state /main_behaviour/creating_circle
-        self.states["/main_behaviour/creating_circle"] = State(3, "/main_behaviour/creating_circle", self)
-        self.states["/main_behaviour/creating_circle"].setEnter(self._main_behaviour_creating_circle_enter)
-        
-        # state /main_behaviour/bouncing
-        self.states["/main_behaviour/bouncing"] = State(4, "/main_behaviour/bouncing", self)
-        self.states["/main_behaviour/bouncing"].setEnter(self._main_behaviour_bouncing_enter)
-        self.states["/main_behaviour/bouncing"].setExit(self._main_behaviour_bouncing_exit)
-        
-        # state /main_behaviour/dragging
-        self.states["/main_behaviour/dragging"] = State(5, "/main_behaviour/dragging", self)
-        
-        # state /main_behaviour/selected
-        self.states["/main_behaviour/selected"] = State(6, "/main_behaviour/selected", self)
-        
-        # state /deleted
-        self.states["/deleted"] = State(7, "/deleted", self)
-        
-        # add children
-        self.states[""].addChild(self.states["/main_behaviour"])
-        self.states[""].addChild(self.states["/deleted"])
-        self.states["/main_behaviour"].addChild(self.states["/main_behaviour/initializing"])
-        self.states["/main_behaviour"].addChild(self.states["/main_behaviour/creating_circle"])
-        self.states["/main_behaviour"].addChild(self.states["/main_behaviour/bouncing"])
-        self.states["/main_behaviour"].addChild(self.states["/main_behaviour/dragging"])
-        self.states["/main_behaviour"].addChild(self.states["/main_behaviour/selected"])
-        self.states[""].fixTree()
-        self.states[""].default_state = self.states["/main_behaviour"]
-        self.states["/main_behaviour"].default_state = self.states["/main_behaviour/initializing"]
-        
-        # transition /main_behaviour/initializing
-        _main_behaviour_initializing_0 = Transition(self, self.states["/main_behaviour/initializing"], [self.states["/main_behaviour/creating_circle"]])
-        _main_behaviour_initializing_0.setAction(self._main_behaviour_initializing_0_exec)
-        _main_behaviour_initializing_0.setTrigger(Event("set_association_name", None))
-        self.states["/main_behaviour/initializing"].addTransition(_main_behaviour_initializing_0)
-        
-        # transition /main_behaviour/creating_circle
-        _main_behaviour_creating_circle_0 = Transition(self, self.states["/main_behaviour/creating_circle"], [self.states["/main_behaviour/bouncing"]])
-        _main_behaviour_creating_circle_0.setAction(self._main_behaviour_creating_circle_0_exec)
-        _main_behaviour_creating_circle_0.setTrigger(Event("circle_created", None))
-        self.states["/main_behaviour/creating_circle"].addTransition(_main_behaviour_creating_circle_0)
-        
-        # transition /main_behaviour/bouncing
-        _main_behaviour_bouncing_0 = Transition(self, self.states["/main_behaviour/bouncing"], [self.states["/main_behaviour/bouncing"]])
-        _main_behaviour_bouncing_0.setAction(self._main_behaviour_bouncing_0_exec)
-        _main_behaviour_bouncing_0.setTrigger(Event("_0after"))
-        self.states["/main_behaviour/bouncing"].addTransition(_main_behaviour_bouncing_0)
-        _main_behaviour_bouncing_1 = Transition(self, self.states["/main_behaviour/bouncing"], [self.states["/main_behaviour/selected"]])
-        _main_behaviour_bouncing_1.setAction(self._main_behaviour_bouncing_1_exec)
-        _main_behaviour_bouncing_1.setTrigger(Event("mouse_press", self.getInPortName("ball_ui")))
-        _main_behaviour_bouncing_1.setGuard(self._main_behaviour_bouncing_1_guard)
-        self.states["/main_behaviour/bouncing"].addTransition(_main_behaviour_bouncing_1)
-        
-        # transition /main_behaviour/dragging
-        _main_behaviour_dragging_0 = Transition(self, self.states["/main_behaviour/dragging"], [self.states["/main_behaviour/dragging"]])
-        _main_behaviour_dragging_0.setAction(self._main_behaviour_dragging_0_exec)
-        _main_behaviour_dragging_0.setTrigger(Event("mouse_move", self.getInPortName("ball_ui")))
-        self.states["/main_behaviour/dragging"].addTransition(_main_behaviour_dragging_0)
-        _main_behaviour_dragging_1 = Transition(self, self.states["/main_behaviour/dragging"], [self.states["/main_behaviour/bouncing"]])
-        _main_behaviour_dragging_1.setAction(self._main_behaviour_dragging_1_exec)
-        _main_behaviour_dragging_1.setTrigger(Event("mouse_release", self.getInPortName("ball_ui")))
-        self.states["/main_behaviour/dragging"].addTransition(_main_behaviour_dragging_1)
-        
-        # transition /main_behaviour/selected
-        _main_behaviour_selected_0 = Transition(self, self.states["/main_behaviour/selected"], [self.states["/main_behaviour/dragging"]])
-        _main_behaviour_selected_0.setAction(self._main_behaviour_selected_0_exec)
-        _main_behaviour_selected_0.setTrigger(Event("mouse_press", self.getInPortName("ball_ui")))
-        _main_behaviour_selected_0.setGuard(self._main_behaviour_selected_0_guard)
-        self.states["/main_behaviour/selected"].addTransition(_main_behaviour_selected_0)
-        _main_behaviour_selected_1 = Transition(self, self.states["/main_behaviour/selected"], [self.states["/deleted"]])
-        _main_behaviour_selected_1.setAction(self._main_behaviour_selected_1_exec)
-        _main_behaviour_selected_1.setTrigger(Event("delete_self", None))
-        self.states["/main_behaviour/selected"].addTransition(_main_behaviour_selected_1)
-    
-    def _main_behaviour_creating_circle_enter(self):
-        self.big_step.outputEvent(Event("create_circle", self.getOutPortName("ui"), [self.canvas_id, self.pos['x'], self.pos['y'], self.r, {'fill':'#000'}, self.inports['ball_ui']]))
-    
-    def _main_behaviour_bouncing_enter(self):
-        self.addTimer(0, 0.02)
-    
-    def _main_behaviour_bouncing_exit(self):
-        self.removeTimer(0)
-    
-    def _main_behaviour_initializing_0_exec(self, parameters):
-        association_name = parameters[0]
-        self.association_name = association_name
-    
-    def _main_behaviour_creating_circle_0_exec(self, parameters):
-        canvas_id = parameters[0]
-        circle_id = parameters[1]
-        self.circle_id = circle_id
-        self.big_step.outputEvent(Event("bind_canvas_event", self.getOutPortName("ui"), [self.canvas_id, circle_id, ui.EVENTS.MOUSE_PRESS, 'mouse_press', self.inports['ball_ui']]))
-        self.big_step.outputEvent(Event("bind_canvas_event", self.getOutPortName("ui"), [self.canvas_id, circle_id, ui.EVENTS.MOUSE_MOVE, 'mouse_move', self.inports['ball_ui']]))
-        self.big_step.outputEvent(Event("bind_canvas_event", self.getOutPortName("ui"), [self.canvas_id, circle_id, ui.EVENTS.MOUSE_RELEASE, 'mouse_release', self.inports['ball_ui']]))
-    
-    def _main_behaviour_bouncing_0_exec(self, parameters):
-        # Invert velocity when colliding with canvas border:
-        if self.pos['x']-self.r <= 0 or self.pos['x']+self.r >= CANVAS_DIMS[0]:
-            self.vel['x'] = -self.vel['x'];
-        if self.pos['y']-self.r <= 0 or self.pos['y']+self.r >= CANVAS_DIMS[1]:
-            self.vel['y'] = -self.vel['y'];
-        self.big_step.outputEvent(Event("move_element", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, self.vel['x'], self.vel['y']]))
-        self.pos['x'] += self.vel['x']
-        self.pos['y'] += self.vel['y']
-    
-    def _main_behaviour_bouncing_1_exec(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, '#ff0']))
-    
-    def _main_behaviour_bouncing_1_guard(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        return button == ui.MOUSE_BUTTONS.LEFT
-    
-    def _main_behaviour_dragging_0_exec(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        # Always keep ball within canvas:
-        x = min(max(0+self.r, x), CANVAS_DIMS[0]-self.r)
-        y = min(max(0+self.r, y), CANVAS_DIMS[1]-self.r)
-        
-        dx = x - self.pos['x']
-        dy = y - self.pos['y']
-        
-        self.vel = {
-            'x': (1-self.smooth)*dx + self.smooth*self.vel['x'],
-            'y': (1-self.smooth)*dy + self.smooth*self.vel['y']
-        }
-        
-        self.pos = {'x': x, 'y': y}
-        self.big_step.outputEvent(Event("set_element_pos", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, x-self.r, y-self.r]))
-    
-    def _main_behaviour_dragging_1_exec(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, '#f00']))
-    
-    def _main_behaviour_selected_0_exec(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        self.mouse_pos = {'x':x, 'y':y};
-    
-    def _main_behaviour_selected_0_guard(self, parameters):
-        x = parameters[0]
-        y = parameters[1]
-        button = parameters[2]
-        return button == ui.MOUSE_BUTTONS.LEFT
-    
-    def _main_behaviour_selected_1_exec(self, parameters):
-        self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("delete_ball", None, [self.association_name])]))
-        self.big_step.outputEvent(Event("destroy_element", self.getOutPortName("ui"), [self.canvas_id, self.element_id]))
-    
-    def initializeStatechart(self):
-        # enter default state
-        self.default_targets = self.states["/main_behaviour"].getEffectiveTargetStates()
-        RuntimeClassBase.initializeStatechart(self)
-
-class Ball(ClassBase):
-    def __init__(self, name):
-        ClassBase.__init__(self, name)
-        self.input = self.addInPort("input")
-        self.glob_outputs["ui"] = self.addOutPort("ui")
-        self.outputs["parent"] = self.addOutPort("parent")
-        self.ball_ui = self.addInPort("ball_ui")
-    
-    def constructObject(self, id, start_port_id, parameters):
-        new_instance = BallInstance(self, id, start_port_id, parameters[1], parameters[2], parameters[3])
-        return new_instance
-
-#class Dummy(ObjectManagerState):
-    #def __init__(self):
-        #ObjectManagerState.__init__(self)
-    
-def instantiate(self, class_name, construct_params):
-    instance = {}
-    instance["name"] = class_name
-    if class_name == "MainApp":
-        self.narrow_cast_id = self.narrow_cast_id + 0
-        instance["associations"] = {}
-        instance["associations"]["fields"] = Association("Field", 0, -1)
-    elif class_name == "Field":
-        self.narrow_cast_id = self.narrow_cast_id + 1
-        instance["associations"] = {}
-        instance["associations"]["balls"] = Association("Ball", 0, -1)
-        instance["associations"]["buttons"] = Association("Button", 0, -1)
-        instance["associations"]["parent"] = Association("MainApp", 1, 1)
-    elif class_name == "Button":
-        self.narrow_cast_id = self.narrow_cast_id + 1
-        instance["associations"] = {}
-        instance["associations"]["parent"] = Association("Field", 1, 1)
-    elif class_name == "Ball":
-        self.narrow_cast_id = self.narrow_cast_id + 1
-        instance["associations"] = {}
-        instance["associations"]["parent"] = Association("Field", 1, 1)
-    else:
-        raise Exception("Cannot instantiate class " + class_name)
-    return instance
-
-ObjectManagerState.instantiate = instantiate
-
-class ObjectManager(ObjectManagerBase):
-    def __init__(self, name):
-        ObjectManagerBase.__init__(self, name)
-        # TODO: changed
-        self.state = ObjectManagerState()
-        self.input = self.addInPort("input")
-        self.output["MainApp"] = self.addOutPort()
-        self.output["Field"] = self.addOutPort()
-        self.output["Button"] = self.addOutPort()
-        self.output["Ball"] = self.addOutPort()
-        self.state.createInstance("MainApp", [])
-        self.state.to_send.append((("MainApp", 0), ("MainApp", 0), Event("start_instance", None, ["MainApp[0]"])))
-
-class Controller(CoupledDEVS):
-    def __init__(self, name):
-        CoupledDEVS.__init__(self, name)
-        self.in_ui = self.addInPort("ui")
-        self.out_ui = self.addOutPort("ui")
-        self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
-        self.atomics = []
-        self.atomics.append(self.addSubModel(MainApp("MainApp")))
-        self.atomics.append(self.addSubModel(Field("Field")))
-        self.atomics.append(self.addSubModel(Button("Button")))
-        self.atomics.append(self.addSubModel(Ball("Ball")))
-        self.connectPorts(self.atomics[0].obj_manager_out, self.objectmanager.input)
-        self.connectPorts(self.objectmanager.output["MainApp"], self.atomics[0].obj_manager_in)
-        self.connectPorts(self.atomics[0].outputs["fields"], self.atomics[1].input)
-        self.connectPorts(self.atomics[1].obj_manager_out, self.objectmanager.input)
-        self.connectPorts(self.objectmanager.output["Field"], self.atomics[1].obj_manager_in)
-        self.connectPorts(self.atomics[1].outputs["balls"], self.atomics[3].input)
-        self.connectPorts(self.atomics[1].outputs["buttons"], self.atomics[2].input)
-        self.connectPorts(self.atomics[1].outputs["parent"], self.atomics[0].input)
-        self.connectPorts(self.atomics[2].obj_manager_out, self.objectmanager.input)
-        self.connectPorts(self.objectmanager.output["Button"], self.atomics[2].obj_manager_in)
-        self.connectPorts(self.atomics[2].outputs["parent"], self.atomics[1].input)
-        self.connectPorts(self.atomics[3].obj_manager_out, self.objectmanager.input)
-        self.connectPorts(self.objectmanager.output["Ball"], self.atomics[3].obj_manager_in)
-        self.connectPorts(self.atomics[3].outputs["parent"], self.atomics[1].input)
-        self.connectPorts(self.atomics[0].glob_outputs["ui"], self.out_ui)
-        self.connectPorts(self.in_ui, self.atomics[0].input)
-        self.connectPorts(self.atomics[1].glob_outputs["ui"], self.out_ui)
-        self.connectPorts(self.in_ui, self.atomics[1].input)
-        self.connectPorts(self.atomics[2].glob_outputs["ui"], self.out_ui)
-        self.connectPorts(self.in_ui, self.atomics[2].input)
-        self.connectPorts(self.atomics[3].glob_outputs["ui"], self.out_ui)
-        self.connectPorts(self.in_ui, self.atomics[3].input)

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 8592
examples/BouncingBalls/PyDEVS/trace.txt


+ 0 - 12
examples/BouncingBalls/Python/output.txt

@@ -1,12 +0,0 @@
-0.006 (event name: create_window; port: ui; parameters: [800, 600, 'BouncingBalls', 'private_2_field_ui'])
-0.027 (event name: bind_event; port: ui; parameters: [0, 'WM_DELETE_WINDOW', 'window_close', 'private_2_field_ui'])
-0.027 (event name: bind_event; port: ui; parameters: [0, '<Key>', 'key_press', 'private_2_field_ui'])
-0.027 (event name: create_canvas; port: ui; parameters: [0, 800, 550, {'background': '#eee'}, 'private_2_field_ui'])
-0.059 (event name: bind_event; port: ui; parameters: [1, '<Button-2>', 'right_click', 'private_2_field_ui'])
-0.059 (event name: bind_event; port: ui; parameters: [1, '<Motion>', 'mouse_move', 'private_2_field_ui'])
-0.059 (event name: bind_event; port: ui; parameters: [1, '<ButtonRelease>', 'mouse_release', 'private_2_field_ui'])
-0.059 (event name: create_button; port: ui; parameters: [0, 'create_new_field', 'private_4_button_ui'])
-0.064 (event name: bind_event; port: ui; parameters: [2, '<Button>', 'mouse_click', 'private_4_button_ui'])
-1.932 (event name: destroy_window; port: ui; parameters: [0])
-1.984 (event name: destroy_all; port: ui)
-0.011 (event name: create_window; port: ui; parameters: [800, 600, 'BouncingBalls', 'private_2_field_ui'])

+ 5 - 0
examples/BouncingBalls/Python/runner.py

@@ -8,6 +8,8 @@ import target as target
 from sccd.runtime.libs.ui_v2 import UI
 from sccd.runtime.tkinter_eventloop import TkEventLoop
 
+from sccd.runtime.statecharts_core import Event
+
 class OutputListener:
 	def __init__(self, ui):
 		self.ui = ui
@@ -26,5 +28,8 @@ if __name__ == '__main__':
 
 	controller.setVerbose("./examples/BouncingBalls/Python/trace.txt")
 
+	actual_event = Event("hello", "ui")
+	controller.addInput(actual_event, 500)
+
 	controller.start()
 	tkroot.mainloop()

+ 1 - 3
examples/BouncingBalls/Python/target.py

@@ -557,9 +557,7 @@ class Ball(RuntimeClassBase):
     def user_defined_constructor(self, canvas_id, x, y):
         self.canvas_id = canvas_id;
         self.r = 20.0;
-        
-        self.vel = {'x': 1, 'y': 1};
-        #self.vel = {'x': random.uniform(-5.0, 5.0), 'y': random.uniform(-5.0, 5.0)};
+        self.vel = {'x': random.uniform(-5.0, 5.0), 'y': random.uniform(-5.0, 5.0)};
         self.pos = {'x': x, 'y': y};
         self.smooth = 0.6; # value between 0 and 1
     

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 0 - 33275
examples/BouncingBalls/Python/trace.txt


+ 0 - 4
examples/BouncingBalls/input_trace.txt

@@ -1,4 +0,0 @@
-0.031 field_ui Event("window_created","private_2_field_ui",[0])
-0.064 field_ui Event("canvas_created","private_2_field_ui",[1])
-0.072 button_ui Event("button_created","private_4_button_ui",[2])
-2.202 field_ui Event("window_close","private_2_field_ui",None)

+ 1 - 3
examples/BouncingBalls/sccd.xml

@@ -330,9 +330,7 @@
             <body>
                 self.canvas_id = canvas_id;
                 self.r = 20.0;
-
-                self.vel = {'x': 1, 'y': 1};
-                #self.vel = {'x': random.uniform(-5.0, 5.0), 'y': random.uniform(-5.0, 5.0)};
+                self.vel = {'x': random.uniform(-5.0, 5.0), 'y': random.uniform(-5.0, 5.0)};
                 self.pos = {'x': x, 'y': y};
                 self.smooth = 0.6; # value between 0 and 1
             </body>

+ 26 - 0
examples/Fail1/Python/runner.py

@@ -0,0 +1,26 @@
+import target as target
+from sccd.runtime.statecharts_core import Event
+import threading
+
+if __name__ == '__main__':
+    controller = target.Controller() 
+    
+    def raw_inputter():
+        while 1:
+            controller.addInput(Event(input(), "input", []))
+    input_thread = threading.Thread(target=raw_inputter)
+    input_thread.daemon = True
+    input_thread.start()
+    
+    output_listener = controller.addOutputListener(["output"])
+    def outputter():
+        while 1:
+            event = output_listener.fetch(-1)
+            print("SIMTIME: %.2fs" % (event.getParameters()[0] / 1000.0))
+            print("ACTTIME: %.2fs" % (event.getParameters()[1]))
+
+    output_thread = threading.Thread(target=outputter)
+    output_thread.daemon = True
+    output_thread.start()
+    
+    controller.start()

tests/1.7) CompositeStateTest/config.json → examples/Fail1/config.json


tests/1.7) CompositeStateTest/expected_trace.txt → examples/Fail1/expected_trace.txt


+ 23 - 0
examples/Fail1/sccd.xml

@@ -0,0 +1,23 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="CompositeNoInitialStateTest">
+    <description>
+        Test 1.8: Test if composite states are handled correctly.
+        When no initial in composite defined, go into the first state that is defined.
+    </description>
+    <class name="MainApp" default="true">
+        <scxml initial="state1">
+            <state id="state1"> 
+                <state id="state10">
+                    <transition target="../state12" />
+                </state>
+                <state id="state11">
+                    <transition target="." />
+                </state>
+                <state id="state12">
+                    <transition target="../../state2" />
+                </state>
+            </state>
+            <state id="state2" />
+        </scxml>
+    </class>
+</diagram>

+ 2 - 4
examples/TrafficLightHistory/Python/target.py

@@ -4,14 +4,12 @@ Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van M
 Model author: Sam Pieters
 Model name:   TrafficLight
 Model description:
-Tkinter frame with Traffic light in a single statechart.
+Tkinter frame with Traffic light in a single statechart (with history).
 """
 
 from sccd.runtime.statecharts_core import *
 from sccd.runtime.libs import ui_v2 as ui
 CANVAS_DIMS = (100, 350)
-CANVAS_WIDTH = 100
-CANVAS_HEIGHT = 350
 
 # package "TrafficLight"
 
@@ -245,7 +243,7 @@ class MainApp(RuntimeClassBase):
         self.states["/on/interrupted"].addTransition(_on_interrupted_0)
     
     def _creating_window_enter(self):
-        self.big_step.outputEvent(Event("create_window", self.getOutPortName("ui"), [CANVAS_DIMS[0], CANVAS_DIMS[1], "Fixed Traffic Light", self.inports['field_ui']]))
+        self.big_step.outputEvent(Event("create_window", self.getOutPortName("ui"), [CANVAS_DIMS[0], CANVAS_DIMS[1], "Traffic Light", self.inports['field_ui']]))
     
     def _creating_canvas_enter(self):
         self.big_step.outputEvent(Event("create_canvas", self.getOutPortName("ui"), [self.window_id, CANVAS_DIMS[0], CANVAS_DIMS[1] - 100, {'background':'#222222'}, self.inports['field_ui']]))

+ 15 - 16
sccd/compiler/DEVS_generator.py

@@ -2,7 +2,7 @@
 #
 # Visits SCCD-domain constructs (see sccd_constructs.py) and converts them
 # to a DEVS language AST (see generic_language_constructs.py), that can
-# then be visited by a target language writer (only supports python).
+# then be visited by a target language writer (only supports Python).
 
 from sccd.compiler.utils import Enum, Logger
 from sccd.compiler.visitor import Visitor
@@ -62,14 +62,14 @@ class DEVSGenerator(Visitor):
         self.writer.beginMethodBody()
 
         self.writer.addAssignment("instance", "{}")
-        self.writer.addAssignment("instance[\"name\"]", "class_name")
-        for index,c in enumerate(class_diagram.classes):
+        self.writer.addAssignment(GLC.ArrayIndexedExpression("instance", GLC.String("name")), "class_name")
+        for c in class_diagram.classes:
             self.writer.beginElseIf(GLC.EqualsExpression("class_name", GLC.String(c.name)))
             if c.isAbstract():
                 # cannot instantiate abstract class
                 self.writer.add(GLC.ThrowExceptionStatement(GLC.String("Cannot instantiate abstract class \"" + c.name + "\" with unimplemented methods \"" + "\", \"".join(c.abstract_method_names) + "\".")))
             else:
-                self.writer.addAssignment("self.narrow_cast_id", f"self.narrow_cast_id + {len(c.inports)}")
+                self.writer.addAssignment(GLC.SelfProperty("narrow_cast_id"), GLC.SelfProperty(f"narrow_cast_id + {len(c.inports)}"))
                 self.writer.addAssignment(
                     "instance[\"associations\"]", GLC.MapExpression())
                 for a in c.associations:
@@ -111,7 +111,7 @@ class DEVSGenerator(Visitor):
             self.writer.addAssignment(GLC.SelfProperty(f"output[\"{class_name}\"]"),
                                       GLC.FunctionCall(GLC.SelfProperty("addOutPort")))
 
-        self.writer.add(GLC.FunctionCall("self.state.createInstance", [GLC.String(class_diagram.default_class.name), "[]"]))
+        self.writer.add(GLC.FunctionCall(GLC.SelfProperty("state.createInstance"), [GLC.String(class_diagram.default_class.name), GLC.ArrayExpression()]))
         self.writer.endMethodBody()
         self.writer.endConstructor()
         self.writer.endClass()
@@ -143,13 +143,12 @@ class DEVSGenerator(Visitor):
                                                                                                GLC.String(
                                                                                                    "ObjectManager")]))])))
         
-        self.writer.addAssignment(GLC.SelfProperty("atomics"), "[]")
+        self.writer.addAssignment(GLC.SelfProperty("atomics"), GLC.ArrayExpression())
         for (i, class_name) in enumerate(class_diagram.class_names):
-            self.writer.add(GLC.FunctionCall("self.atomics.append", GLC.ActualParameters([(GLC.FunctionCall(GLC.SelfProperty("addSubModel"), [GLC.FunctionCall(class_name,
-                                                                                                           GLC.ActualParameters(
-                                                                                                               [
-                                                                                                                   GLC.String(
-                                                                                                                       class_name)]))]))])))
+            self.writer.add(GLC.ArrayPushBack(
+                GLC.SelfProperty("atomics"), 
+                GLC.FunctionCall(GLC.SelfProperty("addSubModel"), 
+                                [GLC.FunctionCall(class_name, GLC.ActualParameters([GLC.String(class_name)]))])))
 
         # Add links between the models
         for (i, the_class) in enumerate(class_diagram.classes):
@@ -272,10 +271,10 @@ class DEVSGenerator(Visitor):
                 GLC.FunctionCall(GLC.Property("controller", "addOutputPort"), [GLC.String(p), GLC.SelfExpression()]))
 
         if class_node.name == class_node.class_diagram.default_class.name:
-            self.writer.addAssignment("new_instance", "self.constructObject(0, 0, [])")
-            self.writer.addAssignment("self.state.instances[new_instance.instance_id]", "new_instance")
+            self.writer.addAssignment("new_instance", GLC.SelfProperty("constructObject(0, 0, [])"))
+            self.writer.addAssignment(GLC.SelfProperty("state.instances[new_instance.instance_id]"), "new_instance")
             self.writer.add(GLC.FunctionCall("new_instance.start"))
-            self.writer.addAssignment("self.state.next_time", "0")
+            self.writer.addAssignment(GLC.SelfProperty("state.next_time"), "0")
 
         self.writer.endMethodBody()
         self.writer.endConstructor()
@@ -369,7 +368,7 @@ class DEVSGenerator(Visitor):
 
         for inp in constructor.parent_class.class_diagram.inports:
             self.writer.addAssignment("port_name", GLC.FunctionCall("addInputPort", [GLC.String(inp), "start_port_id", "True"]))
-            self.writer.addAssignment("atomdevs.state.port_mappings[port_name]", "id")
+            self.writer.addAssignment("atomdevs.state.port_mappings[port_name]", "None")
 
         self.writer.addAssignment("port_name", GLC.FunctionCall("addInputPort", [GLC.String("<narrow_cast>"), "start_port_id"]))
         self.writer.addAssignment("atomdevs.state.port_mappings[port_name]", "id")
@@ -377,7 +376,7 @@ class DEVSGenerator(Visitor):
         for index, inp in enumerate(constructor.parent_class.inports):
             self.writer.addAssignment("port_name", GLC.FunctionCall("addInputPort", [GLC.String(inp), f"start_port_id + {index + 1}"]))
             self.writer.addAssignment("atomdevs.state.port_mappings[port_name]", "id")
-            self.writer.addAssignment(f"self.inports[\"{inp}\"]", "port_name")
+            self.writer.addAssignment(GLC.SelfProperty(f"inports[\"{inp}\"]"), "port_name")
 
         self.writer.endMethodBody()
         self.writer.endConstructor()

+ 0 - 1
sccd/compiler/sccdc.py

@@ -56,7 +56,6 @@ def sccdToGeneric(sccd, platform):
 	return generic
 
 def sccdToDEVS(sccd, platform):
-	succesfull_generation = False
 	generator = DEVSGenerator(platform)
 	sccd.accept(generator)
 	generic = generator.get()

+ 12 - 8
sccd/runtime/DEVS_statecharts_core.py

@@ -8,17 +8,11 @@ from sccd.runtime.statecharts_core import StatechartSemantics, BigStepState, Com
 from sccd.runtime.statecharts_core import State, HistoryState, ShallowHistoryState, DeepHistoryState, ParallelState
 from sccd.runtime.statecharts_core import RuntimeException, AssociationException,AssociationReferenceException, ParameterException, InputException
 from sccd.runtime.statecharts_core import ELSE_GUARD, Association, Event
+from sccd.runtime.libs import DEVSutils
 
 
 from heapq import heappush, heappop, heapify
 import threading
-
-def get_private_port(text):
-    match = re.search(r'private_\d+_(\w+)', text)
-
-    if match:
-        result = match.group(1)
-        return result
     
 class Transition:
     def __init__(self, obj, source, targets):
@@ -484,7 +478,7 @@ class ClassState():
                 target_instance = self.port_mappings[e.getPort()]
                 if target_instance is not None:
                     target_instance = self.instances[target_instance] 
-                    e.port = get_private_port(e.port)
+                    e.port = DEVSutils.get_general_port(e.port)
             if target_instance == None:
                 self.broadcast(None,e, event_time - self.simulated_time)
             else:
@@ -496,6 +490,12 @@ class ClassState():
             input_event_list = [input_event_list]
 
         for e in input_event_list:
+            # TODO: check, probably more wrong with global inport, sending to multiple instances
+            # If a global event arrives but there are no instances, the event should be ignored
+            # (otherwise the port checking will raise an exception)
+            if len(self.instances) == 0:
+                break
+
             if e.getName() == "":
                 raise InputException("Input event can't have an empty name.")
             
@@ -517,6 +517,8 @@ class ClassState():
 class ClassBase(AtomicDEVS):    
     def __init__(self, name):
         AtomicDEVS.__init__(self, name)
+
+        self.glob_inputs = {}
         self.glob_outputs = {}
         self.outputs = {}
         self.state = ClassState(name)
@@ -580,6 +582,8 @@ class ClassBase(AtomicDEVS):
         # Collect all inputs
         all_inputs = [item for input_list in inputs.values() for item in (input_list if isinstance(input_list, (tuple, list)) else [input_list])]
         for input in all_inputs:
+            if isinstance(input, Event):
+                input = (None, None, input)
             if isinstance(input, str):
                 input = (None, None, eval(input))
             if input[2].getName() in self.handlers:

+ 11 - 0
sccd/runtime/libs/DEVSutils.py

@@ -0,0 +1,11 @@
+import re
+
+def get_general_port(text):
+    # Get the general name of a private port with regex
+    match = re.search(r'private_\d+_(\w+)', text)
+
+    if match:
+        result = match.group(1)
+        return result
+    else:
+        return text

+ 25 - 1
sccd/runtime/statecharts_core.py

@@ -585,7 +585,30 @@ class ControllerBase(object):
 
     def getEarliestEventTime(self):
         return min(self.object_manager.getEarliestEventTime(), self.input_queue.getEarliestTime())
+    
+    def handleInput(self):
+        while not self.input_queue.isEmpty():
+            event_time = self.input_queue.getEarliestTime()
 
+            # SAM: Changed the handleInput function
+            # The function now waits to input the event when the simulated time is equal to the event first event time
+            # This is because the addINput fnuction adds input at time zero to an instance with a delay to the real time 
+            # the event should trigger, but at time zero this instance may not exist
+            if event_time == self.simulated_time:
+                e = self.input_queue.pop()
+                input_port = self.input_ports[e.getPort()]
+                # e.port = input_port.virtual_name
+                target_instance = input_port.instance
+                if target_instance == None:
+                    self.broadcast(e, event_time - self.simulated_time)
+                    self.tracers.tracesInput(input_port, e)
+                else:
+                    target_instance.addEvent(e, event_time - self.simulated_time)
+                    self.tracers.tracesInput(input_port, e)
+            else:
+                break
+
+    '''
     def handleInput(self):
         while not self.input_queue.isEmpty():
             event_time = self.input_queue.getEarliestTime()
@@ -599,7 +622,7 @@ class ControllerBase(object):
             else:
                 target_instance.addEvent(e, event_time - self.simulated_time)
                 self.tracers.tracesInput(input_port, e)
-
+    '''
     def outputEvent(self, event):
         #TODO: This is the output event, needs to be traced
         self.tracers.tracesOutput(event)
@@ -607,6 +630,7 @@ class ControllerBase(object):
             listener.add(event)
 
 
+
     def addOutputListener(self, ports):
         listener = OutputListener(ports)
         self.output_listeners.append(listener)

+ 1 - 1
tests/1.0) EventlessTransitionTest/sccd.xml

@@ -1,7 +1,7 @@
 <?xml version="1.1" ?>
 <diagram author="Sam Pieters" name="EventlessTransitionTest">
     <description>
-        Test 1: Check if a statechart directly transitions without an event being raised. 
+        Check if a statechart directly transitions without an event being raised. 
     </description>
     <class name="MainApp" default="true">
         <scxml initial="state1">

+ 1 - 1
tests/1.1) AfterTransitionTest/sccd.xml

@@ -1,7 +1,7 @@
 <?xml version="1.1" ?>
 <diagram author="Sam Pieters" name="AfterTransitionTest">
     <description>
-        Test 2: Check if a statechart transitions after a certain time.
+        Check if a statechart transitions after a certain time.
     </description>
     <class name="MainApp" default="true">
         <scxml initial="state1">

+ 5 - 3
tests/1.10) ShallowHistoryTest/sccd.xml

@@ -1,6 +1,8 @@
-<?xml version="1.0" ?>
-<diagram author="Raphael Mannadiar" name="">
-    <inport name="ui" />
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="ShallowHistoryTest">
+    <description>
+        Test if a shallow history keeps the state when leaving out of composite.
+    </description>
     <class name="MainApp" default="true">
         <scxml initial="on">
             <state id="on" initial="normal">

+ 5 - 3
tests/1.11) DeepHistoryTest/sccd.xml

@@ -1,6 +1,8 @@
-<?xml version="1.0" ?>
-<diagram author="Raphael Mannadiar" name="">
-    <inport name="ui" />
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="DeepHistoryTest">
+    <description>
+        Test if a deep history keeps the deepest state when leaving out of composite.
+    </description>
     <class name="MainApp" default="true">
         <scxml initial="on">
             <state id="on" initial="normal">

+ 6 - 2
tests/1.12) NonDeterminismTest/sccd.xml

@@ -1,5 +1,9 @@
-<?xml version="1.0" ?>
-<diagram author="Raphael Mannadiar" name="">
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="NonDeterminismTest">
+    <description>
+        Test if nondeterminism works as expected. 
+        There are two states defined in a composite that fire the same moment but these get resolved as the composite state also has an upper trnasition.
+    </description>
     <class name="MainApp" default="true">
         <scxml initial="Y">
             <state id="Y" initial="A"> 

+ 1 - 1
tests/1.2) GuardConditionTest/sccd.xml

@@ -1,7 +1,7 @@
 <?xml version="1.1" ?>
 <diagram author="Sam Pieters" name="GuardConditionTest">
     <description>
-        Test 5: Test if the guard condition for a transition works
+        Test if the guard condition for a transition works
     </description>
     <top>
         VALUE = 5

+ 1 - 1
tests/1.3) TransitionToItselfTest/sccd.xml

@@ -1,7 +1,7 @@
 <?xml version="1.1" ?>
 <diagram author="Sam Pieters" name="AfterTransitionTest">
     <description>
-        Test 3: Check if a state can transition to itself
+        Check if a state can transition to itself
     </description>
     <class name="MainApp" default="true">
         <constructor>

+ 2 - 2
tests/1.4) ScriptTransitionTest/sccd.xml

@@ -1,7 +1,7 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="AfterTransitionTest">
+<diagram author="Sam Pieters" name="ScriptTransitionTest">
     <description>
-        Test 3: Check if a script works by updating parameters.
+        Check if a script works by updating parameters when transitioning.
     </description>
     <class name="MainApp" default="true">
         <constructor>

+ 2 - 2
tests/1.5) ScriptEntryTest/sccd.xml

@@ -1,7 +1,7 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="AfterTransitionTest">
+<diagram author="Sam Pieters" name="ScriptEntryTest">
     <description>
-        Test 3: Check if a script works by updating parameters.
+        Check if a script works by updating parameters in the entry of a state.
     </description>
     <class name="MainApp" default="true">
         <constructor>

+ 2 - 2
tests/1.6) ScriptExitTest/sccd.xml

@@ -1,7 +1,7 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="AfterTransitionTest">
+<diagram author="Sam Pieters" name="ScriptExitTest">
     <description>
-        Test 3: Check if a script works by updating parameters.
+        Check if a script works by updating parameters in the exit of a state.
     </description>
     <class name="MainApp" default="true">
         <constructor>

tests/1.8) ParallelStateTest/config.json → tests/1.7) CompositeInitialStateTest/config.json


+ 7 - 0
tests/1.7) CompositeInitialStateTest/expected_trace.txt

@@ -0,0 +1,7 @@
+0.00 MainApp: exit /state1/state11
+0.00 MainApp: transition (/state1/state11 -> /state1/state12)
+0.00 MainApp: enter /state1/state12
+0.00 MainApp: exit /state1/state12
+0.00 MainApp: exit /state1
+0.00 MainApp: transition (/state1/state12 -> /state2)
+0.00 MainApp: enter /state2

+ 3 - 2
tests/1.7) CompositeStateTest/sccd.xml

@@ -1,7 +1,8 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="AfterTransitionTest">
+<diagram author="Sam Pieters" name="CompositeInitialStateTest">
     <description>
-        Test 3: Test if the composite state works as expected
+        Test if composite states are handled correctly.
+        When initial in composite defined, don't go into the first state that is defined but in the initial.
     </description>
     <class name="MainApp" default="true">
         <scxml initial="state1">

+ 3 - 0
tests/1.9) ParallelStateTest/config.json

@@ -0,0 +1,3 @@
+{
+    "trace": "statechart"
+}

tests/1.8) ParallelStateTest/expected_trace.txt → tests/1.9) ParallelStateTest/expected_trace.txt


+ 2 - 2
tests/1.8) ParallelStateTest/sccd.xml

@@ -1,7 +1,7 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="AfterTransitionTest">
+<diagram author="Sam Pieters" name="ParallelStateTest">
     <description>
-        Test 2: Check if a statechart transitions after a certain time.
+        Test if a parallel state is executed correctly.
     </description>
     <class name="MainApp" default="true">
         <scxml initial="state1">

+ 1 - 1
tests/10.0) TrafficLightTest/input.txt

@@ -7,4 +7,4 @@
 0.00 (event name: button_created; port: private_1_field_ui; parameters: [3])
 1.00 (event name: interrupt_clicked; port: private_1_field_ui; parameters: [58, 24, 1])
 1.99 (event name: interrupt_clicked; port: private_1_field_ui; parameters: [58, 24, 1])
-3.00 (event name: quit_clicked; port: private_1_field_ui; parameters: [58, 45, 1])
+3.00 (event name: quit_clicked; port: private_1_field_ui; parameters: [58, 45, 1])

+ 0 - 250
tests/10.0) TrafficLightTest/output.txt

@@ -1,250 +0,0 @@
-__  Current Time:   0.000000 __________________________________________ 
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: create_window; port: ui; parameters: [100, 350, 'Fixed Traffic Light', 'private_1_field_ui'])
-
-__  Current Time:   0.008000 __________________________________________ 
-
-INPUT EVENT from <ObjectManager>
-	\Type: cd
-	\Event: (event name: window_created; port: private_1_field_ui; parameters: [0])
-
-INPUT EVENT from port <private_1_field_ui>
-	\Type: field_ui
-	\Event: (event name: window_created; port: private_1_field_ui; parameters: [0])
-
-EXIT STATE in model <MainApp>
-		State: /creating_window
-
-TRANSITION FIRED in model <MainApp>
-		Transition(/creating_window -> /creating_canvas)
-
-ENTER STATE in model <MainApp>
-		State: /creating_canvas
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: bind_event; port: ui; parameters: [0, 'WM_DELETE_WINDOW', 'window_close', 'private_1_field_ui'])
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: create_canvas; port: ui; parameters: [0, 100, 250, {'background': '#222222'}, 'private_1_field_ui'])
-
-__  Current Time:   0.021000 __________________________________________ 
-
-INPUT EVENT from <ObjectManager>
-	\Type: cd
-	\Event: (event name: canvas_created; port: private_1_field_ui; parameters: [1])
-
-INPUT EVENT from port <private_1_field_ui>
-	\Type: field_ui
-	\Event: (event name: canvas_created; port: private_1_field_ui; parameters: [1])
-
-EXIT STATE in model <MainApp>
-		State: /creating_canvas
-
-TRANSITION FIRED in model <MainApp>
-		Transition(/creating_canvas -> /creating_trafficlight)
-
-ENTER STATE in model <MainApp>
-		State: /creating_trafficlight
-
-ENTER STATE in model <MainApp>
-		State: /creating_trafficlight/creating_greenlight
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: create_rectangle; port: ui; parameters: [1, 50, 50, 50, 50, {'fill': '#000'}, 'private_1_field_ui'])
-
-__  Current Time:   0.022000 __________________________________________ 
-
-INPUT EVENT from <ObjectManager>
-	\Type: cd
-	\Event: (event name: rectangle_created; port: private_1_field_ui; parameters: [1, 1])
-
-INPUT EVENT from port <private_1_field_ui>
-	\Type: field_ui
-	\Event: (event name: rectangle_created; port: private_1_field_ui; parameters: [1, 1])
-
-EXIT STATE in model <MainApp>
-		State: /creating_trafficlight/creating_greenlight
-
-TRANSITION FIRED in model <MainApp>
-		Transition(/creating_trafficlight/creating_greenlight -> /creating_trafficlight/creating_yellowlight)
-
-ENTER STATE in model <MainApp>
-		State: /creating_trafficlight/creating_yellowlight
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: create_rectangle; port: ui; parameters: [1, 50, 110, 50, 50, {'fill': '#000'}, 'private_1_field_ui'])
-
-
-INPUT EVENT from <ObjectManager>
-	\Type: cd
-	\Event: (event name: rectangle_created; port: private_1_field_ui; parameters: [1, 2])
-
-INPUT EVENT from port <private_1_field_ui>
-	\Type: field_ui
-	\Event: (event name: rectangle_created; port: private_1_field_ui; parameters: [1, 2])
-
-EXIT STATE in model <MainApp>
-		State: /creating_trafficlight/creating_yellowlight
-
-TRANSITION FIRED in model <MainApp>
-		Transition(/creating_trafficlight/creating_yellowlight -> /creating_trafficlight/creating_redlight)
-
-ENTER STATE in model <MainApp>
-		State: /creating_trafficlight/creating_redlight
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: create_rectangle; port: ui; parameters: [1, 50, 170, 50, 50, {'fill': '#000'}, 'private_1_field_ui'])
-
-__  Current Time:   0.023000 __________________________________________ 
-
-INPUT EVENT from <ObjectManager>
-	\Type: cd
-	\Event: (event name: rectangle_created; port: private_1_field_ui; parameters: [1, 3])
-
-INPUT EVENT from port <private_1_field_ui>
-	\Type: field_ui
-	\Event: (event name: rectangle_created; port: private_1_field_ui; parameters: [1, 3])
-
-EXIT STATE in model <MainApp>
-		State: /creating_trafficlight/creating_redlight
-
-EXIT STATE in model <MainApp>
-		State: /creating_trafficlight
-
-TRANSITION FIRED in model <MainApp>
-		Transition(/creating_trafficlight/creating_redlight -> /creating_interrupt_button)
-
-ENTER STATE in model <MainApp>
-		State: /creating_interrupt_button
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: create_button; port: ui; parameters: [0, 'Police Interrupt', 'private_1_field_ui'])
-
-__  Current Time:   0.025000 __________________________________________ 
-
-INPUT EVENT from <ObjectManager>
-	\Type: cd
-	\Event: (event name: button_created; port: private_1_field_ui; parameters: [2])
-
-INPUT EVENT from port <private_1_field_ui>
-	\Type: field_ui
-	\Event: (event name: button_created; port: private_1_field_ui; parameters: [2])
-
-EXIT STATE in model <MainApp>
-		State: /creating_interrupt_button
-
-TRANSITION FIRED in model <MainApp>
-		Transition(/creating_interrupt_button -> /creating_quit_button)
-
-ENTER STATE in model <MainApp>
-		State: /creating_quit_button
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: bind_event; port: ui; parameters: [2, '<Button>', 'interrupt_clicked', 'private_1_field_ui'])
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: create_button; port: ui; parameters: [0, 'Quit', 'private_1_field_ui'])
-
-__  Current Time:   0.026000 __________________________________________ 
-
-INPUT EVENT from <ObjectManager>
-	\Type: cd
-	\Event: (event name: button_created; port: private_1_field_ui; parameters: [3])
-
-INPUT EVENT from port <private_1_field_ui>
-	\Type: field_ui
-	\Event: (event name: button_created; port: private_1_field_ui; parameters: [3])
-
-EXIT STATE in model <MainApp>
-		State: /creating_quit_button
-
-TRANSITION FIRED in model <MainApp>
-		Transition(/creating_quit_button -> /on)
-
-ENTER STATE in model <MainApp>
-		State: /on
-
-ENTER STATE in model <MainApp>
-		State: /on/normal
-
-ENTER STATE in model <MainApp>
-		State: /on/normal/red
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: bind_event; port: ui; parameters: [3, '<Button>', 'quit_clicked', 'private_1_field_ui'])
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: set_element_color; port: ui; parameters: [1, 2, 'black'])
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: set_element_color; port: ui; parameters: [1, 3, 'red'])
-
-__  Current Time:   3.026000 __________________________________________ 
-
-EXIT STATE in model <MainApp>
-		State: /on/normal/red
-
-TRANSITION FIRED in model <MainApp>
-		Transition(/on/normal/red -> /on/normal/green)
-
-ENTER STATE in model <MainApp>
-		State: /on/normal/green
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: set_element_color; port: ui; parameters: [1, 3, 'black'])
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: set_element_color; port: ui; parameters: [1, 1, 'green'])
-
-__  Current Time:   5.026000 __________________________________________ 
-
-EXIT STATE in model <MainApp>
-		State: /on/normal/green
-
-TRANSITION FIRED in model <MainApp>
-		Transition(/on/normal/green -> /on/normal/yellow)
-
-ENTER STATE in model <MainApp>
-		State: /on/normal/yellow
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: set_element_color; port: ui; parameters: [1, 1, 'black'])
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: set_element_color; port: ui; parameters: [1, 2, 'yellow'])
-
-__  Current Time:   6.026000 __________________________________________ 
-
-EXIT STATE in model <MainApp>
-		State: /on/normal/yellow
-
-TRANSITION FIRED in model <MainApp>
-		Transition(/on/normal/yellow -> /on/normal/red)
-
-ENTER STATE in model <MainApp>
-		State: /on/normal/red
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: set_element_color; port: ui; parameters: [1, 2, 'black'])
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: set_element_color; port: ui; parameters: [1, 3, 'red'])
-
-__  Current Time:   9.026000 __________________________________________ 
-
-EXIT STATE in model <MainApp>
-		State: /on/normal/red
-
-TRANSITION FIRED in model <MainApp>
-		Transition(/on/normal/red -> /on/normal/green)
-
-ENTER STATE in model <MainApp>
-		State: /on/normal/green
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: set_element_color; port: ui; parameters: [1, 3, 'black'])
-
-OUTPUT EVENT to port <ui>
-	\Event: (event name: set_element_color; port: ui; parameters: [1, 1, 'green'])
-

+ 1 - 1
tests/10.0) TrafficLightTest/sccd.xml

@@ -1,4 +1,4 @@
-<?xml version="1.0" ?>
+<?xml version="1.1" ?>
 <diagram author="Sam Pieters" name="TrafficLight">
     <description>
         Tkinter frame with Traffic light in a single statechart.

+ 0 - 4
tests/10.1) BouncingBallsTest/input.txt

@@ -1,4 +0,0 @@
-0.5 (event name: window_created; port: ui; parameters: [0])
-1.0 (event name: canvas_created; port: ui; parameters: [1])
-1.5 (event name: button_created; port: ui; parameters: [2])
-2.0 (event name: window_close; port: ui; parameters: None)

+ 3 - 0
tests/10.1) TrafficLightHistory/config.json

@@ -0,0 +1,3 @@
+{
+    "trace": "statechart"
+}

+ 43 - 0
tests/10.1) TrafficLightHistory/expected_trace.txt

@@ -0,0 +1,43 @@
+0.00 MainApp: exit /creating_window
+0.00 MainApp: transition (/creating_window -> /creating_canvas)
+0.00 MainApp: enter /creating_canvas
+0.00 MainApp: exit /creating_canvas
+0.00 MainApp: transition (/creating_canvas -> /creating_trafficlight)
+0.00 MainApp: enter /creating_trafficlight
+0.00 MainApp: enter /creating_trafficlight/creating_greenlight
+0.00 MainApp: exit /creating_trafficlight/creating_greenlight
+0.00 MainApp: transition (/creating_trafficlight/creating_greenlight -> /creating_trafficlight/creating_yellowlight)
+0.00 MainApp: enter /creating_trafficlight/creating_yellowlight
+0.00 MainApp: exit /creating_trafficlight/creating_yellowlight
+0.00 MainApp: transition (/creating_trafficlight/creating_yellowlight -> /creating_trafficlight/creating_redlight)
+0.00 MainApp: enter /creating_trafficlight/creating_redlight
+0.00 MainApp: exit /creating_trafficlight/creating_redlight
+0.00 MainApp: exit /creating_trafficlight
+0.00 MainApp: transition (/creating_trafficlight/creating_redlight -> /creating_interrupt_button)
+0.00 MainApp: enter /creating_interrupt_button
+0.00 MainApp: exit /creating_interrupt_button
+0.00 MainApp: transition (/creating_interrupt_button -> /creating_quit_button)
+0.00 MainApp: enter /creating_quit_button
+0.00 MainApp: exit /creating_quit_button
+0.00 MainApp: transition (/creating_quit_button -> /on)
+0.00 MainApp: enter /on
+0.00 MainApp: enter /on/normal
+0.00 MainApp: enter /on/normal/red
+3.00 MainApp: exit /on/normal/red
+3.00 MainApp: transition (/on/normal/red -> /on/normal/green)
+3.00 MainApp: enter /on/normal/green
+3.10 MainApp: exit /on/normal/green
+3.10 MainApp: exit /on/normal
+3.10 MainApp: transition (/on/normal -> /on/interrupted)
+3.10 MainApp: enter /on/interrupted
+3.10 MainApp: enter /on/interrupted/yellow
+3.50 MainApp: exit /on/interrupted/yellow
+3.50 MainApp: exit /on/interrupted
+3.50 MainApp: transition (/on/interrupted -> /on/normal/history)
+3.50 MainApp: enter /on/normal
+3.50 MainApp: enter /on/normal/green
+5.00 MainApp: exit /on/normal/green
+5.00 MainApp: exit /on/normal
+5.00 MainApp: exit /on
+5.00 MainApp: transition (/on/normal -> /off)
+5.00 MainApp: enter /off

+ 10 - 0
tests/10.1) TrafficLightHistory/input.txt

@@ -0,0 +1,10 @@
+0.00 (event name: window_created; port: private_1_field_ui; parameters: [0])
+0.00 (event name: canvas_created; port: private_1_field_ui; parameters: [1])
+0.00 (event name: rectangle_created; port: private_1_field_ui; parameters: [1, 1])
+0.00 (event name: rectangle_created; port: private_1_field_ui; parameters: [1, 2])
+0.00 (event name: rectangle_created; port: private_1_field_ui; parameters: [1, 3])
+0.00 (event name: button_created; port: private_1_field_ui; parameters: [2])
+0.00 (event name: button_created; port: private_1_field_ui; parameters: [3])
+3.1 (event name: interrupt_clicked; port: private_1_field_ui; parameters: [58, 24, 1])
+3.5 (event name: interrupt_clicked; port: private_1_field_ui; parameters: [58, 24, 1])
+5 (event name: quit_clicked; port: private_1_field_ui; parameters: [58, 45, 1])

+ 292 - 0
tests/10.1) TrafficLightHistory/sccd.xml

@@ -0,0 +1,292 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="TrafficLight">
+    <description>
+        Tkinter frame with Traffic light in a single statechart (with history).
+    </description>
+    <top>
+        from sccd.runtime.libs import ui_v2 as ui
+        CANVAS_DIMS = (100, 350)
+    </top>
+    <inport name="ui" />
+    <outport name="ui"/>
+    <class name="MainApp" default="true">
+        <attribute name="window_id" />
+        <attribute name="canvas_id" />
+        <attribute name="green_id" />
+        <attribute name="yellow_id" />
+        <attribute name="red_id" />
+        <attribute name="police_button_id" />
+        <atrribute name="quit_button_id" />
+        <inport name="field_ui"/>
+        <scxml initial="creating_window">
+            <state id="creating_window">
+                <onentry>
+                    <raise port="ui" event="create_window">
+                        <parameter expr="CANVAS_DIMS[0]"/>
+                        <parameter expr="CANVAS_DIMS[1]"/>
+                        <parameter expr='"Traffic Light"'/>
+                        <parameter expr="self.inports['field_ui']"/>
+                    </raise>
+                </onentry>
+                <transition event="window_created" target="../creating_canvas">
+                    <parameter name="window_id" type="int" />
+                    <script>
+                        self.window_id = window_id
+                    </script>
+                    <raise port="ui" event="bind_event">
+                        <parameter expr="window_id"/>
+                        <parameter expr="ui.EVENTS.WINDOW_CLOSE"/>
+                        <parameter expr="'window_close'"/>
+                        <parameter expr="self.inports['field_ui']"/>
+                    </raise>
+                </transition>
+            </state>
+            <state id="creating_canvas">
+                <onentry>
+                    <raise port="ui" event="create_canvas">
+                        <parameter expr="self.window_id"/>
+                        <parameter expr="CANVAS_DIMS[0]"/>
+                        <parameter expr="CANVAS_DIMS[1] - 100"/>
+                        <parameter expr="{'background':'#222222'}"/>
+                        <parameter expr="self.inports['field_ui']"/>
+                    </raise>
+                </onentry>
+                <transition event="canvas_created" target="../creating_trafficlight">
+                    <parameter name="canvas_id" type="int"/>
+                    <script>
+                        self.canvas_id = canvas_id
+                    </script>
+                </transition>
+            </state>
+            <state id="creating_trafficlight" initial="creating_greenlight">
+                <state id="creating_greenlight">
+                    <onentry>
+                        <raise port="ui" event="create_rectangle">
+                            <parameter expr="self.canvas_id" />
+                            <parameter expr="50" />
+                            <parameter expr="50" />
+                            <parameter expr="50" />
+                            <parameter expr="50" />
+                            <parameter expr="{'fill':'#000'}" />
+                            <parameter expr="self.inports['field_ui']" />
+                        </raise>
+                    </onentry>
+                    <transition event="rectangle_created" target="../creating_yellowlight">
+                        <parameter name="canvas_id" type="int"/>
+                        <parameter name="green_id" type="int" />
+                        <script>
+                            self.green_id = green_id
+                        </script>
+                    </transition>
+                </state>
+                <state id="creating_yellowlight">
+                    <onentry>
+                        <raise port="ui" event="create_rectangle">
+                            <parameter expr="self.canvas_id" />
+                            <parameter expr="50" />
+                            <parameter expr="110" />
+                            <parameter expr="50" />
+                            <parameter expr="50" />
+                            <parameter expr="{'fill':'#000'}" />
+                            <parameter expr="self.inports['field_ui']" />
+                        </raise>
+                    </onentry>
+                    <transition event="rectangle_created" target="../creating_redlight">
+                        <parameter name="canvas_id" type="int"/>
+                        <parameter name="yellow_id" type="int" />
+                        <script>
+                            self.yellow_id = yellow_id
+                        </script>
+                    </transition>
+                </state>
+                <state id="creating_redlight">
+                    <onentry>
+                        <raise port="ui" event="create_rectangle">
+                            <parameter expr="self.canvas_id" />
+                            <parameter expr="50" />
+                            <parameter expr="170" />
+                            <parameter expr="50" />
+                            <parameter expr="50" />
+                            <parameter expr="{'fill':'#000'}" />
+                            <parameter expr="self.inports['field_ui']" />
+                        </raise>
+                    </onentry>
+                    <transition event="rectangle_created" target="../../creating_interrupt_button">
+                        <parameter name="canvas_id" type="int"/>
+                        <parameter name="red_id" type="int" />
+                        <script>
+                            self.red_id = red_id
+                        </script>
+                    </transition>
+                </state>
+            </state>
+            <state id="creating_interrupt_button">
+                <onentry>
+                    <raise port="ui" event="create_button">
+                        <parameter expr="self.window_id" />
+                        <parameter expr="'Police Interrupt'" />
+                        <parameter expr="self.inports['field_ui']" />
+                    </raise>
+                </onentry>
+                <transition event="button_created" target="../creating_quit_button">
+                    <parameter name="button_id" type="int"/>
+                    <script>
+                        self.police_button_id = button_id
+                    </script> 
+                    <raise port="ui" event="bind_event">
+                        <parameter expr="button_id"/>
+                        <parameter expr="ui.EVENTS.MOUSE_CLICK"/>
+                        <parameter expr='"interrupt_clicked"'/>
+                        <parameter expr="self.inports['field_ui']"/>
+                    </raise>
+                </transition>
+            </state>
+            <state id="creating_quit_button">
+                <onentry>
+                    <raise port="ui" event="create_button">
+                        <parameter expr="self.window_id" />
+                        <parameter expr="'Quit'" />
+                        <parameter expr="self.inports['field_ui']" />
+                    </raise>
+                </onentry>
+                <transition event="button_created" target="../on">
+                    <parameter name="button_id" type="int"/>
+                    <script>
+                        self.quit_button_id = button_id
+                    </script> 
+                    <raise port="ui" event="bind_event">
+                        <parameter expr="button_id"/>
+                        <parameter expr="ui.EVENTS.MOUSE_CLICK"/>
+                        <parameter expr='"quit_clicked"'/>
+                        <parameter expr="self.inports['field_ui']"/>
+                    </raise>
+                </transition>
+            </state>
+            <state id="on" initial="normal">
+                <state id="normal" initial="red">
+                    <transition port="field_ui" event="window_close" target="../../deleted" >
+                        <raise port="ui" event="destroy_all" />
+                    </transition>
+                    <transition port='field_ui' event="quit_clicked" target='../../off' cond="button == ui.MOUSE_BUTTONS.LEFT">
+                        <parameter name="x" />
+                        <parameter name="y" />
+                        <parameter name="button" />
+                    </transition>
+                    <transition port='field_ui' event="interrupt_clicked" target='../interrupted' cond="button == ui.MOUSE_BUTTONS.LEFT">
+                        <parameter name="x" />
+                        <parameter name="y" />
+                        <parameter name="button" />
+                        <raise port="ui" event="set_element_color">
+                            <parameter expr="self.canvas_id" />
+                            <parameter expr="self.green_id" />
+                            <parameter expr="'black'" />
+                        </raise>
+                        <raise port="ui" event="set_element_color">
+                            <parameter expr="self.canvas_id" />
+                            <parameter expr="self.yellow_id" />
+                            <parameter expr="'black'" />
+                        </raise>
+                        <raise port="ui" event="set_element_color">
+                            <parameter expr="self.canvas_id" />
+                            <parameter expr="self.red_id" />
+                            <parameter expr="'black'" />
+                        </raise>
+                    </transition>
+                    <state id="red">
+                        <onentry>
+                            <raise port="ui" event="set_element_color">
+                                <parameter expr="self.canvas_id" />
+                                <parameter expr="self.yellow_id" />
+                                <parameter expr="'black'" />
+                            </raise>
+                            <raise port="ui" event="set_element_color">
+                                <parameter expr="self.canvas_id" />
+                                <parameter expr="self.red_id" />
+                                <parameter expr="'red'" />
+                            </raise>
+                        </onentry>
+                        <transition after='3' target='../green'/>
+                    </state>
+                    <state id="green">
+                        <onentry>
+                            <raise port="ui" event="set_element_color">
+                                <parameter expr="self.canvas_id" />
+                                <parameter expr="self.red_id" />
+                                <parameter expr="'black'" />
+                            </raise>
+                            <raise port="ui" event="set_element_color">
+                                <parameter expr="self.canvas_id" />
+                                <parameter expr="self.green_id" />
+                                <parameter expr="'green'" />
+                            </raise>
+                        </onentry>
+                        <transition after='2' target='../yellow'/>
+                    </state>
+                    <state id="yellow">
+                        <onentry>
+                            <raise port="ui" event="set_element_color">
+                                <parameter expr="self.canvas_id" />
+                                <parameter expr="self.green_id" />
+                                <parameter expr="'black'" />
+                            </raise>
+                            <raise port="ui" event="set_element_color">
+                                <parameter expr="self.canvas_id" />
+                                <parameter expr="self.yellow_id" />
+                                <parameter expr="'yellow'" />
+                            </raise>
+                        </onentry>
+                        <transition after='1' target='../red'/>
+                    </state>
+                    <history id="history"/>
+                </state>
+                <state id="interrupted" initial="yellow">
+                    <state id="yellow">
+                        <onentry>
+                            <raise port="ui" event="set_element_color">
+                                <parameter expr="self.canvas_id" />
+                                <parameter expr="self.yellow_id" />
+                                <parameter expr="'yellow'" />
+                            </raise>
+                        </onentry>
+                        <transition after='.5' target='../black'/>
+                    </state>
+                    <state id="black">
+                        <onentry>
+                            <raise port="ui" event="set_element_color">
+                                <parameter expr="self.canvas_id" />
+                                <parameter expr="self.yellow_id" />
+                                <parameter expr="'black'" />
+                            </raise>
+                        </onentry>
+                        <transition after='.5' target='../yellow'/>
+                    </state>
+                    <transition port='field_ui' event="interrupt_clicked" target='../normal/history' cond="button == ui.MOUSE_BUTTONS.LEFT">
+                        <parameter name="x" />
+                        <parameter name="y" />
+                        <parameter name="button" />
+                    </transition>
+                </state>
+            </state>
+            <state id="off">
+                <onentry>
+                    <raise port="ui" event="set_element_color">
+                        <parameter expr="self.canvas_id" />
+                        <parameter expr="self.green_id" />
+                        <parameter expr="'black'" />
+                    </raise>
+                    <raise port="ui" event="set_element_color">
+                        <parameter expr="self.canvas_id" />
+                        <parameter expr="self.yellow_id" />
+                        <parameter expr="'black'" />
+                    </raise>
+                    <raise port="ui" event="set_element_color">
+                        <parameter expr="self.canvas_id" />
+                        <parameter expr="self.red_id" />
+                        <parameter expr="'black'" />
+                    </raise>
+                </onentry>
+            </state>
+            <state id="deleted" />
+        </scxml>
+    </class>
+</diagram>

+ 3 - 0
tests/10.2) SimplestBouncingBallsTest/config.json

@@ -0,0 +1,3 @@
+{
+    "trace": ["statechart", "external"]
+}

+ 70 - 0
tests/10.2) SimplestBouncingBallsTest/expected_trace.txt

@@ -0,0 +1,70 @@
+0.00 MainApp: exit /running/root/main_behaviour/initializing
+0.00 MainApp: transition (/running/root/main_behaviour/initializing -> /running/root/main_behaviour/running)
+0.00 MainApp: enter /running/root/main_behaviour/running
+0.00 MainApp: exit /running/root/cd_behaviour/waiting
+0.00 MainApp: transition (/running/root/cd_behaviour/waiting -> /running/root/cd_behaviour/creating)
+0.00 MainApp: enter /running/root/cd_behaviour/creating
+0.00 MainApp: exit /running/root/cd_behaviour/creating
+0.00 MainApp: transition (/running/root/cd_behaviour/creating -> /running/root/cd_behaviour/waiting)
+0.00 MainApp: enter /running/root/cd_behaviour/waiting
+0.00 Field: exit /root/waiting
+0.00 Field: transition (/root/waiting -> /root/creating_window)
+0.00 Field: enter /root/creating_window
+0.00 (event name: create_window; port: Outport; parameters: [800, 600, 'BouncingBalls', 'Inport'])
+0.50 Field: exit /root/creating_window
+0.50 Field: transition (/root/creating_window -> /root/creating_canvas)
+0.50 Field: enter /root/creating_canvas
+0.50 (event name: bind_event; port: Outport; parameters: [0, 'WM_DELETE_WINDOW', 'window_close', 'Inport'])
+0.50 (event name: bind_event; port: Outport; parameters: [0, '<Key>', 'key_press', 'Inport'])
+0.50 (event name: create_canvas; port: Outport; parameters: [0, 800, 550, {'background': '#eee'}, 'Inport'])
+1.00 Field: exit /root/creating_canvas
+1.00 Field: transition (/root/creating_canvas -> /root/creating_button)
+1.00 Field: enter /root/creating_button
+1.00 (event name: bind_event; port: Outport; parameters: [1, '<Button-2>', 'right_click', 'Inport'])
+1.00 (event name: bind_event; port: Outport; parameters: [1, '<Motion>', 'mouse_move', 'Inport'])
+1.00 (event name: bind_event; port: Outport; parameters: [1, '<ButtonRelease>', 'mouse_release', 'Inport'])
+1.00 Field: exit /root/creating_button
+1.00 Field: transition (/root/creating_button -> /root/running)
+1.00 Field: enter /root/running
+1.00 Field: enter /root/running/main_behaviour
+1.00 Field: enter /root/running/main_behaviour/running
+1.00 Field: enter /root/running/deleting_behaviour
+1.00 Field: enter /root/running/deleting_behaviour/running
+1.00 Field: enter /root/running/child_behaviour
+1.00 Field: enter /root/running/child_behaviour/listening
+1.00 Field: enter /root/running/deleting_balls_behaviour
+1.00 Field: enter /root/running/deleting_balls_behaviour/listening
+1.00 (event name: create_button; port: Outport; parameters: [0, 'create_new_field', 'Inport'])
+1.50 Button: exit /creating_button
+1.50 Button: transition (/creating_button -> /running)
+1.50 Button: enter /running
+1.50 (event name: bind_event; port: Outport; parameters: [2, '<Button>', 'mouse_click', 'Inport'])
+2.00 Field: exit /root/running/deleting_balls_behaviour/listening
+2.00 Field: exit /root/running/child_behaviour/listening
+2.00 Field: exit /root/running/deleting_behaviour/running
+2.00 Field: exit /root/running/main_behaviour/running
+2.00 Field: exit /root/running/deleting_balls_behaviour
+2.00 Field: exit /root/running/child_behaviour
+2.00 Field: exit /root/running/deleting_behaviour
+2.00 Field: exit /root/running/main_behaviour
+2.00 Field: exit /root/running
+2.00 Field: transition (/root/running -> /root/deleting)
+2.00 Field: enter /root/deleting
+2.00 Field: exit /root/deleting
+2.00 Field: transition (/root/deleting -> /root/deleted)
+2.00 Field: enter /root/deleted
+2.00 (event name: destroy_window; port: Outport; parameters: [0])
+2.00 MainApp: exit /running/root/cd_behaviour/waiting
+2.00 MainApp: transition (/running/root/cd_behaviour/waiting -> /running/root/cd_behaviour/check_nr_of_fields)
+2.00 MainApp: enter /running/root/cd_behaviour/check_nr_of_fields
+2.05 MainApp: exit /running/root/cd_behaviour/check_nr_of_fields
+2.05 MainApp: transition (/running/root/cd_behaviour/check_nr_of_fields -> /running/root/cd_behaviour/stopped)
+2.05 MainApp: enter /running/root/cd_behaviour/stopped
+2.05 MainApp: exit /running/root/cd_behaviour/stopped
+2.05 MainApp: exit /running/root/main_behaviour/running
+2.05 MainApp: exit /running/root/cd_behaviour
+2.05 MainApp: exit /running/root/main_behaviour
+2.05 MainApp: exit /running/root
+2.05 MainApp: transition (/running/root -> /running/stopped)
+2.05 MainApp: enter /running/stopped
+2.05 (event name: destroy_all; port: Outport)

+ 4 - 0
tests/10.2) SimplestBouncingBallsTest/input.txt

@@ -0,0 +1,4 @@
+0.5 (event name: window_created; port: Inport; parameters: [0])
+1.0 (event name: canvas_created; port: Inport; parameters: [1])
+1.5 (event name: button_created; port: Inport; parameters: [2])
+2.0 (event name: window_close; port: Inport; parameters: None)

+ 43 - 42
tests/10.1) BouncingBallsTest/sccd.xml

@@ -9,7 +9,8 @@
 
         CANVAS_DIMS = (800, 550)
     </top>
-    <inport name="ui"/>
+    <inport name="Inport"/>
+    <outport name="Outport" />
     <class name="MainApp" default="true">
         <relationships>
             <association name="fields" class="Field" />
@@ -75,7 +76,7 @@
                         <state id="stopped" />
                     </state>
                     <transition target="../stopped" event="stop">
-                        <raise port="ui" event="destroy_all"/>
+                        <raise port="Outport" event="destroy_all"/>
                     </transition>
                 </parallel>
                 <state id="stopped" />
@@ -104,11 +105,11 @@
                 </state>
                 <state id="creating_window">
                     <onentry>
-                        <raise port="ui" event="create_window">
+                        <raise port="Outport" event="create_window">
                             <parameter expr="800"/>                     <!-- width -->
                             <parameter expr="600"/>                     <!-- height -->
                             <parameter expr='"BouncingBalls"'/>         <!-- title -->
-                            <parameter expr="self.inports['field_ui']"/><!-- inport for response -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
                         </raise>
                     </onentry>
                     <transition event="window_created" target="../creating_canvas">
@@ -116,28 +117,28 @@
                         <script>
                             self.window_id = window_id
                         </script>
-                        <raise port="ui" event="bind_event">
+                        <raise port="Outport" event="bind_event">
                             <parameter expr="window_id"/>               <!-- widget_id -->
                             <parameter expr="ui.EVENTS.WINDOW_CLOSE"/>  <!-- tk_event -->
                             <parameter expr="'window_close'"/>          <!-- sccd_event_name -->
-                            <parameter expr="self.inports['field_ui']"/><!-- inport for response -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
                         </raise>
-                        <raise port="ui" event="bind_event">
+                        <raise port="Outport" event="bind_event">
                             <parameter expr="window_id"/>               <!-- widget_id -->
                             <parameter expr="ui.EVENTS.KEY_PRESS"/>     <!-- tk_event -->
                             <parameter expr="'key_press'"/>             <!-- sccd_event_name -->
-                            <parameter expr="self.inports['field_ui']"/><!-- inport for response -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
                         </raise>
                     </transition>
                 </state>
                 <state id="creating_canvas">
                     <onentry>
-                        <raise port="ui" event="create_canvas">
+                        <raise port="Outport" event="create_canvas">
                             <parameter expr="self.window_id"/>          <!-- window_id -->
                             <parameter expr="CANVAS_DIMS[0]"/>          <!-- width -->
                             <parameter expr="CANVAS_DIMS[1]"/>          <!-- height -->
                             <parameter expr="{'background':'#eee'}"/>   <!-- style -->
-                            <parameter expr="self.inports['field_ui']"/><!-- inport for response -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
                         </raise>
                     </onentry>
                     <transition event="canvas_created" target="../creating_button">
@@ -145,23 +146,23 @@
                         <script>
                             self.canvas_id = canvas_id
                         </script>
-                        <raise port="ui" event="bind_event">
+                        <raise port="Outport" event="bind_event">
                             <parameter expr="canvas_id"/>                   <!-- widget_id -->
                             <parameter expr="ui.EVENTS.MOUSE_RIGHT_CLICK"/> <!-- tk_event -->
                             <parameter expr="'right_click'"/>               <!-- sccd_event_name -->
-                            <parameter expr="self.inports['field_ui']"/>    <!-- inport for response -->
+                            <parameter expr='"Inport"'/>    <!-- inport for response -->
                         </raise>
-                        <raise port="ui" event="bind_event">
+                        <raise port="Outport" event="bind_event">
                             <parameter expr="canvas_id"/>                   <!-- widget_id -->
                             <parameter expr="ui.EVENTS.MOUSE_MOVE"/>        <!-- tk_event -->
                             <parameter expr="'mouse_move'"/>                <!-- sccd_event_name -->
-                            <parameter expr="self.inports['field_ui']"/>    <!-- inport for response -->
+                            <parameter expr='"Inport"'/>    <!-- inport for response -->
                         </raise>
-                        <raise port="ui" event="bind_event">
+                        <raise port="Outport" event="bind_event">
                             <parameter expr="canvas_id"/><!-- widget_id -->
                             <parameter expr="ui.EVENTS.MOUSE_RELEASE"/><!-- tk_event -->
                             <parameter expr="'mouse_release'"/><!-- sccd_event_name -->
-                            <parameter expr="self.inports['field_ui']"/><!-- inport for response -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
                         </raise>
                     </transition>
                 </state>
@@ -183,7 +184,7 @@
                     </transition>
                 </state>
                  <parallel id="running">
-                    <transition port="field_ui" event="window_close" target="../deleting">
+                    <transition port="Inport" event="window_close" target="../deleting">
                         <raise event="delete_instance" scope="cd">
                             <parameter expr='"buttons"' />
                         </raise>
@@ -193,7 +194,7 @@
                     </transition>
                     <state id="main_behaviour" initial="running">
                         <state id="running">
-                            <transition port="field_ui" event="right_click" target="../creating_ball">
+                            <transition port="Inport" event="right_click" target="../creating_ball">
                                 <parameter name="x" />
                                 <parameter name="y" />
                                 <parameter name="button" />
@@ -240,7 +241,7 @@
                     </state>
                     <state id="deleting_balls_behaviour" initial="listening">
                         <state id="listening">
-                            <transition port="field_ui" event="key_press" target="." cond="key == ui.KEYCODES.DELETE">
+                            <transition port="Inport" event="key_press" target="." cond="key == ui.KEYCODES.DELETE">
                                 <parameter name="key" />
                                 <raise event="delete_self" scope="narrow" target="'balls'" />
                             </transition>
@@ -252,7 +253,7 @@
                         <raise event="delete_field" scope="narrow" target="'parent'">
                             <parameter expr='self.association_name' />
                         </raise>
-                        <raise port="ui" event="destroy_window">
+                        <raise port="Outport" event="destroy_window">
                             <parameter expr="self.window_id"/><!-- window to destroy -->
                         </raise>
                     </transition>
@@ -282,10 +283,10 @@
         <scxml initial="creating_button">
             <state id="creating_button">
                 <onentry>
-                    <raise port="ui" event="create_button">
+                    <raise port="Outport" event="create_button">
                         <parameter expr="self.window_id"/><!-- window_id -->
                         <parameter expr="self.event_name"/><!-- text -->
-                        <parameter expr="self.inports['button_ui']"/><!-- inport for response -->
+                        <parameter expr="'Inport'"/><!-- inport for response -->
                     </raise>
                 </onentry>
                 <transition event="button_created" target="../running">
@@ -293,16 +294,16 @@
                     <script>
                         self.button_id = button_id
                     </script>
-                    <raise port="ui" event="bind_event">
+                    <raise port="Outport" event="bind_event">
                         <parameter expr="button_id"/><!-- widget_id -->
                         <parameter expr="ui.EVENTS.MOUSE_CLICK"/><!-- tk_event -->
                         <parameter expr='"mouse_click"'/><!-- sccd_event_name -->
-                        <parameter expr="self.inports['button_ui']"/><!-- inport for response -->
+                        <parameter expr="'Inport'"/><!-- inport for response -->
                     </raise>
                 </transition>
             </state>
              <state id="running">
-                <transition port='button_ui' event="mouse_click" target='.' cond="button == ui.MOUSE_BUTTONS.LEFT">
+                <transition port='Inport' event="mouse_click" target='.' cond="button == ui.MOUSE_BUTTONS.LEFT">
                     <parameter name="x" />
                     <parameter name="y" />
                     <parameter name="button" />
@@ -348,13 +349,13 @@
                 </state>
                 <state id="creating_circle">
                     <onentry>
-                        <raise port="ui" event="create_circle">
+                        <raise port="Outport" event="create_circle">
                             <parameter expr="self.canvas_id"/><!-- canvas_id -->
                             <parameter expr="self.pos['x']"/><!-- x -->
                             <parameter expr="self.pos['y']"/><!-- y -->
                             <parameter expr="self.r"/><!-- r -->
                             <parameter expr="{'fill':'#000'}"/><!-- style -->
-                            <parameter expr="self.inports['ball_ui']"/><!-- inport for response -->
+                            <parameter expr="'Inport'"/><!-- inport for response -->
                         </raise>
                     </onentry>
                     <transition event="circle_created" target="../bouncing">
@@ -363,26 +364,26 @@
                         <script>
                             self.circle_id = circle_id
                         </script>
-                        <raise port="ui" event="bind_canvas_event">
+                        <raise port="Outport" event="bind_canvas_event">
                             <parameter expr="self.canvas_id"/>
                             <parameter expr="circle_id"/>
                             <parameter expr="ui.EVENTS.MOUSE_PRESS"/>
                             <parameter expr="'mouse_press'"/>
-                            <parameter expr="self.inports['ball_ui']"/>
+                            <parameter expr="'Inport'"/>
                         </raise>
-                        <raise port="ui" event="bind_canvas_event">
+                        <raise port="Outport" event="bind_canvas_event">
                             <parameter expr="self.canvas_id"/>
                             <parameter expr="circle_id"/>
                             <parameter expr="ui.EVENTS.MOUSE_MOVE"/>
                             <parameter expr="'mouse_move'"/>
-                            <parameter expr="self.inports['ball_ui']"/>
+                            <parameter expr="'Inport'"/>
                         </raise>
-                        <raise port="ui" event="bind_canvas_event">
+                        <raise port="Outport" event="bind_canvas_event">
                             <parameter expr="self.canvas_id"/>
                             <parameter expr="circle_id"/>
                             <parameter expr="ui.EVENTS.MOUSE_RELEASE"/>
                             <parameter expr="'mouse_release'"/>
-                            <parameter expr="self.inports['ball_ui']"/>
+                            <parameter expr="'Inport'"/>
                         </raise>
                     </transition>
                 </state>
@@ -398,7 +399,7 @@
                                 self.vel['y'] = -self.vel['y'];
                             ]]>
                         </script>
-                        <raise port="ui" event="move_element">
+                        <raise port="Outport" event="move_element">
                             <parameter expr="self.canvas_id"/>
                             <parameter expr="self.circle_id"/>
                             <parameter expr="self.vel['x']"/>
@@ -409,11 +410,11 @@
                             self.pos['y'] += self.vel['y']
                         </script>
                     </transition>
-                    <transition port="ball_ui" event="mouse_press" target="../selected" cond="button == ui.MOUSE_BUTTONS.LEFT">
+                    <transition port="Inport" event="mouse_press" target="../selected" cond="button == ui.MOUSE_BUTTONS.LEFT">
                         <parameter name="x" />
                         <parameter name="y" />
                         <parameter name="button" />
-                        <raise port="ui" event="set_element_color">
+                        <raise port="Outport" event="set_element_color">
                             <parameter expr="self.canvas_id"/>
                             <parameter expr="self.circle_id"/>
                             <parameter expr="'#ff0'"/>
@@ -421,7 +422,7 @@
                     </transition>
                 </state>
                 <state id="dragging">
-                    <transition port="ball_ui" event="mouse_move" target=".">
+                    <transition port="Inport" event="mouse_move" target=".">
                         <parameter name="x" />
                         <parameter name="y" />
                         <parameter name="button" />
@@ -440,17 +441,17 @@
                             
                             self.pos = {'x': x, 'y': y}
                         </script>
-                        <raise port="ui" event="set_element_pos">
+                        <raise port="Outport" event="set_element_pos">
                             <parameter expr="self.canvas_id"/>
                             <parameter expr="self.circle_id"/>
                             <parameter expr="x-self.r"/>
                             <parameter expr="y-self.r"/>
                         </raise>
                     </transition>
-                    <transition port="ball_ui" event="mouse_release" target="../bouncing">
+                    <transition port="Inport" event="mouse_release" target="../bouncing">
                         <parameter name="x" />
                         <parameter name="y" />
-                        <raise port="ui" event="set_element_color">
+                        <raise port="Outport" event="set_element_color">
                             <parameter expr="self.canvas_id"/>
                             <parameter expr="self.circle_id"/>
                             <parameter expr="'#f00'"/>
@@ -458,7 +459,7 @@
                     </transition>
                 </state>
                 <state id='selected'>
-                    <transition port="ball_ui" event="mouse_press" target="../dragging" cond="button == ui.MOUSE_BUTTONS.LEFT">
+                    <transition port="Inport" event="mouse_press" target="../dragging" cond="button == ui.MOUSE_BUTTONS.LEFT">
                         <parameter name="x" />
                         <parameter name="y" />
                         <parameter name="button" />
@@ -470,7 +471,7 @@
                         <raise event="delete_ball" scope="narrow" target="'parent'">
                             <parameter expr='self.association_name' />
                         </raise>
-                        <raise port="ui" event="destroy_element">
+                        <raise port="Outport" event="destroy_element">
                             <parameter expr="self.canvas_id" />
                             <parameter expr="self.element_id" />
                         </raise>

+ 3 - 0
tests/10.3) OneBallBouncingBallsTest/config.json

@@ -0,0 +1,3 @@
+{
+    "trace": ["statechart", "external"]
+}

+ 186 - 0
tests/10.3) OneBallBouncingBallsTest/expected_trace.txt

@@ -0,0 +1,186 @@
+0.00 MainApp: exit /running/root/main_behaviour/initializing
+0.00 MainApp: transition (/running/root/main_behaviour/initializing -> /running/root/main_behaviour/running)
+0.00 MainApp: enter /running/root/main_behaviour/running
+0.00 MainApp: exit /running/root/cd_behaviour/waiting
+0.00 MainApp: transition (/running/root/cd_behaviour/waiting -> /running/root/cd_behaviour/creating)
+0.00 MainApp: enter /running/root/cd_behaviour/creating
+0.00 MainApp: exit /running/root/cd_behaviour/creating
+0.00 MainApp: transition (/running/root/cd_behaviour/creating -> /running/root/cd_behaviour/waiting)
+0.00 MainApp: enter /running/root/cd_behaviour/waiting
+0.00 Field: exit /root/waiting
+0.00 Field: transition (/root/waiting -> /root/creating_window)
+0.00 Field: enter /root/creating_window
+0.00 (event name: create_window; port: Outport; parameters: [800, 600, 'BouncingBalls', 'Inport'])
+0.50 Field: exit /root/creating_window
+0.50 Field: transition (/root/creating_window -> /root/creating_canvas)
+0.50 Field: enter /root/creating_canvas
+0.50 (event name: bind_event; port: Outport; parameters: [0, 'WM_DELETE_WINDOW', 'window_close', 'Inport'])
+0.50 (event name: bind_event; port: Outport; parameters: [0, '<Key>', 'key_press', 'Inport'])
+0.50 (event name: create_canvas; port: Outport; parameters: [0, 800, 550, {'background': '#eee'}, 'Inport'])
+1.00 Field: exit /root/creating_canvas
+1.00 Field: transition (/root/creating_canvas -> /root/creating_button)
+1.00 Field: enter /root/creating_button
+1.00 (event name: bind_event; port: Outport; parameters: [1, '<Button-2>', 'right_click', 'Inport'])
+1.00 (event name: bind_event; port: Outport; parameters: [1, '<Motion>', 'mouse_move', 'Inport'])
+1.00 (event name: bind_event; port: Outport; parameters: [1, '<ButtonRelease>', 'mouse_release', 'Inport'])
+1.00 Field: exit /root/creating_button
+1.00 Field: transition (/root/creating_button -> /root/running)
+1.00 Field: enter /root/running
+1.00 Field: enter /root/running/main_behaviour
+1.00 Field: enter /root/running/main_behaviour/running
+1.00 Field: enter /root/running/deleting_behaviour
+1.00 Field: enter /root/running/deleting_behaviour/running
+1.00 Field: enter /root/running/child_behaviour
+1.00 Field: enter /root/running/child_behaviour/listening
+1.00 Field: enter /root/running/deleting_balls_behaviour
+1.00 Field: enter /root/running/deleting_balls_behaviour/listening
+1.00 (event name: create_button; port: Outport; parameters: [0, 'create_new_field', 'Inport'])
+1.50 Button: exit /creating_button
+1.50 Button: transition (/creating_button -> /running)
+1.50 Button: enter /running
+1.50 (event name: bind_event; port: Outport; parameters: [2, '<Button>', 'mouse_click', 'Inport'])
+2.00 Field: exit /root/running/main_behaviour/running
+2.00 Field: transition (/root/running/main_behaviour/running -> /root/running/main_behaviour/creating_ball)
+2.00 Field: enter /root/running/main_behaviour/creating_ball
+2.00 Field: exit /root/running/main_behaviour/creating_ball
+2.00 Field: transition (/root/running/main_behaviour/creating_ball -> /root/running/main_behaviour/running)
+2.00 Field: enter /root/running/main_behaviour/running
+2.00 Ball: exit /main_behaviour/initializing
+2.00 Ball: transition (/main_behaviour/initializing -> /main_behaviour/creating_circle)
+2.00 Ball: enter /main_behaviour/creating_circle
+2.00 (event name: create_circle; port: Outport; parameters: [1, 206, 77, 20.0, {'fill': '#000'}, 'Inport'])
+2.50 Ball: exit /main_behaviour/creating_circle
+2.50 Ball: transition (/main_behaviour/creating_circle -> /main_behaviour/bouncing)
+2.50 Ball: enter /main_behaviour/bouncing
+2.50 (event name: bind_canvas_event; port: Outport; parameters: [1, 1, '<ButtonPress>', 'mouse_press', 'Inport'])
+2.50 (event name: bind_canvas_event; port: Outport; parameters: [1, 1, '<Motion>', 'mouse_move', 'Inport'])
+2.50 (event name: bind_canvas_event; port: Outport; parameters: [1, 1, '<ButtonRelease>', 'mouse_release', 'Inport'])
+2.52 Ball: exit /main_behaviour/bouncing
+2.52 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.52 Ball: enter /main_behaviour/bouncing
+2.52 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.54 Ball: exit /main_behaviour/bouncing
+2.54 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.54 Ball: enter /main_behaviour/bouncing
+2.54 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.56 Ball: exit /main_behaviour/bouncing
+2.56 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.56 Ball: enter /main_behaviour/bouncing
+2.56 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.58 Ball: exit /main_behaviour/bouncing
+2.58 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.58 Ball: enter /main_behaviour/bouncing
+2.58 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.60 Ball: exit /main_behaviour/bouncing
+2.60 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.60 Ball: enter /main_behaviour/bouncing
+2.60 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.62 Ball: exit /main_behaviour/bouncing
+2.62 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.62 Ball: enter /main_behaviour/bouncing
+2.62 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.64 Ball: exit /main_behaviour/bouncing
+2.64 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.64 Ball: enter /main_behaviour/bouncing
+2.64 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.66 Ball: exit /main_behaviour/bouncing
+2.66 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.66 Ball: enter /main_behaviour/bouncing
+2.66 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.68 Ball: exit /main_behaviour/bouncing
+2.68 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.68 Ball: enter /main_behaviour/bouncing
+2.68 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.70 Ball: exit /main_behaviour/bouncing
+2.70 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.70 Ball: enter /main_behaviour/bouncing
+2.70 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.72 Ball: exit /main_behaviour/bouncing
+2.72 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.72 Ball: enter /main_behaviour/bouncing
+2.72 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.74 Ball: exit /main_behaviour/bouncing
+2.74 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.74 Ball: enter /main_behaviour/bouncing
+2.74 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.76 Ball: exit /main_behaviour/bouncing
+2.76 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.76 Ball: enter /main_behaviour/bouncing
+2.76 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.78 Ball: exit /main_behaviour/bouncing
+2.78 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.78 Ball: enter /main_behaviour/bouncing
+2.78 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.80 Ball: exit /main_behaviour/bouncing
+2.80 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.80 Ball: enter /main_behaviour/bouncing
+2.80 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.82 Ball: exit /main_behaviour/bouncing
+2.82 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.82 Ball: enter /main_behaviour/bouncing
+2.82 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.84 Ball: exit /main_behaviour/bouncing
+2.84 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.84 Ball: enter /main_behaviour/bouncing
+2.84 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.86 Ball: exit /main_behaviour/bouncing
+2.86 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.86 Ball: enter /main_behaviour/bouncing
+2.86 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.88 Ball: exit /main_behaviour/bouncing
+2.88 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.88 Ball: enter /main_behaviour/bouncing
+2.88 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.90 Ball: exit /main_behaviour/bouncing
+2.90 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.90 Ball: enter /main_behaviour/bouncing
+2.90 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.92 Ball: exit /main_behaviour/bouncing
+2.92 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.92 Ball: enter /main_behaviour/bouncing
+2.92 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.94 Ball: exit /main_behaviour/bouncing
+2.94 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.94 Ball: enter /main_behaviour/bouncing
+2.94 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.96 Ball: exit /main_behaviour/bouncing
+2.96 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.96 Ball: enter /main_behaviour/bouncing
+2.96 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.98 Ball: exit /main_behaviour/bouncing
+2.98 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.98 Ball: enter /main_behaviour/bouncing
+2.98 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.00 Ball: exit /main_behaviour/bouncing
+3.00 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.00 Ball: enter /main_behaviour/bouncing
+3.00 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.00 Field: exit /root/running/deleting_balls_behaviour/listening
+3.00 Field: exit /root/running/child_behaviour/listening
+3.00 Field: exit /root/running/deleting_behaviour/running
+3.00 Field: exit /root/running/main_behaviour/running
+3.00 Field: exit /root/running/deleting_balls_behaviour
+3.00 Field: exit /root/running/child_behaviour
+3.00 Field: exit /root/running/deleting_behaviour
+3.00 Field: exit /root/running/main_behaviour
+3.00 Field: exit /root/running
+3.00 Field: transition (/root/running -> /root/deleting)
+3.00 Field: enter /root/deleting
+3.00 Field: exit /root/deleting
+3.00 Field: transition (/root/deleting -> /root/deleted)
+3.00 Field: enter /root/deleted
+3.00 (event name: destroy_window; port: Outport; parameters: [0])
+3.00 MainApp: exit /running/root/cd_behaviour/waiting
+3.00 MainApp: transition (/running/root/cd_behaviour/waiting -> /running/root/cd_behaviour/check_nr_of_fields)
+3.00 MainApp: enter /running/root/cd_behaviour/check_nr_of_fields
+3.05 MainApp: exit /running/root/cd_behaviour/check_nr_of_fields
+3.05 MainApp: transition (/running/root/cd_behaviour/check_nr_of_fields -> /running/root/cd_behaviour/stopped)
+3.05 MainApp: enter /running/root/cd_behaviour/stopped
+3.05 MainApp: exit /running/root/cd_behaviour/stopped
+3.05 MainApp: exit /running/root/main_behaviour/running
+3.05 MainApp: exit /running/root/cd_behaviour
+3.05 MainApp: exit /running/root/main_behaviour
+3.05 MainApp: exit /running/root
+3.05 MainApp: transition (/running/root -> /running/stopped)
+3.05 MainApp: enter /running/stopped
+3.05 (event name: destroy_all; port: Outport)

+ 6 - 0
tests/10.3) OneBallBouncingBallsTest/input.txt

@@ -0,0 +1,6 @@
+0.5 (event name: window_created; port: Inport; parameters: [0])
+1.0 (event name: canvas_created; port: Inport; parameters: [1])
+1.5 (event name: button_created; port: Inport; parameters: [2])
+2.0 (event name: right_click; port: Inport; parameters: [206, 77, 2])
+2.5 (event name: circle_created; port: Inport; parameters: [1, 1])
+3.0 (event name: window_close; port: Inport; parameters: None)

+ 484 - 0
tests/10.3) OneBallBouncingBallsTest/sccd.xml

@@ -0,0 +1,484 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="Bouncing_Balls_DEVS_Version">
+    <description>
+        Tkinter frame with bouncing balls in it.
+    </description>
+    <top>
+        from sccd.runtime.libs import ui_v2 as ui
+        import random
+
+        CANVAS_DIMS = (800, 550)
+    </top>
+    <inport name="Inport"/>
+    <outport name="Outport" />
+    <class name="MainApp" default="true">
+        <relationships>
+            <association name="fields" class="Field" />
+        </relationships>
+        <constructor>
+            <body>
+                self.nr_of_fields = 0
+            </body>
+        </constructor>
+        <scxml initial="running">
+            <state id="running" initial="root">
+                <parallel id="root">
+                    <state id="main_behaviour" initial="initializing">
+                        <state id="initializing">
+                            <transition target="../running">
+                                <raise event="create_field" />        
+                            </transition>
+                        </state>
+                        <state id="running">
+                            <transition target='.' event='button_pressed' cond='event_name == "create_new_field"'>
+                                <parameter name="event_name" type="str" />
+                                <raise event="create_field" />
+                            </transition>
+                        </state>
+                    </state>
+                    <state id="cd_behaviour" initial="waiting">
+                        <state id="waiting">
+                            <transition event="create_field" target="../creating">
+                                <raise scope="cd" event="create_instance">
+                                    <parameter expr='"fields"' />
+                                </raise>
+                            </transition>
+                            <transition event="delete_field" target='../check_nr_of_fields'>
+                                <parameter name="association_name" type="str"/>
+                                <raise scope="cd" event="delete_instance">
+                                    <parameter expr='association_name' />
+                                </raise>
+                                <script>
+                                    self.nr_of_fields -= 1
+                                </script>
+                            </transition>
+                        </state>
+                        <state id="creating">
+                            <transition event="instance_created" target="../waiting">
+                                <parameter name="association_name" type="string"/>
+                                <raise scope="cd" event="start_instance">
+                                    <parameter expr="association_name" />
+                                </raise>
+                                <raise scope="narrow" event="set_association_name" target="association_name">
+                                    <parameter expr="association_name" />
+                                </raise>
+                                <script>
+                                    self.nr_of_fields += 1
+                                </script>
+                            </transition>
+                        </state>
+                        <state id="check_nr_of_fields">
+                            <transition target="../stopped" cond="self.nr_of_fields == 0" after="0.05">
+                                <raise event="stop" />
+                            </transition>
+                            <transition target="../waiting" cond="self.nr_of_fields != 0"/>
+                        </state>
+                        <state id="stopped" />
+                    </state>
+                    <transition target="../stopped" event="stop">
+                        <raise port="Outport" event="destroy_all"/>
+                    </transition>
+                </parallel>
+                <state id="stopped" />
+            </state>
+        </scxml>
+    </class>
+
+    <class name="Field">
+        <attribute name="window_id" />
+        <attribute name="canvas_id" />
+        <inport name="field_ui"/>
+        <relationships>
+            <association name="balls" class="Ball" />
+            <association name="buttons" class="Button" />
+            <association name="parent" class="MainApp" min="1" max="1" />
+        </relationships>
+        <scxml initial="root">
+            <state id="root" initial="waiting">
+                <state id="waiting">
+                    <transition event="set_association_name" target="../creating_window">
+                        <parameter name="association_name" type="str" />
+                        <script>
+                            self.association_name = association_name
+                        </script>
+                    </transition>
+                </state>
+                <state id="creating_window">
+                    <onentry>
+                        <raise port="Outport" event="create_window">
+                            <parameter expr="800"/>                     <!-- width -->
+                            <parameter expr="600"/>                     <!-- height -->
+                            <parameter expr='"BouncingBalls"'/>         <!-- title -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
+                        </raise>
+                    </onentry>
+                    <transition event="window_created" target="../creating_canvas">
+                        <parameter name="window_id" type="int" />
+                        <script>
+                            self.window_id = window_id
+                        </script>
+                        <raise port="Outport" event="bind_event">
+                            <parameter expr="window_id"/>               <!-- widget_id -->
+                            <parameter expr="ui.EVENTS.WINDOW_CLOSE"/>  <!-- tk_event -->
+                            <parameter expr="'window_close'"/>          <!-- sccd_event_name -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
+                        </raise>
+                        <raise port="Outport" event="bind_event">
+                            <parameter expr="window_id"/>               <!-- widget_id -->
+                            <parameter expr="ui.EVENTS.KEY_PRESS"/>     <!-- tk_event -->
+                            <parameter expr="'key_press'"/>             <!-- sccd_event_name -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
+                        </raise>
+                    </transition>
+                </state>
+                <state id="creating_canvas">
+                    <onentry>
+                        <raise port="Outport" event="create_canvas">
+                            <parameter expr="self.window_id"/>          <!-- window_id -->
+                            <parameter expr="CANVAS_DIMS[0]"/>          <!-- width -->
+                            <parameter expr="CANVAS_DIMS[1]"/>          <!-- height -->
+                            <parameter expr="{'background':'#eee'}"/>   <!-- style -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
+                        </raise>
+                    </onentry>
+                    <transition event="canvas_created" target="../creating_button">
+                        <parameter name="canvas_id" type="int"/>
+                        <script>
+                            self.canvas_id = canvas_id
+                        </script>
+                        <raise port="Outport" event="bind_event">
+                            <parameter expr="canvas_id"/>                   <!-- widget_id -->
+                            <parameter expr="ui.EVENTS.MOUSE_RIGHT_CLICK"/> <!-- tk_event -->
+                            <parameter expr="'right_click'"/>               <!-- sccd_event_name -->
+                            <parameter expr='"Inport"'/>    <!-- inport for response -->
+                        </raise>
+                        <raise port="Outport" event="bind_event">
+                            <parameter expr="canvas_id"/>                   <!-- widget_id -->
+                            <parameter expr="ui.EVENTS.MOUSE_MOVE"/>        <!-- tk_event -->
+                            <parameter expr="'mouse_move'"/>                <!-- sccd_event_name -->
+                            <parameter expr='"Inport"'/>    <!-- inport for response -->
+                        </raise>
+                        <raise port="Outport" event="bind_event">
+                            <parameter expr="canvas_id"/><!-- widget_id -->
+                            <parameter expr="ui.EVENTS.MOUSE_RELEASE"/><!-- tk_event -->
+                            <parameter expr="'mouse_release'"/><!-- sccd_event_name -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
+                        </raise>
+                    </transition>
+                </state>
+                <state id="creating_button">
+                    <onentry>
+                        <raise scope="cd" event="create_instance">
+                            <parameter expr='"buttons"' />
+                            <parameter expr='"Button"' />
+                            <parameter expr="self.window_id" />
+                            <parameter expr="'create_new_field'" />
+                            <parameter expr="'Spawn New Window'" />
+                        </raise>
+                    </onentry>
+                    <transition event='instance_created' target='../running'>
+                        <parameter name="association_name" type="string"/>
+                        <raise scope="cd" event="start_instance">
+                            <parameter expr="association_name" />
+                        </raise>
+                    </transition>
+                </state>
+                 <parallel id="running">
+                    <transition port="Inport" event="window_close" target="../deleting">
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr='"buttons"' />
+                        </raise>
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr='"balls"' />
+                        </raise>
+                    </transition>
+                    <state id="main_behaviour" initial="running">
+                        <state id="running">
+                            <transition port="Inport" event="right_click" target="../creating_ball">
+                                <parameter name="x" />
+                                <parameter name="y" />
+                                <parameter name="button" />
+                                <raise scope="cd" event="create_instance">
+                                    <parameter expr='"balls"' />
+                                    <parameter expr='"Ball"' />
+                                    <parameter expr="self.canvas_id" />
+                                    <parameter expr="x" />
+                                    <parameter expr="y" />
+                                </raise>
+                            </transition>
+                        </state>
+                        <state id="creating_ball">
+                            <transition event="instance_created" target="../running">
+                                <parameter name="association_name" type="string"/>
+                                <raise scope="cd" event="start_instance">
+                                    <parameter expr="association_name" />
+                                </raise>
+                                <raise scope="narrow" event="set_association_name" target="association_name">
+                                    <parameter expr="association_name" />
+                                </raise>
+                            </transition>
+                        </state>
+                    </state>
+                    <state id="deleting_behaviour" initial="running">
+                        <state id="running">
+                            <transition event="delete_ball" target='.'>
+                                <parameter name="association_name" type="str"/>
+                                <raise scope="cd" event="delete_instance">
+                                    <parameter expr='association_name' />
+                                </raise>
+                            </transition>
+                        </state>
+                    </state>
+                    <state id="child_behaviour" initial="listening">
+                        <state id="listening">
+                            <transition event="button_pressed" target='.'>
+                                <parameter name="event_name" type="str" />
+                                <raise event="button_pressed" scope="narrow" target="'parent'">
+                                    <parameter expr='event_name' />
+                                </raise>
+                            </transition>
+                        </state>
+                    </state>
+                    <state id="deleting_balls_behaviour" initial="listening">
+                        <state id="listening">
+                            <transition port="Inport" event="key_press" target="." cond="key == ui.KEYCODES.DELETE">
+                                <parameter name="key" />
+                                <raise event="delete_self" scope="narrow" target="'balls'" />
+                            </transition>
+                        </state>
+                    </state>
+                </parallel>
+                <state id="deleting">
+                    <transition target="../deleted">
+                        <raise event="delete_field" scope="narrow" target="'parent'">
+                            <parameter expr='self.association_name' />
+                        </raise>
+                        <raise port="Outport" event="destroy_window">
+                            <parameter expr="self.window_id"/><!-- window to destroy -->
+                        </raise>
+                    </transition>
+                </state>
+                <state id="deleted" />
+            </state>
+        </scxml>
+    </class>
+    
+    <class name="Button">
+        <attribute name="window_id" />
+        <attribute name="event_name" />
+        <attribute name="button_id" />
+        <relationships>
+            <association name="parent" class="Field" min="1" max="1" />
+        </relationships>
+        <inport name="button_ui"/>
+        <constructor>
+            <parameter name="window_id" type="int" />
+            <parameter name="event_name" type="str" />
+            <parameter name="button_text" type="str" />
+            <body>
+                self.window_id = window_id;
+                self.event_name = event_name;
+            </body>
+        </constructor>
+        <scxml initial="creating_button">
+            <state id="creating_button">
+                <onentry>
+                    <raise port="Outport" event="create_button">
+                        <parameter expr="self.window_id"/><!-- window_id -->
+                        <parameter expr="self.event_name"/><!-- text -->
+                        <parameter expr="'Inport'"/><!-- inport for response -->
+                    </raise>
+                </onentry>
+                <transition event="button_created" target="../running">
+                    <parameter name="button_id" type="int"/>
+                    <script>
+                        self.button_id = button_id
+                    </script>
+                    <raise port="Outport" event="bind_event">
+                        <parameter expr="button_id"/><!-- widget_id -->
+                        <parameter expr="ui.EVENTS.MOUSE_CLICK"/><!-- tk_event -->
+                        <parameter expr='"mouse_click"'/><!-- sccd_event_name -->
+                        <parameter expr="'Inport'"/><!-- inport for response -->
+                    </raise>
+                </transition>
+            </state>
+             <state id="running">
+                <transition port='Inport' event="mouse_click" target='.' cond="button == ui.MOUSE_BUTTONS.LEFT">
+                    <parameter name="x" />
+                    <parameter name="y" />
+                    <parameter name="button" />
+                    <raise event="button_pressed" scope="narrow" target="'parent'">
+                        <parameter expr="self.event_name" />
+                    </raise>
+                </transition>
+            </state>
+        </scxml>
+    </class>
+    
+    <class name="Ball">
+        <attribute name="canvas_id" />
+        <atrribute name="circle_id" />
+        <attribute name="pos" />
+        <inport name="ball_ui" />
+        <relationships>
+            <association name="parent" class="Field" min="1" max="1" />
+        </relationships>
+        <constructor>
+            <parameter name="canvas_id" />
+            <parameter name="x" />
+            <parameter name="y" />
+            <body>
+                self.canvas_id = canvas_id;
+                self.r = 20.0;
+                self.vel = {'x': 1, 'y': 1};
+                self.pos = {'x': x, 'y': y};
+                self.smooth = 0.6; # value between 0 and 1
+            </body>
+        </constructor>
+        <destructor>
+        </destructor>
+        <scxml initial="main_behaviour">
+            <state id="main_behaviour" initial="initializing">
+                <state id="initializing">
+                    <transition event="set_association_name" target="../creating_circle">
+                        <parameter name="association_name" type="str" />
+                        <script>
+                            self.association_name = association_name
+                        </script>
+                    </transition>
+                </state>
+                <state id="creating_circle">
+                    <onentry>
+                        <raise port="Outport" event="create_circle">
+                            <parameter expr="self.canvas_id"/><!-- canvas_id -->
+                            <parameter expr="self.pos['x']"/><!-- x -->
+                            <parameter expr="self.pos['y']"/><!-- y -->
+                            <parameter expr="self.r"/><!-- r -->
+                            <parameter expr="{'fill':'#000'}"/><!-- style -->
+                            <parameter expr="'Inport'"/><!-- inport for response -->
+                        </raise>
+                    </onentry>
+                    <transition event="circle_created" target="../bouncing">
+                        <parameter name="canvas_id"/>
+                        <parameter name="circle_id"/>
+                        <script>
+                            self.circle_id = circle_id
+                        </script>
+                        <raise port="Outport" event="bind_canvas_event">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="circle_id"/>
+                            <parameter expr="ui.EVENTS.MOUSE_PRESS"/>
+                            <parameter expr="'mouse_press'"/>
+                            <parameter expr="'Inport'"/>
+                        </raise>
+                        <raise port="Outport" event="bind_canvas_event">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="circle_id"/>
+                            <parameter expr="ui.EVENTS.MOUSE_MOVE"/>
+                            <parameter expr="'mouse_move'"/>
+                            <parameter expr="'Inport'"/>
+                        </raise>
+                        <raise port="Outport" event="bind_canvas_event">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="circle_id"/>
+                            <parameter expr="ui.EVENTS.MOUSE_RELEASE"/>
+                            <parameter expr="'mouse_release'"/>
+                            <parameter expr="'Inport'"/>
+                        </raise>
+                    </transition>
+                </state>
+                <state id="bouncing">
+                    <!-- <transition after="(20 - self.getSimulatedTime() % 20) / 1000.0" target="."> -->
+                    <transition after="0.02" target=".">
+                        <script>
+                            <![CDATA[
+                            # Invert velocity when colliding with canvas border:
+                            if self.pos['x']-self.r <= 0 or self.pos['x']+self.r >= CANVAS_DIMS[0]:
+                                self.vel['x'] = -self.vel['x'];
+                            if self.pos['y']-self.r <= 0 or self.pos['y']+self.r >= CANVAS_DIMS[1]:
+                                self.vel['y'] = -self.vel['y'];
+                            ]]>
+                        </script>
+                        <raise port="Outport" event="move_element">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="self.circle_id"/>
+                            <parameter expr="self.vel['x']"/>
+                            <parameter expr="self.vel['y']"/>
+                        </raise>
+                        <script>
+                            self.pos['x'] += self.vel['x']
+                            self.pos['y'] += self.vel['y']
+                        </script>
+                    </transition>
+                    <transition port="Inport" event="mouse_press" target="../selected" cond="button == ui.MOUSE_BUTTONS.LEFT">
+                        <parameter name="x" />
+                        <parameter name="y" />
+                        <parameter name="button" />
+                        <raise port="Outport" event="set_element_color">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="self.circle_id"/>
+                            <parameter expr="'#ff0'"/>
+                        </raise>
+                    </transition>
+                </state>
+                <state id="dragging">
+                    <transition port="Inport" event="mouse_move" target=".">
+                        <parameter name="x" />
+                        <parameter name="y" />
+                        <parameter name="button" />
+                        <script>
+                            # Always keep ball within canvas:
+                            x = min(max(0+self.r, x), CANVAS_DIMS[0]-self.r)
+                            y = min(max(0+self.r, y), CANVAS_DIMS[1]-self.r)
+
+                            dx = x - self.pos['x']
+                            dy = y - self.pos['y']
+
+                            self.vel = {
+                                'x': (1-self.smooth)*dx + self.smooth*self.vel['x'],
+                                'y': (1-self.smooth)*dy + self.smooth*self.vel['y']
+                            }
+                            
+                            self.pos = {'x': x, 'y': y}
+                        </script>
+                        <raise port="Outport" event="set_element_pos">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="self.circle_id"/>
+                            <parameter expr="x-self.r"/>
+                            <parameter expr="y-self.r"/>
+                        </raise>
+                    </transition>
+                    <transition port="Inport" event="mouse_release" target="../bouncing">
+                        <parameter name="x" />
+                        <parameter name="y" />
+                        <raise port="Outport" event="set_element_color">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="self.circle_id"/>
+                            <parameter expr="'#f00'"/>
+                        </raise>
+                    </transition>
+                </state>
+                <state id='selected'>
+                    <transition port="Inport" event="mouse_press" target="../dragging" cond="button == ui.MOUSE_BUTTONS.LEFT">
+                        <parameter name="x" />
+                        <parameter name="y" />
+                        <parameter name="button" />
+                        <script>
+                            self.mouse_pos = {'x':x, 'y':y};
+                        </script>
+                    </transition>
+                    <transition event="delete_self" target='../../deleted'>                    
+                        <raise event="delete_ball" scope="narrow" target="'parent'">
+                            <parameter expr='self.association_name' />
+                        </raise>
+                        <raise port="Outport" event="destroy_element">
+                            <parameter expr="self.canvas_id" />
+                            <parameter expr="self.element_id" />
+                        </raise>
+                    </transition>
+                </state>
+            </state>
+            <state id='deleted' />
+        </scxml>
+    </class>
+</diagram>

+ 3 - 0
tests/10.4) CreateExtraFieldBouncingBallsTest/config.json

@@ -0,0 +1,3 @@
+{
+    "trace": ["statechart", "external"]
+}

+ 597 - 0
tests/10.4) CreateExtraFieldBouncingBallsTest/expected_trace.txt

@@ -0,0 +1,597 @@
+0.00 MainApp: exit /running/root/main_behaviour/initializing
+0.00 MainApp: transition (/running/root/main_behaviour/initializing -> /running/root/main_behaviour/running)
+0.00 MainApp: enter /running/root/main_behaviour/running
+0.00 MainApp: exit /running/root/cd_behaviour/waiting
+0.00 MainApp: transition (/running/root/cd_behaviour/waiting -> /running/root/cd_behaviour/creating)
+0.00 MainApp: enter /running/root/cd_behaviour/creating
+0.00 MainApp: exit /running/root/cd_behaviour/creating
+0.00 MainApp: transition (/running/root/cd_behaviour/creating -> /running/root/cd_behaviour/waiting)
+0.00 MainApp: enter /running/root/cd_behaviour/waiting
+0.00 Field: exit /root/waiting
+0.00 Field: transition (/root/waiting -> /root/creating_window)
+0.00 Field: enter /root/creating_window
+0.00 (event name: create_window; port: Outport; parameters: [800, 600, 'BouncingBalls', 'Inport'])
+0.50 Field: exit /root/creating_window
+0.50 Field: transition (/root/creating_window -> /root/creating_canvas)
+0.50 Field: enter /root/creating_canvas
+0.50 (event name: bind_event; port: Outport; parameters: [0, 'WM_DELETE_WINDOW', 'window_close', 'Inport'])
+0.50 (event name: bind_event; port: Outport; parameters: [0, '<Key>', 'key_press', 'Inport'])
+0.50 (event name: create_canvas; port: Outport; parameters: [0, 800, 550, {'background': '#eee'}, 'Inport'])
+1.00 Field: exit /root/creating_canvas
+1.00 Field: transition (/root/creating_canvas -> /root/creating_button)
+1.00 Field: enter /root/creating_button
+1.00 (event name: bind_event; port: Outport; parameters: [1, '<Button-2>', 'right_click', 'Inport'])
+1.00 (event name: bind_event; port: Outport; parameters: [1, '<Motion>', 'mouse_move', 'Inport'])
+1.00 (event name: bind_event; port: Outport; parameters: [1, '<ButtonRelease>', 'mouse_release', 'Inport'])
+1.00 Field: exit /root/creating_button
+1.00 Field: transition (/root/creating_button -> /root/running)
+1.00 Field: enter /root/running
+1.00 Field: enter /root/running/main_behaviour
+1.00 Field: enter /root/running/main_behaviour/running
+1.00 Field: enter /root/running/deleting_behaviour
+1.00 Field: enter /root/running/deleting_behaviour/running
+1.00 Field: enter /root/running/child_behaviour
+1.00 Field: enter /root/running/child_behaviour/listening
+1.00 Field: enter /root/running/deleting_balls_behaviour
+1.00 Field: enter /root/running/deleting_balls_behaviour/listening
+1.00 (event name: create_button; port: Outport; parameters: [0, 'create_new_field', 'Inport'])
+1.50 Button: exit /creating_button
+1.50 Button: transition (/creating_button -> /running)
+1.50 Button: enter /running
+1.50 (event name: bind_event; port: Outport; parameters: [2, '<Button>', 'mouse_click', 'Inport'])
+2.00 Field: exit /root/running/main_behaviour/running
+2.00 Field: transition (/root/running/main_behaviour/running -> /root/running/main_behaviour/creating_ball)
+2.00 Field: enter /root/running/main_behaviour/creating_ball
+2.00 Field: exit /root/running/main_behaviour/creating_ball
+2.00 Field: transition (/root/running/main_behaviour/creating_ball -> /root/running/main_behaviour/running)
+2.00 Field: enter /root/running/main_behaviour/running
+2.00 Ball: exit /main_behaviour/initializing
+2.00 Ball: transition (/main_behaviour/initializing -> /main_behaviour/creating_circle)
+2.00 Ball: enter /main_behaviour/creating_circle
+2.00 (event name: create_circle; port: Outport; parameters: [1, 206, 77, 20.0, {'fill': '#000'}, 'Inport'])
+2.50 Ball: exit /main_behaviour/creating_circle
+2.50 Ball: transition (/main_behaviour/creating_circle -> /main_behaviour/bouncing)
+2.50 Ball: enter /main_behaviour/bouncing
+2.50 (event name: bind_canvas_event; port: Outport; parameters: [1, 1, '<ButtonPress>', 'mouse_press', 'Inport'])
+2.50 (event name: bind_canvas_event; port: Outport; parameters: [1, 1, '<Motion>', 'mouse_move', 'Inport'])
+2.50 (event name: bind_canvas_event; port: Outport; parameters: [1, 1, '<ButtonRelease>', 'mouse_release', 'Inport'])
+2.52 Ball: exit /main_behaviour/bouncing
+2.52 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.52 Ball: enter /main_behaviour/bouncing
+2.52 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.54 Ball: exit /main_behaviour/bouncing
+2.54 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.54 Ball: enter /main_behaviour/bouncing
+2.54 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.56 Ball: exit /main_behaviour/bouncing
+2.56 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.56 Ball: enter /main_behaviour/bouncing
+2.56 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.58 Ball: exit /main_behaviour/bouncing
+2.58 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.58 Ball: enter /main_behaviour/bouncing
+2.58 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.60 Ball: exit /main_behaviour/bouncing
+2.60 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.60 Ball: enter /main_behaviour/bouncing
+2.60 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.62 Ball: exit /main_behaviour/bouncing
+2.62 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.62 Ball: enter /main_behaviour/bouncing
+2.62 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.64 Ball: exit /main_behaviour/bouncing
+2.64 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.64 Ball: enter /main_behaviour/bouncing
+2.64 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.66 Ball: exit /main_behaviour/bouncing
+2.66 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.66 Ball: enter /main_behaviour/bouncing
+2.66 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.68 Ball: exit /main_behaviour/bouncing
+2.68 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.68 Ball: enter /main_behaviour/bouncing
+2.68 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.70 Ball: exit /main_behaviour/bouncing
+2.70 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.70 Ball: enter /main_behaviour/bouncing
+2.70 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.72 Ball: exit /main_behaviour/bouncing
+2.72 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.72 Ball: enter /main_behaviour/bouncing
+2.72 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.74 Ball: exit /main_behaviour/bouncing
+2.74 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.74 Ball: enter /main_behaviour/bouncing
+2.74 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.76 Ball: exit /main_behaviour/bouncing
+2.76 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.76 Ball: enter /main_behaviour/bouncing
+2.76 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.78 Ball: exit /main_behaviour/bouncing
+2.78 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.78 Ball: enter /main_behaviour/bouncing
+2.78 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.80 Ball: exit /main_behaviour/bouncing
+2.80 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.80 Ball: enter /main_behaviour/bouncing
+2.80 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.82 Ball: exit /main_behaviour/bouncing
+2.82 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.82 Ball: enter /main_behaviour/bouncing
+2.82 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.84 Ball: exit /main_behaviour/bouncing
+2.84 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.84 Ball: enter /main_behaviour/bouncing
+2.84 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.86 Ball: exit /main_behaviour/bouncing
+2.86 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.86 Ball: enter /main_behaviour/bouncing
+2.86 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.88 Ball: exit /main_behaviour/bouncing
+2.88 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.88 Ball: enter /main_behaviour/bouncing
+2.88 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.90 Ball: exit /main_behaviour/bouncing
+2.90 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.90 Ball: enter /main_behaviour/bouncing
+2.90 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.92 Ball: exit /main_behaviour/bouncing
+2.92 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.92 Ball: enter /main_behaviour/bouncing
+2.92 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.94 Ball: exit /main_behaviour/bouncing
+2.94 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.94 Ball: enter /main_behaviour/bouncing
+2.94 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.96 Ball: exit /main_behaviour/bouncing
+2.96 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.96 Ball: enter /main_behaviour/bouncing
+2.96 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+2.98 Ball: exit /main_behaviour/bouncing
+2.98 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+2.98 Ball: enter /main_behaviour/bouncing
+2.98 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.00 Ball: exit /main_behaviour/bouncing
+3.00 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.00 Ball: enter /main_behaviour/bouncing
+3.00 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.00 Button: exit /running
+3.00 Button: transition (/running -> /running)
+3.00 Button: enter /running
+3.00 Field: exit /root/running/child_behaviour/listening
+3.00 Field: transition (/root/running/child_behaviour/listening -> /root/running/child_behaviour/listening)
+3.00 Field: enter /root/running/child_behaviour/listening
+3.00 MainApp: exit /running/root/main_behaviour/running
+3.00 MainApp: transition (/running/root/main_behaviour/running -> /running/root/main_behaviour/running)
+3.00 MainApp: enter /running/root/main_behaviour/running
+3.00 MainApp: exit /running/root/cd_behaviour/waiting
+3.00 MainApp: transition (/running/root/cd_behaviour/waiting -> /running/root/cd_behaviour/creating)
+3.00 MainApp: enter /running/root/cd_behaviour/creating
+3.00 MainApp: exit /running/root/cd_behaviour/creating
+3.00 MainApp: transition (/running/root/cd_behaviour/creating -> /running/root/cd_behaviour/waiting)
+3.00 MainApp: enter /running/root/cd_behaviour/waiting
+3.00 Field: exit /root/waiting
+3.00 Field: transition (/root/waiting -> /root/creating_window)
+3.00 Field: enter /root/creating_window
+3.00 (event name: create_window; port: Outport; parameters: [800, 600, 'BouncingBalls', 'Inport'])
+3.02 Ball: exit /main_behaviour/bouncing
+3.02 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.02 Ball: enter /main_behaviour/bouncing
+3.02 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.04 Ball: exit /main_behaviour/bouncing
+3.04 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.04 Ball: enter /main_behaviour/bouncing
+3.04 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.06 Ball: exit /main_behaviour/bouncing
+3.06 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.06 Ball: enter /main_behaviour/bouncing
+3.06 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.08 Ball: exit /main_behaviour/bouncing
+3.08 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.08 Ball: enter /main_behaviour/bouncing
+3.08 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.10 Ball: exit /main_behaviour/bouncing
+3.10 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.10 Ball: enter /main_behaviour/bouncing
+3.10 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.12 Ball: exit /main_behaviour/bouncing
+3.12 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.12 Ball: enter /main_behaviour/bouncing
+3.12 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.14 Ball: exit /main_behaviour/bouncing
+3.14 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.14 Ball: enter /main_behaviour/bouncing
+3.14 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.16 Ball: exit /main_behaviour/bouncing
+3.16 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.16 Ball: enter /main_behaviour/bouncing
+3.16 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.18 Ball: exit /main_behaviour/bouncing
+3.18 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.18 Ball: enter /main_behaviour/bouncing
+3.18 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.20 Ball: exit /main_behaviour/bouncing
+3.20 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.20 Ball: enter /main_behaviour/bouncing
+3.20 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.22 Ball: exit /main_behaviour/bouncing
+3.22 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.22 Ball: enter /main_behaviour/bouncing
+3.22 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.24 Ball: exit /main_behaviour/bouncing
+3.24 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.24 Ball: enter /main_behaviour/bouncing
+3.24 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.26 Ball: exit /main_behaviour/bouncing
+3.26 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.26 Ball: enter /main_behaviour/bouncing
+3.26 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.28 Ball: exit /main_behaviour/bouncing
+3.28 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.28 Ball: enter /main_behaviour/bouncing
+3.28 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.30 Ball: exit /main_behaviour/bouncing
+3.30 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.30 Ball: enter /main_behaviour/bouncing
+3.30 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.32 Ball: exit /main_behaviour/bouncing
+3.32 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.32 Ball: enter /main_behaviour/bouncing
+3.32 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.34 Ball: exit /main_behaviour/bouncing
+3.34 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.34 Ball: enter /main_behaviour/bouncing
+3.34 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.36 Ball: exit /main_behaviour/bouncing
+3.36 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.36 Ball: enter /main_behaviour/bouncing
+3.36 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.38 Ball: exit /main_behaviour/bouncing
+3.38 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.38 Ball: enter /main_behaviour/bouncing
+3.38 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.40 Ball: exit /main_behaviour/bouncing
+3.40 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.40 Ball: enter /main_behaviour/bouncing
+3.40 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.42 Ball: exit /main_behaviour/bouncing
+3.42 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.42 Ball: enter /main_behaviour/bouncing
+3.42 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.44 Ball: exit /main_behaviour/bouncing
+3.44 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.44 Ball: enter /main_behaviour/bouncing
+3.44 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.46 Ball: exit /main_behaviour/bouncing
+3.46 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.46 Ball: enter /main_behaviour/bouncing
+3.46 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.48 Ball: exit /main_behaviour/bouncing
+3.48 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.48 Ball: enter /main_behaviour/bouncing
+3.48 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.50 Ball: exit /main_behaviour/bouncing
+3.50 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.50 Ball: enter /main_behaviour/bouncing
+3.50 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.52 Ball: exit /main_behaviour/bouncing
+3.52 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.52 Ball: enter /main_behaviour/bouncing
+3.52 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.54 Ball: exit /main_behaviour/bouncing
+3.54 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.54 Ball: enter /main_behaviour/bouncing
+3.54 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.56 Ball: exit /main_behaviour/bouncing
+3.56 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.56 Ball: enter /main_behaviour/bouncing
+3.56 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.58 Ball: exit /main_behaviour/bouncing
+3.58 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.58 Ball: enter /main_behaviour/bouncing
+3.58 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.60 Ball: exit /main_behaviour/bouncing
+3.60 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.60 Ball: enter /main_behaviour/bouncing
+3.60 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.62 Ball: exit /main_behaviour/bouncing
+3.62 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.62 Ball: enter /main_behaviour/bouncing
+3.62 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.64 Ball: exit /main_behaviour/bouncing
+3.64 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.64 Ball: enter /main_behaviour/bouncing
+3.64 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.66 Ball: exit /main_behaviour/bouncing
+3.66 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.66 Ball: enter /main_behaviour/bouncing
+3.66 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.68 Ball: exit /main_behaviour/bouncing
+3.68 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.68 Ball: enter /main_behaviour/bouncing
+3.68 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.70 Ball: exit /main_behaviour/bouncing
+3.70 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.70 Ball: enter /main_behaviour/bouncing
+3.70 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.72 Ball: exit /main_behaviour/bouncing
+3.72 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.72 Ball: enter /main_behaviour/bouncing
+3.72 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.74 Ball: exit /main_behaviour/bouncing
+3.74 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.74 Ball: enter /main_behaviour/bouncing
+3.74 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.76 Ball: exit /main_behaviour/bouncing
+3.76 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.76 Ball: enter /main_behaviour/bouncing
+3.76 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.78 Ball: exit /main_behaviour/bouncing
+3.78 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.78 Ball: enter /main_behaviour/bouncing
+3.78 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.80 Ball: exit /main_behaviour/bouncing
+3.80 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.80 Ball: enter /main_behaviour/bouncing
+3.80 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.82 Ball: exit /main_behaviour/bouncing
+3.82 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.82 Ball: enter /main_behaviour/bouncing
+3.82 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.84 Ball: exit /main_behaviour/bouncing
+3.84 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.84 Ball: enter /main_behaviour/bouncing
+3.84 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.86 Ball: exit /main_behaviour/bouncing
+3.86 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.86 Ball: enter /main_behaviour/bouncing
+3.86 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.88 Ball: exit /main_behaviour/bouncing
+3.88 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.88 Ball: enter /main_behaviour/bouncing
+3.88 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.90 Ball: exit /main_behaviour/bouncing
+3.90 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.90 Ball: enter /main_behaviour/bouncing
+3.90 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.92 Ball: exit /main_behaviour/bouncing
+3.92 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.92 Ball: enter /main_behaviour/bouncing
+3.92 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.94 Ball: exit /main_behaviour/bouncing
+3.94 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.94 Ball: enter /main_behaviour/bouncing
+3.94 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.96 Ball: exit /main_behaviour/bouncing
+3.96 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.96 Ball: enter /main_behaviour/bouncing
+3.96 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+3.98 Ball: exit /main_behaviour/bouncing
+3.98 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+3.98 Ball: enter /main_behaviour/bouncing
+3.98 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.00 Ball: exit /main_behaviour/bouncing
+4.00 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.00 Ball: enter /main_behaviour/bouncing
+4.00 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.02 Ball: exit /main_behaviour/bouncing
+4.02 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.02 Ball: enter /main_behaviour/bouncing
+4.02 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.04 Ball: exit /main_behaviour/bouncing
+4.04 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.04 Ball: enter /main_behaviour/bouncing
+4.04 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.06 Ball: exit /main_behaviour/bouncing
+4.06 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.06 Ball: enter /main_behaviour/bouncing
+4.06 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.08 Ball: exit /main_behaviour/bouncing
+4.08 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.08 Ball: enter /main_behaviour/bouncing
+4.08 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.10 Ball: exit /main_behaviour/bouncing
+4.10 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.10 Ball: enter /main_behaviour/bouncing
+4.10 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.12 Ball: exit /main_behaviour/bouncing
+4.12 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.12 Ball: enter /main_behaviour/bouncing
+4.12 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.14 Ball: exit /main_behaviour/bouncing
+4.14 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.14 Ball: enter /main_behaviour/bouncing
+4.14 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.16 Ball: exit /main_behaviour/bouncing
+4.16 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.16 Ball: enter /main_behaviour/bouncing
+4.16 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.18 Ball: exit /main_behaviour/bouncing
+4.18 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.18 Ball: enter /main_behaviour/bouncing
+4.18 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.20 Ball: exit /main_behaviour/bouncing
+4.20 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.20 Ball: enter /main_behaviour/bouncing
+4.20 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.22 Ball: exit /main_behaviour/bouncing
+4.22 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.22 Ball: enter /main_behaviour/bouncing
+4.22 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.24 Ball: exit /main_behaviour/bouncing
+4.24 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.24 Ball: enter /main_behaviour/bouncing
+4.24 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.26 Ball: exit /main_behaviour/bouncing
+4.26 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.26 Ball: enter /main_behaviour/bouncing
+4.26 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.28 Ball: exit /main_behaviour/bouncing
+4.28 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.28 Ball: enter /main_behaviour/bouncing
+4.28 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.30 Ball: exit /main_behaviour/bouncing
+4.30 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.30 Ball: enter /main_behaviour/bouncing
+4.30 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.32 Ball: exit /main_behaviour/bouncing
+4.32 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.32 Ball: enter /main_behaviour/bouncing
+4.32 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.34 Ball: exit /main_behaviour/bouncing
+4.34 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.34 Ball: enter /main_behaviour/bouncing
+4.34 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.36 Ball: exit /main_behaviour/bouncing
+4.36 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.36 Ball: enter /main_behaviour/bouncing
+4.36 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.38 Ball: exit /main_behaviour/bouncing
+4.38 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.38 Ball: enter /main_behaviour/bouncing
+4.38 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.40 Ball: exit /main_behaviour/bouncing
+4.40 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.40 Ball: enter /main_behaviour/bouncing
+4.40 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.42 Ball: exit /main_behaviour/bouncing
+4.42 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.42 Ball: enter /main_behaviour/bouncing
+4.42 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.44 Ball: exit /main_behaviour/bouncing
+4.44 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.44 Ball: enter /main_behaviour/bouncing
+4.44 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.46 Ball: exit /main_behaviour/bouncing
+4.46 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.46 Ball: enter /main_behaviour/bouncing
+4.46 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.48 Ball: exit /main_behaviour/bouncing
+4.48 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.48 Ball: enter /main_behaviour/bouncing
+4.48 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.50 Ball: exit /main_behaviour/bouncing
+4.50 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.50 Ball: enter /main_behaviour/bouncing
+4.50 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.52 Ball: exit /main_behaviour/bouncing
+4.52 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.52 Ball: enter /main_behaviour/bouncing
+4.52 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.54 Ball: exit /main_behaviour/bouncing
+4.54 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.54 Ball: enter /main_behaviour/bouncing
+4.54 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.56 Ball: exit /main_behaviour/bouncing
+4.56 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.56 Ball: enter /main_behaviour/bouncing
+4.56 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.58 Ball: exit /main_behaviour/bouncing
+4.58 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.58 Ball: enter /main_behaviour/bouncing
+4.58 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.60 Ball: exit /main_behaviour/bouncing
+4.60 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.60 Ball: enter /main_behaviour/bouncing
+4.60 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.62 Ball: exit /main_behaviour/bouncing
+4.62 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.62 Ball: enter /main_behaviour/bouncing
+4.62 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.64 Ball: exit /main_behaviour/bouncing
+4.64 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.64 Ball: enter /main_behaviour/bouncing
+4.64 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.66 Ball: exit /main_behaviour/bouncing
+4.66 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.66 Ball: enter /main_behaviour/bouncing
+4.66 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.68 Ball: exit /main_behaviour/bouncing
+4.68 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.68 Ball: enter /main_behaviour/bouncing
+4.68 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.70 Ball: exit /main_behaviour/bouncing
+4.70 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.70 Ball: enter /main_behaviour/bouncing
+4.70 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.72 Ball: exit /main_behaviour/bouncing
+4.72 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.72 Ball: enter /main_behaviour/bouncing
+4.72 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.74 Ball: exit /main_behaviour/bouncing
+4.74 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.74 Ball: enter /main_behaviour/bouncing
+4.74 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.76 Ball: exit /main_behaviour/bouncing
+4.76 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.76 Ball: enter /main_behaviour/bouncing
+4.76 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.78 Ball: exit /main_behaviour/bouncing
+4.78 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.78 Ball: enter /main_behaviour/bouncing
+4.78 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.80 Ball: exit /main_behaviour/bouncing
+4.80 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.80 Ball: enter /main_behaviour/bouncing
+4.80 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.82 Ball: exit /main_behaviour/bouncing
+4.82 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.82 Ball: enter /main_behaviour/bouncing
+4.82 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.84 Ball: exit /main_behaviour/bouncing
+4.84 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.84 Ball: enter /main_behaviour/bouncing
+4.84 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.86 Ball: exit /main_behaviour/bouncing
+4.86 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.86 Ball: enter /main_behaviour/bouncing
+4.86 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.88 Ball: exit /main_behaviour/bouncing
+4.88 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.88 Ball: enter /main_behaviour/bouncing
+4.88 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.90 Ball: exit /main_behaviour/bouncing
+4.90 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.90 Ball: enter /main_behaviour/bouncing
+4.90 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.92 Ball: exit /main_behaviour/bouncing
+4.92 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.92 Ball: enter /main_behaviour/bouncing
+4.92 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.94 Ball: exit /main_behaviour/bouncing
+4.94 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.94 Ball: enter /main_behaviour/bouncing
+4.94 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.96 Ball: exit /main_behaviour/bouncing
+4.96 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.96 Ball: enter /main_behaviour/bouncing
+4.96 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+4.98 Ball: exit /main_behaviour/bouncing
+4.98 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+4.98 Ball: enter /main_behaviour/bouncing
+4.98 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+5.00 Ball: exit /main_behaviour/bouncing
+5.00 Ball: transition (/main_behaviour/bouncing -> /main_behaviour/bouncing)
+5.00 Ball: enter /main_behaviour/bouncing
+5.00 (event name: move_element; port: Outport; parameters: [1, 1, 1, 1])
+5.00 Field: exit /root/running/deleting_balls_behaviour/listening
+5.00 Field: exit /root/running/child_behaviour/listening
+5.00 Field: exit /root/running/deleting_behaviour/running
+5.00 Field: exit /root/running/main_behaviour/running
+5.00 Field: exit /root/running/deleting_balls_behaviour
+5.00 Field: exit /root/running/child_behaviour
+5.00 Field: exit /root/running/deleting_behaviour
+5.00 Field: exit /root/running/main_behaviour
+5.00 Field: exit /root/running
+5.00 Field: transition (/root/running -> /root/deleting)
+5.00 Field: enter /root/deleting
+5.00 Field: exit /root/deleting
+5.00 Field: transition (/root/deleting -> /root/deleted)
+5.00 Field: enter /root/deleted
+5.00 (event name: destroy_window; port: Outport; parameters: [0])
+5.00 MainApp: exit /running/root/cd_behaviour/waiting
+5.00 MainApp: transition (/running/root/cd_behaviour/waiting -> /running/root/cd_behaviour/check_nr_of_fields)
+5.00 MainApp: enter /running/root/cd_behaviour/check_nr_of_fields
+5.00 MainApp: exit /running/root/cd_behaviour/check_nr_of_fields
+5.00 MainApp: transition (/running/root/cd_behaviour/check_nr_of_fields -> /running/root/cd_behaviour/waiting)
+5.00 MainApp: enter /running/root/cd_behaviour/waiting

+ 7 - 0
tests/10.4) CreateExtraFieldBouncingBallsTest/input.txt

@@ -0,0 +1,7 @@
+0.5 (event name: window_created; port: Inport; parameters: [0])
+1.0 (event name: canvas_created; port: Inport; parameters: [1])
+1.5 (event name: button_created; port: Inport; parameters: [2])
+2.0 (event name: right_click; port: Inport; parameters: [206, 77, 2])
+2.5 (event name: circle_created; port: Inport; parameters: [1, 1])
+3.0 (event name: mouse_click; port: Inport; parameters: [396, 22, 1])
+5.0 (event name: window_close; port: Inport; parameters: None)

+ 484 - 0
tests/10.4) CreateExtraFieldBouncingBallsTest/sccd.xml

@@ -0,0 +1,484 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="Bouncing_Balls_DEVS_Version">
+    <description>
+        Tkinter frame with bouncing balls in it.
+    </description>
+    <top>
+        from sccd.runtime.libs import ui_v2 as ui
+        import random
+
+        CANVAS_DIMS = (800, 550)
+    </top>
+    <inport name="Inport"/>
+    <outport name="Outport" />
+    <class name="MainApp" default="true">
+        <relationships>
+            <association name="fields" class="Field" />
+        </relationships>
+        <constructor>
+            <body>
+                self.nr_of_fields = 0
+            </body>
+        </constructor>
+        <scxml initial="running">
+            <state id="running" initial="root">
+                <parallel id="root">
+                    <state id="main_behaviour" initial="initializing">
+                        <state id="initializing">
+                            <transition target="../running">
+                                <raise event="create_field" />        
+                            </transition>
+                        </state>
+                        <state id="running">
+                            <transition target='.' event='button_pressed' cond='event_name == "create_new_field"'>
+                                <parameter name="event_name" type="str" />
+                                <raise event="create_field" />
+                            </transition>
+                        </state>
+                    </state>
+                    <state id="cd_behaviour" initial="waiting">
+                        <state id="waiting">
+                            <transition event="create_field" target="../creating">
+                                <raise scope="cd" event="create_instance">
+                                    <parameter expr='"fields"' />
+                                </raise>
+                            </transition>
+                            <transition event="delete_field" target='../check_nr_of_fields'>
+                                <parameter name="association_name" type="str"/>
+                                <raise scope="cd" event="delete_instance">
+                                    <parameter expr='association_name' />
+                                </raise>
+                                <script>
+                                    self.nr_of_fields -= 1
+                                </script>
+                            </transition>
+                        </state>
+                        <state id="creating">
+                            <transition event="instance_created" target="../waiting">
+                                <parameter name="association_name" type="string"/>
+                                <raise scope="cd" event="start_instance">
+                                    <parameter expr="association_name" />
+                                </raise>
+                                <raise scope="narrow" event="set_association_name" target="association_name">
+                                    <parameter expr="association_name" />
+                                </raise>
+                                <script>
+                                    self.nr_of_fields += 1
+                                </script>
+                            </transition>
+                        </state>
+                        <state id="check_nr_of_fields">
+                            <transition target="../stopped" cond="self.nr_of_fields == 0" after="0.05">
+                                <raise event="stop" />
+                            </transition>
+                            <transition target="../waiting" cond="self.nr_of_fields != 0"/>
+                        </state>
+                        <state id="stopped" />
+                    </state>
+                    <transition target="../stopped" event="stop">
+                        <raise port="Outport" event="destroy_all"/>
+                    </transition>
+                </parallel>
+                <state id="stopped" />
+            </state>
+        </scxml>
+    </class>
+
+    <class name="Field">
+        <attribute name="window_id" />
+        <attribute name="canvas_id" />
+        <inport name="field_ui"/>
+        <relationships>
+            <association name="balls" class="Ball" />
+            <association name="buttons" class="Button" />
+            <association name="parent" class="MainApp" min="1" max="1" />
+        </relationships>
+        <scxml initial="root">
+            <state id="root" initial="waiting">
+                <state id="waiting">
+                    <transition event="set_association_name" target="../creating_window">
+                        <parameter name="association_name" type="str" />
+                        <script>
+                            self.association_name = association_name
+                        </script>
+                    </transition>
+                </state>
+                <state id="creating_window">
+                    <onentry>
+                        <raise port="Outport" event="create_window">
+                            <parameter expr="800"/>                     <!-- width -->
+                            <parameter expr="600"/>                     <!-- height -->
+                            <parameter expr='"BouncingBalls"'/>         <!-- title -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
+                        </raise>
+                    </onentry>
+                    <transition event="window_created" target="../creating_canvas">
+                        <parameter name="window_id" type="int" />
+                        <script>
+                            self.window_id = window_id
+                        </script>
+                        <raise port="Outport" event="bind_event">
+                            <parameter expr="window_id"/>               <!-- widget_id -->
+                            <parameter expr="ui.EVENTS.WINDOW_CLOSE"/>  <!-- tk_event -->
+                            <parameter expr="'window_close'"/>          <!-- sccd_event_name -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
+                        </raise>
+                        <raise port="Outport" event="bind_event">
+                            <parameter expr="window_id"/>               <!-- widget_id -->
+                            <parameter expr="ui.EVENTS.KEY_PRESS"/>     <!-- tk_event -->
+                            <parameter expr="'key_press'"/>             <!-- sccd_event_name -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
+                        </raise>
+                    </transition>
+                </state>
+                <state id="creating_canvas">
+                    <onentry>
+                        <raise port="Outport" event="create_canvas">
+                            <parameter expr="self.window_id"/>          <!-- window_id -->
+                            <parameter expr="CANVAS_DIMS[0]"/>          <!-- width -->
+                            <parameter expr="CANVAS_DIMS[1]"/>          <!-- height -->
+                            <parameter expr="{'background':'#eee'}"/>   <!-- style -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
+                        </raise>
+                    </onentry>
+                    <transition event="canvas_created" target="../creating_button">
+                        <parameter name="canvas_id" type="int"/>
+                        <script>
+                            self.canvas_id = canvas_id
+                        </script>
+                        <raise port="Outport" event="bind_event">
+                            <parameter expr="canvas_id"/>                   <!-- widget_id -->
+                            <parameter expr="ui.EVENTS.MOUSE_RIGHT_CLICK"/> <!-- tk_event -->
+                            <parameter expr="'right_click'"/>               <!-- sccd_event_name -->
+                            <parameter expr='"Inport"'/>    <!-- inport for response -->
+                        </raise>
+                        <raise port="Outport" event="bind_event">
+                            <parameter expr="canvas_id"/>                   <!-- widget_id -->
+                            <parameter expr="ui.EVENTS.MOUSE_MOVE"/>        <!-- tk_event -->
+                            <parameter expr="'mouse_move'"/>                <!-- sccd_event_name -->
+                            <parameter expr='"Inport"'/>    <!-- inport for response -->
+                        </raise>
+                        <raise port="Outport" event="bind_event">
+                            <parameter expr="canvas_id"/><!-- widget_id -->
+                            <parameter expr="ui.EVENTS.MOUSE_RELEASE"/><!-- tk_event -->
+                            <parameter expr="'mouse_release'"/><!-- sccd_event_name -->
+                            <parameter expr='"Inport"'/><!-- inport for response -->
+                        </raise>
+                    </transition>
+                </state>
+                <state id="creating_button">
+                    <onentry>
+                        <raise scope="cd" event="create_instance">
+                            <parameter expr='"buttons"' />
+                            <parameter expr='"Button"' />
+                            <parameter expr="self.window_id" />
+                            <parameter expr="'create_new_field'" />
+                            <parameter expr="'Spawn New Window'" />
+                        </raise>
+                    </onentry>
+                    <transition event='instance_created' target='../running'>
+                        <parameter name="association_name" type="string"/>
+                        <raise scope="cd" event="start_instance">
+                            <parameter expr="association_name" />
+                        </raise>
+                    </transition>
+                </state>
+                 <parallel id="running">
+                    <transition port="Inport" event="window_close" target="../deleting">
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr='"buttons"' />
+                        </raise>
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr='"balls"' />
+                        </raise>
+                    </transition>
+                    <state id="main_behaviour" initial="running">
+                        <state id="running">
+                            <transition port="Inport" event="right_click" target="../creating_ball">
+                                <parameter name="x" />
+                                <parameter name="y" />
+                                <parameter name="button" />
+                                <raise scope="cd" event="create_instance">
+                                    <parameter expr='"balls"' />
+                                    <parameter expr='"Ball"' />
+                                    <parameter expr="self.canvas_id" />
+                                    <parameter expr="x" />
+                                    <parameter expr="y" />
+                                </raise>
+                            </transition>
+                        </state>
+                        <state id="creating_ball">
+                            <transition event="instance_created" target="../running">
+                                <parameter name="association_name" type="string"/>
+                                <raise scope="cd" event="start_instance">
+                                    <parameter expr="association_name" />
+                                </raise>
+                                <raise scope="narrow" event="set_association_name" target="association_name">
+                                    <parameter expr="association_name" />
+                                </raise>
+                            </transition>
+                        </state>
+                    </state>
+                    <state id="deleting_behaviour" initial="running">
+                        <state id="running">
+                            <transition event="delete_ball" target='.'>
+                                <parameter name="association_name" type="str"/>
+                                <raise scope="cd" event="delete_instance">
+                                    <parameter expr='association_name' />
+                                </raise>
+                            </transition>
+                        </state>
+                    </state>
+                    <state id="child_behaviour" initial="listening">
+                        <state id="listening">
+                            <transition event="button_pressed" target='.'>
+                                <parameter name="event_name" type="str" />
+                                <raise event="button_pressed" scope="narrow" target="'parent'">
+                                    <parameter expr='event_name' />
+                                </raise>
+                            </transition>
+                        </state>
+                    </state>
+                    <state id="deleting_balls_behaviour" initial="listening">
+                        <state id="listening">
+                            <transition port="Inport" event="key_press" target="." cond="key == ui.KEYCODES.DELETE">
+                                <parameter name="key" />
+                                <raise event="delete_self" scope="narrow" target="'balls'" />
+                            </transition>
+                        </state>
+                    </state>
+                </parallel>
+                <state id="deleting">
+                    <transition target="../deleted">
+                        <raise event="delete_field" scope="narrow" target="'parent'">
+                            <parameter expr='self.association_name' />
+                        </raise>
+                        <raise port="Outport" event="destroy_window">
+                            <parameter expr="self.window_id"/><!-- window to destroy -->
+                        </raise>
+                    </transition>
+                </state>
+                <state id="deleted" />
+            </state>
+        </scxml>
+    </class>
+    
+    <class name="Button">
+        <attribute name="window_id" />
+        <attribute name="event_name" />
+        <attribute name="button_id" />
+        <relationships>
+            <association name="parent" class="Field" min="1" max="1" />
+        </relationships>
+        <inport name="button_ui"/>
+        <constructor>
+            <parameter name="window_id" type="int" />
+            <parameter name="event_name" type="str" />
+            <parameter name="button_text" type="str" />
+            <body>
+                self.window_id = window_id;
+                self.event_name = event_name;
+            </body>
+        </constructor>
+        <scxml initial="creating_button">
+            <state id="creating_button">
+                <onentry>
+                    <raise port="Outport" event="create_button">
+                        <parameter expr="self.window_id"/><!-- window_id -->
+                        <parameter expr="self.event_name"/><!-- text -->
+                        <parameter expr="'Inport'"/><!-- inport for response -->
+                    </raise>
+                </onentry>
+                <transition event="button_created" target="../running">
+                    <parameter name="button_id" type="int"/>
+                    <script>
+                        self.button_id = button_id
+                    </script>
+                    <raise port="Outport" event="bind_event">
+                        <parameter expr="button_id"/><!-- widget_id -->
+                        <parameter expr="ui.EVENTS.MOUSE_CLICK"/><!-- tk_event -->
+                        <parameter expr='"mouse_click"'/><!-- sccd_event_name -->
+                        <parameter expr="'Inport'"/><!-- inport for response -->
+                    </raise>
+                </transition>
+            </state>
+             <state id="running">
+                <transition port='Inport' event="mouse_click" target='.' cond="button == ui.MOUSE_BUTTONS.LEFT">
+                    <parameter name="x" />
+                    <parameter name="y" />
+                    <parameter name="button" />
+                    <raise event="button_pressed" scope="narrow" target="'parent'">
+                        <parameter expr="self.event_name" />
+                    </raise>
+                </transition>
+            </state>
+        </scxml>
+    </class>
+    
+    <class name="Ball">
+        <attribute name="canvas_id" />
+        <atrribute name="circle_id" />
+        <attribute name="pos" />
+        <inport name="ball_ui" />
+        <relationships>
+            <association name="parent" class="Field" min="1" max="1" />
+        </relationships>
+        <constructor>
+            <parameter name="canvas_id" />
+            <parameter name="x" />
+            <parameter name="y" />
+            <body>
+                self.canvas_id = canvas_id;
+                self.r = 20.0;
+                self.vel = {'x': 1, 'y': 1};
+                self.pos = {'x': x, 'y': y};
+                self.smooth = 0.6; # value between 0 and 1
+            </body>
+        </constructor>
+        <destructor>
+        </destructor>
+        <scxml initial="main_behaviour">
+            <state id="main_behaviour" initial="initializing">
+                <state id="initializing">
+                    <transition event="set_association_name" target="../creating_circle">
+                        <parameter name="association_name" type="str" />
+                        <script>
+                            self.association_name = association_name
+                        </script>
+                    </transition>
+                </state>
+                <state id="creating_circle">
+                    <onentry>
+                        <raise port="Outport" event="create_circle">
+                            <parameter expr="self.canvas_id"/><!-- canvas_id -->
+                            <parameter expr="self.pos['x']"/><!-- x -->
+                            <parameter expr="self.pos['y']"/><!-- y -->
+                            <parameter expr="self.r"/><!-- r -->
+                            <parameter expr="{'fill':'#000'}"/><!-- style -->
+                            <parameter expr="'Inport'"/><!-- inport for response -->
+                        </raise>
+                    </onentry>
+                    <transition event="circle_created" target="../bouncing">
+                        <parameter name="canvas_id"/>
+                        <parameter name="circle_id"/>
+                        <script>
+                            self.circle_id = circle_id
+                        </script>
+                        <raise port="Outport" event="bind_canvas_event">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="circle_id"/>
+                            <parameter expr="ui.EVENTS.MOUSE_PRESS"/>
+                            <parameter expr="'mouse_press'"/>
+                            <parameter expr="'Inport'"/>
+                        </raise>
+                        <raise port="Outport" event="bind_canvas_event">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="circle_id"/>
+                            <parameter expr="ui.EVENTS.MOUSE_MOVE"/>
+                            <parameter expr="'mouse_move'"/>
+                            <parameter expr="'Inport'"/>
+                        </raise>
+                        <raise port="Outport" event="bind_canvas_event">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="circle_id"/>
+                            <parameter expr="ui.EVENTS.MOUSE_RELEASE"/>
+                            <parameter expr="'mouse_release'"/>
+                            <parameter expr="'Inport'"/>
+                        </raise>
+                    </transition>
+                </state>
+                <state id="bouncing">
+                    <!-- <transition after="(20 - self.getSimulatedTime() % 20) / 1000.0" target="."> -->
+                    <transition after="0.02" target=".">
+                        <script>
+                            <![CDATA[
+                            # Invert velocity when colliding with canvas border:
+                            if self.pos['x']-self.r <= 0 or self.pos['x']+self.r >= CANVAS_DIMS[0]:
+                                self.vel['x'] = -self.vel['x'];
+                            if self.pos['y']-self.r <= 0 or self.pos['y']+self.r >= CANVAS_DIMS[1]:
+                                self.vel['y'] = -self.vel['y'];
+                            ]]>
+                        </script>
+                        <raise port="Outport" event="move_element">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="self.circle_id"/>
+                            <parameter expr="self.vel['x']"/>
+                            <parameter expr="self.vel['y']"/>
+                        </raise>
+                        <script>
+                            self.pos['x'] += self.vel['x']
+                            self.pos['y'] += self.vel['y']
+                        </script>
+                    </transition>
+                    <transition port="Inport" event="mouse_press" target="../selected" cond="button == ui.MOUSE_BUTTONS.LEFT">
+                        <parameter name="x" />
+                        <parameter name="y" />
+                        <parameter name="button" />
+                        <raise port="Outport" event="set_element_color">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="self.circle_id"/>
+                            <parameter expr="'#ff0'"/>
+                        </raise>
+                    </transition>
+                </state>
+                <state id="dragging">
+                    <transition port="Inport" event="mouse_move" target=".">
+                        <parameter name="x" />
+                        <parameter name="y" />
+                        <parameter name="button" />
+                        <script>
+                            # Always keep ball within canvas:
+                            x = min(max(0+self.r, x), CANVAS_DIMS[0]-self.r)
+                            y = min(max(0+self.r, y), CANVAS_DIMS[1]-self.r)
+
+                            dx = x - self.pos['x']
+                            dy = y - self.pos['y']
+
+                            self.vel = {
+                                'x': (1-self.smooth)*dx + self.smooth*self.vel['x'],
+                                'y': (1-self.smooth)*dy + self.smooth*self.vel['y']
+                            }
+                            
+                            self.pos = {'x': x, 'y': y}
+                        </script>
+                        <raise port="Outport" event="set_element_pos">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="self.circle_id"/>
+                            <parameter expr="x-self.r"/>
+                            <parameter expr="y-self.r"/>
+                        </raise>
+                    </transition>
+                    <transition port="Inport" event="mouse_release" target="../bouncing">
+                        <parameter name="x" />
+                        <parameter name="y" />
+                        <raise port="Outport" event="set_element_color">
+                            <parameter expr="self.canvas_id"/>
+                            <parameter expr="self.circle_id"/>
+                            <parameter expr="'#f00'"/>
+                        </raise>
+                    </transition>
+                </state>
+                <state id='selected'>
+                    <transition port="Inport" event="mouse_press" target="../dragging" cond="button == ui.MOUSE_BUTTONS.LEFT">
+                        <parameter name="x" />
+                        <parameter name="y" />
+                        <parameter name="button" />
+                        <script>
+                            self.mouse_pos = {'x':x, 'y':y};
+                        </script>
+                    </transition>
+                    <transition event="delete_self" target='../../deleted'>                    
+                        <raise event="delete_ball" scope="narrow" target="'parent'">
+                            <parameter expr='self.association_name' />
+                        </raise>
+                        <raise port="Outport" event="destroy_element">
+                            <parameter expr="self.canvas_id" />
+                            <parameter expr="self.element_id" />
+                        </raise>
+                    </transition>
+                </state>
+            </state>
+            <state id='deleted' />
+        </scxml>
+    </class>
+</diagram>

+ 3 - 3
tests/2.0) GlobalInputTest/expected_trace.txt

@@ -1,3 +1,3 @@
-0.00 MainApp: exit /state1
-0.00 MainApp: transition (/state1 -> /state2)
-0.00 MainApp: enter /state2
+1.00 MainApp: exit /state1
+1.00 MainApp: transition (/state1 -> /state2)
+1.00 MainApp: enter /state2

+ 2 - 1
tests/2.0) GlobalInputTest/input.txt

@@ -1 +1,2 @@
-0.00 (event name: input_event; port: ui; parameters: ['0.00'])
+0.50 (event name: not_input_event; port: Input; parameters: [])
+1.00 (event name: input_event; port: Input; parameters: [])

+ 3 - 3
tests/2.0) GlobalInputTest/sccd.xml

@@ -1,9 +1,9 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="Global Input Test">
+<diagram author="Sam Pieters" name="GlobalInputTest">
     <description>
-        Test 2.0: Check if the model receives input.
+        Check if the model receives input.
     </description>
-    <inport name="ui"/>
+    <inport name="Input"/>
     <class name="MainApp" default="true">
         <scxml initial="state1">
             <state id="state1">

+ 3 - 0
tests/2.1) GlobalInputCheckTest/config.json

@@ -0,0 +1,3 @@
+{
+    "trace": "statechart"
+}

+ 3 - 0
tests/2.1) GlobalInputCheckTest/expected_trace.txt

@@ -0,0 +1,3 @@
+1.00 MainApp: exit /state1
+1.00 MainApp: transition (/state1 -> /state2)
+1.00 MainApp: enter /state2

+ 2 - 0
tests/2.1) GlobalInputCheckTest/input.txt

@@ -0,0 +1,2 @@
+0.5 (event name: input_event; port: FalseInput; parameters: [])
+1.00 (event name: input_event; port: Input; parameters: [])

+ 16 - 0
tests/2.1) GlobalInputCheckTest/sccd.xml

@@ -0,0 +1,16 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="GlobalInputCheckTest">
+    <description>
+        Check if the model receives input from the right port and not from just any port.
+    </description>
+    <inport name="FalseInput"/>
+    <inport name="Input"/>
+    <class name="MainApp" default="true">
+        <scxml initial="state1">
+            <state id="state1">
+                <transition port="Input" event="input_event" target="../state2" />
+            </state>
+            <state id="state2" />
+        </scxml>
+    </class>
+</diagram>

+ 3 - 0
tests/2.2) GlobalInputParameterTest/config.json

@@ -0,0 +1,3 @@
+{
+    "trace": "statechart"
+}

+ 6 - 0
tests/2.2) GlobalInputParameterTest/expected_trace.txt

@@ -0,0 +1,6 @@
+1.00 MainApp: exit /state1
+1.00 MainApp: transition (/state1 -> /state2)
+1.00 MainApp: enter /state2
+1.00 MainApp: exit /state2
+1.00 MainApp: transition (/state2 -> /state3)
+1.00 MainApp: enter /state3

+ 1 - 0
tests/2.2) GlobalInputParameterTest/input.txt

@@ -0,0 +1 @@
+1.00 (event name: input_event; port: Input; parameters: [3])

+ 28 - 0
tests/2.2) GlobalInputParameterTest/sccd.xml

@@ -0,0 +1,28 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="GlobalInputParameterTest">
+    <description>
+        Check if the model receives input with parameters.
+    </description>
+    <inport name="Input"/>
+    <class name="MainApp" default="true">
+        <constructor>
+            <body>
+                self.test_value = 0
+            </body>
+        </constructor>
+        <scxml initial="state1">
+            <state id="state1">
+                <transition port="Input" event="input_event" target="../state2">
+                    <parameter name="int_value" />
+                    <script>
+                        self.test_value = int_value
+                    </script>
+                </transition>
+            </state>
+            <state id="state2">
+                <transition target="../state3" cond="self.test_value == 3"/>
+            </state>
+            <state id="state3" />
+        </scxml>
+    </class>
+</diagram>

tests/2.1) GlobalOutputTest/expected_trace.txt → tests/2.3) GlobalOutputTest/expected_trace.txt


+ 2 - 2
tests/2.1) GlobalOutputTest/sccd.xml

@@ -1,7 +1,7 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="Global Output Test">
+<diagram author="Sam Pieters" name="GlobalOutputTest">
     <description>
-        Test 2.1: Check if the model raises output.
+        Check if the model raises an output.
     </description>
     <outport name="Outport"/>
     <class name="MainApp" default="true">

+ 0 - 1
tests/2.3) TimedOutputTest/expected_trace.txt

@@ -1 +0,0 @@
-1.00 (event name: test_event; port: ui; parameters: ['1.00'])

+ 1 - 0
tests/2.4) GlobalTimedOutputTest/expected_trace.txt

@@ -0,0 +1 @@
+0.57 (event name: output_event; port: Outport)

+ 17 - 0
tests/2.4) GlobalTimedOutputTest/sccd.xml

@@ -0,0 +1,17 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="GlobalTimedOutputTest">
+    <description>
+        Check if the model raises a timed output.
+    </description>
+    <outport name="Outport"/>
+    <class name="MainApp" default="true">
+        <scxml initial="state1">
+            <state id="state1">
+                <transition after="0.57" target="../state2">
+                    <raise port="Outport" event="output_event" />
+                </transition>
+            </state>
+            <state id="state2" />
+        </scxml>
+    </class>
+</diagram>

+ 1 - 0
tests/2.5) GlobalTimedOutputTest/expected_trace.txt

@@ -0,0 +1 @@
+1.00 (event name: test_event; port: Outport)

+ 4 - 7
tests/2.3) TimedOutputTest/sccd.xml

@@ -1,10 +1,9 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="Output Test">
+<diagram author="Sam Pieters" name="GlobalTimedOutputTest">
     <description>
-        Test 2: Check if the model outputs one event on the right time.
+        Check if the model outputs one event on the right time (sends it different than 2.4).
     </description>
-    <inport name="ui"/>
-    <outport name="ui"/>
+    <outport name="Outport"/>
     <class name="MainApp" default="true">
         <scxml initial="state1">
             <state id="state1">
@@ -12,9 +11,7 @@
             </state>
             <state id="end">
                 <onentry>
-                    <raise port="ui" event="test_event">
-                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
-                    </raise>
+                    <raise port="Outport" event="test_event" />
                 </onentry>
             </state>
         </scxml>

+ 0 - 5
tests/2.5) MultipleOutputTest/expected_trace.txt

@@ -1,5 +0,0 @@
-1.00 (event name: test_event; port: ui; parameters: ['1', '1.00'])
-2.00 (event name: test_event; port: ui; parameters: ['2', '2.00'])
-3.00 (event name: test_event; port: ui; parameters: ['3', '3.00'])
-4.00 (event name: test_event; port: ui; parameters: ['4', '4.00'])
-5.00 (event name: test_event; port: ui; parameters: ['5', '5.00'])

tests/2.2) GlobalIOTest/expected_trace.txt → tests/2.6) GlobalIOTest/expected_trace.txt


tests/2.2) GlobalIOTest/input.txt → tests/2.6) GlobalIOTest/input.txt


+ 2 - 2
tests/2.2) GlobalIOTest/sccd.xml

@@ -1,7 +1,7 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="Global IO Test">
+<diagram author="Sam Pieters" name="GlobalIOTest">
     <description>
-        Test 2.0: Check if the model receives input and directly sends an output
+        Check if the model receives input and directly sends an output
     </description>
     <inport name="Inport"/>
     <outport name="Outport"/>

+ 3 - 0
tests/2.7) MultipleInstanceGlobalInputTest/config.json

@@ -0,0 +1,3 @@
+{
+    "trace": "statechart"
+}

+ 12 - 0
tests/2.7) MultipleInstanceGlobalInputTest/expected_trace.txt

@@ -0,0 +1,12 @@
+0.00 MainApp: exit /state1
+0.00 MainApp: transition (/state1 -> /state2)
+0.00 MainApp: enter /state2
+0.00 MainApp: exit /state2
+0.00 MainApp: transition (/state2 -> /state2)
+0.00 MainApp: enter /state2
+1.00 A: exit /state1
+1.00 A: transition (/state1 -> /state2)
+1.00 A: enter /state2
+1.00 MainApp: exit /state2
+1.00 MainApp: transition (/state2 -> /state3)
+1.00 MainApp: enter /state3

+ 1 - 0
tests/2.7) MultipleInstanceGlobalInputTest/input.txt

@@ -0,0 +1 @@
+1.00 (event name: input_event; port: Inport; parameters: ['0.00'])

+ 42 - 0
tests/2.7) MultipleInstanceGlobalInputTest/sccd.xml

@@ -0,0 +1,42 @@
+<?xml version="1.1" ?>
+<diagram author="Sam Pieters" name="MultipleInstanceGlobalInputTest">
+    <description>
+        Check if multiple SCCD classes receive the events from the inport
+    </description>
+    <inport name="Inport"/>
+    <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 scope="cd" event="start_instance">
+                        <parameter expr="association_name" />
+                    </raise>
+                </transition>
+            </state>
+            <state id="state2">
+                <transition event='instance_started' target='.' />
+                <transition event='input_event' target='../state3'/>
+            </state>
+            <state id="state3" />
+        </scxml>
+    </class>
+
+    <class name="A">
+        <scxml initial="state1">
+            <state id="state1">
+                <transition event='input_event' target='../state2'/>
+            </state>
+            <state id="state2" />
+        </scxml>
+    </class>
+</diagram>

+ 5 - 0
tests/2.8) MultipleOutputTest/expected_trace.txt

@@ -0,0 +1,5 @@
+1.00 (event name: test_event; port: Outport; parameters: ['1'])
+2.00 (event name: test_event; port: Outport; parameters: ['2'])
+3.00 (event name: test_event; port: Outport; parameters: ['3'])
+4.00 (event name: test_event; port: Outport; parameters: ['4'])
+5.00 (event name: test_event; port: Outport; parameters: ['5'])

+ 4 - 6
tests/2.5) MultipleOutputTest/sccd.xml

@@ -1,10 +1,9 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="Multiple Output Test">
+<diagram author="Sam Pieters" name="MultipleOutputTest">
     <description>
-        Test 3: Check if the model outputs multiple events with an interval on the right time.
+        Check if the model outputs multiple events with an interval on the right time.
     </description>
-    <inport name="ui"/>
-    <outport name="ui"/>
+    <outport name="Outport"/>
     <class name="MainApp" default="true">
         <constructor>
             <body>
@@ -17,9 +16,8 @@
             </state>
             <state id="state2">
                 <onentry>
-                    <raise port="ui" event="test_event">
+                    <raise port="Outport" event="test_event">
                         <parameter expr="str(self.amount)" />
-                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
                     </raise>
                 </onentry>
                 <transition target="../state1" cond="self.amount != 5">

+ 1 - 1
tests/3.0) ClassCreation/expected_trace.txt

@@ -1 +1 @@
-0.00 (event name: instance_created_succesfully; port: ui; parameters: ['0.00', 'linkA[0]'])
+0.00 (event name: instance_created_succesfully; port: Outport; parameters: ['linkA[0]'])

+ 5 - 9
tests/3.0) ClassCreation/sccd.xml

@@ -1,10 +1,9 @@
 <?xml version="1.1" ?>
-<diagram author="Sam Pieters" name="Create Instance">
+<diagram author="Sam Pieters" name="ClassCreation">
     <description>
-        Test 6: Check if an instance in created successfully (other than the main app, without parameters)
+        Check if an instance in created successfully (other than the main app, without parameters)
     </description>
-    <inport name="ui"/>
-    <outport name="ui"/>
+    <outport name="Outport"/>
     <class name="MainApp" default="true">
         <relationships>
             <association name="linkA" class="A" />
@@ -19,8 +18,7 @@
                 </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))" />
+                    <raise port="Outport" event="instance_created_succesfully">
                         <parameter expr="association_name" />
                     </raise>
                 </transition>
@@ -34,9 +32,7 @@
         <scxml initial="state1">
             <state id="state1">
                 <onentry>
-                    <raise port="ui" event="not_possible">
-                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
-                    </raise>
+                    <raise port="Outport" event="not_possible" />
                 </onentry>
             </state>
         </scxml>

+ 3 - 0
tests/3.1) ClassInitialisation/expected_trace.txt

@@ -0,0 +1,3 @@
+0.00 (event name: instance_created_succesfully; port: Outport; parameters: ['linkA[0]'])
+0.00 (event name: statechart_started_succesfully; port: Outport)
+0.00 (event name: instance_started_succesfully; port: Outport; parameters: ['linkA[0]'])

+ 5 - 9
tests/3.1) ClassInitialization/sccd.xml

@@ -1,10 +1,9 @@
 <?xml version="1.1" ?>
 <diagram author="Sam Pieters" name="Create and Start Instance">
     <description>
-        Test 7: Check if an instance is created and started successfully (other than the main app)
+        Check if an instance is created and started successfully (other than the main app)
     </description>
-    <inport name="ui"/>
-    <outport name="ui"/>
+    <outport name="Outport"/>
     <class name="MainApp" default="true">
         <relationships>
             <association name="linkA" class="A" />
@@ -19,8 +18,7 @@
                 </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))" />
+                    <raise port="Outport" event="instance_created_succesfully">
                         <parameter expr="association_name" />
                     </raise>
                     <raise scope="cd" event="start_instance">
@@ -31,8 +29,7 @@
             <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))" />
+                    <raise port="Outport" event="instance_started_succesfully">
                         <parameter expr="association_name" />
                     </raise>
                 </transition>
@@ -44,8 +41,7 @@
         <scxml initial="state1">
             <state id="state1">
                 <onentry>
-                    <raise port="ui" event="statechart_started_succesfully">
-                        <parameter expr="str('%.2f' % (self.getSimulatedTime() / 1000.0))" />
+                    <raise port="Outport" event="statechart_started_succesfully">
                     </raise>
                 </onentry>
             </state>

+ 0 - 3
tests/3.1) ClassInitialization/expected_trace.txt

@@ -1,3 +0,0 @@
-0.00 (event name: instance_created_succesfully; port: ui; parameters: ['0.00', 'linkA[0]'])
-0.00 (event name: statechart_started_succesfully; port: ui; parameters: ['0.00'])
-0.00 (event name: instance_started_succesfully; port: ui; parameters: ['0.00', 'linkA[0]'])

+ 0 - 6
tests/3.10) DeleteBadFromNonParent/expected_trace.txt

@@ -1,6 +0,0 @@
-0.00 (event name: instance_created_succesfully; port: ui; parameters: ['linkA[0]'])
-0.00 (event name: statechart_started_succesfully; port: ui)
-0.00 (event name: instance_started_succesfully; port: ui; parameters: ['linkA[0]'])
-0.00 (event name: instance_created_succesfully; port: ui; parameters: ['linkB[0]'])
-0.00 (event name: statechart_started_succesfully; port: ui)
-0.00 (event name: instance_started_succesfully; port: ui; parameters: ['linkB[0]'])

+ 0 - 0
tests/3.10) DeleteGoodFromNonParent/expected_trace.txt


Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů