Kaynağa Gözat

fixed output ports + added black box testing (can't reach simulation time of pypDEVS)

sampieters 1 yıl önce
ebeveyn
işleme
cb133246ef

+ 0 - 8
.idea/.gitignore

@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml

+ 0 - 91
devs_test.txt

@@ -1,91 +0,0 @@
-__  Current Time:   0.000000 __________________________________________ 
-__  Current Time:   0.000000 __________________________________________ 
-	EXTERNAL TRANSITION in model <controller.MainApp>
-		Input Port Configuration:
-			port <obj_manager_in>:
-				('MainApp', 'MainApp', (event name: start_instance; port: None; parameters: ['MainApp[0]']))
-			port <input>:
-			port <private_0_<narrow_cast>>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10c1889e0>}
-		Next scheduled internal transition at time 0.000000
-__  Current Time:   0.000000 __________________________________________ 
-	EXTERNAL TRANSITION in model <controller.ObjectManager>
-		Input Port Configuration:
-			port <input>:
-				('MainApp', 'MainApp', (event name: instance_started; port: None; parameters: ['MainApp[0]']))
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10bbb50a0>
-		Next scheduled internal transition at time 0.000000
-__  Current Time:   0.000000 __________________________________________ 
-__  Current Time:   0.000000 __________________________________________ 
-	EXTERNAL TRANSITION in model <controller.ObjectManager>
-		Input Port Configuration:
-			port <input>:
-				('MainApp', 'Field', (event name: create_instance; port: None; parameters: ['fields']))
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10bbb50a0>
-		Next scheduled internal transition at time 0.000000
-__  Current Time:   0.000000 __________________________________________ 
-	EXTERNAL TRANSITION in model <controller.Field>
-		Input Port Configuration:
-			port <obj_manager_in>:
-				('MainApp', 'Field', (event name: create_instance; port: None; parameters: ['fields']))
-			port <input>:
-			port <field_ui>:
-			port <private_1_<narrow_cast>>:
-			port <private_2_field_ui>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10c25cd10>}
-		Next scheduled internal transition at time 0.000000
-__  Current Time:   0.000000 __________________________________________ 
-	EXTERNAL TRANSITION in model <controller.ObjectManager>
-		Input Port Configuration:
-			port <input>:
-				('Field', 'MainApp', (event name: instance_created; port: None; parameters: ['fields[0]']))
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10bbb50a0>
-		Next scheduled internal transition at time 0.000000
-__  Current Time:   0.000000 __________________________________________ 
-	EXTERNAL TRANSITION in model <controller.MainApp>
-		Input Port Configuration:
-			port <obj_manager_in>:
-				('Field', 'MainApp', (event name: instance_created; port: None; parameters: ['fields[0]']))
-			port <input>:
-			port <private_0_<narrow_cast>>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10c1889e0>}
-		Next scheduled internal transition at time 0.000000
-__  Current Time:   0.000000 __________________________________________ 
-__  Current Time:   0.000000 __________________________________________ 
-__  Current Time:   0.000000 __________________________________________ 
-	EXTERNAL TRANSITION in model <controller.ObjectManager>
-		Input Port Configuration:
-			port <input>:
-				('MainApp', 'Field', (event name: start_instance; port: None; parameters: ['fields[0]']))
-				('MainApp', 'Field', (event name: set_association_name; port: None; parameters: ['fields[0]']))
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10bbb50a0>
-		Next scheduled internal transition at time 0.000000
-__  Current Time:   0.000000 __________________________________________ 
-	EXTERNAL TRANSITION in model <controller.Field>
-		Input Port Configuration:
-			port <obj_manager_in>:
-				('MainApp', 'Field', (event name: start_instance; port: None; parameters: ['fields[0]']))
-				('MainApp', 'Field', (event name: set_association_name; port: None; parameters: ['fields[0]']))
-			port <input>:
-			port <field_ui>:
-			port <private_1_<narrow_cast>>:
-			port <private_2_field_ui>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10c25cd10>}
-		Next scheduled internal transition at time 0.000000
-__  Current Time:   0.000000 __________________________________________ 
-	EXTERNAL TRANSITION in model <controller.ObjectManager>
-		Input Port Configuration:
-			port <input>:
-				('Field', 'MainApp', (event name: instance_started; port: None; parameters: ['fields[0]']))
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10bbb50a0>
-		Next scheduled internal transition at time 0.000000
-__  Current Time:   0.000000 __________________________________________ 
-	EXTERNAL TRANSITION in model <controller.MainApp>
-		Input Port Configuration:
-			port <obj_manager_in>:
-				('Field', 'MainApp', (event name: instance_started; port: None; parameters: ['fields[0]']))
-			port <input>:
-			port <private_0_<narrow_cast>>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10c1889e0>}
-		Next scheduled internal transition at time 0.000000
-__  Current Time:   0.000000 __________________________________________ 

+ 11 - 0
examples/BouncingBalls/PyDEVS/output.txt

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

+ 11 - 11
examples/BouncingBalls/PyDEVS/runner.py

@@ -7,13 +7,11 @@ class OutputListener:
 	def __init__(self, ui):
 		self.ui = ui
 
-	def add(self, event):
-		if event.port == "ui":
-			method = getattr(self.ui, event.name)
-			method(*event.parameters)
-
-def my_function(event):
-    print("Observed the following event: " + str(event))
+	def add(self, events):
+		for event in events:
+			if event.port == "ui":
+				method = getattr(self.ui, event.name)
+				method(*event.parameters)
 
 if __name__ == '__main__':
 	model = target.Controller(name="controller")
@@ -21,15 +19,17 @@ if __name__ == '__main__':
 
 	tkroot = tk.Tk()
 	tkroot.withdraw()
-	sim = DEVSSimulator(model)
+	sim = DEVSSimulator(model, refs)
 	sim.setRealTime(True)
 	#sim.setRealTimeInputFile("./examples/BouncingBalls/input_trace.txt")
-	sim.setRealTimePorts(refs)
-	#sim.setVerbose("./examples/BouncingBalls/PyDEVS/trace.txt")
-	sim.setListenPorts(model.out_ui, my_function)
+	sim.setVerbose("./examples/BouncingBalls/PyDEVS/trace.txt")
+	
 	sim.setRealTimePlatformTk(tkroot)
 
 	ui = UI(tkroot, sim)
+
+	listener = OutputListener(ui)
+	sim.setListenPorts(model.out_ui, listener.add)
 	#model.atomic1.addMyOwnOutputListener(OutputListener(ui))
 	#model.atomic2.addMyOwnOutputListener(OutputListener(ui))
 	#model.atomic3.addMyOwnOutputListener(OutputListener(ui))

+ 5 - 29
examples/BouncingBalls/PyDEVS/target.py

@@ -34,6 +34,8 @@ class MainAppInstance(RuntimeClassBase):
         
         # call user defined constructor
         MainAppInstance.user_defined_constructor(self)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
     
     def user_defined_constructor(self):
         self.nr_of_fields = 0
@@ -203,8 +205,6 @@ class MainApp(ObjectManagerBase):
         self.outputs["fields"] = self.addOutPort("fields")
         self.instances[self.next_instance] = MainAppInstance(self)
         self.next_instance = self.next_instance + 1
-        port_name = Ports.addInputPort("<narrow_cast>", 0)
-        self.addInPort(port_name)
     
     def constructObject(self, parameters):
         new_instance = MainAppInstance(self)
@@ -233,19 +233,12 @@ class FieldInstance(RuntimeClassBase):
         
         # call user defined constructor
         FieldInstance.user_defined_constructor(self)
-        #self.inports["field_ui"] = ('field_ui', atomdevs.next_instance)
-
-
         port_name = Ports.addInputPort("<narrow_cast>", self)
         atomdevs.addInPort(port_name)
-
         port_name = Ports.addInputPort("field_ui", self)
         atomdevs.addInPort(port_name)
         atomdevs.port_mappings[port_name] = atomdevs.next_instance
-
-
         self.inports["field_ui"] = port_name
-
     
     def user_defined_constructor(self):
         pass
@@ -486,8 +479,6 @@ class Field(ObjectManagerBase):
         self.outputs["buttons"] = self.addOutPort("buttons")
         self.outputs["parent"] = self.addOutPort("parent")
         self.field_ui = self.addInPort("field_ui")
-
-        self.port_mappings = {}
     
     def constructObject(self, parameters):
         new_instance = FieldInstance(self)
@@ -515,15 +506,11 @@ class ButtonInstance(RuntimeClassBase):
         
         # call user defined constructor
         ButtonInstance.user_defined_constructor(self, window_id, event_name, button_text)
-        #self.inports["button_ui"] = ('button_ui', atomdevs.next_instance)
-
         port_name = Ports.addInputPort("<narrow_cast>", self)
         atomdevs.addInPort(port_name)
-
         port_name = Ports.addInputPort("button_ui", self)
         atomdevs.addInPort(port_name)
         atomdevs.port_mappings[port_name] = atomdevs.next_instance
-
         self.inports["button_ui"] = port_name
     
     def user_defined_constructor(self, window_id, event_name, button_text):
@@ -598,8 +585,6 @@ class Button(ObjectManagerBase):
         self.output = self.addOutPort("ui")
         self.outputs["parent"] = self.addOutPort("parent")
         self.button_ui = self.addInPort("button_ui")
