best_target.py 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300
  1. """
  2. Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration) and Sam Pieters (DEVS)
  3. Model author: Simon Van Mierlo+Raphael Mannadiar
  4. Model name: Bouncing_Balls_Python_Version
  5. Model description:
  6. Tkinter frame with bouncing balls in it.
  7. """
  8. from sccd.runtime.DEVS_statecharts_core import *
  9. from pypdevs.DEVS import *
  10. from pypdevs.infinity import *
  11. from pypdevs.simulator import *
  12. from sccd.runtime.libs import ui_v2 as ui
  13. from sccd.runtime.libs.utils import utils
  14. import random
  15. CANVAS_WIDTH = 800
  16. CANVAS_HEIGHT = 550
  17. # package "Bouncing_Balls_Python_Version"
  18. class MainAppInstance(RuntimeClassBase):
  19. def __init__(self, atomdevs):
  20. RuntimeClassBase.__init__(self, atomdevs)
  21. self.associations = {}
  22. self.associations["fields"] = Association("Field", 0, -1)
  23. self.semantics.big_step_maximality = StatechartSemantics.TakeMany
  24. self.semantics.internal_event_lifeline = StatechartSemantics.Queue
  25. self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
  26. self.semantics.priority = StatechartSemantics.SourceParent
  27. self.semantics.concurrency = StatechartSemantics.Single
  28. # build Statechart structure
  29. self.build_statechart_structure()
  30. # call user defined constructor
  31. MainAppInstance.user_defined_constructor(self)
  32. def user_defined_constructor(self):
  33. self.nr_of_fields = 0
  34. def user_defined_destructor(self):
  35. pass
  36. # builds Statechart structure
  37. def build_statechart_structure(self):
  38. # state <root>
  39. self.states[""] = State(0, "", self)
  40. # state /running
  41. self.states["/running"] = State(1, "/running", self)
  42. # state /running/root
  43. self.states["/running/root"] = ParallelState(2, "/running/root", self)
  44. # state /running/root/main_behaviour
  45. self.states["/running/root/main_behaviour"] = State(3, "/running/root/main_behaviour", self)
  46. # state /running/root/main_behaviour/initializing
  47. self.states["/running/root/main_behaviour/initializing"] = State(4, "/running/root/main_behaviour/initializing", self)
  48. # state /running/root/main_behaviour/running
  49. self.states["/running/root/main_behaviour/running"] = State(5, "/running/root/main_behaviour/running", self)
  50. # state /running/root/cd_behaviour
  51. self.states["/running/root/cd_behaviour"] = State(6, "/running/root/cd_behaviour", self)
  52. # state /running/root/cd_behaviour/waiting
  53. self.states["/running/root/cd_behaviour/waiting"] = State(7, "/running/root/cd_behaviour/waiting", self)
  54. # state /running/root/cd_behaviour/creating
  55. self.states["/running/root/cd_behaviour/creating"] = State(8, "/running/root/cd_behaviour/creating", self)
  56. # state /running/root/cd_behaviour/check_nr_of_fields
  57. self.states["/running/root/cd_behaviour/check_nr_of_fields"] = State(9, "/running/root/cd_behaviour/check_nr_of_fields", self)
  58. self.states["/running/root/cd_behaviour/check_nr_of_fields"].setEnter(self._running_root_cd_behaviour_check_nr_of_fields_enter)
  59. self.states["/running/root/cd_behaviour/check_nr_of_fields"].setExit(self._running_root_cd_behaviour_check_nr_of_fields_exit)
  60. # state /running/root/cd_behaviour/stopped
  61. self.states["/running/root/cd_behaviour/stopped"] = State(10, "/running/root/cd_behaviour/stopped", self)
  62. # state /running/stopped
  63. self.states["/running/stopped"] = State(11, "/running/stopped", self)
  64. # add children
  65. self.states[""].addChild(self.states["/running"])
  66. self.states["/running"].addChild(self.states["/running/root"])
  67. self.states["/running"].addChild(self.states["/running/stopped"])
  68. self.states["/running/root"].addChild(self.states["/running/root/main_behaviour"])
  69. self.states["/running/root"].addChild(self.states["/running/root/cd_behaviour"])
  70. self.states["/running/root/main_behaviour"].addChild(self.states["/running/root/main_behaviour/initializing"])
  71. self.states["/running/root/main_behaviour"].addChild(self.states["/running/root/main_behaviour/running"])
  72. self.states["/running/root/cd_behaviour"].addChild(self.states["/running/root/cd_behaviour/waiting"])
  73. self.states["/running/root/cd_behaviour"].addChild(self.states["/running/root/cd_behaviour/creating"])
  74. self.states["/running/root/cd_behaviour"].addChild(self.states["/running/root/cd_behaviour/check_nr_of_fields"])
  75. self.states["/running/root/cd_behaviour"].addChild(self.states["/running/root/cd_behaviour/stopped"])
  76. self.states[""].fixTree()
  77. self.states[""].default_state = self.states["/running"]
  78. self.states["/running"].default_state = self.states["/running/root"]
  79. self.states["/running/root/main_behaviour"].default_state = self.states["/running/root/main_behaviour/initializing"]
  80. self.states["/running/root/cd_behaviour"].default_state = self.states["/running/root/cd_behaviour/waiting"]
  81. # transition /running/root/main_behaviour/initializing
  82. _running_root_main_behaviour_initializing_0 = Transition(self, self.states["/running/root/main_behaviour/initializing"], [self.states["/running/root/main_behaviour/running"]])
  83. _running_root_main_behaviour_initializing_0.setAction(self._running_root_main_behaviour_initializing_0_exec)
  84. _running_root_main_behaviour_initializing_0.setTrigger(None)
  85. self.states["/running/root/main_behaviour/initializing"].addTransition(_running_root_main_behaviour_initializing_0)
  86. # transition /running/root/main_behaviour/running
  87. _running_root_main_behaviour_running_0 = Transition(self, self.states["/running/root/main_behaviour/running"], [self.states["/running/root/main_behaviour/running"]])
  88. _running_root_main_behaviour_running_0.setAction(self._running_root_main_behaviour_running_0_exec)
  89. _running_root_main_behaviour_running_0.setTrigger(Event("button_pressed", None))
  90. _running_root_main_behaviour_running_0.setGuard(self._running_root_main_behaviour_running_0_guard)
  91. self.states["/running/root/main_behaviour/running"].addTransition(_running_root_main_behaviour_running_0)
  92. # transition /running/root/cd_behaviour/waiting
  93. _running_root_cd_behaviour_waiting_0 = Transition(self, self.states["/running/root/cd_behaviour/waiting"], [self.states["/running/root/cd_behaviour/creating"]])
  94. _running_root_cd_behaviour_waiting_0.setAction(self._running_root_cd_behaviour_waiting_0_exec)
  95. _running_root_cd_behaviour_waiting_0.setTrigger(Event("create_field", None))
  96. self.states["/running/root/cd_behaviour/waiting"].addTransition(_running_root_cd_behaviour_waiting_0)
  97. _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"]])
  98. _running_root_cd_behaviour_waiting_1.setAction(self._running_root_cd_behaviour_waiting_1_exec)
  99. _running_root_cd_behaviour_waiting_1.setTrigger(Event("delete_field", None))
  100. self.states["/running/root/cd_behaviour/waiting"].addTransition(_running_root_cd_behaviour_waiting_1)
  101. # transition /running/root/cd_behaviour/creating
  102. _running_root_cd_behaviour_creating_0 = Transition(self, self.states["/running/root/cd_behaviour/creating"], [self.states["/running/root/cd_behaviour/waiting"]])
  103. _running_root_cd_behaviour_creating_0.setAction(self._running_root_cd_behaviour_creating_0_exec)
  104. _running_root_cd_behaviour_creating_0.setTrigger(Event("instance_created", None))
  105. self.states["/running/root/cd_behaviour/creating"].addTransition(_running_root_cd_behaviour_creating_0)
  106. # transition /running/root/cd_behaviour/check_nr_of_fields
  107. _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"]])
  108. _running_root_cd_behaviour_check_nr_of_fields_0.setAction(self._running_root_cd_behaviour_check_nr_of_fields_0_exec)
  109. _running_root_cd_behaviour_check_nr_of_fields_0.setTrigger(Event("_0after"))
  110. _running_root_cd_behaviour_check_nr_of_fields_0.setGuard(self._running_root_cd_behaviour_check_nr_of_fields_0_guard)
  111. self.states["/running/root/cd_behaviour/check_nr_of_fields"].addTransition(_running_root_cd_behaviour_check_nr_of_fields_0)
  112. _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"]])
  113. _running_root_cd_behaviour_check_nr_of_fields_1.setTrigger(None)
  114. _running_root_cd_behaviour_check_nr_of_fields_1.setGuard(self._running_root_cd_behaviour_check_nr_of_fields_1_guard)
  115. self.states["/running/root/cd_behaviour/check_nr_of_fields"].addTransition(_running_root_cd_behaviour_check_nr_of_fields_1)
  116. # transition /running/root
  117. _running_root_0 = Transition(self, self.states["/running/root"], [self.states["/running/stopped"]])
  118. _running_root_0.setAction(self._running_root_0_exec)
  119. _running_root_0.setTrigger(Event("stop", None))
  120. self.states["/running/root"].addTransition(_running_root_0)
  121. def _running_root_cd_behaviour_check_nr_of_fields_enter(self):
  122. self.addTimer(0, 0.05)
  123. def _running_root_cd_behaviour_check_nr_of_fields_exit(self):
  124. self.removeTimer(0)
  125. def _running_root_0_exec(self, parameters):
  126. self.big_step.outputEvent(Event("destroy_all", self.getOutPortName("ui"), []))
  127. def _running_root_main_behaviour_initializing_0_exec(self, parameters):
  128. self.raiseInternalEvent(Event("create_field", None, []))
  129. def _running_root_main_behaviour_running_0_exec(self, parameters):
  130. event_name = parameters[0]
  131. self.raiseInternalEvent(Event("create_field", None, []))
  132. def _running_root_main_behaviour_running_0_guard(self, parameters):
  133. event_name = parameters[0]
  134. return event_name == "create_new_field"
  135. def _running_root_cd_behaviour_waiting_0_exec(self, parameters):
  136. self.big_step.outputEventOM(Event("create_instance", None, [self, "fields"]))
  137. def _running_root_cd_behaviour_waiting_1_exec(self, parameters):
  138. association_name = parameters[0]
  139. self.big_step.outputEventOM(Event("delete_instance", None, [self, association_name]))
  140. self.nr_of_fields -= 1
  141. def _running_root_cd_behaviour_creating_0_exec(self, parameters):
  142. association_name = parameters[0]
  143. self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
  144. self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("set_association_name", None, [association_name])]))
  145. self.nr_of_fields += 1
  146. def _running_root_cd_behaviour_check_nr_of_fields_0_exec(self, parameters):
  147. self.raiseInternalEvent(Event("stop", None, []))
  148. def _running_root_cd_behaviour_check_nr_of_fields_0_guard(self, parameters):
  149. return self.nr_of_fields == 0
  150. def _running_root_cd_behaviour_check_nr_of_fields_1_guard(self, parameters):
  151. return self.nr_of_fields != 0
  152. def initializeStatechart(self):
  153. # enter default state
  154. self.default_targets = self.states["/running"].getEffectiveTargetStates()
  155. RuntimeClassBase.initializeStatechart(self)
  156. class MainApp(AtomicDEVS, ObjectManagerBase):
  157. def __init__(self, name):
  158. AtomicDEVS.__init__(self, name)
  159. ObjectManagerBase.__init__(self)
  160. self.elapsed = 0
  161. self.name = "MainApp"
  162. self.obj_manager_out = self.addOutPort("obj_manager_out")
  163. self.outputs = {}
  164. self.outputs["fields"] = self.addOutPort("fields")
  165. self.obj_manager_in = self.addInPort("obj_manager_in")
  166. self.input = self.addInPort("input")
  167. self.instances.add(MainAppInstance(self))
  168. self.next_time = INFINITY
  169. def extTransition(self, inputs):
  170. self.next_time = 0
  171. all_inputs = []
  172. if self.obj_manager_in in inputs:
  173. all_inputs.extend(inputs[self.obj_manager_in])
  174. if self.input in inputs:
  175. all_inputs.extend(inputs[self.input])
  176. for input in all_inputs:
  177. if isinstance(input, str):
  178. tem = eval(input)
  179. self.addInput(tem)
  180. elif input[3].name == "create_instance":
  181. self.instances.add(MainAppInstance(self))
  182. ev = Event("instance_created", None, parameters=[f"{input[3].parameters[0]}[{len(self.instances)-1}]"])
  183. self.to_send.append((input[1], input[0], input[2], ev))
  184. elif input[3].name == "start_instance":
  185. instance = list(self.instances)[input[2]]
  186. instance.start()
  187. ev = Event("instance_started", None, parameters=[f"{input[0]}[{input[2]}]"])
  188. self.to_send.append((input[0], input[1], input[2], ev))
  189. elif input[3].name == "delete_instance":
  190. ev = Event("instance_deleted", None, parameters=[TODO])
  191. self.to_send.append((self.name, TODO, TODO, ev))
  192. elif input[3].name == "associate_instance":
  193. ev = Event("instance_associated", None, parameters=[TODO])
  194. self.to_send.append((self.name, TODO, TODO, ev))
  195. elif input[3].name == "disassociate_instance":
  196. ev = Event("instance_disassociated", None, parameters=[TODO])
  197. self.to_send.append((self.name, TODO, TODO, ev))
  198. elif input[3].name == "instance_created":
  199. association = self.processAssociationReference(input[3].parameters[0])[0]
  200. instance = list(self.instances)[input[2]]
  201. p = instance.associations.get(association[0])
  202. if p:
  203. p.addInstance(input[3].parameters[0])
  204. instance.addEvent(input[3])
  205. #instance.associations['fields'].instances[0] = input[3].parameters[0]
  206. #association = self.processAssociationReference(input[3].parameters[0])[0]
  207. #instance = list(self.instances)[input[2]]
  208. #p = instance.associations.get(association[0])
  209. #if p:
  210. # p.addInstance(input[3].parameters[0])
  211. #instance.addEvent(input[3])
  212. elif input[3].name == "instance_started":
  213. instance = list(self.instances)[input[2]]
  214. instance.addEvent(input[3])
  215. elif input[3].name == "instance_deleted":
  216. instance = list(self.instances)[input[2]]
  217. instance.addEvent(input[3])
  218. elif input[3].name == "instance_associated":
  219. instance = list(self.instances)[input[2]]
  220. instance.addEvent(input[3])
  221. elif input[3].name == "instance_disassociated":
  222. instance = list(self.instances)[input[2]]
  223. instance.addEvent(input[3])
  224. elif input[3].name == "set_association_name":
  225. ev = input[3]
  226. self.addInput(ev, force_internal=True)
  227. else:
  228. ev = input[3]
  229. self.addInput(ev)
  230. return self.instances
  231. def intTransition(self):
  232. earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  233. if not (earliest == INFINITY):
  234. self.simulated_time = earliest
  235. self.to_send = []
  236. self.handleInput()
  237. self.stepAll()
  238. next_earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  239. if not (len(self.to_send) == 0):
  240. self.next_time = 0
  241. elif next_earliest == INFINITY:
  242. self.next_time = INFINITY
  243. else:
  244. self.next_time = next_earliest - earliest
  245. return self.instances
  246. def outputFnc(self):
  247. to_dict = {}
  248. for sending in self.to_send:
  249. if sending[3].port == None:
  250. if self.obj_manager_out in to_dict:
  251. to_dict[self.obj_manager_out].append(sending)
  252. else:
  253. to_dict[self.obj_manager_out] = [sending]
  254. else:
  255. the_port = None
  256. for port in self.OPorts:
  257. if port.name == sending[0]:
  258. the_port = port
  259. if the_port in to_dict:
  260. to_dict[the_port].append(sending)
  261. else:
  262. to_dict[the_port] = [sending]
  263. return to_dict
  264. def timeAdvance(self):
  265. return self.next_time
  266. class FieldInstance(RuntimeClassBase):
  267. num_instances = 0
  268. def __init__(self, atomdevs):
  269. RuntimeClassBase.__init__(self, atomdevs)
  270. self.associations = {}
  271. self.associations["balls"] = Association("Ball", 0, -1)
  272. self.associations["buttons"] = Association("Button", 0, -1)
  273. self.associations["parent"] = Association("MainApp", 1, 1)
  274. self.semantics.big_step_maximality = StatechartSemantics.TakeMany
  275. self.semantics.internal_event_lifeline = StatechartSemantics.Queue
  276. self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
  277. self.semantics.priority = StatechartSemantics.SourceParent
  278. self.semantics.concurrency = StatechartSemantics.Single
  279. # build Statechart structure
  280. self.build_statechart_structure()
  281. # user defined attributes
  282. self.window_id = None
  283. self.canvas_id = None
  284. # call user defined constructor
  285. FieldInstance.user_defined_constructor(self)
  286. self.inports['field_ui'] = ('field_ui', FieldInstance.num_instances)
  287. FieldInstance.num_instances += 1
  288. def user_defined_constructor(self):
  289. pass
  290. def user_defined_destructor(self):
  291. pass
  292. # builds Statechart structure
  293. def build_statechart_structure(self):
  294. # state <root>
  295. self.states[""] = State(0, "", self)
  296. # state /root
  297. self.states["/root"] = State(1, "/root", self)
  298. # state /root/waiting
  299. self.states["/root/waiting"] = State(2, "/root/waiting", self)
  300. # state /root/creating_window
  301. self.states["/root/creating_window"] = State(3, "/root/creating_window", self)
  302. self.states["/root/creating_window"].setEnter(self._root_creating_window_enter)
  303. # state /root/creating_canvas
  304. self.states["/root/creating_canvas"] = State(4, "/root/creating_canvas", self)
  305. self.states["/root/creating_canvas"].setEnter(self._root_creating_canvas_enter)
  306. # state /root/creating_button
  307. self.states["/root/creating_button"] = State(5, "/root/creating_button", self)
  308. self.states["/root/creating_button"].setEnter(self._root_creating_button_enter)
  309. # state /root/running
  310. self.states["/root/running"] = ParallelState(6, "/root/running", self)
  311. # state /root/running/main_behaviour
  312. self.states["/root/running/main_behaviour"] = State(7, "/root/running/main_behaviour", self)
  313. # state /root/running/main_behaviour/running
  314. self.states["/root/running/main_behaviour/running"] = State(8, "/root/running/main_behaviour/running", self)
  315. # state /root/running/main_behaviour/creating_ball
  316. self.states["/root/running/main_behaviour/creating_ball"] = State(9, "/root/running/main_behaviour/creating_ball", self)
  317. # state /root/running/deleting_behaviour
  318. self.states["/root/running/deleting_behaviour"] = State(10, "/root/running/deleting_behaviour", self)
  319. # state /root/running/deleting_behaviour/running
  320. self.states["/root/running/deleting_behaviour/running"] = State(11, "/root/running/deleting_behaviour/running", self)
  321. # state /root/running/child_behaviour
  322. self.states["/root/running/child_behaviour"] = State(12, "/root/running/child_behaviour", self)
  323. # state /root/running/child_behaviour/listening
  324. self.states["/root/running/child_behaviour/listening"] = State(13, "/root/running/child_behaviour/listening", self)
  325. # state /root/running/deleting_balls_behaviour
  326. self.states["/root/running/deleting_balls_behaviour"] = State(14, "/root/running/deleting_balls_behaviour", self)
  327. # state /root/running/deleting_balls_behaviour/listening
  328. self.states["/root/running/deleting_balls_behaviour/listening"] = State(15, "/root/running/deleting_balls_behaviour/listening", self)
  329. # state /root/deleting
  330. self.states["/root/deleting"] = State(16, "/root/deleting", self)
  331. # state /root/deleted
  332. self.states["/root/deleted"] = State(17, "/root/deleted", self)
  333. # add children
  334. self.states[""].addChild(self.states["/root"])
  335. self.states["/root"].addChild(self.states["/root/waiting"])
  336. self.states["/root"].addChild(self.states["/root/creating_window"])
  337. self.states["/root"].addChild(self.states["/root/creating_canvas"])
  338. self.states["/root"].addChild(self.states["/root/creating_button"])
  339. self.states["/root"].addChild(self.states["/root/running"])
  340. self.states["/root"].addChild(self.states["/root/deleting"])
  341. self.states["/root"].addChild(self.states["/root/deleted"])
  342. self.states["/root/running"].addChild(self.states["/root/running/main_behaviour"])
  343. self.states["/root/running"].addChild(self.states["/root/running/deleting_behaviour"])
  344. self.states["/root/running"].addChild(self.states["/root/running/child_behaviour"])
  345. self.states["/root/running"].addChild(self.states["/root/running/deleting_balls_behaviour"])
  346. self.states["/root/running/main_behaviour"].addChild(self.states["/root/running/main_behaviour/running"])
  347. self.states["/root/running/main_behaviour"].addChild(self.states["/root/running/main_behaviour/creating_ball"])
  348. self.states["/root/running/deleting_behaviour"].addChild(self.states["/root/running/deleting_behaviour/running"])
  349. self.states["/root/running/child_behaviour"].addChild(self.states["/root/running/child_behaviour/listening"])
  350. self.states["/root/running/deleting_balls_behaviour"].addChild(self.states["/root/running/deleting_balls_behaviour/listening"])
  351. self.states[""].fixTree()
  352. self.states[""].default_state = self.states["/root"]
  353. self.states["/root"].default_state = self.states["/root/waiting"]
  354. self.states["/root/running/main_behaviour"].default_state = self.states["/root/running/main_behaviour/running"]
  355. self.states["/root/running/deleting_behaviour"].default_state = self.states["/root/running/deleting_behaviour/running"]
  356. self.states["/root/running/child_behaviour"].default_state = self.states["/root/running/child_behaviour/listening"]
  357. self.states["/root/running/deleting_balls_behaviour"].default_state = self.states["/root/running/deleting_balls_behaviour/listening"]
  358. # transition /root/waiting
  359. _root_waiting_0 = Transition(self, self.states["/root/waiting"], [self.states["/root/creating_window"]])
  360. _root_waiting_0.setAction(self._root_waiting_0_exec)
  361. _root_waiting_0.setTrigger(Event("set_association_name", None))
  362. self.states["/root/waiting"].addTransition(_root_waiting_0)
  363. # transition /root/creating_window
  364. _root_creating_window_0 = Transition(self, self.states["/root/creating_window"], [self.states["/root/creating_canvas"]])
  365. _root_creating_window_0.setAction(self._root_creating_window_0_exec)
  366. _root_creating_window_0.setTrigger(Event("window_created", None))
  367. self.states["/root/creating_window"].addTransition(_root_creating_window_0)
  368. # transition /root/creating_canvas
  369. _root_creating_canvas_0 = Transition(self, self.states["/root/creating_canvas"], [self.states["/root/creating_button"]])
  370. _root_creating_canvas_0.setAction(self._root_creating_canvas_0_exec)
  371. _root_creating_canvas_0.setTrigger(Event("canvas_created", None))
  372. self.states["/root/creating_canvas"].addTransition(_root_creating_canvas_0)
  373. # transition /root/creating_button
  374. _root_creating_button_0 = Transition(self, self.states["/root/creating_button"], [self.states["/root/running"]])
  375. _root_creating_button_0.setAction(self._root_creating_button_0_exec)
  376. _root_creating_button_0.setTrigger(Event("instance_created", None))
  377. self.states["/root/creating_button"].addTransition(_root_creating_button_0)
  378. # transition /root/running/main_behaviour/running
  379. _root_running_main_behaviour_running_0 = Transition(self, self.states["/root/running/main_behaviour/running"], [self.states["/root/running/main_behaviour/creating_ball"]])
  380. _root_running_main_behaviour_running_0.setAction(self._root_running_main_behaviour_running_0_exec)
  381. _root_running_main_behaviour_running_0.setTrigger(Event("right_click", self.getInPortName("field_ui")))
  382. self.states["/root/running/main_behaviour/running"].addTransition(_root_running_main_behaviour_running_0)
  383. # transition /root/running/main_behaviour/creating_ball
  384. _root_running_main_behaviour_creating_ball_0 = Transition(self, self.states["/root/running/main_behaviour/creating_ball"], [self.states["/root/running/main_behaviour/running"]])
  385. _root_running_main_behaviour_creating_ball_0.setAction(self._root_running_main_behaviour_creating_ball_0_exec)
  386. _root_running_main_behaviour_creating_ball_0.setTrigger(Event("instance_created", None))
  387. self.states["/root/running/main_behaviour/creating_ball"].addTransition(_root_running_main_behaviour_creating_ball_0)
  388. # transition /root/running/deleting_behaviour/running
  389. _root_running_deleting_behaviour_running_0 = Transition(self, self.states["/root/running/deleting_behaviour/running"], [self.states["/root/running/deleting_behaviour/running"]])
  390. _root_running_deleting_behaviour_running_0.setAction(self._root_running_deleting_behaviour_running_0_exec)
  391. _root_running_deleting_behaviour_running_0.setTrigger(Event("delete_ball", None))
  392. self.states["/root/running/deleting_behaviour/running"].addTransition(_root_running_deleting_behaviour_running_0)
  393. # transition /root/running/child_behaviour/listening
  394. _root_running_child_behaviour_listening_0 = Transition(self, self.states["/root/running/child_behaviour/listening"], [self.states["/root/running/child_behaviour/listening"]])
  395. _root_running_child_behaviour_listening_0.setAction(self._root_running_child_behaviour_listening_0_exec)
  396. _root_running_child_behaviour_listening_0.setTrigger(Event("button_pressed", None))
  397. self.states["/root/running/child_behaviour/listening"].addTransition(_root_running_child_behaviour_listening_0)
  398. # transition /root/running/deleting_balls_behaviour/listening
  399. _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"]])
  400. _root_running_deleting_balls_behaviour_listening_0.setAction(self._root_running_deleting_balls_behaviour_listening_0_exec)
  401. _root_running_deleting_balls_behaviour_listening_0.setTrigger(Event("key_press", self.getInPortName("field_ui")))
  402. _root_running_deleting_balls_behaviour_listening_0.setGuard(self._root_running_deleting_balls_behaviour_listening_0_guard)
  403. self.states["/root/running/deleting_balls_behaviour/listening"].addTransition(_root_running_deleting_balls_behaviour_listening_0)
  404. # transition /root/deleting
  405. _root_deleting_0 = Transition(self, self.states["/root/deleting"], [self.states["/root/deleted"]])
  406. _root_deleting_0.setAction(self._root_deleting_0_exec)
  407. _root_deleting_0.setTrigger(None)
  408. self.states["/root/deleting"].addTransition(_root_deleting_0)
  409. # transition /root/running
  410. _root_running_0 = Transition(self, self.states["/root/running"], [self.states["/root/deleting"]])
  411. _root_running_0.setAction(self._root_running_0_exec)
  412. _root_running_0.setTrigger(Event("window_close", self.getInPortName("field_ui")))
  413. self.states["/root/running"].addTransition(_root_running_0)
  414. def _root_creating_window_enter(self):
  415. self.big_step.outputEvent(Event("create_window", self.getOutPortName("ui"), [800, 600, "BouncingBalls", self.inports['field_ui']]))
  416. def _root_creating_canvas_enter(self):
  417. self.big_step.outputEvent(Event("create_canvas", self.getOutPortName("ui"), [self.window_id, CANVAS_WIDTH, CANVAS_HEIGHT, {'background':'#eee'}, self.inports['field_ui']]))
  418. def _root_creating_button_enter(self):
  419. self.big_step.outputEventOM(Event("create_instance", None, [self, "buttons", "Button", self.window_id, 'create_new_field', 'Spawn New Window']))
  420. def _root_running_0_exec(self, parameters):
  421. self.big_step.outputEventOM(Event("delete_instance", None, [self, "buttons"]))
  422. self.big_step.outputEventOM(Event("delete_instance", None, [self, "balls"]))
  423. def _root_waiting_0_exec(self, parameters):
  424. association_name = parameters[0]
  425. self.association_name = association_name
  426. def _root_creating_window_0_exec(self, parameters):
  427. window_id = parameters[0]
  428. self.window_id = window_id
  429. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [window_id, ui.EVENTS.WINDOW_CLOSE, 'window_close', self.inports['field_ui']]))
  430. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [window_id, ui.EVENTS.KEY_PRESS, 'key_press', self.inports['field_ui']]))
  431. def _root_creating_canvas_0_exec(self, parameters):
  432. canvas_id = parameters[0]
  433. self.canvas_id = canvas_id
  434. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [canvas_id, ui.EVENTS.MOUSE_RIGHT_CLICK, 'right_click', self.inports['field_ui']]))
  435. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [canvas_id, ui.EVENTS.MOUSE_MOVE, 'mouse_move', self.inports['field_ui']]))
  436. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [canvas_id, ui.EVENTS.MOUSE_RELEASE, 'mouse_release', self.inports['field_ui']]))
  437. def _root_creating_button_0_exec(self, parameters):
  438. association_name = parameters[0]
  439. self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
  440. def _root_running_main_behaviour_running_0_exec(self, parameters):
  441. x = parameters[0]
  442. y = parameters[1]
  443. button = parameters[2]
  444. self.big_step.outputEventOM(Event("create_instance", None, [self, "balls", "Ball", self.canvas_id, x, y]))
  445. def _root_running_main_behaviour_creating_ball_0_exec(self, parameters):
  446. association_name = parameters[0]
  447. self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
  448. self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("set_association_name", None, [association_name])]))
  449. def _root_running_deleting_behaviour_running_0_exec(self, parameters):
  450. association_name = parameters[0]
  451. self.big_step.outputEventOM(Event("delete_instance", None, [self, association_name]))
  452. def _root_running_child_behaviour_listening_0_exec(self, parameters):
  453. event_name = parameters[0]
  454. self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("button_pressed", None, [event_name])]))
  455. def _root_running_deleting_balls_behaviour_listening_0_exec(self, parameters):
  456. key = parameters[0]
  457. self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'balls', Event("delete_self", None, [])]))
  458. def _root_running_deleting_balls_behaviour_listening_0_guard(self, parameters):
  459. key = parameters[0]
  460. return key == ui.KEYCODES.DELETE
  461. def _root_deleting_0_exec(self, parameters):
  462. self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("delete_field", None, [self.association_name])]))
  463. self.big_step.outputEvent(Event("destroy_window", self.getOutPortName("ui"), [self.window_id]))
  464. def initializeStatechart(self):
  465. # enter default state
  466. self.default_targets = self.states["/root"].getEffectiveTargetStates()
  467. RuntimeClassBase.initializeStatechart(self)
  468. class Field(AtomicDEVS, ObjectManagerBase):
  469. def __init__(self, name):
  470. AtomicDEVS.__init__(self, name)
  471. ObjectManagerBase.__init__(self)
  472. self.elapsed = 0
  473. self.name = "Field"
  474. self.obj_manager_out = self.addOutPort("obj_manager_out")
  475. self.outputs = {}
  476. self.outputs["balls"] = self.addOutPort("balls")
  477. self.outputs["buttons"] = self.addOutPort("buttons")
  478. self.outputs["parent"] = self.addOutPort("parent")
  479. self.field_ui = self.addInPort("field_ui")
  480. self.obj_manager_in = self.addInPort("obj_manager_in")
  481. self.input = self.addInPort("input")
  482. self.next_time = INFINITY
  483. def extTransition(self, inputs):
  484. self.next_time = 0
  485. all_inputs = []
  486. if self.field_ui in inputs:
  487. all_inputs.extend(inputs[self.field_ui])
  488. if self.obj_manager_in in inputs:
  489. all_inputs.extend(inputs[self.obj_manager_in])
  490. if self.input in inputs:
  491. all_inputs.extend(inputs[self.input])
  492. for input in all_inputs:
  493. if isinstance(input, str):
  494. tem = eval(input)
  495. self.addInput(tem)
  496. elif input[3].name == "create_instance":
  497. new_instance = FieldInstance(self)
  498. self.instances.add(new_instance)
  499. #TODO: hardcoded but needs to be fixed
  500. p = new_instance.associations.get("parent")
  501. if p:
  502. p.addInstance(f"mainapp[0]")
  503. ev = Event("instance_created", None, parameters=[f"{input[3].parameters[0]}[{len(self.instances)-1}]"])
  504. self.to_send.append((input[1], input[0], input[2], ev))
  505. elif input[3].name == "start_instance":
  506. instance = list(self.instances)[input[2]]
  507. instance.start()
  508. ev = Event("instance_started", None, parameters=[f"{input[0]}[{input[2]}]"])
  509. self.to_send.append((input[0], input[1], input[2], ev))
  510. elif input[3].name == "delete_instance":
  511. ev = Event("instance_deleted", None, parameters=[TODO])
  512. self.to_send.append((self.name, TODO, TODO, ev))
  513. elif input[3].name == "associate_instance":
  514. ev = Event("instance_associated", None, parameters=[TODO])
  515. self.to_send.append((self.name, TODO, TODO, ev))
  516. elif input[3].name == "disassociate_instance":
  517. ev = Event("instance_disassociated", None, parameters=[TODO])
  518. self.to_send.append((self.name, TODO, TODO, ev))
  519. elif input[3].name == "instance_created":
  520. association = self.processAssociationReference(input[3].parameters[0])[0]
  521. instance = list(self.instances)[input[2]]
  522. p = instance.associations.get(association[0])
  523. if p:
  524. p.addInstance(input[3].parameters[0])
  525. instance.addEvent(input[3])
  526. elif input[3].name == "instance_started":
  527. instance = list(self.instances)[input[2]]
  528. instance.addEvent(input[3])
  529. elif input[3].name == "instance_deleted":
  530. instance = list(self.instances)[input[2]]
  531. instance.addEvent(input[3])
  532. elif input[3].name == "instance_associated":
  533. instance = list(self.instances)[input[2]]
  534. instance.addEvent(input[3])
  535. elif input[3].name == "instance_disassociated":
  536. instance = list(self.instances)[input[2]]
  537. instance.addEvent(input[3])
  538. elif input[3].name == "set_association_name":
  539. ev = input[3]
  540. self.addInput(ev, force_internal=True)
  541. else:
  542. ev = input[3]
  543. self.addInput(ev)
  544. return self.instances
  545. def intTransition(self):
  546. earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  547. if not (earliest == INFINITY):
  548. self.simulated_time = earliest
  549. self.to_send = []
  550. self.handleInput()
  551. self.stepAll()
  552. next_earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  553. if not (len(self.to_send) == 0):
  554. self.next_time = 0
  555. elif next_earliest == INFINITY:
  556. self.next_time = INFINITY
  557. else:
  558. self.next_time = next_earliest - earliest
  559. return self.instances
  560. def outputFnc(self):
  561. to_dict = {}
  562. for sending in self.to_send:
  563. if sending[3].port == None:
  564. if self.obj_manager_out in to_dict:
  565. to_dict[self.obj_manager_out].append(sending)
  566. else:
  567. to_dict[self.obj_manager_out] = [sending]
  568. else:
  569. the_port = None
  570. for port in self.OPorts:
  571. if port.name == sending[0]:
  572. the_port = port
  573. if the_port in to_dict:
  574. to_dict[the_port].append(sending)
  575. else:
  576. to_dict[the_port] = [sending]
  577. return to_dict
  578. def timeAdvance(self):
  579. return self.next_time
  580. class ButtonInstance(RuntimeClassBase):
  581. num_instances = 0
  582. def __init__(self, atomdevs, window_id, event_name, button_text):
  583. RuntimeClassBase.__init__(self, atomdevs)
  584. self.associations = {}
  585. self.associations["parent"] = Association("Field", 1, 1)
  586. self.semantics.big_step_maximality = StatechartSemantics.TakeMany
  587. self.semantics.internal_event_lifeline = StatechartSemantics.Queue
  588. self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
  589. self.semantics.priority = StatechartSemantics.SourceParent
  590. self.semantics.concurrency = StatechartSemantics.Single
  591. # build Statechart structure
  592. self.build_statechart_structure()
  593. # user defined attributes
  594. self.window_id = None
  595. self.event_name = None
  596. self.button_id = None
  597. # call user defined constructor
  598. ButtonInstance.user_defined_constructor(self, window_id, event_name, button_text)
  599. self.inports['button_ui'] = ('button_ui', ButtonInstance.num_instances)
  600. ButtonInstance.num_instances += 1
  601. def user_defined_constructor(self, window_id, event_name, button_text):
  602. self.window_id = window_id;
  603. self.event_name = event_name;
  604. def user_defined_destructor(self):
  605. pass
  606. # builds Statechart structure
  607. def build_statechart_structure(self):
  608. # state <root>
  609. self.states[""] = State(0, "", self)
  610. # state /creating_button
  611. self.states["/creating_button"] = State(1, "/creating_button", self)
  612. self.states["/creating_button"].setEnter(self._creating_button_enter)
  613. # state /running
  614. self.states["/running"] = State(2, "/running", self)
  615. # add children
  616. self.states[""].addChild(self.states["/creating_button"])
  617. self.states[""].addChild(self.states["/running"])
  618. self.states[""].fixTree()
  619. self.states[""].default_state = self.states["/creating_button"]
  620. # transition /creating_button
  621. _creating_button_0 = Transition(self, self.states["/creating_button"], [self.states["/running"]])
  622. _creating_button_0.setAction(self._creating_button_0_exec)
  623. _creating_button_0.setTrigger(Event("button_created", None))
  624. self.states["/creating_button"].addTransition(_creating_button_0)
  625. # transition /running
  626. _running_0 = Transition(self, self.states["/running"], [self.states["/running"]])
  627. _running_0.setAction(self._running_0_exec)
  628. _running_0.setTrigger(Event("mouse_click", self.getInPortName("button_ui")))
  629. _running_0.setGuard(self._running_0_guard)
  630. self.states["/running"].addTransition(_running_0)
  631. def _creating_button_enter(self):
  632. self.big_step.outputEvent(Event("create_button", self.getOutPortName("ui"), [self.window_id, self.event_name, self.inports['button_ui']]))
  633. def _creating_button_0_exec(self, parameters):
  634. button_id = parameters[0]
  635. self.button_id = button_id
  636. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [button_id, ui.EVENTS.MOUSE_CLICK, "mouse_click", self.inports['button_ui']]))
  637. def _running_0_exec(self, parameters):
  638. x = parameters[0]
  639. y = parameters[1]
  640. button = parameters[2]
  641. self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("button_pressed", None, [self.event_name])]))
  642. def _running_0_guard(self, parameters):
  643. x = parameters[0]
  644. y = parameters[1]
  645. button = parameters[2]
  646. return button == ui.MOUSE_BUTTONS.LEFT
  647. def initializeStatechart(self):
  648. # enter default state
  649. self.default_targets = self.states["/creating_button"].getEffectiveTargetStates()
  650. RuntimeClassBase.initializeStatechart(self)
  651. class Button(AtomicDEVS, ObjectManagerBase):
  652. def __init__(self, name):
  653. AtomicDEVS.__init__(self, name)
  654. ObjectManagerBase.__init__(self)
  655. self.elapsed = 0
  656. self.name = "Button"
  657. self.obj_manager_out = self.addOutPort("obj_manager_out")
  658. self.outputs = {}
  659. self.outputs["parent"] = self.addOutPort("parent")
  660. self.button_ui = self.addInPort("button_ui")
  661. self.obj_manager_in = self.addInPort("obj_manager_in")
  662. self.input = self.addInPort("input")
  663. self.next_time = INFINITY
  664. def extTransition(self, inputs):
  665. self.next_time = 0
  666. all_inputs = []
  667. if self.button_ui in inputs:
  668. all_inputs.extend(inputs[self.button_ui])
  669. if self.obj_manager_in in inputs:
  670. all_inputs.extend(inputs[self.obj_manager_in])
  671. if self.input in inputs:
  672. all_inputs.extend(inputs[self.input])
  673. for input in all_inputs:
  674. if isinstance(input, str):
  675. tem = eval(input)
  676. self.addInput(tem)
  677. elif input[3].name == "create_instance":
  678. new_instance = ButtonInstance(self, input[3].parameters[1], input[3].parameters[2], input[3].parameters[3])
  679. self.instances.add(new_instance)
  680. #TODO: hardcoded but needs to be fixed
  681. p = new_instance.associations.get("parent")
  682. if p:
  683. p.addInstance(f"fields[0]")
  684. ev = Event("instance_created", None, parameters=[f"{input[3].parameters[0]}[{len(self.instances)-1}]"])
  685. self.to_send.append((input[1], input[0], input[2], ev))
  686. elif input[3].name == "start_instance":
  687. instance = list(self.instances)[input[2]]
  688. instance.start()
  689. ev = Event("instance_started", None, parameters=[f"{input[0]}[{input[2]}]"])
  690. self.to_send.append((input[0], input[1], input[2], ev))
  691. elif input[3].name == "delete_instance":
  692. instance = list(self.instances)[input[2]]
  693. instance.user_defined_destructor()
  694. instance.stop()
  695. ev = Event("instance_deleted", None, parameters=[self, input[0]])
  696. self.to_send.append((self.name, input[1], input[2], ev))
  697. elif input[3].name == "associate_instance":
  698. ev = Event("instance_associated", None, parameters=[TODO])
  699. self.to_send.append((self.name, TODO, TODO, ev))
  700. elif input[3].name == "disassociate_instance":
  701. ev = Event("instance_disassociated", None, parameters=[TODO])
  702. self.to_send.append((self.name, TODO, TODO, ev))
  703. elif input[3].name == "instance_created":
  704. instance = list(self.instances)[input[2]]
  705. instance.addEvent(input[3])
  706. instance.associations['fields'].instances[0] = input[3].parameters[0]
  707. elif input[3].name == "instance_started":
  708. instance = list(self.instances)[input[2]]
  709. instance.addEvent(input[3])
  710. elif input[3].name == "instance_deleted":
  711. instance = list(self.instances)[input[2]]
  712. instance.addEvent(input[3])
  713. elif input[3].name == "instance_associated":
  714. instance = list(self.instances)[input[2]]
  715. instance.addEvent(input[3])
  716. elif input[3].name == "instance_disassociated":
  717. instance = list(self.instances)[input[2]]
  718. instance.addEvent(input[3])
  719. elif input[3].name == "set_association_name":
  720. ev = input[3]
  721. self.addInput(ev, force_internal=True)
  722. return self.instances
  723. def intTransition(self):
  724. earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  725. if not (earliest == INFINITY):
  726. self.simulated_time = earliest
  727. self.to_send = []
  728. self.handleInput()
  729. self.stepAll()
  730. next_earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  731. if not (len(self.to_send) == 0):
  732. self.next_time = 0
  733. elif next_earliest == INFINITY:
  734. self.next_time = INFINITY
  735. else:
  736. self.next_time = next_earliest - earliest
  737. return self.instances
  738. def outputFnc(self):
  739. to_dict = {}
  740. for sending in self.to_send:
  741. if sending[3].port == None:
  742. if self.obj_manager_out in to_dict:
  743. to_dict[self.obj_manager_out].append(sending)
  744. else:
  745. to_dict[self.obj_manager_out] = [sending]
  746. else:
  747. the_port = None
  748. for port in self.OPorts:
  749. if port.name == sending[0]:
  750. the_port = port
  751. if the_port in to_dict:
  752. to_dict[the_port].append(sending)
  753. else:
  754. to_dict[the_port] = [sending]
  755. return to_dict
  756. def timeAdvance(self):
  757. return self.next_time
  758. class BallInstance(RuntimeClassBase):
  759. num_instances = 0
  760. def __init__(self, atomdevs, canvas_id, x, y):
  761. RuntimeClassBase.__init__(self, atomdevs)
  762. self.associations = {}
  763. self.associations["parent"] = Association("Field", 1, 1)
  764. self.semantics.big_step_maximality = StatechartSemantics.TakeMany
  765. self.semantics.internal_event_lifeline = StatechartSemantics.Queue
  766. self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
  767. self.semantics.priority = StatechartSemantics.SourceParent
  768. self.semantics.concurrency = StatechartSemantics.Single
  769. # build Statechart structure
  770. self.build_statechart_structure()
  771. # user defined attributes
  772. self.canvas_id = None
  773. self.pos = None
  774. # call user defined constructor
  775. BallInstance.user_defined_constructor(self, canvas_id, x, y)
  776. self.inports['ball_ui'] = ('ball_ui', BallInstance.num_instances)
  777. BallInstance.num_instances += 1
  778. def user_defined_constructor(self, canvas_id, x, y):
  779. self.canvas_id = canvas_id;
  780. self.r = 20.0;
  781. self.vel = {'x': random.uniform(-5.0, 5.0), 'y': random.uniform(-5.0, 5.0)};
  782. self.pos = {'x': x, 'y': y};
  783. self.smooth = 0.6; # value between 0 and 1
  784. # TODO:
  785. #circle = self.canvas.add_circle(x, y, self.r, {'fill':'#000'});
  786. #ui.bind_event(circle, ui.EVENTS.MOUSE_PRESS, self.controller, 'mouse_press', self.inports["ball_ui"]);
  787. #ui.bind_event(circle, ui.EVENTS.MOUSE_MOVE, self.controller, 'mouse_move', self.inports['ball_ui']);
  788. #ui.bind_event(circle, ui.EVENTS.MOUSE_RELEASE, self.controller, 'mouse_release', self.inports['ball_ui']);
  789. #self.element = circle;
  790. def user_defined_destructor(self):
  791. #self.canvas.remove_element(self.element);
  792. pass
  793. # builds Statechart structure
  794. def build_statechart_structure(self):
  795. # state <root>
  796. self.states[""] = State(0, "", self)
  797. # state /main_behaviour
  798. self.states["/main_behaviour"] = State(1, "/main_behaviour", self)
  799. # state /main_behaviour/initializing
  800. self.states["/main_behaviour/initializing"] = State(2, "/main_behaviour/initializing", self)
  801. # state /main_behaviour/creating_circle
  802. self.states["/main_behaviour/creating_circle"] = State(3, "/main_behaviour/creating_circle", self)
  803. self.states["/main_behaviour/creating_circle"].setEnter(self._main_behaviour_creating_circle_enter)
  804. # state /main_behaviour/bouncing
  805. self.states["/main_behaviour/bouncing"] = State(4, "/main_behaviour/bouncing", self)
  806. self.states["/main_behaviour/bouncing"].setEnter(self._main_behaviour_bouncing_enter)
  807. self.states["/main_behaviour/bouncing"].setExit(self._main_behaviour_bouncing_exit)
  808. # state /main_behaviour/dragging
  809. self.states["/main_behaviour/dragging"] = State(5, "/main_behaviour/dragging", self)
  810. # state /main_behaviour/selected
  811. self.states["/main_behaviour/selected"] = State(6, "/main_behaviour/selected", self)
  812. # state /deleted
  813. self.states["/deleted"] = State(7, "/deleted", self)
  814. # add children
  815. self.states[""].addChild(self.states["/main_behaviour"])
  816. self.states[""].addChild(self.states["/deleted"])
  817. self.states["/main_behaviour"].addChild(self.states["/main_behaviour/initializing"])
  818. self.states["/main_behaviour"].addChild(self.states["/main_behaviour/creating_circle"])
  819. self.states["/main_behaviour"].addChild(self.states["/main_behaviour/bouncing"])
  820. self.states["/main_behaviour"].addChild(self.states["/main_behaviour/dragging"])
  821. self.states["/main_behaviour"].addChild(self.states["/main_behaviour/selected"])
  822. self.states[""].fixTree()
  823. self.states[""].default_state = self.states["/main_behaviour"]
  824. self.states["/main_behaviour"].default_state = self.states["/main_behaviour/initializing"]
  825. # transition /main_behaviour/initializing
  826. _main_behaviour_initializing_0 = Transition(self, self.states["/main_behaviour/initializing"], [self.states["/main_behaviour/creating_circle"]])
  827. _main_behaviour_initializing_0.setAction(self._main_behaviour_initializing_0_exec)
  828. _main_behaviour_initializing_0.setTrigger(Event("set_association_name", None))
  829. self.states["/main_behaviour/initializing"].addTransition(_main_behaviour_initializing_0)
  830. # transition /main_behaviour/creating_circle
  831. _main_behaviour_creating_circle_0 = Transition(self, self.states["/main_behaviour/creating_circle"], [self.states["/main_behaviour/bouncing"]])
  832. _main_behaviour_creating_circle_0.setAction(self._main_behaviour_creating_circle_0_exec)
  833. _main_behaviour_creating_circle_0.setTrigger(Event("circle_created", None))
  834. self.states["/main_behaviour/creating_circle"].addTransition(_main_behaviour_creating_circle_0)
  835. # transition /main_behaviour/bouncing
  836. _main_behaviour_bouncing_0 = Transition(self, self.states["/main_behaviour/bouncing"], [self.states["/main_behaviour/bouncing"]])
  837. _main_behaviour_bouncing_0.setAction(self._main_behaviour_bouncing_0_exec)
  838. _main_behaviour_bouncing_0.setTrigger(Event("_0after"))
  839. self.states["/main_behaviour/bouncing"].addTransition(_main_behaviour_bouncing_0)
  840. _main_behaviour_bouncing_1 = Transition(self, self.states["/main_behaviour/bouncing"], [self.states["/main_behaviour/selected"]])
  841. _main_behaviour_bouncing_1.setAction(self._main_behaviour_bouncing_1_exec)
  842. _main_behaviour_bouncing_1.setTrigger(Event("mouse_press", self.getInPortName("ball_ui")))
  843. _main_behaviour_bouncing_1.setGuard(self._main_behaviour_bouncing_1_guard)
  844. self.states["/main_behaviour/bouncing"].addTransition(_main_behaviour_bouncing_1)
  845. # transition /main_behaviour/dragging
  846. _main_behaviour_dragging_0 = Transition(self, self.states["/main_behaviour/dragging"], [self.states["/main_behaviour/dragging"]])
  847. _main_behaviour_dragging_0.setAction(self._main_behaviour_dragging_0_exec)
  848. _main_behaviour_dragging_0.setTrigger(Event("mouse_move", self.getInPortName("ball_ui")))
  849. self.states["/main_behaviour/dragging"].addTransition(_main_behaviour_dragging_0)
  850. _main_behaviour_dragging_1 = Transition(self, self.states["/main_behaviour/dragging"], [self.states["/main_behaviour/bouncing"]])
  851. _main_behaviour_dragging_1.setAction(self._main_behaviour_dragging_1_exec)
  852. _main_behaviour_dragging_1.setTrigger(Event("mouse_release", self.getInPortName("ball_ui")))
  853. self.states["/main_behaviour/dragging"].addTransition(_main_behaviour_dragging_1)
  854. # transition /main_behaviour/selected
  855. _main_behaviour_selected_0 = Transition(self, self.states["/main_behaviour/selected"], [self.states["/main_behaviour/dragging"]])
  856. _main_behaviour_selected_0.setAction(self._main_behaviour_selected_0_exec)
  857. _main_behaviour_selected_0.setTrigger(Event("mouse_press", self.getInPortName("ball_ui")))
  858. _main_behaviour_selected_0.setGuard(self._main_behaviour_selected_0_guard)
  859. self.states["/main_behaviour/selected"].addTransition(_main_behaviour_selected_0)
  860. _main_behaviour_selected_1 = Transition(self, self.states["/main_behaviour/selected"], [self.states["/deleted"]])
  861. _main_behaviour_selected_1.setAction(self._main_behaviour_selected_1_exec)
  862. _main_behaviour_selected_1.setTrigger(Event("delete_self", None))
  863. self.states["/main_behaviour/selected"].addTransition(_main_behaviour_selected_1)
  864. def _main_behaviour_creating_circle_enter(self):
  865. 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']]))
  866. def _main_behaviour_bouncing_enter(self):
  867. self.addTimer(0, 0.02)
  868. def _main_behaviour_bouncing_exit(self):
  869. self.removeTimer(0)
  870. def _main_behaviour_initializing_0_exec(self, parameters):
  871. association_name = parameters[0]
  872. self.association_name = association_name
  873. def _main_behaviour_creating_circle_0_exec(self, parameters):
  874. canvas_id = parameters[0]
  875. circle_id = parameters[1]
  876. self.circle_id = circle_id
  877. 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']]))
  878. 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']]))
  879. 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']]))
  880. def _main_behaviour_bouncing_0_exec(self, parameters):
  881. # Invert velocity when colliding with canvas border:
  882. if self.pos['x']-self.r <= 0 or self.pos['x']+self.r >= CANVAS_WIDTH:
  883. self.vel['x'] = -self.vel['x'];
  884. if self.pos['y']-self.r <= 0 or self.pos['y']+self.r >= CANVAS_HEIGHT:
  885. self.vel['y'] = -self.vel['y'];
  886. self.big_step.outputEvent(Event("move_element", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, self.vel['x'], self.vel['y']]))
  887. self.pos['x'] += self.vel['x']
  888. self.pos['y'] += self.vel['y']
  889. def _main_behaviour_bouncing_1_exec(self, parameters):
  890. x = parameters[0]
  891. y = parameters[1]
  892. button = parameters[2]
  893. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, '#ff0']))
  894. def _main_behaviour_bouncing_1_guard(self, parameters):
  895. x = parameters[0]
  896. y = parameters[1]
  897. button = parameters[2]
  898. return button == ui.MOUSE_BUTTONS.LEFT
  899. def _main_behaviour_dragging_0_exec(self, parameters):
  900. x = parameters[0]
  901. y = parameters[1]
  902. button = parameters[2]
  903. # Always keep ball within canvas:
  904. x = min(max(0+self.r, x), CANVAS_WIDTH-self.r)
  905. y = min(max(0+self.r, y), CANVAS_HEIGHT-self.r)
  906. dx = x - self.pos['x']
  907. dy = y - self.pos['y']
  908. self.vel = {
  909. 'x': (1-self.smooth)*dx + self.smooth*self.vel['x'],
  910. 'y': (1-self.smooth)*dy + self.smooth*self.vel['y']
  911. }
  912. self.pos = {'x': x, 'y': y}
  913. self.big_step.outputEvent(Event("set_element_pos", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, x-self.r, y-self.r]))
  914. def _main_behaviour_dragging_1_exec(self, parameters):
  915. x = parameters[0]
  916. y = parameters[1]
  917. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, '#f00']))
  918. def _main_behaviour_selected_0_exec(self, parameters):
  919. x = parameters[0]
  920. y = parameters[1]
  921. button = parameters[2]
  922. self.mouse_pos = {'x':x, 'y':y};
  923. def _main_behaviour_selected_0_guard(self, parameters):
  924. x = parameters[0]
  925. y = parameters[1]
  926. button = parameters[2]
  927. return button == ui.MOUSE_BUTTONS.LEFT
  928. def _main_behaviour_selected_1_exec(self, parameters):
  929. self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("delete_ball", None, [self.association_name])]))
  930. self.big_step.outputEvent(Event("destroy_element", self.getOutPortName("ui"), [self.canvas_id, self.element_id]))
  931. def initializeStatechart(self):
  932. # enter default state
  933. self.default_targets = self.states["/main_behaviour"].getEffectiveTargetStates()
  934. RuntimeClassBase.initializeStatechart(self)
  935. class Ball(AtomicDEVS, ObjectManagerBase):
  936. def __init__(self, name):
  937. AtomicDEVS.__init__(self, name)
  938. ObjectManagerBase.__init__(self)
  939. self.elapsed = 0
  940. self.name = "Ball"
  941. self.obj_manager_out = self.addOutPort("obj_manager_out")
  942. self.outputs = {}
  943. self.outputs["parent"] = self.addOutPort("parent")
  944. self.ball_ui = self.addInPort("ball_ui")
  945. self.obj_manager_in = self.addInPort("obj_manager_in")
  946. self.input = self.addInPort("input")
  947. self.next_time = INFINITY
  948. def extTransition(self, inputs):
  949. self.simulated_time += self.elapsed
  950. self.next_time = 0
  951. all_inputs = []
  952. if self.ball_ui in inputs:
  953. all_inputs.extend(inputs[self.ball_ui])
  954. if self.obj_manager_in in inputs:
  955. all_inputs.extend(inputs[self.obj_manager_in])
  956. if self.input in inputs:
  957. all_inputs.extend(inputs[self.input])
  958. for input in all_inputs:
  959. if isinstance(input, str):
  960. tem = eval(input)
  961. self.addInput(tem)
  962. elif input[3].name == "create_instance":
  963. self.instances.add(BallInstance(self, input[3].parameters[1], input[3].parameters[2], input[3].parameters[3]))
  964. ev = Event("instance_created", None, parameters=[f"{input[3].parameters[0]}[{len(self.instances)-1}]"])
  965. self.to_send.append((self.name, input[0], input[2], ev))
  966. elif input[3].name == "start_instance":
  967. instance = list(self.instances)[input[3].parameters[0]]
  968. instance.start()
  969. ev = Event("instance_started", None, parameters=[input[3].parameters[0]])
  970. self.to_send.append((input[0], input[1], input[3].parameters[0], ev))
  971. elif input[3].name == "delete_instance":
  972. ev = Event("instance_deleted", None, parameters=[])
  973. self.to_send.append((self.name, input[0], input[2], ev))
  974. elif input[3].name == "associate_instance":
  975. ev = Event("instance_associated", None, parameters=[TODO])
  976. self.to_send.append((self.name, TODO, TODO, ev))
  977. elif input[3].name == "disassociate_instance":
  978. ev = Event("instance_disassociated", None, parameters=[TODO])
  979. self.to_send.append((self.name, TODO, TODO, ev))
  980. elif input[3].name == "instance_created":
  981. association = self.processAssociationReference(input[3].parameters[0])[0]
  982. instance = list(self.instances)[association[1]]
  983. instance.addEvent(input[3])
  984. instance.associations['fields'].instances[0] = input[3].parameters[0]
  985. elif input[3].name == "instance_started":
  986. instance = list(self.instances)[input[3].parameters[0]]
  987. instance.addEvent(input[3])
  988. elif input[3].name == "instance_deleted":
  989. instance = list(self.instances)[input[2]]
  990. instance.addEvent(input[3])
  991. elif input[3].name == "instance_associated":
  992. instance = list(self.instances)[input[2]]
  993. instance.addEvent(input[3])
  994. elif input[3].name == "instance_disassociated":
  995. instance = list(self.instances)[input[2]]
  996. instance.addEvent(input[3])
  997. elif input[3].name == "set_association_name":
  998. ev = input[3]
  999. self.addInput(ev, force_internal=True)
  1000. return self.instances
  1001. def intTransition(self):
  1002. # TODO: self.simulated_time added here, do this everywhere
  1003. earliest = min(self.getEarliestEventTime(), self.simulated_time + self.input_queue.getEarliestTime())
  1004. if not (earliest == INFINITY):
  1005. self.simulated_time = earliest
  1006. self.to_send = []
  1007. self.handleInput()
  1008. self.stepAll()
  1009. next_earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  1010. if not (len(self.to_send) == 0):
  1011. self.next_time = 0
  1012. elif next_earliest == INFINITY:
  1013. self.next_time = INFINITY
  1014. else:
  1015. self.next_time = next_earliest - earliest
  1016. #helping = self.time_next[0] - self.time_last[0]
  1017. return self.instances
  1018. def outputFnc(self):
  1019. to_dict = {}
  1020. for sending in self.to_send:
  1021. if sending[3].port == None:
  1022. if self.obj_manager_out in to_dict:
  1023. to_dict[self.obj_manager_out].append(sending)
  1024. else:
  1025. to_dict[self.obj_manager_out] = [sending]
  1026. else:
  1027. the_port = None
  1028. for port in self.OPorts:
  1029. if port.name == sending[0]:
  1030. the_port = port
  1031. if the_port in to_dict:
  1032. to_dict[the_port].append(sending)
  1033. else:
  1034. to_dict[the_port] = [sending]
  1035. return to_dict
  1036. def timeAdvance(self):
  1037. return self.next_time
  1038. class ObjectManagerState:
  1039. def __init__(self):
  1040. self.to_send = [(None, "MainApp", 0, Event("start_instance", None, None))]
  1041. class ObjectManager(AtomicDEVS):
  1042. def __init__(self, name):
  1043. AtomicDEVS.__init__(self, name)
  1044. self.State = ObjectManagerState()
  1045. self.input = self.addInPort("input")
  1046. self.output = {}
  1047. self.output["MainApp"] = self.addOutPort()
  1048. self.output["Field"] = self.addOutPort()
  1049. self.output["Button"] = self.addOutPort()
  1050. self.output["Ball"] = self.addOutPort()
  1051. def extTransition(self, inputs):
  1052. all_inputs = inputs[self.input]
  1053. for input in all_inputs:
  1054. self.State.to_send.append(input)
  1055. return self.State
  1056. def intTransition(self):
  1057. self.State.to_send = []
  1058. return self.State
  1059. def outputFnc(self):
  1060. out_dict = {}
  1061. for (source, target, id, message) in self.State.to_send:
  1062. if self.output[target] in out_dict:
  1063. out_dict[self.output[target]].append((source, target, id, message))
  1064. else:
  1065. out_dict[self.output[target]] = [(source, target, id, message)]
  1066. return out_dict
  1067. def timeAdvance(self):
  1068. if self.State.to_send:
  1069. return 0
  1070. return INFINITY
  1071. class Controller(CoupledDEVS):
  1072. def __init__(self, name):
  1073. CoupledDEVS.__init__(self, name)
  1074. self.ui = self.addInPort("ui")
  1075. self.addOutPort("ui")
  1076. self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
  1077. self.atomic0 = self.addSubModel(MainApp("MainApp"))
  1078. self.atomic1 = self.addSubModel(Field("Field"))
  1079. self.atomic2 = self.addSubModel(Button("Button"))
  1080. self.atomic3 = self.addSubModel(Ball("Ball"))
  1081. self.connectPorts(self.atomic0.obj_manager_out, self.objectmanager.input)
  1082. self.connectPorts(self.objectmanager.output["MainApp"], self.atomic0.obj_manager_in)
  1083. self.connectPorts(self.atomic0.outputs["fields"], self.atomic1.input)
  1084. self.connectPorts(self.atomic1.obj_manager_out, self.objectmanager.input)
  1085. self.connectPorts(self.objectmanager.output["Field"], self.atomic1.obj_manager_in)
  1086. self.connectPorts(self.atomic1.outputs["balls"], self.atomic3.input)
  1087. self.connectPorts(self.atomic1.outputs["buttons"], self.atomic2.input)
  1088. self.connectPorts(self.atomic1.outputs["parent"], self.atomic0.input)
  1089. self.connectPorts(self.atomic2.obj_manager_out, self.objectmanager.input)
  1090. self.connectPorts(self.objectmanager.output["Button"], self.atomic2.obj_manager_in)
  1091. self.connectPorts(self.atomic2.outputs["parent"], self.atomic1.input)
  1092. self.connectPorts(self.atomic3.obj_manager_out, self.objectmanager.input)
  1093. self.connectPorts(self.objectmanager.output["Ball"], self.atomic3.obj_manager_in)
  1094. self.connectPorts(self.atomic3.outputs["parent"], self.atomic1.input)