target.py 10 KB

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