-
-        self.port_mappings = {}
     
     def constructObject(self, parameters):
         new_instance = ButtonInstance(self, parameters[2], parameters[3], parameters[4])
@@ -626,16 +611,11 @@ class BallInstance(RuntimeClassBase):
         
         # call user defined constructor
         BallInstance.user_defined_constructor(self, canvas_id, x, y)
-        #self.inports["ball_ui"] = ('ball_ui', atomdevs.next_instance)
-
         port_name = Ports.addInputPort("<narrow_cast>", self)
         atomdevs.addInPort(port_name)
-
         port_name = Ports.addInputPort("ball_ui", self)
         atomdevs.addInPort(port_name)
         atomdevs.port_mappings[port_name] = atomdevs.next_instance
-
-
         self.inports["ball_ui"] = port_name
     
     def user_defined_constructor(self, canvas_id, x, y):
@@ -830,8 +810,6 @@ class Ball(ObjectManagerBase):
         self.output = self.addOutPort("ui")
         self.outputs["parent"] = self.addOutPort("parent")
         self.ball_ui = self.addInPort("ball_ui")
-
-        self.port_mappings = {}
     
     def constructObject(self, parameters):
         new_instance = BallInstance(self, parameters[2], parameters[3], parameters[4])
@@ -853,14 +831,13 @@ class ObjectManager(TheObjectManager):
 
 class Controller(CoupledDEVS):
     def __init__(self, name):
+        self.terminate = False
+
         CoupledDEVS.__init__(self, name)
         self.in_ui = self.addInPort("ui")
-        self.out_ui = self.addOutPort("ui")
-
         Ports.addInputPort("ui")
+        self.out_ui = self.addOutPort("ui")
         Ports.addOutputPort("ui")
-
-
         self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
         self.atomic0 = self.addSubModel(MainApp("MainApp"))
         self.atomic1 = self.addSubModel(Field("Field"))
@@ -880,7 +857,6 @@ class Controller(CoupledDEVS):
         self.connectPorts(self.atomic3.obj_manager_out, self.objectmanager.input)
         self.connectPorts(self.objectmanager.output["Ball"], self.atomic3.obj_manager_in)
         self.connectPorts(self.atomic3.outputs["parent"], self.atomic1.input)
-
         self.connectPorts(self.atomic0.output, self.out_ui)
         self.connectPorts(self.atomic1.output, self.out_ui)
         self.connectPorts(self.atomic2.output, self.out_ui)

+ 25 - 36
examples/BouncingBalls/PyDEVS/test_runner.py

@@ -2,50 +2,39 @@ import tkinter as tk
 import examples.BouncingBalls.PyDEVS.target as target
 from sccd.runtime.libs.ui_v2 import UI
 from sccd.runtime.DEVS_loop import DEVSSimulator
-
-from pypdevs.DEVS import AtomicDEVS
-from pypdevs.infinity import INFINITY
-
-class OutputListener(AtomicDEVS):
-    def __init__(self, name):
-        AtomicDEVS.__init__(self, name)
-        self.simulated_time = 0
-        self.input = self.addInPort("input")
-
-    def extTransition(self, inputs):
-        self.simulated_time += self.elapsed
-        
-
-    def intTransition(self):
-        pass
-
-    def outputFnc(self):
-        pass
-    
-    def timeAdvance(self):
-        return INFINITY
+from pypdevs.DEVS import AtomicDEVS, CoupledDEVS
+
+class OutputListener:
+	def __init__(self, model, log_file):
+		self.model = model
+		self.log_file = log_file
+
+		# Clear the log file when the listener is initialized
+		with open(self.log_file, 'w') as file:
+			file.write('')  # This will create a new empty file or clear the existing file
+		
+	def add(self, events):
+		with open(self.log_file, 'a') as file:
+			for event in events:
+				file.write(f'{event}\n')
+
+				# IMPORTANT: This is here because we add our own inputs but tkinter will not close properly because of this
+				#if event.name == "destroy_all":
+					#self.tk.destroy()
 
 if __name__ == '__main__':
 	model = target.Controller(name="controller")
-	listener = model.addSubModel(OutputListener("listener"))
-	model.connectPorts(model.ui, listener.input) 
-
-	refs = {"ui": model.ui, "field_ui": model.atomic1.field_ui, "button_ui": model.atomic2.button_ui, "ball_ui": model.atomic3.ball_ui}
+	refs = {"ui": model.in_ui, "field_ui": model.atomic1.field_ui, "button_ui": model.atomic2.button_ui, "ball_ui": model.atomic3.ball_ui}
 
 	tkroot = tk.Tk()
 	tkroot.withdraw()
-	sim = DEVSSimulator(model)
-	sim.setRealTime(True)
+	sim = DEVSSimulator(model, refs)
 	sim.setRealTimeInputFile("./examples/BouncingBalls/input_trace.txt")
-	sim.setRealTimePorts(refs)
-	sim.setVerbose("./examples/BouncingBalls/PyDEVS/trace.txt")
+	
 	sim.setRealTimePlatformTk(tkroot)
-     
 
+	listener = OutputListener(model, "./examples/BouncingBalls/PyDEVS/output.txt")
+	sim.setListenPorts(model.out_ui, listener.add)
 
-	#ui = UI(tkroot, sim)
-	#model.atomic1.addMyOwnOutputListener(OutputListener(ui))
-	#model.atomic2.addMyOwnOutputListener(OutputListener(ui))
-	#model.atomic3.addMyOwnOutputListener(OutputListener(ui))
 	sim.simulate()
-	tkroot.mainloop()
+	tkroot.mainloop()

+ 113 - 96
examples/BouncingBalls/PyDEVS/trace.txt

@@ -27,11 +27,6 @@ __  Current Time:   0.000000 __________________________________________
 		Next scheduled internal transition at time 0.000000
 
 
-	INITIAL CONDITIONS in model <controller.listener>
-		Initial State: None
-		Next scheduled internal transition at time inf
-
-
 __  Current Time:   0.000000 __________________________________________ 
 
 
@@ -41,12 +36,12 @@ __  Current Time:   0.000000 __________________________________________
 				('MainApp', 'MainApp', (event name: start_instance; port: None; parameters: ['MainApp[0]']))
 			port <input>:
 			port <private_0_<narrow_cast>>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10550d940>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10ef09b20>}
 		Next scheduled internal transition at time 0.000000
 
 
 	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
 		Output Port Configuration:
 			port <port1>:
 				('MainApp', 'MainApp', (event name: start_instance; port: None; parameters: ['MainApp[0]']))
@@ -63,15 +58,16 @@ __  Current Time:   0.000000 __________________________________________
 		Input Port Configuration:
 			port <input>:
 				('MainApp', 'MainApp', (event name: instance_started; port: None; parameters: ['MainApp[0]']))
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
 		Next scheduled internal transition at time 0.000000
 
 
 	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10550d940>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10ef09b20>}
 		Output Port Configuration:
 			port <obj_manager_out>:
 				('MainApp', 'MainApp', (event name: instance_started; port: None; parameters: ['MainApp[0]']))
+			port <ui>:
 			port <fields>:
 		Next scheduled internal transition at time 0.000000
 
@@ -85,15 +81,16 @@ __  Current Time:   0.000000 __________________________________________
 				('MainApp', 'MainApp', (event name: instance_started; port: None; parameters: ['MainApp[0]']))
 			port <input>: 
 			port <private_0_<narrow_cast>>: 
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10550d940>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10ef09b20>}
 		Output Port Configuration:
 			port <obj_manager_out>:
+			port <ui>:
 			port <fields>:
 		Next scheduled internal transition at time 0.000000
 
 
 	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
 		Output Port Configuration:
 			port <port1>:
 				('MainApp', 'MainApp', (event name: instance_started; port: None; parameters: ['MainApp[0]']))
@@ -110,15 +107,16 @@ __  Current Time:   0.000000 __________________________________________
 		Input Port Configuration:
 			port <input>:
 				('MainApp', 'Field', (event name: create_instance; port: None; parameters: ['fields']))
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
 		Next scheduled internal transition at time 0.000000
 
 
 	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10550d940>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10ef09b20>}
 		Output Port Configuration:
 			port <obj_manager_out>:
 				('MainApp', 'Field', (event name: create_instance; port: None; parameters: ['fields']))
+			port <ui>:
 			port <fields>:
 		Next scheduled internal transition at time inf
 
@@ -134,12 +132,12 @@ __  Current Time:   0.000000 __________________________________________
 			port <field_ui>:
 			port <private_1_<narrow_cast>>:
 			port <private_2_field_ui>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
 		Next scheduled internal transition at time 0.000000
 
 
 	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
 		Output Port Configuration:
 			port <port1>:
 			port <port2>:
@@ -156,15 +154,16 @@ __  Current Time:   0.000000 __________________________________________
 		Input Port Configuration:
 			port <input>:
 				('Field', 'MainApp', (event name: instance_created; port: None; parameters: ['fields[0]']))
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
 		Next scheduled internal transition at time 0.000000
 
 
 	INTERNAL TRANSITION in model <controller.Field>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
 		Output Port Configuration:
 			port <obj_manager_out>:
 				('Field', 'MainApp', (event name: instance_created; port: None; parameters: ['fields[0]']))
+			port <ui>:
 			port <balls>:
 			port <buttons>:
 			port <parent>:
