target.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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 sccd.runtime.accurate_time import AccurateTime
  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':'#eee'})
  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.obj_manager_out = self.addOutPort("obj_manager_out")
  95. self.outputs = {}
  96. self.obj_manager_in = self.addInPort("obj_manager_in")
  97. self.input = self.addInPort("input")
  98. self.instances.add(MainAppInstance(self))
  99. self.next_time = 0
  100. def extTransition(self, inputs):
  101. self.next_time = 0
  102. all_inputs = []
  103. if self.obj_manager_in in inputs:
  104. all_inputs.extend(inputs[self.obj_manager_in])
  105. if self.input in inputs:
  106. all_inputs.extend(inputs[self.input])
  107. for input in all_inputs:
  108. if isinstance(input, str):
  109. tem = eval(input)
  110. self.addInput(tem)
  111. if input[3].name == "create_instance":
  112. self.instances.add(MainAppInstance(self))
  113. ev = Event("instance_created", None, parameters=[f"{input[0]}[{len(self.instances)-1}]"])
  114. self.to_send.append(("MainApp", TODO, input[2], ev))
  115. elif input[3].name == "start_instance":
  116. instance = list(self.instances)[input[2]]
  117. instance.start()
  118. ev = Event("instance_started", None, parameters=[])
  119. self.to_send.append((input[0], input[1], input[2], ev))
  120. elif input[3].name == "delete_instance":
  121. ev = Event("instance_deleted", None, parameters=[TODO])
  122. self.to_send.append((TODO, TODO, TODO, ev))
  123. elif input[3].name == "associate_instance":
  124. ev = Event("instance_associated", None, parameters=[TODO])
  125. self.to_send.append((TODO, TODO, TODO, ev))
  126. elif input[3].name == "disassociate_instance":
  127. ev = Event("instance_disassociated", None, parameters=[TODO])
  128. self.to_send.append((TODO, TODO, TODO, ev))
  129. elif input[3].name == "instance_created":
  130. instance = list(self.instances)[input[2]]
  131. instance.addEvent(input[3])
  132. instance.associations['fields'].instances[0] = input[3].parameters[0]
  133. elif input[3].name == "instance_started":
  134. instance = list(self.instances)[input[2]]
  135. instance.addEvent(input[3])
  136. elif input[3].name == "instance_deleted":
  137. instance = list(self.instances)[input[2]]
  138. instance.addEvent(input[3])
  139. elif input[3].name == "instance_associated":
  140. instance = list(self.instances)[input[2]]
  141. instance.addEvent(input[3])
  142. elif input[3].name == "instance_disassociated":
  143. instance = list(self.instances)[input[2]]
  144. instance.addEvent(input[3])
  145. elif input[3].name == "set_association_name":
  146. ev = input[3]
  147. self.addInput(ev, force_internal=True)
  148. return self.instances
  149. def intTransition(self):
  150. earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  151. if not (earliest == INFINITY):
  152. self.simulated_time = earliest
  153. self.to_send = []
  154. self.handleInput()
  155. self.stepAll()
  156. next_earliest = min(self.getEarliestEventTime(), self.input_queue.getEarliestTime())
  157. self.next_time = next_earliest - earliest
  158. return self.instances
  159. def outputFnc(self):
  160. to_dict = {}
  161. for sending in self.to_send:
  162. if sending[0] == None:
  163. if self.obj_manager_out in to_dict:
  164. to_dict[self.obj_manager_out].append(sending)
  165. else:
  166. to_dict[self.obj_manager_out] = [sending]
  167. else:
  168. the_port = None
  169. for port in self.OPorts:
  170. if port.name == sending[0]:
  171. the_port = port
  172. if the_port in to_dict:
  173. to_dict[the_port].append(sending)
  174. else:
  175. to_dict[the_port] = [sending]
  176. return to_dict
  177. def timeAdvance(self):
  178. return self.next_time
  179. class ObjectManagerState:
  180. def __init__(self):
  181. self.to_send = [(None, "MainApp", 0, Event("start_instance", None, None))]
  182. class ObjectManager(AtomicDEVS):
  183. def __init__(self, name):
  184. AtomicDEVS.__init__(self, name)
  185. self.State = ObjectManagerState()
  186. self.input = self.addInPort("input")
  187. self.output = {}
  188. self.output["MainApp"] = self.addOutPort()
  189. def extTransition(self, inputs):
  190. all_inputs = inputs[self.input]
  191. for input in all_inputs:
  192. self.State.to_send.append(input)
  193. return self.State
  194. def intTransition(self):
  195. self.State.to_send = []
  196. return self.State
  197. def outputFnc(self):
  198. out_dict = {}
  199. for (source, target, id, message) in self.State.to_send:
  200. out_dict[self.output[target]] = [(source, target, id, message)]
  201. return out_dict
  202. def timeAdvance(self):
  203. if self.State.to_send:
  204. return 0
  205. return INFINITY
  206. class Controller(CoupledDEVS):
  207. def __init__(self, name):
  208. CoupledDEVS.__init__(self, name)
  209. self.ui = self.addInPort("ui")
  210. self.objectmanager = self.addSubModel(ObjectManager("ObjectManager"))
  211. self.atomic0 = self.addSubModel(MainApp("MainApp"))
  212. self.connectPorts(self.atomic0.obj_manager_out, self.objectmanager.input)
  213. self.connectPorts(self.objectmanager.output["MainApp"], self.atomic0.obj_manager_in)