target.py 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236
  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. instance = list(self.instances)[input[2]]
  200. instance.addEvent(input[3])
  201. instance.associations['fields'].instances[0] = input[3].parameters[0]
  202. elif input[3].name == "instance_started":
  203. instance = list(self.instances)[input[2]]
  204. instance.addEvent(input[3])
  205. elif input[3].name == "instance_deleted":
  206. instance = list(self.instances)[input[2]]
  207. instance.addEvent(input[3])
  208. elif input[3].name == "instance_associated":
  209. instance = list(self.instances)[input[2]]
  210. instance.addEvent(input[3])
  211. elif input[3].name == "instance_disassociated":
  212. instance = list(self.instances)[input[2]]
  213. instance.addEvent(input[3])
  214. elif input[3].name == "set_association_name":
  215. ev = input[3]
  216. self.addInput(ev, force_internal=True)
  217. return self.instances
  218. def intTransition(self):
  219. earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  220. if not (earliest == INFINITY):
  221. self.simulated_time = earliest
  222. self.to_send = []
  223. self.handleInput()
  224. self.stepAll()
  225. next_earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  226. if not (len(self.to_send) == 0):
  227. self.next_time = 0
  228. elif next_earliest == INFINITY:
  229. self.next_time = INFINITY
  230. else:
  231. self.next_time = next_earliest - earliest
  232. return self.instances
  233. def outputFnc(self):
  234. to_dict = {}
  235. for sending in self.to_send:
  236. if sending[3].port == None:
  237. if self.obj_manager_out in to_dict:
  238. to_dict[self.obj_manager_out].append(sending)
  239. else:
  240. to_dict[self.obj_manager_out] = [sending]
  241. else:
  242. the_port = None
  243. for port in self.OPorts:
  244. if port.name == sending[0]:
  245. the_port = port
  246. if the_port in to_dict:
  247. to_dict[the_port].append(sending)
  248. else:
  249. to_dict[the_port] = [sending]
  250. return to_dict
  251. def timeAdvance(self):
  252. return self.next_time
  253. class FieldInstance(RuntimeClassBase):
  254. def __init__(self, atomdevs):
  255. RuntimeClassBase.__init__(self, atomdevs)
  256. self.associations = {}
  257. self.associations["balls"] = Association("Ball", 0, -1)
  258. self.associations["buttons"] = Association("Button", 0, -1)
  259. self.associations["parent"] = Association("MainApp", 1, 1)
  260. self.semantics.big_step_maximality = StatechartSemantics.TakeMany
  261. self.semantics.internal_event_lifeline = StatechartSemantics.Queue
  262. self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
  263. self.semantics.priority = StatechartSemantics.SourceParent
  264. self.semantics.concurrency = StatechartSemantics.Single
  265. # build Statechart structure
  266. self.build_statechart_structure()
  267. # user defined attributes
  268. self.window_id = None
  269. self.canvas_id = None
  270. # call user defined constructor
  271. FieldInstance.user_defined_constructor(self)
  272. def user_defined_constructor(self):
  273. pass
  274. def user_defined_destructor(self):
  275. pass
  276. # builds Statechart structure
  277. def build_statechart_structure(self):
  278. # state <root>
  279. self.states[""] = State(0, "", self)
  280. # state /root
  281. self.states["/root"] = State(1, "/root", self)
  282. # state /root/waiting
  283. self.states["/root/waiting"] = State(2, "/root/waiting", self)
  284. # state /root/creating_window
  285. self.states["/root/creating_window"] = State(3, "/root/creating_window", self)
  286. self.states["/root/creating_window"].setEnter(self._root_creating_window_enter)
  287. # state /root/creating_canvas
  288. self.states["/root/creating_canvas"] = State(4, "/root/creating_canvas", self)
  289. self.states["/root/creating_canvas"].setEnter(self._root_creating_canvas_enter)
  290. # state /root/creating_button
  291. self.states["/root/creating_button"] = State(5, "/root/creating_button", self)
  292. self.states["/root/creating_button"].setEnter(self._root_creating_button_enter)
  293. # state /root/running
  294. self.states["/root/running"] = ParallelState(6, "/root/running", self)
  295. # state /root/running/main_behaviour
  296. self.states["/root/running/main_behaviour"] = State(7, "/root/running/main_behaviour", self)
  297. # state /root/running/main_behaviour/running
  298. self.states["/root/running/main_behaviour/running"] = State(8, "/root/running/main_behaviour/running", self)
  299. # state /root/running/main_behaviour/creating_ball
  300. self.states["/root/running/main_behaviour/creating_ball"] = State(9, "/root/running/main_behaviour/creating_ball", self)
  301. # state /root/running/deleting_behaviour
  302. self.states["/root/running/deleting_behaviour"] = State(10, "/root/running/deleting_behaviour", self)
  303. # state /root/running/deleting_behaviour/running
  304. self.states["/root/running/deleting_behaviour/running"] = State(11, "/root/running/deleting_behaviour/running", self)
  305. # state /root/running/child_behaviour
  306. self.states["/root/running/child_behaviour"] = State(12, "/root/running/child_behaviour", self)
  307. # state /root/running/child_behaviour/listening
  308. self.states["/root/running/child_behaviour/listening"] = State(13, "/root/running/child_behaviour/listening", self)
  309. # state /root/running/deleting_balls_behaviour
  310. self.states["/root/running/deleting_balls_behaviour"] = State(14, "/root/running/deleting_balls_behaviour", self)
  311. # state /root/running/deleting_balls_behaviour/listening
  312. self.states["/root/running/deleting_balls_behaviour/listening"] = State(15, "/root/running/deleting_balls_behaviour/listening", self)
  313. # state /root/deleting
  314. self.states["/root/deleting"] = State(16, "/root/deleting", self)
  315. # state /root/deleted
  316. self.states["/root/deleted"] = State(17, "/root/deleted", self)
  317. # add children
  318. self.states[""].addChild(self.states["/root"])
  319. self.states["/root"].addChild(self.states["/root/waiting"])
  320. self.states["/root"].addChild(self.states["/root/creating_window"])
  321. self.states["/root"].addChild(self.states["/root/creating_canvas"])
  322. self.states["/root"].addChild(self.states["/root/creating_button"])
  323. self.states["/root"].addChild(self.states["/root/running"])
  324. self.states["/root"].addChild(self.states["/root/deleting"])
  325. self.states["/root"].addChild(self.states["/root/deleted"])
  326. self.states["/root/running"].addChild(self.states["/root/running/main_behaviour"])
  327. self.states["/root/running"].addChild(self.states["/root/running/deleting_behaviour"])
  328. self.states["/root/running"].addChild(self.states["/root/running/child_behaviour"])
  329. self.states["/root/running"].addChild(self.states["/root/running/deleting_balls_behaviour"])
  330. self.states["/root/running/main_behaviour"].addChild(self.states["/root/running/main_behaviour/running"])
  331. self.states["/root/running/main_behaviour"].addChild(self.states["/root/running/main_behaviour/creating_ball"])
  332. self.states["/root/running/deleting_behaviour"].addChild(self.states["/root/running/deleting_behaviour/running"])
  333. self.states["/root/running/child_behaviour"].addChild(self.states["/root/running/child_behaviour/listening"])
  334. self.states["/root/running/deleting_balls_behaviour"].addChild(self.states["/root/running/deleting_balls_behaviour/listening"])
  335. self.states[""].fixTree()
  336. self.states[""].default_state = self.states["/root"]
  337. self.states["/root"].default_state = self.states["/root/waiting"]
  338. self.states["/root/running/main_behaviour"].default_state = self.states["/root/running/main_behaviour/running"]
  339. self.states["/root/running/deleting_behaviour"].default_state = self.states["/root/running/deleting_behaviour/running"]
  340. self.states["/root/running/child_behaviour"].default_state = self.states["/root/running/child_behaviour/listening"]
  341. self.states["/root/running/deleting_balls_behaviour"].default_state = self.states["/root/running/deleting_balls_behaviour/listening"]
  342. # transition /root/waiting
  343. _root_waiting_0 = Transition(self, self.states["/root/waiting"], [self.states["/root/creating_window"]])
  344. _root_waiting_0.setAction(self._root_waiting_0_exec)
  345. _root_waiting_0.setTrigger(Event("set_association_name", None))
  346. self.states["/root/waiting"].addTransition(_root_waiting_0)
  347. # transition /root/creating_window
  348. _root_creating_window_0 = Transition(self, self.states["/root/creating_window"], [self.states["/root/creating_canvas"]])
  349. _root_creating_window_0.setAction(self._root_creating_window_0_exec)
  350. _root_creating_window_0.setTrigger(Event("window_created", None))
  351. self.states["/root/creating_window"].addTransition(_root_creating_window_0)
  352. # transition /root/creating_canvas
  353. _root_creating_canvas_0 = Transition(self, self.states["/root/creating_canvas"], [self.states["/root/creating_button"]])
  354. _root_creating_canvas_0.setAction(self._root_creating_canvas_0_exec)
  355. _root_creating_canvas_0.setTrigger(Event("canvas_created", None))
  356. self.states["/root/creating_canvas"].addTransition(_root_creating_canvas_0)
  357. # transition /root/creating_button
  358. _root_creating_button_0 = Transition(self, self.states["/root/creating_button"], [self.states["/root/running"]])
  359. _root_creating_button_0.setAction(self._root_creating_button_0_exec)
  360. _root_creating_button_0.setTrigger(Event("instance_created", None))
  361. self.states["/root/creating_button"].addTransition(_root_creating_button_0)
  362. # transition /root/running/main_behaviour/running
  363. _root_running_main_behaviour_running_0 = Transition(self, self.states["/root/running/main_behaviour/running"], [self.states["/root/running/main_behaviour/creating_ball"]])
  364. _root_running_main_behaviour_running_0.setAction(self._root_running_main_behaviour_running_0_exec)
  365. _root_running_main_behaviour_running_0.setTrigger(Event("right_click", self.getInPortName("field_ui")))
  366. self.states["/root/running/main_behaviour/running"].addTransition(_root_running_main_behaviour_running_0)
  367. # transition /root/running/main_behaviour/creating_ball
  368. _root_running_main_behaviour_creating_ball_0 = Transition(self, self.states["/root/running/main_behaviour/creating_ball"], [self.states["/root/running/main_behaviour/running"]])
  369. _root_running_main_behaviour_creating_ball_0.setAction(self._root_running_main_behaviour_creating_ball_0_exec)
  370. _root_running_main_behaviour_creating_ball_0.setTrigger(Event("instance_created", None))
  371. self.states["/root/running/main_behaviour/creating_ball"].addTransition(_root_running_main_behaviour_creating_ball_0)
  372. # transition /root/running/deleting_behaviour/running
  373. _root_running_deleting_behaviour_running_0 = Transition(self, self.states["/root/running/deleting_behaviour/running"], [self.states["/root/running/deleting_behaviour/running"]])
  374. _root_running_deleting_behaviour_running_0.setAction(self._root_running_deleting_behaviour_running_0_exec)
  375. _root_running_deleting_behaviour_running_0.setTrigger(Event("delete_ball", None))
  376. self.states["/root/running/deleting_behaviour/running"].addTransition(_root_running_deleting_behaviour_running_0)
  377. # transition /root/running/child_behaviour/listening
  378. _root_running_child_behaviour_listening_0 = Transition(self, self.states["/root/running/child_behaviour/listening"], [self.states["/root/running/child_behaviour/listening"]])
  379. _root_running_child_behaviour_listening_0.setAction(self._root_running_child_behaviour_listening_0_exec)
  380. _root_running_child_behaviour_listening_0.setTrigger(Event("button_pressed", None))
  381. self.states["/root/running/child_behaviour/listening"].addTransition(_root_running_child_behaviour_listening_0)
  382. # transition /root/running/deleting_balls_behaviour/listening
  383. _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"]])
  384. _root_running_deleting_balls_behaviour_listening_0.setAction(self._root_running_deleting_balls_behaviour_listening_0_exec)
  385. _root_running_deleting_balls_behaviour_listening_0.setTrigger(Event("key_press", self.getInPortName("field_ui")))
  386. _root_running_deleting_balls_behaviour_listening_0.setGuard(self._root_running_deleting_balls_behaviour_listening_0_guard)
  387. self.states["/root/running/deleting_balls_behaviour/listening"].addTransition(_root_running_deleting_balls_behaviour_listening_0)
  388. # transition /root/deleting
  389. _root_deleting_0 = Transition(self, self.states["/root/deleting"], [self.states["/root/deleted"]])
  390. _root_deleting_0.setAction(self._root_deleting_0_exec)
  391. _root_deleting_0.setTrigger(None)
  392. self.states["/root/deleting"].addTransition(_root_deleting_0)
  393. # transition /root/running
  394. _root_running_0 = Transition(self, self.states["/root/running"], [self.states["/root/deleting"]])
  395. _root_running_0.setAction(self._root_running_0_exec)
  396. _root_running_0.setTrigger(Event("window_close", self.getInPortName("field_ui")))
  397. self.states["/root/running"].addTransition(_root_running_0)
  398. def _root_creating_window_enter(self):
  399. self.big_step.outputEvent(Event("create_window", self.getOutPortName("ui"), [800, 600, "BouncingBalls", self.inports['field_ui']]))
  400. def _root_creating_canvas_enter(self):
  401. self.big_step.outputEvent(Event("create_canvas", self.getOutPortName("ui"), [self.window_id, CANVAS_WIDTH, CANVAS_HEIGHT, {'background':'#eee'}, self.inports['field_ui']]))
  402. def _root_creating_button_enter(self):
  403. self.big_step.outputEventOM(Event("create_instance", None, [self, "buttons", "Button", self.window_id, 'create_new_field', 'Spawn New Window']))
  404. def _root_running_0_exec(self, parameters):
  405. self.big_step.outputEventOM(Event("delete_instance", None, [self, "buttons"]))
  406. self.big_step.outputEventOM(Event("delete_instance", None, [self, "balls"]))
  407. def _root_waiting_0_exec(self, parameters):
  408. association_name = parameters[0]
  409. self.association_name = association_name
  410. def _root_creating_window_0_exec(self, parameters):
  411. window_id = parameters[0]
  412. self.window_id = window_id
  413. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [window_id, ui.EVENTS.WINDOW_CLOSE, 'window_close', self.inports['field_ui']]))
  414. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [window_id, ui.EVENTS.KEY_PRESS, 'key_press', self.inports['field_ui']]))
  415. def _root_creating_canvas_0_exec(self, parameters):
  416. canvas_id = parameters[0]
  417. self.canvas_id = canvas_id
  418. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [canvas_id, ui.EVENTS.MOUSE_RIGHT_CLICK, 'right_click', self.inports['field_ui']]))
  419. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [canvas_id, ui.EVENTS.MOUSE_MOVE, 'mouse_move', self.inports['field_ui']]))
  420. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [canvas_id, ui.EVENTS.MOUSE_RELEASE, 'mouse_release', self.inports['field_ui']]))
  421. def _root_creating_button_0_exec(self, parameters):
  422. association_name = parameters[0]
  423. self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
  424. def _root_running_main_behaviour_running_0_exec(self, parameters):
  425. x = parameters[0]
  426. y = parameters[1]
  427. button = parameters[2]
  428. self.big_step.outputEventOM(Event("create_instance", None, [self, "balls", "Ball", self.canvas_id, x, y]))
  429. def _root_running_main_behaviour_creating_ball_0_exec(self, parameters):
  430. association_name = parameters[0]
  431. self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
  432. self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("set_association_name", None, [association_name])]))
  433. def _root_running_deleting_behaviour_running_0_exec(self, parameters):
  434. association_name = parameters[0]
  435. self.big_step.outputEventOM(Event("delete_instance", None, [self, association_name]))
  436. def _root_running_child_behaviour_listening_0_exec(self, parameters):
  437. event_name = parameters[0]
  438. self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("button_pressed", None, [event_name])]))
  439. def _root_running_deleting_balls_behaviour_listening_0_exec(self, parameters):
  440. key = parameters[0]
  441. self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'balls', Event("delete_self", None, [])]))
  442. def _root_running_deleting_balls_behaviour_listening_0_guard(self, parameters):
  443. key = parameters[0]
  444. return key == ui.KEYCODES.DELETE
  445. def _root_deleting_0_exec(self, parameters):
  446. self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("delete_field", None, [self.association_name])]))
  447. self.big_step.outputEvent(Event("destroy_window", self.getOutPortName("ui"), [self.window_id]))
  448. def initializeStatechart(self):
  449. # enter default state
  450. self.default_targets = self.states["/root"].getEffectiveTargetStates()
  451. RuntimeClassBase.initializeStatechart(self)
  452. class Field(AtomicDEVS, ObjectManagerBase):
  453. def __init__(self, name):
  454. AtomicDEVS.__init__(self, name)
  455. ObjectManagerBase.__init__(self)
  456. self.elapsed = 0
  457. self.name = "Field"
  458. self.obj_manager_out = self.addOutPort("obj_manager_out")
  459. self.outputs = {}
  460. self.outputs["balls"] = self.addOutPort("balls")
  461. self.outputs["buttons"] = self.addOutPort("buttons")
  462. self.outputs["parent"] = self.addOutPort("parent")
  463. self.field_ui = self.addInPort("field_ui")
  464. self.obj_manager_in = self.addInPort("obj_manager_in")
  465. self.input = self.addInPort("input")
  466. self.next_time = INFINITY
  467. def extTransition(self, inputs):
  468. self.next_time = 0
  469. all_inputs = []
  470. if self.field_ui in inputs:
  471. all_inputs.extend(inputs[self.field_ui])
  472. if self.obj_manager_in in inputs:
  473. all_inputs.extend(inputs[self.obj_manager_in])
  474. if self.input in inputs:
  475. all_inputs.extend(inputs[self.input])
  476. for input in all_inputs:
  477. if isinstance(input, str):
  478. tem = eval(input)
  479. self.addInput(tem)
  480. elif input[3].name == "create_instance":
  481. self.instances.add(FieldInstance(self))
  482. ev = Event("instance_created", None, parameters=[f"{input[3].parameters[0]}[{len(self.instances)-1}]"])
  483. self.to_send.append((input[1], input[0], input[2], ev))
  484. elif input[3].name == "start_instance":
  485. instance = list(self.instances)[input[2]]
  486. instance.start()
  487. ev = Event("instance_started", None, parameters=[f"{input[0]}[{input[2]}]"])
  488. self.to_send.append((input[0], input[1], input[2], ev))
  489. elif input[3].name == "delete_instance":
  490. ev = Event("instance_deleted", None, parameters=[TODO])
  491. self.to_send.append((self.name, TODO, TODO, ev))
  492. elif input[3].name == "associate_instance":
  493. ev = Event("instance_associated", None, parameters=[TODO])
  494. self.to_send.append((self.name, TODO, TODO, ev))
  495. elif input[3].name == "disassociate_instance":
  496. ev = Event("instance_disassociated", None, parameters=[TODO])
  497. self.to_send.append((self.name, TODO, TODO, ev))
  498. elif input[3].name == "instance_created":
  499. instance = list(self.instances)[input[2]]
  500. instance.addEvent(input[3])
  501. instance.associations['fields'].instances[0] = input[3].parameters[0]
  502. elif input[3].name == "instance_started":
  503. instance = list(self.instances)[input[2]]
  504. instance.addEvent(input[3])
  505. elif input[3].name == "instance_deleted":
  506. instance = list(self.instances)[input[2]]
  507. instance.addEvent(input[3])
  508. elif input[3].name == "instance_associated":
  509. instance = list(self.instances)[input[2]]
  510. instance.addEvent(input[3])
  511. elif input[3].name == "instance_disassociated":
  512. instance = list(self.instances)[input[2]]
  513. instance.addEvent(input[3])
  514. elif input[3].name == "set_association_name":
  515. ev = input[3]
  516. self.addInput(ev, force_internal=True)
  517. return self.instances
  518. def intTransition(self):
  519. earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  520. if not (earliest == INFINITY):
  521. self.simulated_time = earliest
  522. self.to_send = []
  523. self.handleInput()
  524. self.stepAll()
  525. next_earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  526. if not (len(self.to_send) == 0):
  527. self.next_time = 0
  528. elif next_earliest == INFINITY:
  529. self.next_time = INFINITY
  530. else:
  531. self.next_time = next_earliest - earliest
  532. return self.instances
  533. def outputFnc(self):
  534. to_dict = {}
  535. for sending in self.to_send:
  536. if sending[3].port == None:
  537. if self.obj_manager_out in to_dict:
  538. to_dict[self.obj_manager_out].append(sending)
  539. else:
  540. to_dict[self.obj_manager_out] = [sending]
  541. else:
  542. the_port = None
  543. for port in self.OPorts:
  544. if port.name == sending[0]:
  545. the_port = port
  546. if the_port in to_dict:
  547. to_dict[the_port].append(sending)
  548. else:
  549. to_dict[the_port] = [sending]
  550. return to_dict
  551. def timeAdvance(self):
  552. return self.next_time
  553. class ButtonInstance(RuntimeClassBase):
  554. def __init__(self, atomdevs, window_id, event_name, button_text):
  555. RuntimeClassBase.__init__(self, atomdevs)
  556. self.associations = {}
  557. self.associations["parent"] = Association("Field", 1, 1)
  558. self.semantics.big_step_maximality = StatechartSemantics.TakeMany
  559. self.semantics.internal_event_lifeline = StatechartSemantics.Queue
  560. self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
  561. self.semantics.priority = StatechartSemantics.SourceParent
  562. self.semantics.concurrency = StatechartSemantics.Single
  563. # build Statechart structure
  564. self.build_statechart_structure()
  565. # user defined attributes
  566. self.window_id = None
  567. self.event_name = None
  568. self.button_id = None
  569. # call user defined constructor
  570. ButtonInstance.user_defined_constructor(self, window_id, event_name, button_text)
  571. def user_defined_constructor(self, window_id, event_name, button_text):
  572. self.window_id = window_id;
  573. self.event_name = event_name;
  574. def user_defined_destructor(self):
  575. pass
  576. # builds Statechart structure
  577. def build_statechart_structure(self):
  578. # state <root>
  579. self.states[""] = State(0, "", self)
  580. # state /creating_button
  581. self.states["/creating_button"] = State(1, "/creating_button", self)
  582. self.states["/creating_button"].setEnter(self._creating_button_enter)
  583. # state /running
  584. self.states["/running"] = State(2, "/running", self)
  585. # add children
  586. self.states[""].addChild(self.states["/creating_button"])
  587. self.states[""].addChild(self.states["/running"])
  588. self.states[""].fixTree()
  589. self.states[""].default_state = self.states["/creating_button"]
  590. # transition /creating_button
  591. _creating_button_0 = Transition(self, self.states["/creating_button"], [self.states["/running"]])
  592. _creating_button_0.setAction(self._creating_button_0_exec)
  593. _creating_button_0.setTrigger(Event("button_created", None))
  594. self.states["/creating_button"].addTransition(_creating_button_0)
  595. # transition /running
  596. _running_0 = Transition(self, self.states["/running"], [self.states["/running"]])
  597. _running_0.setAction(self._running_0_exec)
  598. _running_0.setTrigger(Event("mouse_click", self.getInPortName("button_ui")))
  599. _running_0.setGuard(self._running_0_guard)
  600. self.states["/running"].addTransition(_running_0)
  601. def _creating_button_enter(self):
  602. self.big_step.outputEvent(Event("create_button", self.getOutPortName("ui"), [self.window_id, self.event_name, self.inports['button_ui']]))
  603. def _creating_button_0_exec(self, parameters):
  604. button_id = parameters[0]
  605. self.button_id = button_id
  606. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [button_id, ui.EVENTS.MOUSE_CLICK, "mouse_click", self.inports['button_ui']]))
  607. def _running_0_exec(self, parameters):
  608. x = parameters[0]
  609. y = parameters[1]
  610. button = parameters[2]
  611. self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("button_pressed", None, [self.event_name])]))
  612. def _running_0_guard(self, parameters):
  613. x = parameters[0]
  614. y = parameters[1]
  615. button = parameters[2]
  616. return button == ui.MOUSE_BUTTONS.LEFT
  617. def initializeStatechart(self):
  618. # enter default state
  619. self.default_targets = self.states["/creating_button"].getEffectiveTargetStates()
  620. RuntimeClassBase.initializeStatechart(self)
  621. class Button(AtomicDEVS, ObjectManagerBase):
  622. def __init__(self, name):
  623. AtomicDEVS.__init__(self, name)
  624. ObjectManagerBase.__init__(self)
  625. self.elapsed = 0
  626. self.name = "Button"
  627. self.obj_manager_out = self.addOutPort("obj_manager_out")
  628. self.outputs = {}
  629. self.outputs["parent"] = self.addOutPort("parent")
  630. self.button_ui = self.addInPort("button_ui")
  631. self.obj_manager_in = self.addInPort("obj_manager_in")
  632. self.input = self.addInPort("input")
  633. self.next_time = INFINITY
  634. def extTransition(self, inputs):
  635. self.next_time = 0
  636. all_inputs = []
  637. if self.button_ui in inputs:
  638. all_inputs.extend(inputs[self.button_ui])
  639. if self.obj_manager_in in inputs:
  640. all_inputs.extend(inputs[self.obj_manager_in])
  641. if self.input in inputs:
  642. all_inputs.extend(inputs[self.input])
  643. for input in all_inputs:
  644. if isinstance(input, str):
  645. tem = eval(input)
  646. self.addInput(tem)
  647. elif input[3].name == "create_instance":
  648. self.instances.add(ButtonInstance(self))
  649. ev = Event("instance_created", None, parameters=[f"{input[3].parameters[0]}[{len(self.instances)-1}]"])
  650. self.to_send.append((input[1], input[0], input[2], ev))
  651. elif input[3].name == "start_instance":
  652. instance = list(self.instances)[input[2]]
  653. instance.start()
  654. ev = Event("instance_started", None, parameters=[f"{input[0]}[{input[2]}]"])
  655. self.to_send.append((input[0], input[1], input[2], ev))
  656. elif input[3].name == "delete_instance":
  657. ev = Event("instance_deleted", None, parameters=[TODO])
  658. self.to_send.append((self.name, TODO, TODO, ev))
  659. elif input[3].name == "associate_instance":
  660. ev = Event("instance_associated", None, parameters=[TODO])
  661. self.to_send.append((self.name, TODO, TODO, ev))
  662. elif input[3].name == "disassociate_instance":
  663. ev = Event("instance_disassociated", None, parameters=[TODO])
  664. self.to_send.append((self.name, TODO, TODO, ev))
  665. elif input[3].name == "instance_created":
  666. instance = list(self.instances)[input[2]]
  667. instance.addEvent(input[3])
  668. instance.associations['fields'].instances[0] = input[3].parameters[0]
  669. elif input[3].name == "instance_started":
  670. instance = list(self.instances)[input[2]]
  671. instance.addEvent(input[3])
  672. elif input[3].name == "instance_deleted":
  673. instance = list(self.instances)[input[2]]
  674. instance.addEvent(input[3])
  675. elif input[3].name == "instance_associated":
  676. instance = list(self.instances)[input[2]]
  677. instance.addEvent(input[3])
  678. elif input[3].name == "instance_disassociated":
  679. instance = list(self.instances)[input[2]]
  680. instance.addEvent(input[3])
  681. elif input[3].name == "set_association_name":
  682. ev = input[3]
  683. self.addInput(ev, force_internal=True)
  684. return self.instances
  685. def intTransition(self):
  686. earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  687. if not (earliest == INFINITY):
  688. self.simulated_time = earliest
  689. self.to_send = []
  690. self.handleInput()
  691. self.stepAll()
  692. next_earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  693. if not (len(self.to_send) == 0):
  694. self.next_time = 0
  695. elif next_earliest == INFINITY:
  696. self.next_time = INFINITY
  697. else:
  698. self.next_time = next_earliest - earliest
  699. return self.instances
  700. def outputFnc(self):
  701. to_dict = {}
  702. for sending in self.to_send:
  703. if sending[3].port == None:
  704. if self.obj_manager_out in to_dict:
  705. to_dict[self.obj_manager_out].append(sending)
  706. else:
  707. to_dict[self.obj_manager_out] = [sending]
  708. else:
  709. the_port = None
  710. for port in self.OPorts:
  711. if port.name == sending[0]:
  712. the_port = port
  713. if the_port in to_dict:
  714. to_dict[the_port].append(sending)
  715. else:
  716. to_dict[the_port] = [sending]
  717. return to_dict
  718. def timeAdvance(self):
  719. return self.next_time
  720. class BallInstance(RuntimeClassBase):
  721. def __init__(self, atomdevs, canvas_id, x, y):
  722. RuntimeClassBase.__init__(self, atomdevs)
  723. self.associations = {}
  724. self.associations["parent"] = Association("Field", 1, 1)
  725. self.semantics.big_step_maximality = StatechartSemantics.TakeMany
  726. self.semantics.internal_event_lifeline = StatechartSemantics.Queue
  727. self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
  728. self.semantics.priority = StatechartSemantics.SourceParent
  729. self.semantics.concurrency = StatechartSemantics.Single
  730. # build Statechart structure
  731. self.build_statechart_structure()
  732. # user defined attributes
  733. self.canvas_id = None
  734. self.pos = None
  735. # call user defined constructor
  736. BallInstance.user_defined_constructor(self, canvas_id, x, y)
  737. def user_defined_constructor(self, canvas_id, x, y):
  738. self.canvas_id = canvas_id;
  739. self.r = 20.0;
  740. self.vel = {'x': random.uniform(-5.0, 5.0), 'y': random.uniform(-5.0, 5.0)};
  741. self.pos = {'x': x, 'y': y};
  742. self.smooth = 0.6; # value between 0 and 1
  743. # TODO:
  744. #circle = self.canvas.add_circle(x, y, self.r, {'fill':'#000'});
  745. #ui.bind_event(circle, ui.EVENTS.MOUSE_PRESS, self.controller, 'mouse_press', self.inports["ball_ui"]);
  746. #ui.bind_event(circle, ui.EVENTS.MOUSE_MOVE, self.controller, 'mouse_move', self.inports['ball_ui']);
  747. #ui.bind_event(circle, ui.EVENTS.MOUSE_RELEASE, self.controller, 'mouse_release', self.inports['ball_ui']);
  748. #self.element = circle;
  749. def user_defined_destructor(self):
  750. #self.canvas.remove_element(self.element);
  751. pass
  752. # builds Statechart structure
  753. def build_statechart_structure(self):
  754. # state <root>
  755. self.states[""] = State(0, "", self)
  756. # state /main_behaviour
  757. self.states["/main_behaviour"] = State(1, "/main_behaviour", self)
  758. # state /main_behaviour/initializing
  759. self.states["/main_behaviour/initializing"] = State(2, "/main_behaviour/initializing", self)
  760. # state /main_behaviour/creating_circle
  761. self.states["/main_behaviour/creating_circle"] = State(3, "/main_behaviour/creating_circle", self)
  762. self.states["/main_behaviour/creating_circle"].setEnter(self._main_behaviour_creating_circle_enter)
  763. # state /main_behaviour/bouncing
  764. self.states["/main_behaviour/bouncing"] = State(4, "/main_behaviour/bouncing", self)
  765. self.states["/main_behaviour/bouncing"].setEnter(self._main_behaviour_bouncing_enter)
  766. self.states["/main_behaviour/bouncing"].setExit(self._main_behaviour_bouncing_exit)
  767. # state /main_behaviour/dragging
  768. self.states["/main_behaviour/dragging"] = State(5, "/main_behaviour/dragging", self)
  769. # state /main_behaviour/selected
  770. self.states["/main_behaviour/selected"] = State(6, "/main_behaviour/selected", self)
  771. # state /deleted
  772. self.states["/deleted"] = State(7, "/deleted", self)
  773. # add children
  774. self.states[""].addChild(self.states["/main_behaviour"])
  775. self.states[""].addChild(self.states["/deleted"])
  776. self.states["/main_behaviour"].addChild(self.states["/main_behaviour/initializing"])
  777. self.states["/main_behaviour"].addChild(self.states["/main_behaviour/creating_circle"])
  778. self.states["/main_behaviour"].addChild(self.states["/main_behaviour/bouncing"])
  779. self.states["/main_behaviour"].addChild(self.states["/main_behaviour/dragging"])
  780. self.states["/main_behaviour"].addChild(self.states["/main_behaviour/selected"])
  781. self.states[""].fixTree()
  782. self.states[""].default_state = self.states["/main_behaviour"]
  783. self.states["/main_behaviour"].default_state = self.states["/main_behaviour/initializing"]
  784. # transition /main_behaviour/initializing
  785. _main_behaviour_initializing_0 = Transition(self, self.states["/main_behaviour/initializing"], [self.states["/main_behaviour/creating_circle"]])
  786. _main_behaviour_initializing_0.setAction(self._main_behaviour_initializing_0_exec)
  787. _main_behaviour_initializing_0.setTrigger(Event("set_association_name", None))
  788. self.states["/main_behaviour/initializing"].addTransition(_main_behaviour_initializing_0)
  789. # transition /main_behaviour/creating_circle
  790. _main_behaviour_creating_circle_0 = Transition(self, self.states["/main_behaviour/creating_circle"], [self.states["/main_behaviour/bouncing"]])
  791. _main_behaviour_creating_circle_0.setAction(self._main_behaviour_creating_circle_0_exec)
  792. _main_behaviour_creating_circle_0.setTrigger(Event("circle_created", None))
  793. self.states["/main_behaviour/creating_circle"].addTransition(_main_behaviour_creating_circle_0)
  794. # transition /main_behaviour/bouncing
  795. _main_behaviour_bouncing_0 = Transition(self, self.states["/main_behaviour/bouncing"], [self.states["/main_behaviour/bouncing"]])
  796. _main_behaviour_bouncing_0.setAction(self._main_behaviour_bouncing_0_exec)
  797. _main_behaviour_bouncing_0.setTrigger(Event("_0after"))
  798. self.states["/main_behaviour/bouncing"].addTransition(_main_behaviour_bouncing_0)
  799. _main_behaviour_bouncing_1 = Transition(self, self.states["/main_behaviour/bouncing"], [self.states["/main_behaviour/selected"]])
  800. _main_behaviour_bouncing_1.setAction(self._main_behaviour_bouncing_1_exec)
  801. _main_behaviour_bouncing_1.setTrigger(Event("mouse_press", self.getInPortName("ball_ui")))
  802. _main_behaviour_bouncing_1.setGuard(self._main_behaviour_bouncing_1_guard)
  803. self.states["/main_behaviour/bouncing"].addTransition(_main_behaviour_bouncing_1)
  804. # transition /main_behaviour/dragging
  805. _main_behaviour_dragging_0 = Transition(self, self.states["/main_behaviour/dragging"], [self.states["/main_behaviour/dragging"]])
  806. _main_behaviour_dragging_0.setAction(self._main_behaviour_dragging_0_exec)
  807. _main_behaviour_dragging_0.setTrigger(Event("mouse_move", self.getInPortName("ball_ui")))
  808. self.states["/main_behaviour/dragging"].addTransition(_main_behaviour_dragging_0)
  809. _main_behaviour_dragging_1 = Transition(self, self.states["/main_behaviour/dragging"], [self.states["/main_behaviour/bouncing"]])
  810. _main_behaviour_dragging_1.setAction(self._main_behaviour_dragging_1_exec)
  811. _main_behaviour_dragging_1.setTrigger(Event("mouse_release", self.getInPortName("ball_ui")))
  812. self.states["/main_behaviour/dragging"].addTransition(_main_behaviour_dragging_1)
  813. # transition /main_behaviour/selected
  814. _main_behaviour_selected_0 = Transition(self, self.states["/main_behaviour/selected"], [self.states["/main_behaviour/dragging"]])
  815. _main_behaviour_selected_0.setAction(self._main_behaviour_selected_0_exec)
  816. _main_behaviour_selected_0.setTrigger(Event("mouse_press", self.getInPortName("ball_ui")))
  817. _main_behaviour_selected_0.setGuard(self._main_behaviour_selected_0_guard)
  818. self.states["/main_behaviour/selected"].addTransition(_main_behaviour_selected_0)
  819. _main_behaviour_selected_1 = Transition(self, self.states["/main_behaviour/selected"], [self.states["/deleted"]])
  820. _main_behaviour_selected_1.setAction(self._main_behaviour_selected_1_exec)
  821. _main_behaviour_selected_1.setTrigger(Event("delete_self", None))
  822. self.states["/main_behaviour/selected"].addTransition(_main_behaviour_selected_1)
  823. def _main_behaviour_creating_circle_enter(self):
  824. 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']]))
  825. def _main_behaviour_bouncing_enter(self):
  826. self.addTimer(0, 0.02)
  827. def _main_behaviour_bouncing_exit(self):
  828. self.removeTimer(0)
  829. def _main_behaviour_initializing_0_exec(self, parameters):
  830. association_name = parameters[0]
  831. self.association_name = association_name
  832. def _main_behaviour_creating_circle_0_exec(self, parameters):
  833. canvas_id = parameters[0]
  834. circle_id = parameters[1]
  835. self.circle_id = circle_id
  836. 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']]))
  837. 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']]))
  838. 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']]))
  839. def _main_behaviour_bouncing_0_exec(self, parameters):
  840. # Invert velocity when colliding with canvas border:
  841. if self.pos['x']-self.r <= 0 or self.pos['x']+self.r >= CANVAS_WIDTH:
  842. self.vel['x'] = -self.vel['x'];
  843. if self.pos['y']-self.r <= 0 or self.pos['y']+self.r >= CANVAS_HEIGHT:
  844. self.vel['y'] = -self.vel['y'];
  845. self.big_step.outputEvent(Event("move_element", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, self.vel['x'], self.vel['y']]))
  846. self.pos['x'] += self.vel['x']
  847. self.pos['y'] += self.vel['y']
  848. def _main_behaviour_bouncing_1_exec(self, parameters):
  849. x = parameters[0]
  850. y = parameters[1]
  851. button = parameters[2]
  852. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, '#ff0']))
  853. def _main_behaviour_bouncing_1_guard(self, parameters):
  854. x = parameters[0]
  855. y = parameters[1]
  856. button = parameters[2]
  857. return button == ui.MOUSE_BUTTONS.LEFT
  858. def _main_behaviour_dragging_0_exec(self, parameters):
  859. x = parameters[0]
  860. y = parameters[1]
  861. button = parameters[2]
  862. # Always keep ball within canvas:
  863. x = min(max(0+self.r, x), CANVAS_WIDTH-self.r)
  864. y = min(max(0+self.r, y), CANVAS_HEIGHT-self.r)
  865. dx = x - self.pos['x']
  866. dy = y - self.pos['y']
  867. self.vel = {
  868. 'x': (1-self.smooth)*dx + self.smooth*self.vel['x'],
  869. 'y': (1-self.smooth)*dy + self.smooth*self.vel['y']
  870. }
  871. self.pos = {'x': x, 'y': y}
  872. self.big_step.outputEvent(Event("set_element_pos", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, x-self.r, y-self.r]))
  873. def _main_behaviour_dragging_1_exec(self, parameters):
  874. x = parameters[0]
  875. y = parameters[1]
  876. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, '#f00']))
  877. def _main_behaviour_selected_0_exec(self, parameters):
  878. x = parameters[0]
  879. y = parameters[1]
  880. button = parameters[2]
  881. self.mouse_pos = {'x':x, 'y':y};
  882. def _main_behaviour_selected_0_guard(self, parameters):
  883. x = parameters[0]
  884. y = parameters[1]
  885. button = parameters[2]
  886. return button == ui.MOUSE_BUTTONS.LEFT
  887. def _main_behaviour_selected_1_exec(self, parameters):
  888. self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("delete_ball", None, [self.association_name])]))
  889. self.big_step.outputEvent(Event("destroy_element", self.getOutPortName("ui"), [self.canvas_id, self.element_id]))
  890. def initializeStatechart(self):
  891. # enter default state
  892. self.default_targets = self.states["/main_behaviour"].getEffectiveTargetStates()
  893. RuntimeClassBase.initializeStatechart(self)
  894. class Ball(AtomicDEVS, ObjectManagerBase):
  895. def __init__(self, name):
  896. AtomicDEVS.__init__(self, name)
  897. ObjectManagerBase.__init__(self)
  898. self.elapsed = 0
  899. self.name = "Ball"
  900. self.obj_manager_out = self.addOutPort("obj_manager_out")
  901. self.outputs = {}
  902. self.outputs["parent"] = self.addOutPort("parent")
  903. self.ball_ui = self.addInPort("ball_ui")
  904. self.obj_manager_in = self.addInPort("obj_manager_in")
  905. self.input = self.addInPort("input")
  906. self.next_time = INFINITY
  907. def extTransition(self, inputs):
  908. self.next_time = 0
  909. all_inputs = []
  910. if self.ball_ui in inputs:
  911. all_inputs.extend(inputs[self.ball_ui])
  912. if self.obj_manager_in in inputs:
  913. all_inputs.extend(inputs[self.obj_manager_in])
  914. if self.input in inputs:
  915. all_inputs.extend(inputs[self.input])
  916. for input in all_inputs:
  917. if isinstance(input, str):
  918. tem = eval(input)
  919. self.addInput(tem)
  920. elif input[3].name == "create_instance":
  921. self.instances.add(BallInstance(self))
  922. ev = Event("instance_created", None, parameters=[f"{input[3].parameters[0]}[{len(self.instances)-1}]"])
  923. self.to_send.append((input[1], input[0], input[2], ev))
  924. elif input[3].name == "start_instance":
  925. instance = list(self.instances)[input[2]]
  926. instance.start()
  927. ev = Event("instance_started", None, parameters=[f"{input[0]}[{input[2]}]"])
  928. self.to_send.append((input[0], input[1], input[2], ev))
  929. elif input[3].name == "delete_instance":
  930. ev = Event("instance_deleted", None, parameters=[TODO])
  931. self.to_send.append((self.name, TODO, TODO, ev))
  932. elif input[3].name == "associate_instance":
  933. ev = Event("instance_associated", None, parameters=[TODO])
  934. self.to_send.append((self.name, TODO, TODO, ev))
  935. elif input[3].name == "disassociate_instance":
  936. ev = Event("instance_disassociated", None, parameters=[TODO])
  937. self.to_send.append((self.name, TODO, TODO, ev))
  938. elif input[3].name == "instance_created":
  939. instance = list(self.instances)[input[2]]
  940. instance.addEvent(input[3])
  941. instance.associations['fields'].instances[0] = input[3].parameters[0]
  942. elif input[3].name == "instance_started":
  943. instance = list(self.instances)[input[2]]
  944. instance.addEvent(input[3])
  945. elif input[3].name == "instance_deleted":
  946. instance = list(self.instances)[input[2]]
  947. instance.addEvent(input[3])
  948. elif input[3].name == "instance_associated":
  949. instance = list(self.instances)[input[2]]
  950. instance.addEvent(input[3])
  951. elif input[3].name == "instance_disassociated":
  952. instance = list(self.instances)[input[2]]
  953. instance.addEvent(input[3])
  954. elif input[3].name == "set_association_name":
  955. ev = input[3]
  956. self.addInput(ev, force_internal=True)
  957. return self.instances
  958. def intTransition(self):
  959. earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  960. if not (earliest == INFINITY):
  961. self.simulated_time = earliest
  962. self.to_send = []
  963. self.handleInput()
  964. self.stepAll()
  965. next_earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  966. if not (len(self.to_send) == 0):
  967. self.next_time = 0
  968. elif next_earliest == INFINITY:
  969. self.next_time = INFINITY
  970. else:
  971. self.next_time = next_earliest - earliest
  972. return self.instances
  973. def outputFnc(self):
  974. to_dict = {}
  975. for sending in self.to_send:
  976. if sending[3].port == None:
  977. if self.obj_manager_out in to_dict:
  978. to_dict[self.obj_manager_out].append(sending)
  979. else:
  980. to_dict[self.obj_manager_out] = [sending]
  981. else:
  982. the_port = None
  983. for port in self.OPorts:
  984. if port.name == sending[0]:
  985. the_port = port
  986. if the_port in to_dict:
  987. to_dict[the_port].append(sending)
  988. else:
  989. to_dict[the_port] = [sending]
  990. return to_dict
  991. def timeAdvance(self):
  992. return self.next_time
  993. class ObjectManagerState:
  994. def __init__(self):
  995. self.to_send = [(None, "MainApp", 0, Event("start_instance", None, None))]
  996. class ObjectManager(AtomicDEVS):
  997. def __init__(self, name):
  998. AtomicDEVS.__init__(self, name)
  999. self.State = ObjectManagerState()
  1000. self.input = self.addInPort("input")
  1001. self.output = {}
  1002. self.output["MainApp"] = self.addOutPort()
  1003. self.output["Field"] = self.addOutPort()
  1004. self.output["Button"] = self.addOutPort()
  1005. self.output["Ball"] = self.addOutPort()
  1006. def extTransition(self, inputs):
  1007. all_inputs = inputs[self.input]
  1008. for input in all_inputs:
  1009. self.State.to_send.append(input)
  1010. return self.State
  1011. def intTransition(self):
  1012. self.State.to_send = []
  1013. return self.State
  1014. def outputFnc(self):
  1015. out_dict = {}
  1016. for (source, target, id, message) in self.State.to_send:
  1017. if self.output[target] in out_dict:
  1018. out_dict[self.output[target]].append((source, target, id, message))
  1019. else:
  1020. out_dict[self.output[target]] = [(source, target, id, message)]
  1021. return out_dict
  1022. def timeAdvance(self):
  1023. if self.State.to_send:
  1024. return 0
  1025. return INFINITY
  1026. class Controller(CoupledDEVS):
  1027. def __init__(self, name):
  1028. CoupledDEVS.__init__(self, name)
  1029. self.ui = self.addInPort("ui")
  1030. self.addOutPort("ui")
  1031. self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
  1032. self.atomic0 = self.addSubModel(MainApp("MainApp"))
  1033. self.atomic1 = self.addSubModel(Field("Field"))
  1034. self.atomic2 = self.addSubModel(Button("Button"))
  1035. self.atomic3 = self.addSubModel(Ball("Ball"))
  1036. self.connectPorts(self.atomic0.obj_manager_out, self.objectmanager.input)
  1037. self.connectPorts(self.objectmanager.output["MainApp"], self.atomic0.obj_manager_in)
  1038. self.connectPorts(self.atomic0.outputs["fields"], self.atomic1.input)
  1039. self.connectPorts(self.atomic1.obj_manager_out, self.objectmanager.input)
  1040. self.connectPorts(self.objectmanager.output["Field"], self.atomic1.obj_manager_in)
  1041. self.connectPorts(self.atomic1.outputs["balls"], self.atomic3.input)
  1042. self.connectPorts(self.atomic1.outputs["buttons"], self.atomic2.input)
  1043. self.connectPorts(self.atomic1.outputs["parent"], self.atomic0.input)
  1044. self.connectPorts(self.atomic2.obj_manager_out, self.objectmanager.input)
  1045. self.connectPorts(self.objectmanager.output["Button"], self.atomic2.obj_manager_in)
  1046. self.connectPorts(self.atomic2.outputs["parent"], self.atomic1.input)
  1047. self.connectPorts(self.atomic3.obj_manager_out, self.objectmanager.input)
  1048. self.connectPorts(self.objectmanager.output["Ball"], self.atomic3.obj_manager_in)
  1049. self.connectPorts(self.atomic3.outputs["parent"], self.atomic1.input)