@@ -180,12 +179,12 @@ __  Current Time:   0.000000 __________________________________________
 				('Field', 'MainApp', (event name: instance_created; port: None; parameters: ['fields[0]']))
 			port <input>:
 			port <private_0_<narrow_cast>>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10550d940>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10ef09b20>}
 		Next scheduled internal transition at time 0.000000
 
 
 	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
 		Output Port Configuration:
 			port <port1>:
 				('Field', 'MainApp', (event name: instance_created; port: None; parameters: ['fields[0]']))
@@ -199,9 +198,10 @@ __  Current Time:   0.000000 __________________________________________
 
 
 	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10550d940>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10ef09b20>}
 		Output Port Configuration:
 			port <obj_manager_out>:
+			port <ui>:
 			port <fields>:
 		Next scheduled internal transition at time 0.000000
 
@@ -210,9 +210,10 @@ __  Current Time:   0.000000 __________________________________________
 
 
 	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10550d940>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10ef09b20>}
 		Output Port Configuration:
 			port <obj_manager_out>:
+			port <ui>:
 			port <fields>:
 		Next scheduled internal transition at time 0.000000
 
@@ -225,16 +226,17 @@ __  Current Time:   0.000000 __________________________________________
 			port <input>:
 				('MainApp', 'Field', (event name: start_instance; port: None; parameters: ['fields[0]']))
 				('MainApp', 'Field', (event name: set_association_name; port: None; parameters: ['fields[0]']))
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
 		Next scheduled internal transition at time 0.000000
 
 
 	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10550d940>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10ef09b20>}
 		Output Port Configuration:
 			port <obj_manager_out>:
 				('MainApp', 'Field', (event name: start_instance; port: None; parameters: ['fields[0]']))
 				('MainApp', 'Field', (event name: set_association_name; port: None; parameters: ['fields[0]']))
+			port <ui>:
 			port <fields>:
 		Next scheduled internal transition at time inf
 
@@ -251,12 +253,12 @@ __  Current Time:   0.000000 __________________________________________
 			port <field_ui>:
 			port <private_1_<narrow_cast>>:
 			port <private_2_field_ui>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
 		Next scheduled internal transition at time 0.000000
 
 
 	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
 		Output Port Configuration:
 			port <port1>:
 			port <port2>:
@@ -274,19 +276,20 @@ __  Current Time:   0.000000 __________________________________________
 		Input Port Configuration:
 			port <input>:
 				('Field', 'MainApp', (event name: instance_started; port: None; parameters: ['fields[0]']))
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
 		Next scheduled internal transition at time 0.000000
 
 
 	INTERNAL TRANSITION in model <controller.Field>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
 		Output Port Configuration:
 			port <obj_manager_out>:
 				('Field', 'MainApp', (event name: instance_started; port: None; parameters: ['fields[0]']))
+			port <ui>:
 			port <balls>:
 			port <buttons>:
 			port <parent>:
-		Next scheduled internal transition at time inf
+		Next scheduled internal transition at time 0.000000
 
 
 __  Current Time:   0.000000 __________________________________________ 
@@ -298,12 +301,24 @@ __  Current Time:   0.000000 __________________________________________
 				('Field', 'MainApp', (event name: instance_started; port: None; parameters: ['fields[0]']))
 			port <input>:
 			port <private_0_<narrow_cast>>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10550d940>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10ef09b20>}
 		Next scheduled internal transition at time 0.000000
 
 
+	INTERNAL TRANSITION in model <controller.Field>
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
+		Output Port Configuration:
+			port <obj_manager_out>:
+			port <ui>:
+				(event name: create_window; port: ui; parameters: [800, 600, 'BouncingBalls', 'private_2_field_ui'])
+			port <balls>:
+			port <buttons>:
+			port <parent>:
+		Next scheduled internal transition at time inf
+
+
 	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
 		Output Port Configuration:
 			port <port1>:
 				('Field', 'MainApp', (event name: instance_started; port: None; parameters: ['fields[0]']))
@@ -317,14 +332,15 @@ __  Current Time:   0.000000 __________________________________________
 
 
 	INTERNAL TRANSITION in model <controller.MainApp>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10550d940>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.MainAppInstance object at 0x10ef09b20>}
 		Output Port Configuration:
 			port <obj_manager_out>:
+			port <ui>:
 			port <fields>:
 		Next scheduled internal transition at time inf
 
 
-__  Current Time:   0.050940 __________________________________________ 
+__  Current Time:   6.117143 __________________________________________ 
 
 
 	EXTERNAL TRANSITION in model <controller.Field>
@@ -335,24 +351,42 @@ __  Current Time:   0.050940 __________________________________________
 				Event("window_created","private_2_field_ui",[0])
 			port <private_1_<narrow_cast>>:
 			port <private_2_field_ui>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
-		Next scheduled internal transition at time 0.050940
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
+		Next scheduled internal transition at time 6.117143
 
 
-__  Current Time:   0.050940 __________________________________________ 
+__  Current Time:   6.117143 __________________________________________ 
 
 
 	INTERNAL TRANSITION in model <controller.Field>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
 		Output Port Configuration:
 			port <obj_manager_out>:
+			port <ui>:
+			port <balls>:
+			port <buttons>:
+			port <parent>:
+		Next scheduled internal transition at time 6.117143
+
+
+__  Current Time:   6.117143 __________________________________________ 
+
+
+	INTERNAL TRANSITION in model <controller.Field>
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
+		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'])
+				(event name: bind_event; port: ui; parameters: [0, '<Key>', 'key_press', 'private_2_field_ui'])
+				(event name: create_canvas; port: ui; parameters: [0, 800, 550, {'background': '#eee'}, 'private_2_field_ui'])
 			port <balls>:
 			port <buttons>:
 			port <parent>:
 		Next scheduled internal transition at time inf
 
 
-__  Current Time:   0.070622 __________________________________________ 
+__  Current Time:   6.121296 __________________________________________ 
 
 
 	EXTERNAL TRANSITION in model <controller.Field>
@@ -363,59 +397,65 @@ __  Current Time:   0.070622 __________________________________________
 				Event("canvas_created","private_2_field_ui",[1])
 			port <private_1_<narrow_cast>>:
 			port <private_2_field_ui>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
-		Next scheduled internal transition at time 0.070622
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
+		Next scheduled internal transition at time 6.121296
 
 
-__  Current Time:   0.070622 __________________________________________ 
+__  Current Time:   6.121296 __________________________________________ 
 
 
 	INTERNAL TRANSITION in model <controller.Field>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
 		Output Port Configuration:
 			port <obj_manager_out>:
+			port <ui>:
 			port <balls>:
 			port <buttons>:
 			port <parent>:
-		Next scheduled internal transition at time 0.070622
+		Next scheduled internal transition at time 6.121296
 
 
-__  Current Time:   0.070622 __________________________________________ 
+__  Current Time:   6.121296 __________________________________________ 
 
 
 	INTERNAL TRANSITION in model <controller.Field>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
 		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'])
+				(event name: bind_event; port: ui; parameters: [1, '<Motion>', 'mouse_move', 'private_2_field_ui'])
+				(event name: bind_event; port: ui; parameters: [1, '<ButtonRelease>', 'mouse_release', 'private_2_field_ui'])
 			port <balls>:
 			port <buttons>:
 			port <parent>:
-		Next scheduled internal transition at time 0.070622
+		Next scheduled internal transition at time 6.121296
 
 
-__  Current Time:   0.070622 __________________________________________ 
+__  Current Time:   6.121296 __________________________________________ 
 
 
 	EXTERNAL TRANSITION in model <controller.ObjectManager>
 		Input Port Configuration:
 			port <input>:
 				('Field', 'Button', (event name: create_instance; port: None; parameters: ['buttons', 'Button', 0, 'create_new_field', 'Spawn New Window']))
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
-		Next scheduled internal transition at time 0.070622
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
+		Next scheduled internal transition at time 6.121296
 
 
 	INTERNAL TRANSITION in model <controller.Field>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
 		Output Port Configuration:
 			port <obj_manager_out>:
 				('Field', 'Button', (event name: create_instance; port: None; parameters: ['buttons', 'Button', 0, 'create_new_field', 'Spawn New Window']))
+			port <ui>:
 			port <balls>:
 			port <buttons>:
 			port <parent>:
 		Next scheduled internal transition at time inf
 
 
-__  Current Time:   0.070622 __________________________________________ 
+__  Current Time:   6.121296 __________________________________________ 
 
 
 	EXTERNAL TRANSITION in model <controller.Button>
@@ -426,12 +466,12 @@ __  Current Time:   0.070622 __________________________________________
 			port <button_ui>:
 			port <private_3_<narrow_cast>>:
 			port <private_4_button_ui>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.ButtonInstance object at 0x1055e5730>}
-		Next scheduled internal transition at time 0.070622
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.ButtonInstance object at 0x10ee89610>}
+		Next scheduled internal transition at time 6.121296
 
 
 	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
 		Output Port Configuration:
 			port <port1>:
 			port <port2>:
@@ -441,27 +481,28 @@ __  Current Time:   0.070622 __________________________________________
 		Next scheduled internal transition at time inf
 
 
