target.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  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: Sam Pieters
  4. Model name: TrafficLight
  5. Model description:
  6. Tkinter frame with Traffic light in a single statechart.
  7. """
  8. from sccd.runtime.DEVS_statecharts_core import *
  9. from sccd.runtime.libs import ui_v2 as ui
  10. CANVAS_DIMS = (100, 350)
  11. # package "TrafficLight"
  12. class MainAppInstance(RuntimeClassBase):
  13. def __init__(self, atomdevs, id, start_port_id):
  14. RuntimeClassBase.__init__(self, atomdevs, id)
  15. self.semantics.big_step_maximality = StatechartSemantics.TakeMany
  16. self.semantics.internal_event_lifeline = StatechartSemantics.Queue
  17. self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
  18. self.semantics.priority = StatechartSemantics.SourceParent
  19. self.semantics.concurrency = StatechartSemantics.Single
  20. # build Statechart structure
  21. self.build_statechart_structure()
  22. # user defined attributes
  23. self.window_id = None
  24. self.canvas_id = None
  25. self.green_id = None
  26. self.yellow_id = None
  27. self.red_id = None
  28. self.police_button_id = None
  29. # call user defined constructor
  30. MainAppInstance.user_defined_constructor(self)
  31. port_name = addInputPort("<narrow_cast>", start_port_id)
  32. atomdevs.state.port_mappings[port_name] = id
  33. port_name = addInputPort("field_ui", start_port_id + 1)
  34. atomdevs.state.port_mappings[port_name] = id
  35. self.inports["field_ui"] = port_name
  36. def user_defined_constructor(self):
  37. pass
  38. def user_defined_destructor(self):
  39. pass
  40. # builds Statechart structure
  41. def build_statechart_structure(self):
  42. # state <root>
  43. self.states[""] = State(0, "", self)
  44. # state /creating_window
  45. self.states["/creating_window"] = State(1, "/creating_window", self)
  46. self.states["/creating_window"].setEnter(self._creating_window_enter)
  47. # state /creating_canvas
  48. self.states["/creating_canvas"] = State(2, "/creating_canvas", self)
  49. self.states["/creating_canvas"].setEnter(self._creating_canvas_enter)
  50. # state /creating_trafficlight
  51. self.states["/creating_trafficlight"] = State(3, "/creating_trafficlight", self)
  52. # state /creating_trafficlight/creating_greenlight
  53. self.states["/creating_trafficlight/creating_greenlight"] = State(4, "/creating_trafficlight/creating_greenlight", self)
  54. self.states["/creating_trafficlight/creating_greenlight"].setEnter(self._creating_trafficlight_creating_greenlight_enter)
  55. # state /creating_trafficlight/creating_yellowlight
  56. self.states["/creating_trafficlight/creating_yellowlight"] = State(5, "/creating_trafficlight/creating_yellowlight", self)
  57. self.states["/creating_trafficlight/creating_yellowlight"].setEnter(self._creating_trafficlight_creating_yellowlight_enter)
  58. # state /creating_trafficlight/creating_redlight
  59. self.states["/creating_trafficlight/creating_redlight"] = State(6, "/creating_trafficlight/creating_redlight", self)
  60. self.states["/creating_trafficlight/creating_redlight"].setEnter(self._creating_trafficlight_creating_redlight_enter)
  61. # state /creating_interrupt_button
  62. self.states["/creating_interrupt_button"] = State(7, "/creating_interrupt_button", self)
  63. self.states["/creating_interrupt_button"].setEnter(self._creating_interrupt_button_enter)
  64. # state /creating_quit_button
  65. self.states["/creating_quit_button"] = State(8, "/creating_quit_button", self)
  66. self.states["/creating_quit_button"].setEnter(self._creating_quit_button_enter)
  67. # state /on
  68. self.states["/on"] = State(9, "/on", self)
  69. # state /on/normal
  70. self.states["/on/normal"] = State(10, "/on/normal", self)
  71. # state /on/normal/red
  72. self.states["/on/normal/red"] = State(11, "/on/normal/red", self)
  73. self.states["/on/normal/red"].setEnter(self._on_normal_red_enter)
  74. self.states["/on/normal/red"].setExit(self._on_normal_red_exit)
  75. # state /on/normal/green
  76. self.states["/on/normal/green"] = State(12, "/on/normal/green", self)
  77. self.states["/on/normal/green"].setEnter(self._on_normal_green_enter)
  78. self.states["/on/normal/green"].setExit(self._on_normal_green_exit)
  79. # state /on/normal/yellow
  80. self.states["/on/normal/yellow"] = State(13, "/on/normal/yellow", self)
  81. self.states["/on/normal/yellow"].setEnter(self._on_normal_yellow_enter)
  82. self.states["/on/normal/yellow"].setExit(self._on_normal_yellow_exit)
  83. # state /on/interrupted
  84. self.states["/on/interrupted"] = State(14, "/on/interrupted", self)
  85. # state /on/interrupted/yellow
  86. self.states["/on/interrupted/yellow"] = State(15, "/on/interrupted/yellow", self)
  87. self.states["/on/interrupted/yellow"].setEnter(self._on_interrupted_yellow_enter)
  88. self.states["/on/interrupted/yellow"].setExit(self._on_interrupted_yellow_exit)
  89. # state /on/interrupted/black
  90. self.states["/on/interrupted/black"] = State(16, "/on/interrupted/black", self)
  91. self.states["/on/interrupted/black"].setEnter(self._on_interrupted_black_enter)
  92. self.states["/on/interrupted/black"].setExit(self._on_interrupted_black_exit)
  93. # state /off
  94. self.states["/off"] = State(17, "/off", self)
  95. self.states["/off"].setEnter(self._off_enter)
  96. # add children
  97. self.states[""].addChild(self.states["/creating_window"])
  98. self.states[""].addChild(self.states["/creating_canvas"])
  99. self.states[""].addChild(self.states["/creating_trafficlight"])
  100. self.states[""].addChild(self.states["/creating_interrupt_button"])
  101. self.states[""].addChild(self.states["/creating_quit_button"])
  102. self.states[""].addChild(self.states["/on"])
  103. self.states[""].addChild(self.states["/off"])
  104. self.states["/creating_trafficlight"].addChild(self.states["/creating_trafficlight/creating_greenlight"])
  105. self.states["/creating_trafficlight"].addChild(self.states["/creating_trafficlight/creating_yellowlight"])
  106. self.states["/creating_trafficlight"].addChild(self.states["/creating_trafficlight/creating_redlight"])
  107. self.states["/on"].addChild(self.states["/on/normal"])
  108. self.states["/on"].addChild(self.states["/on/interrupted"])
  109. self.states["/on/normal"].addChild(self.states["/on/normal/red"])
  110. self.states["/on/normal"].addChild(self.states["/on/normal/green"])
  111. self.states["/on/normal"].addChild(self.states["/on/normal/yellow"])
  112. self.states["/on/interrupted"].addChild(self.states["/on/interrupted/yellow"])
  113. self.states["/on/interrupted"].addChild(self.states["/on/interrupted/black"])
  114. self.states[""].fixTree()
  115. self.states[""].default_state = self.states["/creating_window"]
  116. self.states["/creating_trafficlight"].default_state = self.states["/creating_trafficlight/creating_greenlight"]
  117. self.states["/on"].default_state = self.states["/on/normal"]
  118. self.states["/on/normal"].default_state = self.states["/on/normal/red"]
  119. self.states["/on/interrupted"].default_state = self.states["/on/interrupted/yellow"]
  120. # transition /creating_window
  121. _creating_window_0 = Transition(self, self.states["/creating_window"], [self.states["/creating_canvas"]])
  122. _creating_window_0.setAction(self._creating_window_0_exec)
  123. _creating_window_0.setTrigger(Event("window_created", None))
  124. self.states["/creating_window"].addTransition(_creating_window_0)
  125. # transition /creating_canvas
  126. _creating_canvas_0 = Transition(self, self.states["/creating_canvas"], [self.states["/creating_trafficlight"]])
  127. _creating_canvas_0.setAction(self._creating_canvas_0_exec)
  128. _creating_canvas_0.setTrigger(Event("canvas_created", None))
  129. self.states["/creating_canvas"].addTransition(_creating_canvas_0)
  130. # transition /creating_trafficlight/creating_greenlight
  131. _creating_trafficlight_creating_greenlight_0 = Transition(self, self.states["/creating_trafficlight/creating_greenlight"], [self.states["/creating_trafficlight/creating_yellowlight"]])
  132. _creating_trafficlight_creating_greenlight_0.setAction(self._creating_trafficlight_creating_greenlight_0_exec)
  133. _creating_trafficlight_creating_greenlight_0.setTrigger(Event("rectangle_created", None))
  134. self.states["/creating_trafficlight/creating_greenlight"].addTransition(_creating_trafficlight_creating_greenlight_0)
  135. # transition /creating_trafficlight/creating_yellowlight
  136. _creating_trafficlight_creating_yellowlight_0 = Transition(self, self.states["/creating_trafficlight/creating_yellowlight"], [self.states["/creating_trafficlight/creating_redlight"]])
  137. _creating_trafficlight_creating_yellowlight_0.setAction(self._creating_trafficlight_creating_yellowlight_0_exec)
  138. _creating_trafficlight_creating_yellowlight_0.setTrigger(Event("rectangle_created", None))
  139. self.states["/creating_trafficlight/creating_yellowlight"].addTransition(_creating_trafficlight_creating_yellowlight_0)
  140. # transition /creating_trafficlight/creating_redlight
  141. _creating_trafficlight_creating_redlight_0 = Transition(self, self.states["/creating_trafficlight/creating_redlight"], [self.states["/creating_interrupt_button"]])
  142. _creating_trafficlight_creating_redlight_0.setAction(self._creating_trafficlight_creating_redlight_0_exec)
  143. _creating_trafficlight_creating_redlight_0.setTrigger(Event("rectangle_created", None))
  144. self.states["/creating_trafficlight/creating_redlight"].addTransition(_creating_trafficlight_creating_redlight_0)
  145. # transition /creating_interrupt_button
  146. _creating_interrupt_button_0 = Transition(self, self.states["/creating_interrupt_button"], [self.states["/creating_quit_button"]])
  147. _creating_interrupt_button_0.setAction(self._creating_interrupt_button_0_exec)
  148. _creating_interrupt_button_0.setTrigger(Event("button_created", None))
  149. self.states["/creating_interrupt_button"].addTransition(_creating_interrupt_button_0)
  150. # transition /creating_quit_button
  151. _creating_quit_button_0 = Transition(self, self.states["/creating_quit_button"], [self.states["/on"]])
  152. _creating_quit_button_0.setAction(self._creating_quit_button_0_exec)
  153. _creating_quit_button_0.setTrigger(Event("button_created", None))
  154. self.states["/creating_quit_button"].addTransition(_creating_quit_button_0)
  155. # transition /on/normal/red
  156. _on_normal_red_0 = Transition(self, self.states["/on/normal/red"], [self.states["/on/normal/green"]])
  157. _on_normal_red_0.setTrigger(Event("_0after"))
  158. self.states["/on/normal/red"].addTransition(_on_normal_red_0)
  159. # transition /on/normal/green
  160. _on_normal_green_0 = Transition(self, self.states["/on/normal/green"], [self.states["/on/normal/yellow"]])
  161. _on_normal_green_0.setTrigger(Event("_1after"))
  162. self.states["/on/normal/green"].addTransition(_on_normal_green_0)
  163. # transition /on/normal/yellow
  164. _on_normal_yellow_0 = Transition(self, self.states["/on/normal/yellow"], [self.states["/on/normal/red"]])
  165. _on_normal_yellow_0.setTrigger(Event("_2after"))
  166. self.states["/on/normal/yellow"].addTransition(_on_normal_yellow_0)
  167. # transition /on/interrupted/yellow
  168. _on_interrupted_yellow_0 = Transition(self, self.states["/on/interrupted/yellow"], [self.states["/on/interrupted/black"]])
  169. _on_interrupted_yellow_0.setTrigger(Event("_3after"))
  170. self.states["/on/interrupted/yellow"].addTransition(_on_interrupted_yellow_0)
  171. # transition /on/interrupted/black
  172. _on_interrupted_black_0 = Transition(self, self.states["/on/interrupted/black"], [self.states["/on/interrupted/yellow"]])
  173. _on_interrupted_black_0.setTrigger(Event("_4after"))
  174. self.states["/on/interrupted/black"].addTransition(_on_interrupted_black_0)
  175. # transition /on
  176. _on_0 = Transition(self, self.states["/on"], [self.states["/off"]])
  177. _on_0.setTrigger(Event("quit_clicked", self.getInPortName("field_ui")))
  178. _on_0.setGuard(self._on_0_guard)
  179. self.states["/on"].addTransition(_on_0)
  180. # transition /on/normal
  181. _on_normal_0 = Transition(self, self.states["/on/normal"], [self.states["/on/interrupted"]])
  182. _on_normal_0.setAction(self._on_normal_0_exec)
  183. _on_normal_0.setTrigger(Event("interrupt_clicked", self.getInPortName("field_ui")))
  184. _on_normal_0.setGuard(self._on_normal_0_guard)
  185. self.states["/on/normal"].addTransition(_on_normal_0)
  186. # transition /on/interrupted
  187. _on_interrupted_0 = Transition(self, self.states["/on/interrupted"], [self.states["/on/normal"]])
  188. _on_interrupted_0.setTrigger(Event("interrupt_clicked", self.getInPortName("field_ui")))
  189. _on_interrupted_0.setGuard(self._on_interrupted_0_guard)
  190. self.states["/on/interrupted"].addTransition(_on_interrupted_0)
  191. def _creating_window_enter(self):
  192. self.big_step.outputEvent(Event("create_window", self.getOutPortName("ui"), [CANVAS_DIMS[0], CANVAS_DIMS[1], "Traffic Light (history)", self.inports['field_ui']]))
  193. def _creating_canvas_enter(self):
  194. self.big_step.outputEvent(Event("create_canvas", self.getOutPortName("ui"), [self.window_id, CANVAS_DIMS[0], CANVAS_DIMS[1] - 100, {'background':'#222222'}, self.inports['field_ui']]))
  195. def _creating_trafficlight_creating_greenlight_enter(self):
  196. self.big_step.outputEvent(Event("create_rectangle", self.getOutPortName("ui"), [self.canvas_id, 50, 50, 50, 50, {'fill':'#000'}, self.inports['field_ui']]))
  197. def _creating_trafficlight_creating_yellowlight_enter(self):
  198. self.big_step.outputEvent(Event("create_rectangle", self.getOutPortName("ui"), [self.canvas_id, 50, 110, 50, 50, {'fill':'#000'}, self.inports['field_ui']]))
  199. def _creating_trafficlight_creating_redlight_enter(self):
  200. self.big_step.outputEvent(Event("create_rectangle", self.getOutPortName("ui"), [self.canvas_id, 50, 170, 50, 50, {'fill':'#000'}, self.inports['field_ui']]))
  201. def _creating_interrupt_button_enter(self):
  202. self.big_step.outputEvent(Event("create_button", self.getOutPortName("ui"), [self.window_id, 'Police Interrupt', self.inports['field_ui']]))
  203. def _creating_quit_button_enter(self):
  204. self.big_step.outputEvent(Event("create_button", self.getOutPortName("ui"), [self.window_id, 'Quit', self.inports['field_ui']]))
  205. def _on_normal_red_enter(self):
  206. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.yellow_id, 'black']))
  207. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.red_id, 'red']))
  208. self.addTimer(0, 3)
  209. def _on_normal_red_exit(self):
  210. self.removeTimer(0)
  211. def _on_normal_green_enter(self):
  212. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.red_id, 'black']))
  213. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.green_id, 'green']))
  214. self.addTimer(1, 2)
  215. def _on_normal_green_exit(self):
  216. self.removeTimer(1)
  217. def _on_normal_yellow_enter(self):
  218. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.green_id, 'black']))
  219. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.yellow_id, 'yellow']))
  220. self.addTimer(2, 1)
  221. def _on_normal_yellow_exit(self):
  222. self.removeTimer(2)
  223. def _on_interrupted_yellow_enter(self):
  224. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.yellow_id, 'yellow']))
  225. self.addTimer(3, .5)
  226. def _on_interrupted_yellow_exit(self):
  227. self.removeTimer(3)
  228. def _on_interrupted_black_enter(self):
  229. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.yellow_id, 'black']))
  230. self.addTimer(4, .5)
  231. def _on_interrupted_black_exit(self):
  232. self.removeTimer(4)
  233. def _off_enter(self):
  234. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.green_id, 'black']))
  235. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.yellow_id, 'black']))
  236. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.red_id, 'black']))
  237. def _on_0_guard(self, parameters):
  238. x = parameters[0]
  239. y = parameters[1]
  240. button = parameters[2]
  241. return button == ui.MOUSE_BUTTONS.LEFT
  242. def _on_normal_0_exec(self, parameters):
  243. x = parameters[0]
  244. y = parameters[1]
  245. button = parameters[2]
  246. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.green_id, 'black']))
  247. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.yellow_id, 'black']))
  248. self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.red_id, 'black']))
  249. def _on_normal_0_guard(self, parameters):
  250. x = parameters[0]
  251. y = parameters[1]
  252. button = parameters[2]
  253. return button == ui.MOUSE_BUTTONS.LEFT
  254. def _on_interrupted_0_guard(self, parameters):
  255. x = parameters[0]
  256. y = parameters[1]
  257. button = parameters[2]
  258. return button == ui.MOUSE_BUTTONS.LEFT
  259. def _creating_window_0_exec(self, parameters):
  260. window_id = parameters[0]
  261. self.window_id = window_id
  262. def _creating_canvas_0_exec(self, parameters):
  263. canvas_id = parameters[0]
  264. self.canvas_id = canvas_id
  265. def _creating_trafficlight_creating_greenlight_0_exec(self, parameters):
  266. canvas_id = parameters[0]
  267. green_id = parameters[1]
  268. self.green_id = green_id
  269. def _creating_trafficlight_creating_yellowlight_0_exec(self, parameters):
  270. canvas_id = parameters[0]
  271. yellow_id = parameters[1]
  272. self.yellow_id = yellow_id
  273. def _creating_trafficlight_creating_redlight_0_exec(self, parameters):
  274. canvas_id = parameters[0]
  275. red_id = parameters[1]
  276. self.red_id = red_id
  277. def _creating_interrupt_button_0_exec(self, parameters):
  278. button_id = parameters[0]
  279. self.police_button_id = button_id
  280. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [button_id, ui.EVENTS.MOUSE_CLICK, "interrupt_clicked", self.inports['field_ui']]))
  281. def _creating_quit_button_0_exec(self, parameters):
  282. button_id = parameters[0]
  283. self.quit_button_id = button_id
  284. self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [button_id, ui.EVENTS.MOUSE_CLICK, "quit_clicked", self.inports['field_ui']]))
  285. def initializeStatechart(self):
  286. # enter default state
  287. self.default_targets = self.states["/creating_window"].getEffectiveTargetStates()
  288. RuntimeClassBase.initializeStatechart(self)
  289. class MainApp(ClassBase):
  290. def __init__(self, name):
  291. ClassBase.__init__(self, name)
  292. self.input = self.addInPort("input")
  293. self.glob_outputs["ui"] = self.addOutPort("ui")
  294. self.field_ui = self.addInPort("field_ui")
  295. new_instance = self.constructObject(0, 0, [])
  296. self.state.instances[new_instance.instance_id] = new_instance
  297. new_instance.start()
  298. self.state.next_time = 0
  299. def constructObject(self, id, start_port_id, parameters):
  300. new_instance = MainAppInstance(self, id, start_port_id)
  301. return new_instance
  302. def instantiate(self, class_name, construct_params):
  303. instance = {}
  304. instance["name"] = class_name
  305. if class_name == "MainApp":
  306. self.narrow_cast_id = self.narrow_cast_id + 1
  307. instance["associations"] = {}
  308. else:
  309. raise Exception("Cannot instantiate class " + class_name)
  310. return instance
  311. ObjectManagerState.instantiate = instantiate
  312. class ObjectManager(ObjectManagerBase):
  313. def __init__(self, name):
  314. ObjectManagerBase.__init__(self, name)
  315. self.state = ObjectManagerState()
  316. self.input = self.addInPort("input")
  317. self.output["MainApp"] = self.addOutPort()
  318. self.state.createInstance("MainApp", [])
  319. class Controller(CoupledDEVS):
  320. def __init__(self, name):
  321. CoupledDEVS.__init__(self, name)
  322. self.out_ui = self.addOutPort("ui")
  323. self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
  324. self.atomics = []
  325. self.atomics.append(self.addSubModel(MainApp("MainApp")))
  326. self.connectPorts(self.atomics[0].obj_manager_out, self.objectmanager.input)
  327. self.connectPorts(self.objectmanager.output["MainApp"], self.atomics[0].obj_manager_in)
  328. self.connectPorts(self.atomics[0].glob_outputs["ui"], self.out_ui)