target.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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
  4. Model name: Timer (Eventloop Version)
  5. """
  6. from sccd.runtime.DEVS_statecharts_core import *
  7. from pypdevs.DEVS import *
  8. from pypdevs.infinity import *
  9. from pypdevs.simulator import *
  10. from sccd.runtime.libs.ui import ui
  11. from time import time
  12. CANVAS_WIDTH = 500
  13. CANVAS_HEIGHT = 250
  14. FONT_SIZE = 50
  15. # package "Timer (Eventloop Version)"
  16. class MainAppInstance(RuntimeClassBase):
  17. def __init__(self, atomdevs):
  18. RuntimeClassBase.__init__(self, atomdevs)
  19. self.associations = {}
  20. self.semantics.big_step_maximality = StatechartSemantics.TakeMany
  21. self.semantics.internal_event_lifeline = StatechartSemantics.Queue
  22. self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
  23. self.semantics.priority = StatechartSemantics.SourceParent
  24. self.semantics.concurrency = StatechartSemantics.Single
  25. # build Statechart structure
  26. self.build_statechart_structure()
  27. # call user defined constructor
  28. MainAppInstance.user_defined_constructor(self)
  29. def user_defined_constructor(self):
  30. self.canvas = ui.append_canvas(ui.window,CANVAS_WIDTH,CANVAS_HEIGHT,{'background':'#222222'})
  31. self.clock_text = self.canvas.element.create_text(
  32. CANVAS_WIDTH / 2,
  33. CANVAS_HEIGHT / 2,
  34. text='0.0',
  35. anchor='center',
  36. font=("TkDefaultFont", FONT_SIZE)
  37. )
  38. self.actual_clock_text = self.canvas.element.create_text(
  39. CANVAS_WIDTH / 2,
  40. (CANVAS_HEIGHT / 2) + FONT_SIZE,
  41. text='0.0',
  42. anchor='center',
  43. font=("TkDefaultFont", FONT_SIZE)
  44. )
  45. interrupt_button = ui.append_button(ui.window, 'INTERRUPT');
  46. continue_button = ui.append_button(ui.window, 'CONTINUE');
  47. #ui.bind_event(interrupt_button.element, ui.EVENTS.MOUSE_CLICK, self.controller, 'interrupt_clicked');
  48. #ui.bind_event(continue_button.element, ui.EVENTS.MOUSE_CLICK, self.controller, 'continue_clicked');
  49. def user_defined_destructor(self):
  50. pass
  51. # user defined method
  52. def update_timers(self):
  53. self.canvas.element.itemconfigure(self.clock_text, text=str('%.2f' % (self.getSimulatedTime() / 1000.0)))
  54. self.canvas.element.itemconfigure(self.actual_clock_text, text='%.2f' % (time() / 1000.0))
  55. # builds Statechart structure
  56. def build_statechart_structure(self):
  57. # state <root>
  58. self.states[""] = State(0, "", self)
  59. # state /running
  60. self.states["/running"] = State(1, "/running", self)
  61. self.states["/running"].setEnter(self._running_enter)
  62. self.states["/running"].setExit(self._running_exit)
  63. # state /interrupted
  64. self.states["/interrupted"] = State(2, "/interrupted", self)
  65. # add children
  66. self.states[""].addChild(self.states["/running"])
  67. self.states[""].addChild(self.states["/interrupted"])
  68. self.states[""].fixTree()
  69. self.states[""].default_state = self.states["/running"]
  70. # transition /running
  71. _running_0 = Transition(self, self.states["/running"], [self.states["/running"]])
  72. _running_0.setAction(self._running_0_exec)
  73. _running_0.setTrigger(Event("_0after"))
  74. self.states["/running"].addTransition(_running_0)
  75. _running_1 = Transition(self, self.states["/running"], [self.states["/interrupted"]])
  76. _running_1.setAction(self._running_1_exec)
  77. _running_1.setTrigger(Event("interrupt_clicked", self.getInPortName("ui")))
  78. self.states["/running"].addTransition(_running_1)
  79. # transition /interrupted
  80. _interrupted_0 = Transition(self, self.states["/interrupted"], [self.states["/interrupted"]])
  81. _interrupted_0.setAction(self._interrupted_0_exec)
  82. _interrupted_0.setTrigger(Event("interrupt_clicked", self.getInPortName("ui")))
  83. self.states["/interrupted"].addTransition(_interrupted_0)
  84. _interrupted_1 = Transition(self, self.states["/interrupted"], [self.states["/running"]])
  85. _interrupted_1.setAction(self._interrupted_1_exec)
  86. _interrupted_1.setTrigger(Event("continue_clicked", self.getInPortName("ui")))
  87. self.states["/interrupted"].addTransition(_interrupted_1)
  88. def _running_enter(self):
  89. self.addTimer(0, 0.05)
  90. def _running_exit(self):
  91. self.removeTimer(0)
  92. def _running_0_exec(self, parameters):
  93. self.update_timers()
  94. def _running_1_exec(self, parameters):
  95. self.update_timers()
  96. def _interrupted_0_exec(self, parameters):
  97. self.update_timers()
  98. def _interrupted_1_exec(self, parameters):
  99. self.update_timers()
  100. def initializeStatechart(self):
  101. # enter default state
  102. self.default_targets = self.states["/running"].getEffectiveTargetStates()
  103. RuntimeClassBase.initializeStatechart(self)
  104. class MainApp(AtomicDEVS, ObjectManagerBase):
  105. def __init__(self, name):
  106. AtomicDEVS.__init__(self, name)
  107. ObjectManagerBase.__init__(self)
  108. self.elapsed = 0
  109. self.name = "MainApp"
  110. self.obj_manager_out = self.addOutPort("obj_manager_out")
  111. self.outputs = {}
  112. self.obj_manager_in = self.addInPort("obj_manager_in")
  113. self.input = self.addInPort("input")
  114. self.instances.append(MainAppInstance(self))
  115. self.next_time = INFINITY
  116. def extTransition(self, inputs):
  117. self.simulated_time = (self.simulated_time + self.elapsed)
  118. self.next_time = 0
  119. all_inputs = []
  120. if self.obj_manager_in in inputs:
  121. all_inputs.extend(inputs[self.obj_manager_in])
  122. if self.input in inputs:
  123. all_inputs.extend(inputs[self.input])
  124. for input in all_inputs:
  125. if isinstance(input, str):
  126. tem = eval(input)
  127. self.addInput(tem)
  128. elif input[2].name == "create_instance":
  129. new_instance = MainAppInstance(self)
  130. self.instances.append(new_instance)
  131. p = new_instance.associations.get("parent")
  132. if p:
  133. p.addInstance(input[2].instance)
  134. ev = Event("instance_created", None, [f"{input[2].parameters[0]}[{len(self.instances)-1}]"], input[2].instance)
  135. self.to_send.append((input[1], input[0], ev))
  136. elif input[2].name == "start_instance":
  137. instance = self.instances[input[2].instance]
  138. instance.start()
  139. ev = Event("instance_started", None, [f"{input[0]}[{len(self.instances)-1}]"], input[2].instance)
  140. self.to_send.append((input[0], input[1], ev))
  141. elif input[2].name == "delete_instance":
  142. pass
  143. elif input[2].name == "associate_instance":
  144. pass
  145. elif input[2].name == "disassociate_instance":
  146. pass
  147. elif input[2].name == "instance_created":
  148. instance = self.instances[input[2].instance]
  149. instance.addEvent(input[2])
  150. elif input[2].name == "instance_started":
  151. instance = self.instances[input[2].instance]
  152. instance.addEvent(input[2])
  153. elif input[2].name == "instance_deleted":
  154. pass
  155. elif input[2].name == "instance_associated":
  156. pass
  157. elif input[2].name == "instance_disassociated":
  158. pass
  159. else:
  160. ev = input[2]
  161. self.addInput(ev)
  162. return self.instances
  163. def intTransition(self):
  164. earliest = min(self.getEarliestEventTime(), self.simulated_time + self.input_queue.getEarliestTime())
  165. if not (earliest == INFINITY):
  166. self.simulated_time = earliest
  167. self.to_send = []
  168. self.handleInput()
  169. self.stepAll()
  170. next_earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  171. if not (len(self.to_send) == 0):
  172. self.next_time = 0
  173. elif next_earliest == INFINITY:
  174. self.next_time = INFINITY
  175. else:
  176. self.next_time = next_earliest - earliest
  177. return self.instances
  178. def outputFnc(self):
  179. to_dict = {}
  180. for sending in self.to_send:
  181. if sending[2].port == None:
  182. if self.obj_manager_out in to_dict:
  183. to_dict[self.obj_manager_out].append(sending)
  184. else:
  185. to_dict[self.obj_manager_out] = [sending]
  186. else:
  187. the_port = None
  188. for port in self.OPorts:
  189. if port.name == sending[0]:
  190. the_port = port
  191. if the_port in to_dict:
  192. to_dict[the_port].append(sending)
  193. else:
  194. to_dict[the_port] = [sending]
  195. return to_dict
  196. def timeAdvance(self):
  197. return self.next_time
  198. class ObjectManagerState:
  199. def __init__(self):
  200. self.to_send = [(None, "MainApp", Event("start_instance", None, [0], 0))]
  201. class ObjectManager(AtomicDEVS):
  202. def __init__(self, name):
  203. AtomicDEVS.__init__(self, name)
  204. self.State = ObjectManagerState()
  205. self.input = self.addInPort("input")
  206. self.output = {}
  207. self.output["MainApp"] = self.addOutPort()
  208. def extTransition(self, inputs):
  209. all_inputs = inputs[self.input]
  210. for input in all_inputs:
  211. self.State.to_send.append(input)
  212. return self.State
  213. def intTransition(self):
  214. self.State.to_send = []
  215. return self.State
  216. def outputFnc(self):
  217. out_dict = {}
  218. for (source, target, message) in self.State.to_send:
  219. if self.output[target] in out_dict:
  220. out_dict[self.output[target]].append((source, target, message))
  221. else:
  222. out_dict[self.output[target]] = [(source, target, message)]
  223. return out_dict
  224. def timeAdvance(self):
  225. if self.State.to_send:
  226. return 0
  227. return INFINITY
  228. class Controller(CoupledDEVS):
  229. def __init__(self, name):
  230. CoupledDEVS.__init__(self, name)
  231. self.ui = self.addInPort("ui")
  232. self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
  233. self.atomic0 = self.addSubModel(MainApp("MainApp"))
  234. self.connectPorts(self.atomic0.obj_manager_out, self.objectmanager.input)
  235. self.connectPorts(self.objectmanager.output["MainApp"], self.atomic0.obj_manager_in)