-__  Current Time:   0.070622 __________________________________________ 
+__  Current Time:   6.121296 __________________________________________ 
 
 
 	EXTERNAL TRANSITION in model <controller.ObjectManager>
 		Input Port Configuration:
 			port <input>:
 				('Button', 'Field', (event name: instance_created; port: None; parameters: ['buttons[0]']))
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
-		Next scheduled internal transition at time 0.070622
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
+		Next scheduled internal transition at time 6.121296
 
 
 	INTERNAL TRANSITION in model <controller.Button>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.ButtonInstance object at 0x1055e5730>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.ButtonInstance object at 0x10ee89610>}
 		Output Port Configuration:
 			port <obj_manager_out>:
 				('Button', 'Field', (event name: instance_created; port: None; parameters: ['buttons[0]']))
+			port <ui>:
 			port <parent>:
 		Next scheduled internal transition at time inf
 
 
-__  Current Time:   0.070622 __________________________________________ 
+__  Current Time:   6.121296 __________________________________________ 
 
 
 	EXTERNAL TRANSITION in model <controller.Field>
@@ -472,12 +513,12 @@ __  Current Time:   0.070622 __________________________________________
 			port <field_ui>:
 			port <private_1_<narrow_cast>>:
 			port <private_2_field_ui>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
-		Next scheduled internal transition at time 0.070622
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
+		Next scheduled internal transition at time 6.121296
 
 
 	INTERNAL TRANSITION in model <controller.ObjectManager>
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
 		Output Port Configuration:
 			port <port1>:
 			port <port2>:
@@ -487,65 +528,41 @@ __  Current Time:   0.070622 __________________________________________
 		Next scheduled internal transition at time inf
 
 
-__  Current Time:   0.070622 __________________________________________ 
+__  Current Time:   6.121296 __________________________________________ 
 
 
 	INTERNAL TRANSITION in model <controller.Field>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
 		Output Port Configuration:
 			port <obj_manager_out>:
+			port <ui>:
 			port <balls>:
 			port <buttons>:
 			port <parent>:
-		Next scheduled internal transition at time 0.070622
+		Next scheduled internal transition at time 6.121296
 
 
-__  Current Time:   0.070622 __________________________________________ 
+__  Current Time:   6.121296 __________________________________________ 
 
 
 	INTERNAL TRANSITION in model <controller.Field>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
+		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x10ee88440>}
 		Output Port Configuration:
 			port <obj_manager_out>:
+			port <ui>:
 			port <balls>:
 			port <buttons>:
 			port <parent>:
-		Next scheduled internal transition at time 0.070622
+		Next scheduled internal transition at time 6.121296
 
 
-__  Current Time:   0.070622 __________________________________________ 
+__  Current Time:   6.121296 __________________________________________ 
 
 
 	EXTERNAL TRANSITION in model <controller.ObjectManager>
 		Input Port Configuration:
 			port <input>:
 				('Field', 'Button', (event name: start_instance; port: None; parameters: ['buttons[0]']))
-		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x1054487a0>
-		Next scheduled internal transition at time 0.070622
-
-
-	INTERNAL TRANSITION in model <controller.Field>
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.FieldInstance object at 0x1055e5a00>}
-		Output Port Configuration:
-			port <obj_manager_out>:
-				('Field', 'Button', (event name: start_instance; port: None; parameters: ['buttons[0]']))
-			port <balls>:
-			port <buttons>:
-			port <parent>:
-		Next scheduled internal transition at time inf
-
-
-__  Current Time:   0.070622 __________________________________________ 
-
-
-	EXTERNAL TRANSITION in model <controller.Button>
-		Input Port Configuration:
-			port <obj_manager_in>:
-				('Field', 'Button', (event name: start_instance; port: None; parameters: ['buttons[0]']))
-			port <input>:
-			port <button_ui>:
-			port <private_3_<narrow_cast>>:
-			port <private_4_button_ui>:
-		New State: {0: <examples.BouncingBalls.PyDEVS.target.ButtonInstance object at 0x1055e5730>}
-		Next scheduled internal transition at time 0.070622
+		New State: <examples.BouncingBalls.PyDEVS.target.ObjectManagerState object at 0x10e947a10>
+		Next scheduled internal transition at time 6.121296
 

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

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

+ 5 - 12
examples/BouncingBalls/Python/test_runner.py

@@ -9,33 +9,26 @@ from sccd.runtime.libs.ui_v2 import UI
 from sccd.runtime.tkinter_eventloop import TkEventLoop
 import time
 
-return_dict = {
-	"create_window": "window_created"
-}
-
-
-
 class OutputListener:
-	def __init__(self, ui, controller):
+	def __init__(self, controller, ui, log_file):
 		self.ui = ui
 		self.controller = controller
+		self.log_file = log_file
 
 	def add(self, event):
+		with open(self.log_file, 'a') as file:
+			file.write(f'{self.controller.getSimulatedTime()/1000} {event}\n')
 		if event.port == "ui":
 			method = getattr(self.ui, event.name)
 			method(*event.parameters)
 
-			#ret_event = return_dict[event.name]
-		#time.sleep(5)
-		#print("check")
-
 
 if __name__ == '__main__':
 	tkroot = tk.Tk()
 	tkroot.withdraw()
 	controller = target.Controller(TkEventLoop(tkroot))
 	ui = UI(tkroot, controller)
-	controller.addMyOwnOutputListener(OutputListener(ui, controller))
+	controller.addMyOwnOutputListener(OutputListener(controller, ui, "./examples/BouncingBalls/Python/output.txt"))
 
 	controller.setVerbose("./examples/BouncingBalls/Python/trace.txt")
 

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 128
examples/BouncingBalls/Python/tester.py


Dosya farkı çok büyük olduğundan ihmal edildi
+ 51 - 2711
examples/BouncingBalls/Python/trace.txt


+ 2 - 13
examples/BouncingBalls/input_trace.txt

@@ -1,15 +1,4 @@
-0.028 field_ui Event("window_created","private_2_field_ui",[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])
-0.87 field_ui Event("mouse_release","private_2_field_ui",[638, 314, 1])
-1.291 field_ui Event("right_click","private_2_field_ui",[638, 314, 2])
-1.292 ball_ui Event("circle_created","private_6_ball_ui",[1, 1])
-1.428 field_ui Event("mouse_release","private_2_field_ui",[638, 314, 2])
-1.842 field_ui Event("mouse_move","private_2_field_ui",[639, 314, '??'])
-1.85 field_ui Event("mouse_move","private_2_field_ui",[650, 312, '??'])
-1.858 field_ui Event("mouse_move","private_2_field_ui",[664, 311, '??'])
-1.866 field_ui Event("mouse_move","private_2_field_ui",[685, 311, '??'])
-1.877 field_ui Event("mouse_move","private_2_field_ui",[706, 311, '??'])
-1.882 field_ui Event("mouse_move","private_2_field_ui",[752, 311, '??'])
-1.89 field_ui Event("mouse_move","private_2_field_ui",[779, 311, '??'])
-3.692 field_ui Event("window_close","private_2_field_ui",None)
+2.202 field_ui Event("window_close","private_2_field_ui",None)

+ 16 - 6
examples/ElevatorBalls/Python/target.py

@@ -165,7 +165,7 @@ class Elevator(RuntimeClassBase):
         self.is_open = False;
         
         self.dim = {'x': 80, 'y': 150};
-        self.vel = {'x': 0, 'y': 0};
+        self.vel = {'x': 0, 'y': -2};
         self.pos = {'x': 400, 'y': 75};
         self.smooth = 0.6; # value between 0 and 1
     
@@ -481,11 +481,21 @@ class Ball(RuntimeClassBase):
         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 <= self.rect_pos['x'] - (self.rect_dim['x'] / 2) or self.pos['x']+self.r >= self.rect_pos['x'] + (self.rect_dim['x'] / 2):
-            self.vel['x'] = -self.vel['x'] + self.rect_vel['x'];
-        if self.pos['y']-self.r <= self.rect_pos['y'] - (self.rect_dim['y'] / 2) or self.pos['y']+self.r >= self.rect_pos['y'] + (self.rect_dim['y'] / 2):
-            self.vel['y'] = -self.vel['y'] + self.rect_vel['y'];
+        # Check collision with the left and right borders
+        if self.pos['x'] - self.r < self.rect_pos['x'] - (self.rect_dim['x'] / 2):
+            self.pos['x'] = self.rect_pos['x'] - (self.rect_dim['x'] / 2) + self.r  # Correct position
+            self.vel['x'] = -self.vel['x'] + self.rect_vel['x']
+        elif self.pos['x'] + self.r > self.rect_pos['x'] + (self.rect_dim['x'] / 2):
+            self.pos['x'] = self.rect_pos['x'] + (self.rect_dim['x'] / 2) - self.r  # Correct position
+            self.vel['x'] = -self.vel['x'] + self.rect_vel['x']
+        
+        # Check collision with the top and bottom borders
+        if self.pos['y'] - self.r < self.rect_pos['y'] - (self.rect_dim['y'] / 2):
+            self.pos['y'] = self.rect_pos['y'] - (self.rect_dim['y'] / 2) + self.r  # Correct position
+            self.vel['y'] = -self.vel['y'] + self.rect_vel['y']
+        elif self.pos['y'] + self.r > self.rect_pos['y'] + (self.rect_dim['y'] / 2):
+            self.pos['y'] = self.rect_pos['y'] + (self.rect_dim['y'] / 2) - self.r  # Correct position
+            self.vel['y'] = -self.vel['y'] + self.rect_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']

+ 16 - 6
examples/ElevatorBalls/sccd.xml

@@ -116,7 +116,7 @@
                 self.is_open = False;
 
                 self.dim = {'x': 80, 'y': 150};
-                self.vel = {'x': 0, 'y': 0};
+                self.vel = {'x': 0, 'y': -2};
                 self.pos = {'x': 400, 'y': 75};
                 self.smooth = 0.6; # value between 0 and 1
                 ]]>
@@ -339,11 +339,21 @@
                     <transition after="0.02" target=".">
                         <script>
                             <![CDATA[
-                            # Invert velocity when colliding with canvas border:
-                            if self.pos['x']-self.r <= self.rect_pos['x'] - (self.rect_dim['x'] / 2) or self.pos['x']+self.r >= self.rect_pos['x'] + (self.rect_dim['x'] / 2):
-                                self.vel['x'] = -self.vel['x'] + self.rect_vel['x'];
-                            if self.pos['y']-self.r <= self.rect_pos['y'] - (self.rect_dim['y'] / 2) or self.pos['y']+self.r >= self.rect_pos['y'] + (self.rect_dim['y'] / 2):
-                                self.vel['y'] = -self.vel['y'] + self.rect_vel['y'];
+                            # Check collision with the left and right borders
+                            if self.pos['x'] - self.r < self.rect_pos['x'] - (self.rect_dim['x'] / 2):
+                                self.pos['x'] = self.rect_pos['x'] - (self.rect_dim['x'] / 2) + self.r  # Correct position
+                                self.vel['x'] = -self.vel['x'] + self.rect_vel['x']
+                            elif self.pos['x'] + self.r > self.rect_pos['x'] + (self.rect_dim['x'] / 2):
+                                self.pos['x'] = self.rect_pos['x'] + (self.rect_dim['x'] / 2) - self.r  # Correct position
+                                self.vel['x'] = -self.vel['x'] + self.rect_vel['x']
+
+                            # Check collision with the top and bottom borders
+                            if self.pos['y'] - self.r < self.rect_pos['y'] - (self.rect_dim['y'] / 2):
+                                self.pos['y'] = self.rect_pos['y'] - (self.rect_dim['y'] / 2) + self.r  # Correct position
+                                self.vel['y'] = -self.vel['y'] + self.rect_vel['y']
+                            elif self.pos['y'] + self.r > self.rect_pos['y'] + (self.rect_dim['y'] / 2):
+                                self.pos['y'] = self.rect_pos['y'] + (self.rect_dim['y'] / 2) - self.r  # Correct position
+                                self.vel['y'] = -self.vel['y'] + self.rect_vel['y']
                             ]]>
                         </script>
                         <raise port="ui" event="move_element">

+ 16 - 10
examples/FixedTimerEventloop/PyDEVS/runner.py

@@ -1,31 +1,37 @@
 import tkinter as tk
-import examples.FixedTimer.PyDEVS.target as target
+import examples.FixedTimerEventloop.PyDEVS.target as target
 from sccd.runtime.libs.ui_v2 import UI
 from sccd.runtime.DEVS_loop import DEVSSimulator
 
+
+
 class OutputListener:
 	def __init__(self, ui):
 		self.ui = ui
 
-	def add(self, event):
-		if event.port == "ui":
-			method = getattr(self.ui, event.name)
-			method(*event.parameters)
+	def add(self, events):
+		for event in events:
+			if event[2].port == "ui":
+				method = getattr(self.ui, event[2].name)
+				method(*event[2].parameters)
 
 if __name__ == '__main__':
 	model = target.Controller(name="controller")
-	refs = {"ui": model.ui, "field_ui": model.atomic0.field_ui}
-	
+	refs = {"ui": model.in_ui, "field_ui": model.atomic0.field_ui}
+
 	tkroot = tk.Tk()
 	tkroot.withdraw()
 	sim = DEVSSimulator(model)
 	sim.setRealTime(True)
-	sim.setRealTimeInputFile(None)
+	#sim.setRealTimeInputFile("./examples/BouncingBalls/input_trace.txt")
 	sim.setRealTimePorts(refs)
-	sim.setVerbose(None)
+	sim.setVerbose("./examples/BouncingBalls/PyDEVS/trace.txt")
+	
 	sim.setRealTimePlatformTk(tkroot)
 
 	ui = UI(tkroot, sim)
+	listener = OutputListener(ui)
+	sim.setListenPorts(model.out_ui, listener.add)
 	model.atomic0.addMyOwnOutputListener(OutputListener(ui))
 	sim.simulate()
-	tkroot.mainloop()
+	tkroot.mainloop()

+ 29 - 10
examples/FixedTimerEventloop/PyDEVS/target.py

@@ -10,8 +10,8 @@ from sccd.runtime.DEVS_statecharts_core import *
 from sccd.runtime.libs.ui import ui
 import time
 
-CANVAS_WIDTH = 800
-CANVAS_HEIGHT = 550
+CANVAS_WIDTH = 350
+CANVAS_HEIGHT = 300
 
 # package "Timer (Eventloop Version)"
 
@@ -39,7 +39,12 @@ class MainAppInstance(RuntimeClassBase):
         
         # call user defined constructor
         MainAppInstance.user_defined_constructor(self)
-        self.inports["field_ui"] = ('field_ui', atomdevs.next_instance)
+        port_name = Ports.addInputPort("<narrow_cast>", self)
+        atomdevs.addInPort(port_name)
+        port_name = Ports.addInputPort("field_ui", self)
+        atomdevs.addInPort(port_name)
+        atomdevs.port_mappings[port_name] = atomdevs.next_instance
+        self.inports["field_ui"] = port_name
     
     def user_defined_constructor(self):
         pass
@@ -129,9 +134,15 @@ class MainAppInstance(RuntimeClassBase):
         _running_0.setTrigger(Event("_0after"))
         self.states["/running"].addTransition(_running_0)
         _running_1 = Transition(self, self.states["/running"], [self.states["/interrupted"]])
-        _running_1.setTrigger(Event("mouse_click", self.getInPortName("button_ui")))
+        _running_1.setTrigger(Event("mouse_click", self.getInPortName("field_ui")))
         _running_1.setGuard(self._running_1_guard)
         self.states["/running"].addTransition(_running_1)
+        
+        # transition /interrupted
+        _interrupted_0 = Transition(self, self.states["/interrupted"], [self.states["/running"]])
+        _interrupted_0.setTrigger(Event("mouse_click", self.getInPortName("field_ui")))
+        _interrupted_0.setGuard(self._interrupted_0_guard)
+        self.states["/interrupted"].addTransition(_interrupted_0)
     
     def _creating_window_enter(self):
         self.big_step.outputEvent(Event("create_window", self.getOutPortName("ui"), [CANVAS_WIDTH, CANVAS_HEIGHT, "Fixed Timer", self.inports['field_ui']]))
@@ -146,7 +157,7 @@ class MainAppInstance(RuntimeClassBase):
         self.big_step.outputEvent(Event("create_text", self.getOutPortName("ui"), [self.canvas_id, 50, 100, '', self.inports['field_ui']]))
     
     def _creating_interrupt_button_enter(self):
-        self.big_step.outputEvent(Event("create_button", self.getOutPortName("ui"), [self.window_id, 'INTERRUPT', self.inports['field_ui']]))
+        self.big_step.outputEvent(Event("create_button", self.getOutPortName("ui"), [self.window_id, 'INTERRUPT/CONTINUE', self.inports['field_ui']]))
     
     def _running_enter(self):
         self.addTimer(0, 0.05)
@@ -164,9 +175,6 @@ class MainAppInstance(RuntimeClassBase):
     def _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 _creating_clock_text_0_exec(self, parameters):
         canvas_id = parameters[0]
@@ -193,6 +201,12 @@ class MainAppInstance(RuntimeClassBase):
         button = parameters[2]
         return button == ui.MOUSE_BUTTONS.LEFT
     
+    def _interrupted_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_window"].getEffectiveTargetStates()
@@ -202,6 +216,7 @@ class MainApp(ObjectManagerBase):
     def __init__(self, name):
         ObjectManagerBase.__init__(self, name)
         self.input = self.addInPort("input")
+        self.output = self.addOutPort("ui")
         self.field_ui = self.addInPort("field_ui")
         self.instances[self.next_instance] = MainAppInstance(self)
         self.next_instance = self.next_instance + 1
@@ -224,8 +239,12 @@ class ObjectManager(TheObjectManager):
 class Controller(CoupledDEVS):
     def __init__(self, name):
         CoupledDEVS.__init__(self, name)
-        self.ui = self.addInPort("ui")
+        self.in_ui = self.addInPort("ui")
+        Ports.addInputPort("ui")
+        self.out_ui = self.addOutPort("ui")
+        Ports.addOutputPort("ui")
         self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
         self.atomic0 = self.addSubModel(MainApp("MainApp"))
         self.connectPorts(self.atomic0.obj_manager_out, self.objectmanager.input)
-        self.connectPorts(self.objectmanager.output["MainApp"], self.atomic0.obj_manager_in)
+        self.connectPorts(self.objectmanager.output["MainApp"], self.atomic0.obj_manager_in)
+        self.connectPorts(self.atomic0.output, self.out_ui)

+ 1 - 0
examples/FixedTimerEventloop/sccd.xml

@@ -9,6 +9,7 @@
     </top>
     
     <inport name="ui" />
+    <outport name="ui"/>
     <class name="MainApp" default="true">
         <attribute name="window_id" />
         <attribute name="canvas_id" />

+ 4 - 4
examples/FixedTimerThread/PyDEVS/runner.py

@@ -1,10 +1,10 @@
-import target as target
+import target as best_target
 from sccd.runtime.DEVS_statecharts_core import Event
 import threading
 
 
 if __name__ == '__main__':
-    controller = target.Controller() 
+    controller = best_target.Controller() 
     
     def raw_inputter():
         while 1:
@@ -29,7 +29,7 @@ if __name__ == '__main__':
 
 
 import tkinter as tk
-import examples.BouncingBalls.PyDEVS.target as target
+import examples.BouncingBalls.PyDEVS.best_target as best_target
 from sccd.runtime.libs.ui_v2 import UI
 from sccd.runtime.DEVS_loop import DEVSSimulator
 
@@ -43,7 +43,7 @@ class OutputListener:
 			method(*event.parameters)
 
 if __name__ == '__main__':
-	model = target.Controller(name="controller")
+	model = best_target.Controller(name="controller")
 	refs = {"ui": model.ui, "field_ui": model.atomic1.field_ui, "button_ui": model.atomic2.button_ui, "ball_ui": model.atomic3.ball_ui}
 
 

+ 24 - 5
sccd/compiler/DEVS_generator.py

@@ -12,7 +12,6 @@ import sccd.compiler.generic_language_constructs as GLC
 
 Platforms = Enum("Threads", "GameLoop", "EventLoop")
 
-
 class DEVSGenerator(Visitor):
     def __init__(self, platform):
         self.platform = platform
@@ -103,10 +102,11 @@ class DEVSGenerator(Visitor):
         self.writer.endSuperClassConstructorCall()
 
         for i in class_diagram.inports:
-            self.writer.addAssignment(GLC.SelfProperty(i),
-                                      GLC.FunctionCall(GLC.SelfProperty("addInPort"), [GLC.String(i)]))
+            self.writer.addAssignment(GLC.SelfProperty("in_" + i), GLC.FunctionCall(GLC.SelfProperty("addInPort"), [GLC.String(i)]))
+            self.writer.add(GLC.FunctionCall("Ports.addInputPort", [GLC.String(i)]))
         for o in class_diagram.outports:
-            self.writer.add(GLC.FunctionCall(GLC.SelfProperty("addOutPort"), [GLC.String(o)]))
+            self.writer.addAssignment(GLC.SelfProperty("out_" + o), GLC.FunctionCall(GLC.SelfProperty("addOutPort"), [GLC.String(o)]))
+            self.writer.add(GLC.FunctionCall("Ports.addOutputPort", [GLC.String(o)]))
 
         # Add AtomicDEVS models
         self.writer.addAssignment(GLC.SelfProperty("objectmanager"), (GLC.FunctionCall(GLC.SelfProperty("addSubModel"),
@@ -138,6 +138,10 @@ class DEVSGenerator(Visitor):
                                                  [GLC.SelfProperty(f"atomic{i}.outputs[\"{association.name}\"]"),
                                                   GLC.SelfProperty(f"atomic{temp}.input")]))
 
+        for (i, the_class) in enumerate(class_diagram.classes):
+            for o in class_diagram.outports:
+                self.writer.add(GLC.FunctionCall(GLC.SelfProperty("connectPorts"), [GLC.SelfProperty(f"atomic{i}.output"), GLC.SelfProperty(f"out_{o}")]))
+
         # TODO: What to do with "actual_parameters"?
         # actual_parameters = [p.getIdent() for p in class_diagram.default_class.constructors[0].parameters]
         # self.writer.add(GLC.FunctionCall(GLC.Property(GLC.SelfProperty("object_manager"), "createInstance"), [GLC.String(class_diagram.default_class.name), GLC.ArrayExpression(actual_parameters)]))
@@ -243,8 +247,17 @@ class DEVSGenerator(Visitor):
             self.writer.addActualParameter(p.getIdent())
         self.writer.endSuperClassMethodCall()
 
+        # TODO
+        #if constructor.parent_class.name != constructor.parent_class.class_diagram.default_class.name:
+        self.writer.addAssignment("port_name", GLC.FunctionCall("Ports.addInputPort", [GLC.String("<narrow_cast>"), "self"]))
+        self.writer.add(GLC.FunctionCall("atomdevs.addInPort", ["port_name"]))
+
         for inp in class_node.inports:
-            self.writer.addAssignment(GLC.SelfProperty(f"inports[\"{inp}\"]"), f"(\'{inp}\', atomdevs.next_instance)")
+            #self.writer.addAssignment(GLC.SelfProperty(f"inports[\"{inp}\"]"), f"(\'{inp}\', atomdevs.next_instance)")
+            self.writer.addAssignment("port_name", GLC.FunctionCall("Ports.addInputPort", [GLC.String(inp), "self"]))
+            self.writer.add(GLC.FunctionCall("atomdevs.addInPort", ["port_name"]))
+            self.writer.addAssignment("atomdevs.port_mappings[port_name]", "atomdevs.next_instance")
+            self.writer.addAssignment(f"self.inports[\"{inp}\"]", "port_name")
 
 
         self.writer.endMethodBody()
@@ -355,6 +368,10 @@ class DEVSGenerator(Visitor):
 
         self.writer.addAssignment(GLC.SelfProperty("input"), GLC.FunctionCall(GLC.SelfProperty("addInPort"), [GLC.String("input")]))
 
+        self.writer.addAssignment(GLC.SelfProperty("output"), GLC.FunctionCall(GLC.SelfProperty("addOutPort"), [GLC.String("ui")]))
+
+
+
         for association in constructor.parent_class.associations:
             self.writer.addAssignment(GLC.SelfProperty(f"outputs[\"{association.name}\"]"),
                                       GLC.FunctionCall(GLC.SelfProperty("addOutPort"), [GLC.String(association.name)]))
@@ -372,6 +389,8 @@ class DEVSGenerator(Visitor):
             #self.writer.add(GLC.FunctionCall(GLC.SelfProperty("instances.append"), [f"{constructor.parent_class.name}Instance(self)"]))
             self.writer.addAssignment("self.instances[self.next_instance]", f"{constructor.parent_class.name}Instance(self)")
             self.writer.addAssignment("self.next_instance", "self.next_instance + 1")
+            #self.writer.addAssignment("port_name", GLC.FunctionCall("Ports.addInputPort", [GLC.String("<narrow_cast>"), "0"]))
+            #self.writer.add(GLC.FunctionCall("self.addInPort", ["port_name"]))
 
         self.writer.endMethodBody()
         self.writer.endConstructor()

+ 4 - 4
sccd/runtime/DEVS_loop.py

@@ -12,13 +12,13 @@ def get_port(text):
 
 
 class DEVSSimulator(Simulator):
-	def __init__(self, model):
-		Simulator.__init__(self, model)	
+	def __init__(self, model, inputs):
+		super().__init__(model)
+		self.setRealTimePorts(inputs)	
 	
 	def addInput(self, event):
 		port_name = get_port(event.port)
-
 		event_string = f"Event(\"{event.name}\",\"{event.port}\",{event.parameters})"
 		event_string = event_string.replace(" ", "")
 		interrupt_string = f"{port_name} {event_string}"
-		self.realtime_interrupt(interrupt_string)
+		self.realtime_interrupt(interrupt_string)

+ 12 - 6
sccd/runtime/DEVS_statecharts_core.py

@@ -808,7 +808,11 @@ class ObjectManagerBase(AtomicDEVS):
         self.handlers[e.getName()](e.getParameters())
 
     def outputEvent(self, event):
-        self.to_send.append((self.name, None, event))
+        self.to_send.append(event)
+        #self.to_send.append((self.name, None, event))
+
+
+
         #for listener in self.output_listeners:
         #    self.to_send.append((self.name, None, event))
         #   listener.add(event)
@@ -1113,18 +1117,20 @@ class ObjectManagerBase(AtomicDEVS):
         self.handleInput()
         self.stepAll()
         next_earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
-        if not (len(self.to_send) == 0):
+        if next_earliest != INFINITY:
+            self.next_time = next_earliest - earliest
+        elif not (len(self.to_send) == 0):
             self.next_time = 0
         elif next_earliest == INFINITY:
             self.next_time = INFINITY
-        else:
-            self.next_time = next_earliest - earliest
+        #else:
+        #    self.next_time = next_earliest - earliest
         return self.instances
 
     def outputFnc(self):
         to_dict = {}
         for sending in self.to_send:
-            if sending[2].port == None:
+            if isinstance(sending, tuple) and sending[2].port == None:
                 if self.obj_manager_out in to_dict:
                     to_dict[self.obj_manager_out].append(sending)
                 else:
@@ -1132,7 +1138,7 @@ class ObjectManagerBase(AtomicDEVS):
             else:
                 the_port = None
                 for port in self.OPorts:
-                    if port.name == sending[2].port:
+                    if port.name == sending.port:
                         the_port = port
                 if the_port in to_dict:
                     to_dict[the_port].append(sending)

+ 0 - 197
sccd_test.txt

@@ -1,197 +0,0 @@
-__  Current Time:   0.000000 __________________________________________ 
-__  Current Time:   0.007000 __________________________________________ 
-INPUT EVENT from port <private_1_<narrow_cast>>
-	\Type: <narrow_cast>
-	\Event: (event name: set_association_name; port: private_1_<narrow_cast>; parameters: ['fields[0]'])
-__  Current Time:   0.028000 __________________________________________ 
-INPUT EVENT from port <private_2_field_ui>
-	\Type: field_ui
-	\Event: (event name: window_created; port: private_2_field_ui; parameters: [0])
-__  Current Time:   0.064000 __________________________________________ 
-INPUT EVENT from port <private_2_field_ui>
-	\Type: field_ui
-	\Event: (event name: canvas_created; port: private_2_field_ui; parameters: [1])
-__  Current Time:   0.072000 __________________________________________ 
-INPUT EVENT from port <private_4_button_ui>
-	\Type: button_ui
-	\Event: (event name: button_created; port: private_4_button_ui; parameters: [2])
-__  Current Time:   0.870000 __________________________________________ 
-INPUT EVENT from port <private_2_field_ui>
-	\Type: field_ui
-	\Event: (event name: mouse_release; port: private_2_field_ui; parameters: [638, 314, 1])
-__  Current Time:   1.291000 __________________________________________ 
-INPUT EVENT from port <private_2_field_ui>
-	\Type: field_ui
-	\Event: (event name: right_click; port: private_2_field_ui; parameters: [638, 314, 2])
-__  Current Time:   1.292000 __________________________________________ 
-INPUT EVENT from port <private_5_<narrow_cast>>
-	\Type: <narrow_cast>
-	\Event: (event name: set_association_name; port: private_5_<narrow_cast>; parameters: ['balls[0]'])
-INPUT EVENT from port <private_6_ball_ui>
-	\Type: ball_ui
-	\Event: (event name: circle_created; port: private_6_ball_ui; parameters: [1, 1])
-__  Current Time:   1.312000 __________________________________________ 
-__  Current Time:   1.332000 __________________________________________ 
-__  Current Time:   1.352000 __________________________________________ 
-__  Current Time:   1.372000 __________________________________________ 
-__  Current Time:   1.392000 __________________________________________ 
-__  Current Time:   1.412000 __________________________________________ 
-__  Current Time:   1.428000 __________________________________________ 
-INPUT EVENT from port <private_2_field_ui>
-	\Type: field_ui
-	\Event: (event name: mouse_release; port: private_2_field_ui; parameters: [638, 314, 2])
-__  Current Time:   1.432000 __________________________________________ 
-__  Current Time:   1.452000 __________________________________________ 
-__  Current Time:   1.472000 __________________________________________ 
-__  Current Time:   1.492000 __________________________________________ 
-__  Current Time:   1.512000 __________________________________________ 
-__  Current Time:   1.532000 __________________________________________ 
-__  Current Time:   1.552000 __________________________________________ 
-__  Current Time:   1.572000 __________________________________________ 
-__  Current Time:   1.592000 __________________________________________ 
-__  Current Time:   1.612000 __________________________________________ 
-__  Current Time:   1.632000 __________________________________________ 
-__  Current Time:   1.652000 __________________________________________ 
-__  Current Time:   1.672000 __________________________________________ 
-__  Current Time:   1.692000 __________________________________________ 
-__  Current Time:   1.712000 __________________________________________ 
-__  Current Time:   1.732000 __________________________________________ 
-__  Current Time:   1.752000 __________________________________________ 
-__  Current Time:   1.772000 __________________________________________ 
-__  Current Time:   1.792000 __________________________________________ 
-__  Current Time:   1.812000 __________________________________________ 
-__  Current Time:   1.832000 __________________________________________ 
-__  Current Time:   1.842000 __________________________________________ 
-INPUT EVENT from port <private_2_field_ui>
-	\Type: field_ui
-	\Event: (event name: mouse_move; port: private_2_field_ui; parameters: [639, 314, '??'])
-__  Current Time:   1.850000 __________________________________________ 
-INPUT EVENT from port <private_2_field_ui>
-	\Type: field_ui
-	\Event: (event name: mouse_move; port: private_2_field_ui; parameters: [650, 312, '??'])
-__  Current Time:   1.852000 __________________________________________ 
-__  Current Time:   1.858000 __________________________________________ 
-INPUT EVENT from port <private_2_field_ui>
-	\Type: field_ui
-	\Event: (event name: mouse_move; port: private_2_field_ui; parameters: [664, 311, '??'])
-__  Current Time:   1.866000 __________________________________________ 
-INPUT EVENT from port <private_2_field_ui>
-	\Type: field_ui
-	\Event: (event name: mouse_move; port: private_2_field_ui; parameters: [685, 311, '??'])
-__  Current Time:   1.872000 __________________________________________ 
-__  Current Time:   1.877000 __________________________________________ 
-INPUT EVENT from port <private_2_field_ui>
-	\Type: field_ui
-	\Event: (event name: mouse_move; port: private_2_field_ui; parameters: [706, 311, '??'])
-__  Current Time:   1.882000 __________________________________________ 
-INPUT EVENT from port <private_2_field_ui>
-	\Type: field_ui
-	\Event: (event name: mouse_move; port: private_2_field_ui; parameters: [752, 311, '??'])
-__  Current Time:   1.890000 __________________________________________ 
-INPUT EVENT from port <private_2_field_ui>
-	\Type: field_ui
-	\Event: (event name: mouse_move; port: private_2_field_ui; parameters: [779, 311, '??'])
-__  Current Time:   1.892000 __________________________________________ 
-__  Current Time:   1.912000 __________________________________________ 
-__  Current Time:   1.932000 __________________________________________ 
-__  Current Time:   1.952000 __________________________________________ 
-__  Current Time:   1.972000 __________________________________________ 
-__  Current Time:   1.992000 __________________________________________ 
-__  Current Time:   2.012000 __________________________________________ 
-__  Current Time:   2.032000 __________________________________________ 
-__  Current Time:   2.052000 __________________________________________ 
-__  Current Time:   2.072000 __________________________________________ 
-__  Current Time:   2.092000 __________________________________________ 
-__  Current Time:   2.112000 __________________________________________ 
-__  Current Time:   2.132000 __________________________________________ 
-__  Current Time:   2.152000 __________________________________________ 
-__  Current Time:   2.172000 __________________________________________ 
-__  Current Time:   2.192000 __________________________________________ 
-__  Current Time:   2.212000 __________________________________________ 
-__  Current Time:   2.232000 __________________________________________ 
-__  Current Time:   2.252000 __________________________________________ 
-__  Current Time:   2.272000 __________________________________________ 
-__  Current Time:   2.292000 __________________________________________ 
-__  Current Time:   2.312000 __________________________________________ 
-__  Current Time:   2.332000 __________________________________________ 
-__  Current Time:   2.352000 __________________________________________ 
-__  Current Time:   2.372000 __________________________________________ 
-__  Current Time:   2.392000 __________________________________________ 
-__  Current Time:   2.412000 __________________________________________ 
-__  Current Time:   2.432000 __________________________________________ 
-__  Current Time:   2.452000 __________________________________________ 
-__  Current Time:   2.472000 __________________________________________ 
-__  Current Time:   2.492000 __________________________________________ 
-__  Current Time:   2.512000 __________________________________________ 
-__  Current Time:   2.532000 __________________________________________ 
-__  Current Time:   2.552000 __________________________________________ 
-__  Current Time:   2.572000 __________________________________________ 
-__  Current Time:   2.592000 __________________________________________ 
-__  Current Time:   2.612000 __________________________________________ 
-__  Current Time:   2.632000 __________________________________________ 
-__  Current Time:   2.652000 __________________________________________ 
-__  Current Time:   2.672000 __________________________________________ 
-__  Current Time:   2.692000 __________________________________________ 
-__  Current Time:   2.712000 __________________________________________ 
-__  Current Time:   2.732000 __________________________________________ 
-__  Current Time:   2.752000 __________________________________________ 
-__  Current Time:   2.772000 __________________________________________ 
-__  Current Time:   2.792000 __________________________________________ 
-__  Current Time:   2.812000 __________________________________________ 
-__  Current Time:   2.832000 __________________________________________ 
-__  Current Time:   2.852000 __________________________________________ 
-__  Current Time:   2.872000 __________________________________________ 
-__  Current Time:   2.892000 __________________________________________ 
-__  Current Time:   2.912000 __________________________________________ 
-__  Current Time:   2.932000 __________________________________________ 
-__  Current Time:   2.952000 __________________________________________ 
-__  Current Time:   2.972000 __________________________________________ 
-__  Current Time:   2.992000 __________________________________________ 
-__  Current Time:   3.012000 __________________________________________ 
-__  Current Time:   3.032000 __________________________________________ 
-__  Current Time:   3.052000 __________________________________________ 
-__  Current Time:   3.072000 __________________________________________ 
-__  Current Time:   3.092000 __________________________________________ 
-__  Current Time:   3.112000 __________________________________________ 
-__  Current Time:   3.132000 __________________________________________ 
-__  Current Time:   3.152000 __________________________________________ 
-__  Current Time:   3.172000 __________________________________________ 
-__  Current Time:   3.192000 __________________________________________ 
-__  Current Time:   3.212000 __________________________________________ 
-__  Current Time:   3.232000 __________________________________________ 
-__  Current Time:   3.252000 __________________________________________ 
-__  Current Time:   3.272000 __________________________________________ 
-__  Current Time:   3.292000 __________________________________________ 
-__  Current Time:   3.312000 __________________________________________ 
-__  Current Time:   3.332000 __________________________________________ 
-__  Current Time:   3.352000 __________________________________________ 
-__  Current Time:   3.372000 __________________________________________ 
-__  Current Time:   3.392000 __________________________________________ 
-__  Current Time:   3.412000 __________________________________________ 
-__  Current Time:   3.432000 __________________________________________ 
-__  Current Time:   3.452000 __________________________________________ 
-__  Current Time:   3.472000 __________________________________________ 
-__  Current Time:   3.492000 __________________________________________ 
-__  Current Time:   3.512000 __________________________________________ 
-__  Current Time:   3.532000 __________________________________________ 
-__  Current Time:   3.552000 __________________________________________ 
-__  Current Time:   3.572000 __________________________________________ 
-__  Current Time:   3.592000 __________________________________________ 
-__  Current Time:   3.612000 __________________________________________ 
-__  Current Time:   3.632000 __________________________________________ 
-__  Current Time:   3.652000 __________________________________________ 
-__  Current Time:   3.672000 __________________________________________ 
-__  Current Time:   3.692000 __________________________________________ 
-INPUT EVENT from port <private_2_field_ui>
-	\Type: field_ui
-	\Event: (event name: window_close; port: private_2_field_ui)
-__  Current Time:   3.712000 __________________________________________ 
-__  Current Time:   3.732000 __________________________________________ 
-__  Current Time:   3.752000 __________________________________________ 
-__  Current Time:   3.758000 __________________________________________ 
-__  Current Time:   3.760000 __________________________________________ 
-INPUT EVENT from port <private_0_<narrow_cast>>
-	\Type: <narrow_cast>
-	\Event: (event name: delete_field; port: private_0_<narrow_cast>; parameters: ['fields[0]'])
-__  Current Time:   3.760000 __________________________________________ 
-__  Current Time:   3.810000 __________________________________________ 

+ 29 - 189
tracechecker/main.py

@@ -1,189 +1,29 @@
-import re
-
-def extract_float(text):
-    # Define a regex pattern to match the float value
-    pattern = r"Current Time:\s+([-+]?\d*\.\d+|\d+)"
-    
-    # Search for the pattern in the text
-    match = re.search(pattern, text)
-    
-    if match:
-        # Extract the matched float value
-        float_value = float(match.group(1))
-        return float_value
-    else:
-        # Handle the case where no match is found
-        return None
-
-def extract_type(text):
-    # Define a regex pattern to match the type value after 'Type:'
-    pattern = r"Type:\s*(\w+)"
-    
-    # Search for the pattern in the text
-    match = re.search(pattern, text)
-    
-    if match:
-        # Extract the matched type value
-        type_value = match.group(1)
-        return type_value
-    else:
-        # Handle the case where no match is found
-        return None
-    
-def extract_event_details(text):
-    #pattern = r"event name:\s*([^;]+);\s*port:\s*([^;]+)(?:;\s*parameters:\s*(\[.*\]))?"
-    pattern = r"event name:\s*([^;]+);\s*port:\s*([^\);]+)(?:;\s*parameters:\s*(\[.*\]))?"
-    match = re.search(pattern, text, re.IGNORECASE)
-    if match:
-        event_name = match.group(1).strip()
-        port = match.group(2).strip()
-        parameters = match.group(3).strip() if match.group(3) else 'None'
-        return event_name, port, parameters
-    else:
-        return None, None, None
-
-
-def generate_input_trace(input_trace, output_file):
-    # Open the file in read mode
-    with open(input_trace, 'r') as file:
-        # Read all lines into a list
-        lines = file.readlines()
-
-    # Open the file in write mode ('w')
-    with open(output_file, 'w') as file:
-        # Traverse each line in the file
-        i = 0
-        current_time = None
-        while i < len(lines):
-            if lines[i].startswith('__'):
-                current_time = extract_float(lines[i].strip())
-
-            # Check if the line starts with 'INPUT'
-            if lines[i].startswith('INPUT'):
-                # Print the line that starts with 'INPUT'
-                print(lines[i].strip())
-                # Check if the next two lines exist and print them
-                the_type = extract_type(lines[i + 1].strip())
-                name, port, parameters = extract_event_details(lines[i + 2].strip())
-
-                if name == None:
-                    name = 'None'
-                if port == None:
-                    port = 'None'
-                if parameters == None:
-                    parameters = 'None'
-
-
-                if the_type is not None:
-                    to_write = str(current_time) + " " + the_type + " Event(\"" + name + "\",\"" + port + "\"," + parameters + ")\n"
-                    file.write(to_write)            
-
-                # Skip the next two lines to avoid reprocessing them
-                i += 2
-            # Move to the next line
-            i += 1
-
-def filter_lines(lines, filter_func):
-    """
-    Filter lines based on the provided filter function.
-    """
-    return [line for line in lines if not filter_func(line)]
-
-def read_and_filter_file(file_path, filter_func):
-    """
-    Read a file and filter its lines using the filter function.
-    """
-    with open(file_path, 'r') as file:
-        lines = file.readlines()
-    return filter_lines(lines, filter_func)
-
-# Fitler, filtering what should be ignored
-temp = False
-def devs_filter(line):
-    global temp
-    if line.startswith('\tEXTERNAL'):
-        temp = True
-    
-    if temp and line.startswith('\n'):
-        temp = False
-
-    condition = not line.startswith('\tEXTERNAL') and not line.startswith('__') and not temp
-
-    return condition
-
-i = 0
-def sccd_filter(line):
-    global i 
-
-    if line.startswith('INPUT'):
-        i = 2
-
-    condition = (not line.startswith('INPUT') and not line.startswith('__'))
-
-    if not line.startswith('INPUT') and i != 0:
-        condition = False
-        i -= 1
-    return condition
-
-def write_filtered_lines_to_file(filtered_lines, output_path):
-    """
-    Write the filtered lines to a file.
-    """
-    with open(output_path, 'w') as file:
-        file.writelines(filtered_lines)
-
-def compare_traces(file1_path, file2_path):
-    """
-    Compare two files line by line after filtering them.
-    """
-
-    filtered_lines1 = read_and_filter_file(file1_path, sccd_filter)
-    filtered_lines2 = read_and_filter_file(file2_path, devs_filter)
-
-    # Write the filtered lines to output files
-    write_filtered_lines_to_file(filtered_lines1, "sccd_test.txt")
-    write_filtered_lines_to_file(filtered_lines2, "devs_test.txt")
-
-    line_num = 1
-    differences = []
-
-    max_lines = max(len(filtered_lines1), len(filtered_lines2))
-    for i in range(max_lines):
-        line1 = filtered_lines1[i] if i < len(filtered_lines1) else ''
-        line2 = filtered_lines2[i] if i < len(filtered_lines2) else ''
-
-        if line1 != line2:
-            differences.append((line_num, line1, line2))
-
-        line_num += 1
-
-    return differences
-
-def print_differences(differences):
-    """
-    Print the differences between the filtered files.
-    """
-    if not differences:
-        print("The files are identical after filtering.")
-    else:
-        for line_num, line1, line2 in differences:
-            print(f"Difference at line {line_num}:")
-            print(f"File1: {line1.strip()}")
-            print(f"File2: {line2.strip()}")
-            print()
-
-# Example filter function to exclude lines starting with a certain keyword
-def example_filter_func(line):
-    return line.startswith('IGNORE')
-
-if __name__ == '__main__':
-    SCCDFile = "./examples/BouncingBalls/Python/trace.txt"
-    DEVSFile = "./examples/BouncingBalls/PyDEVS/trace.txt"
-
-    inputTrace = "./examples/BouncingBalls/input_trace.txt"
-
-    option = 2
-    if option == 1:
-        generate_input_trace(SCCDFile, inputTrace)
-    if option == 2:
-        compare_traces(SCCDFile, DEVSFile)
+import difflib
+
+def are_files_identical(file1_path, file2_path):
+    """Check if two files have the same contents."""
+    with open(file1_path, 'r') as file1, open(file2_path, 'r') as file2:
+        file1_contents = file1.read()
+        file2_contents = file2.read()
+        
+        return file1_contents == file2_contents
+
+def show_file_differences(file1_path, file2_path):
+    """Show differences between two files."""
+    with open(file1_path, 'r') as file1, open(file2_path, 'r') as file2:
+        file1_lines = file1.readlines()
+        file2_lines = file2.readlines()
+        
+        diff = difflib.unified_diff(file1_lines, file2_lines, fromfile='file1', tofile='file2')
+        return ''.join(diff)
+
+# Example usage
+file1_path = "./examples/BouncingBalls/Python/output.txt"
+file2_path = "./examples/BouncingBalls/PyDEVS/output.txt"
+
+if are_files_identical(file1_path, file2_path):
+    print("The files are identical.")
+else:
+    print("The files are different. Here are the differences:")
+    differences = show_file_differences(file1_path, file2_path)
+    print(differences)