|
@@ -0,0 +1,587 @@
|
|
|
+"""
|
|
|
+Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
|
|
|
+
|
|
|
+Model author: Sam Pieters
|
|
|
+Model name: Elevator Balls
|
|
|
+
|
|
|
+"""
|
|
|
+
|
|
|
+from sccd.runtime.statecharts_core import *
|
|
|
+from sccd.runtime.libs.ui import ui
|
|
|
+import random
|
|
|
+import time
|
|
|
+
|
|
|
+CANVAS_WIDTH = 800
|
|
|
+CANVAS_HEIGHT = 550
|
|
|
+
|
|
|
+# package "Elevator Balls"
|
|
|
+
|
|
|
+class MainApp(RuntimeClassBase):
|
|
|
+ def __init__(self, controller):
|
|
|
+ RuntimeClassBase.__init__(self, controller)
|
|
|
+
|
|
|
+ self.inports["field_ui"] = controller.addInputPort("field_ui", self)
|
|
|
+
|
|
|
+ self.semantics.big_step_maximality = StatechartSemantics.TakeMany
|
|
|
+ self.semantics.internal_event_lifeline = StatechartSemantics.Queue
|
|
|
+ self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
|
|
|
+ self.semantics.priority = StatechartSemantics.SourceParent
|
|
|
+ self.semantics.concurrency = StatechartSemantics.Single
|
|
|
+
|
|
|
+ # build Statechart structure
|
|
|
+ self.build_statechart_structure()
|
|
|
+
|
|
|
+ # user defined attributes
|
|
|
+ self.window_id = None
|
|
|
+ self.canvas_id = None
|
|
|
+ self.floor_dimensions = None
|
|
|
+
|
|
|
+ # call user defined constructor
|
|
|
+ MainApp.user_defined_constructor(self)
|
|
|
+
|
|
|
+ def user_defined_constructor(self):
|
|
|
+ pass
|
|
|
+
|
|
|
+ def user_defined_destructor(self):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+ # builds Statechart structure
|
|
|
+ def build_statechart_structure(self):
|
|
|
+
|
|
|
+ # state <root>
|
|
|
+ self.states[""] = State(0, "", self)
|
|
|
+
|
|
|
+ # state /creating_window
|
|
|
+ self.states["/creating_window"] = State(1, "/creating_window", self)
|
|
|
+ self.states["/creating_window"].setEnter(self._creating_window_enter)
|
|
|
+
|
|
|
+ # state /creating_canvas
|
|
|
+ self.states["/creating_canvas"] = State(2, "/creating_canvas", self)
|
|
|
+ self.states["/creating_canvas"].setEnter(self._creating_canvas_enter)
|
|
|
+
|
|
|
+ # state /create_elevator
|
|
|
+ self.states["/create_elevator"] = State(3, "/create_elevator", self)
|
|
|
+
|
|
|
+ # state /creating
|
|
|
+ self.states["/creating"] = State(4, "/creating", self)
|
|
|
+
|
|
|
+ # state /waiting
|
|
|
+ self.states["/waiting"] = State(5, "/waiting", self)
|
|
|
+
|
|
|
+ # add children
|
|
|
+ self.states[""].addChild(self.states["/creating_window"])
|
|
|
+ self.states[""].addChild(self.states["/creating_canvas"])
|
|
|
+ self.states[""].addChild(self.states["/create_elevator"])
|
|
|
+ self.states[""].addChild(self.states["/creating"])
|
|
|
+ self.states[""].addChild(self.states["/waiting"])
|
|
|
+ self.states[""].fixTree()
|
|
|
+ self.states[""].default_state = self.states["/creating_window"]
|
|
|
+
|
|
|
+ # transition /creating_window
|
|
|
+ _creating_window_0 = Transition(self, self.states["/creating_window"], [self.states["/creating_canvas"]])
|
|
|
+ _creating_window_0.setAction(self._creating_window_0_exec)
|
|
|
+ _creating_window_0.setTrigger(Event("window_created", None))
|
|
|
+ self.states["/creating_window"].addTransition(_creating_window_0)
|
|
|
+
|
|
|
+ # transition /creating_canvas
|
|
|
+ _creating_canvas_0 = Transition(self, self.states["/creating_canvas"], [self.states["/create_elevator"]])
|
|
|
+ _creating_canvas_0.setAction(self._creating_canvas_0_exec)
|
|
|
+ _creating_canvas_0.setTrigger(Event("canvas_created", None))
|
|
|
+ self.states["/creating_canvas"].addTransition(_creating_canvas_0)
|
|
|
+
|
|
|
+ # transition /create_elevator
|
|
|
+ _create_elevator_0 = Transition(self, self.states["/create_elevator"], [self.states["/creating"]])
|
|
|
+ _create_elevator_0.setAction(self._create_elevator_0_exec)
|
|
|
+ _create_elevator_0.setTrigger(None)
|
|
|
+ self.states["/create_elevator"].addTransition(_create_elevator_0)
|
|
|
+
|
|
|
+ # transition /creating
|
|
|
+ _creating_0 = Transition(self, self.states["/creating"], [self.states["/waiting"]])
|
|
|
+ _creating_0.setAction(self._creating_0_exec)
|
|
|
+ _creating_0.setTrigger(Event("instance_created", None))
|
|
|
+ self.states["/creating"].addTransition(_creating_0)
|
|
|
+
|
|
|
+ def _creating_window_enter(self):
|
|
|
+ self.big_step.outputEvent(Event("create_window", self.getOutPortName("ui"), [CANVAS_WIDTH, CANVAS_HEIGHT, "Bouncing Balls Elevator", self.inports['field_ui']]))
|
|
|
+
|
|
|
+ def _creating_canvas_enter(self):
|
|
|
+ self.big_step.outputEvent(Event("create_canvas", self.getOutPortName("ui"), [self.window_id, CANVAS_WIDTH, CANVAS_HEIGHT - 200, {'background':'#fff'}, self.inports['field_ui']]))
|
|
|
+
|
|
|
+ def _creating_window_0_exec(self, parameters):
|
|
|
+ window_id = parameters[0]
|
|
|
+ self.window_id = window_id
|
|
|
+ self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [window_id, ui.EVENTS.WINDOW_CLOSE, 'window_close', self.inports['field_ui']]))
|
|
|
+ self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [window_id, ui.EVENTS.KEY_PRESS, 'key_press', self.inports['field_ui']]))
|
|
|
+
|
|
|
+ def _creating_canvas_0_exec(self, parameters):
|
|
|
+ canvas_id = parameters[0]
|
|
|
+ self.canvas_id = canvas_id
|
|
|
+
|
|
|
+ def _create_elevator_0_exec(self, parameters):
|
|
|
+ self.big_step.outputEventOM(Event("create_instance", None, [self, "elevator", "Elevator", self.canvas_id]))
|
|
|
+
|
|
|
+ def _creating_0_exec(self, parameters):
|
|
|
+ association_name = parameters[0]
|
|
|
+ self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
|
|
|
+ self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("set_association_name", None, [association_name, self.canvas_id, self.window_id])]))
|
|
|
+
|
|
|
+ def initializeStatechart(self):
|
|
|
+ # enter default state
|
|
|
+ self.default_targets = self.states["/creating_window"].getEffectiveTargetStates()
|
|
|
+ RuntimeClassBase.initializeStatechart(self)
|
|
|
+
|
|
|
+class Elevator(RuntimeClassBase):
|
|
|
+ def __init__(self, controller, canvas_id):
|
|
|
+ RuntimeClassBase.__init__(self, controller)
|
|
|
+
|
|
|
+ self.inports["elevator_ui"] = controller.addInputPort("elevator_ui", self)
|
|
|
+
|
|
|
+ self.semantics.big_step_maximality = StatechartSemantics.TakeMany
|
|
|
+ self.semantics.internal_event_lifeline = StatechartSemantics.Queue
|
|
|
+ self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
|
|
|
+ self.semantics.priority = StatechartSemantics.SourceParent
|
|
|
+ self.semantics.concurrency = StatechartSemantics.Single
|
|
|
+
|
|
|
+ # build Statechart structure
|
|
|
+ self.build_statechart_structure()
|
|
|
+
|
|
|
+ # user defined attributes
|
|
|
+ self.window_id = None
|
|
|
+ self.canvas_id = None
|
|
|
+ self.elevator_id = None
|
|
|
+
|
|
|
+ # call user defined constructor
|
|
|
+ Elevator.user_defined_constructor(self, canvas_id)
|
|
|
+
|
|
|
+ def user_defined_constructor(self, canvas_id):
|
|
|
+ self.canvas_id = canvas_id;
|
|
|
+ self.button_ids = {
|
|
|
+ 'up': None,
|
|
|
+ 'down': None,
|
|
|
+ 'open': None
|
|
|
+ };
|
|
|
+ self.open_button = None;
|
|
|
+ self.is_open = False;
|
|
|
+
|
|
|
+ self.dim = {'x': 80, 'y': 150};
|
|
|
+ self.vel = {'x': 0, 'y': 0};
|
|
|
+ self.pos = {'x': 400, 'y': 75};
|
|
|
+ self.smooth = 0.6; # value between 0 and 1
|
|
|
+
|
|
|
+ def user_defined_destructor(self):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+ # builds Statechart structure
|
|
|
+ def build_statechart_structure(self):
|
|
|
+
|
|
|
+ # state <root>
|
|
|
+ self.states[""] = State(0, "", self)
|
|
|
+
|
|
|
+ # state /root
|
|
|
+ self.states["/root"] = State(1, "/root", self)
|
|
|
+
|
|
|
+ # state /root/waiting
|
|
|
+ self.states["/root/waiting"] = State(2, "/root/waiting", self)
|
|
|
+
|
|
|
+ # state /root/creating_elevator
|
|
|
+ self.states["/root/creating_elevator"] = State(3, "/root/creating_elevator", self)
|
|
|
+ self.states["/root/creating_elevator"].setEnter(self._root_creating_elevator_enter)
|
|
|
+
|
|
|
+ # state /root/create_elevator_controls
|
|
|
+ self.states["/root/create_elevator_controls"] = State(4, "/root/create_elevator_controls", self)
|
|
|
+
|
|
|
+ # state /root/create_elevator_controls/create_up
|
|
|
+ self.states["/root/create_elevator_controls/create_up"] = State(5, "/root/create_elevator_controls/create_up", self)
|
|
|
+ self.states["/root/create_elevator_controls/create_up"].setEnter(self._root_create_elevator_controls_create_up_enter)
|
|
|
+
|
|
|
+ # state /root/create_elevator_controls/create_down
|
|
|
+ self.states["/root/create_elevator_controls/create_down"] = State(6, "/root/create_elevator_controls/create_down", self)
|
|
|
+ self.states["/root/create_elevator_controls/create_down"].setEnter(self._root_create_elevator_controls_create_down_enter)
|
|
|
+
|
|
|
+ # state /root/create_elevator_controls/create_open
|
|
|
+ self.states["/root/create_elevator_controls/create_open"] = State(7, "/root/create_elevator_controls/create_open", self)
|
|
|
+ self.states["/root/create_elevator_controls/create_open"].setEnter(self._root_create_elevator_controls_create_open_enter)
|
|
|
+
|
|
|
+ # state /root/running
|
|
|
+ self.states["/root/running"] = State(8, "/root/running", self)
|
|
|
+ self.states["/root/running"].setEnter(self._root_running_enter)
|
|
|
+ self.states["/root/running"].setExit(self._root_running_exit)
|
|
|
+
|
|
|
+ # add children
|
|
|
+ self.states[""].addChild(self.states["/root"])
|
|
|
+ self.states["/root"].addChild(self.states["/root/waiting"])
|
|
|
+ self.states["/root"].addChild(self.states["/root/creating_elevator"])
|
|
|
+ self.states["/root"].addChild(self.states["/root/create_elevator_controls"])
|
|
|
+ self.states["/root"].addChild(self.states["/root/running"])
|
|
|
+ self.states["/root/create_elevator_controls"].addChild(self.states["/root/create_elevator_controls/create_up"])
|
|
|
+ self.states["/root/create_elevator_controls"].addChild(self.states["/root/create_elevator_controls/create_down"])
|
|
|
+ self.states["/root/create_elevator_controls"].addChild(self.states["/root/create_elevator_controls/create_open"])
|
|
|
+ self.states[""].fixTree()
|
|
|
+ self.states[""].default_state = self.states["/root"]
|
|
|
+ self.states["/root"].default_state = self.states["/root/waiting"]
|
|
|
+ self.states["/root/create_elevator_controls"].default_state = self.states["/root/create_elevator_controls/create_up"]
|
|
|
+
|
|
|
+ # transition /root/waiting
|
|
|
+ _root_waiting_0 = Transition(self, self.states["/root/waiting"], [self.states["/root/creating_elevator"]])
|
|
|
+ _root_waiting_0.setAction(self._root_waiting_0_exec)
|
|
|
+ _root_waiting_0.setTrigger(Event("set_association_name", None))
|
|
|
+ self.states["/root/waiting"].addTransition(_root_waiting_0)
|
|
|
+
|
|
|
+ # transition /root/creating_elevator
|
|
|
+ _root_creating_elevator_0 = Transition(self, self.states["/root/creating_elevator"], [self.states["/root/create_elevator_controls"]])
|
|
|
+ _root_creating_elevator_0.setAction(self._root_creating_elevator_0_exec)
|
|
|
+ _root_creating_elevator_0.setTrigger(Event("rectangle_created", None))
|
|
|
+ self.states["/root/creating_elevator"].addTransition(_root_creating_elevator_0)
|
|
|
+
|
|
|
+ # transition /root/create_elevator_controls/create_up
|
|
|
+ _root_create_elevator_controls_create_up_0 = Transition(self, self.states["/root/create_elevator_controls/create_up"], [self.states["/root/create_elevator_controls/create_down"]])
|
|
|
+ _root_create_elevator_controls_create_up_0.setAction(self._root_create_elevator_controls_create_up_0_exec)
|
|
|
+ _root_create_elevator_controls_create_up_0.setTrigger(Event("button_created", None))
|
|
|
+ self.states["/root/create_elevator_controls/create_up"].addTransition(_root_create_elevator_controls_create_up_0)
|
|
|
+
|
|
|
+ # transition /root/create_elevator_controls/create_down
|
|
|
+ _root_create_elevator_controls_create_down_0 = Transition(self, self.states["/root/create_elevator_controls/create_down"], [self.states["/root/create_elevator_controls/create_open"]])
|
|
|
+ _root_create_elevator_controls_create_down_0.setAction(self._root_create_elevator_controls_create_down_0_exec)
|
|
|
+ _root_create_elevator_controls_create_down_0.setTrigger(Event("button_created", None))
|
|
|
+ self.states["/root/create_elevator_controls/create_down"].addTransition(_root_create_elevator_controls_create_down_0)
|
|
|
+
|
|
|
+ # transition /root/create_elevator_controls/create_open
|
|
|
+ _root_create_elevator_controls_create_open_0 = Transition(self, self.states["/root/create_elevator_controls/create_open"], [self.states["/root/running"]])
|
|
|
+ _root_create_elevator_controls_create_open_0.setAction(self._root_create_elevator_controls_create_open_0_exec)
|
|
|
+ _root_create_elevator_controls_create_open_0.setTrigger(Event("button_created", None))
|
|
|
+ self.states["/root/create_elevator_controls/create_open"].addTransition(_root_create_elevator_controls_create_open_0)
|
|
|
+
|
|
|
+ # transition /root/running
|
|
|
+ _root_running_0 = Transition(self, self.states["/root/running"], [self.states["/root/running"]])
|
|
|
+ _root_running_0.setAction(self._root_running_0_exec)
|
|
|
+ _root_running_0.setTrigger(Event("_0after"))
|
|
|
+ self.states["/root/running"].addTransition(_root_running_0)
|
|
|
+ _root_running_1 = Transition(self, self.states["/root/running"], [self.states["/root/running"]])
|
|
|
+ _root_running_1.setAction(self._root_running_1_exec)
|
|
|
+ _root_running_1.setTrigger(Event("right_click", self.getInPortName("elevator_ui")))
|
|
|
+ self.states["/root/running"].addTransition(_root_running_1)
|
|
|
+ _root_running_2 = Transition(self, self.states["/root/running"], [self.states["/root/running"]])
|
|
|
+ _root_running_2.setAction(self._root_running_2_exec)
|
|
|
+ _root_running_2.setTrigger(Event("instance_created", None))
|
|
|
+ self.states["/root/running"].addTransition(_root_running_2)
|
|
|
+
|
|
|
+ def _root_creating_elevator_enter(self):
|
|
|
+ self.big_step.outputEvent(Event("create_rectangle", self.getOutPortName("ui"), [self.canvas_id, self.pos['x'], self.pos['y'], self.dim['x'], self.dim['y'], {'fill':'white', 'outline': 'black'}, self.inports['elevator_ui']]))
|
|
|
+
|
|
|
+ def _root_create_elevator_controls_create_up_enter(self):
|
|
|
+ self.big_step.outputEvent(Event("create_button", self.getOutPortName("ui"), [self.window_id, 'START', self.inports['elevator_ui']]))
|
|
|
+
|
|
|
+ def _root_create_elevator_controls_create_down_enter(self):
|
|
|
+ self.big_step.outputEvent(Event("create_button", self.getOutPortName("ui"), [self.window_id, 'STOP', self.inports['elevator_ui']]))
|
|
|
+
|
|
|
+ def _root_create_elevator_controls_create_open_enter(self):
|
|
|
+ self.big_step.outputEvent(Event("create_button", self.getOutPortName("ui"), [self.window_id, 'OPEN', self.inports['elevator_ui']]))
|
|
|
+
|
|
|
+ def _root_running_enter(self):
|
|
|
+ self.addTimer(0, 0.02)
|
|
|
+
|
|
|
+ def _root_running_exit(self):
|
|
|
+ self.removeTimer(0)
|
|
|
+
|
|
|
+ def _root_waiting_0_exec(self, parameters):
|
|
|
+ association_name = parameters[0]
|
|
|
+ canvas_id = parameters[1]
|
|
|
+ window_id = parameters[2]
|
|
|
+ self.association_name = association_name
|
|
|
+ self.canvas_id = canvas_id
|
|
|
+ self.window_id = window_id
|
|
|
+
|
|
|
+ def _root_creating_elevator_0_exec(self, parameters):
|
|
|
+ canvas_id = parameters[0]
|
|
|
+ rect_id = parameters[1]
|
|
|
+ self.elevator_id = rect_id
|
|
|
+ self.big_step.outputEvent(Event("bind_event", self.getOutPortName("ui"), [canvas_id, ui.EVENTS.MOUSE_RIGHT_CLICK, 'right_click', self.inports['elevator_ui']]))
|
|
|
+
|
|
|
+ def _root_create_elevator_controls_create_up_0_exec(self, parameters):
|
|
|
+ button_id = parameters[0]
|
|
|
+ self.button_ids['up'] = button_id
|
|
|
+
|
|
|
+ def _root_create_elevator_controls_create_down_0_exec(self, parameters):
|
|
|
+ button_id = parameters[0]
|
|
|
+ self.button_ids['down'] = button_id
|
|
|
+
|
|
|
+ def _root_create_elevator_controls_create_open_0_exec(self, parameters):
|
|
|
+ button_id = parameters[0]
|
|
|
+ self.button_ids['open'] = button_id
|
|
|
+
|
|
|
+ def _root_running_0_exec(self, parameters):
|
|
|
+ # Invert velocity when colliding with canvas border:
|
|
|
+ if self.pos['y']-(self.dim['y']/2) <= 0 or self.pos['y']+(self.dim['y']/2) >= CANVAS_HEIGHT:
|
|
|
+ self.vel['y'] = -self.vel['y'];
|
|
|
+ self.big_step.outputEvent(Event("move_element", self.getOutPortName("ui"), [self.canvas_id, self.elevator_id, self.vel['x'], self.vel['y']]))
|
|
|
+ self.pos['x'] += self.vel['x']
|
|
|
+ self.pos['y'] += self.vel['y']
|
|
|
+ self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'balls', Event("update_bounds", None, [self.pos, self.dim, self.vel])]))
|
|
|
+
|
|
|
+ def _root_running_1_exec(self, parameters):
|
|
|
+ x = parameters[0]
|
|
|
+ y = parameters[1]
|
|
|
+ button = parameters[2]
|
|
|
+ self.big_step.outputEventOM(Event("create_instance", None, [self, "balls", "Ball", self.canvas_id, x, y]))
|
|
|
+
|
|
|
+ def _root_running_2_exec(self, parameters):
|
|
|
+ association_name = parameters[0]
|
|
|
+ self.big_step.outputEventOM(Event("start_instance", None, [self, association_name]))
|
|
|
+ self.big_step.outputEventOM(Event("narrow_cast", None, [self, association_name, Event("set_association_name", None, [association_name])]))
|
|
|
+
|
|
|
+ def initializeStatechart(self):
|
|
|
+ # enter default state
|
|
|
+ self.default_targets = self.states["/root"].getEffectiveTargetStates()
|
|
|
+ RuntimeClassBase.initializeStatechart(self)
|
|
|
+
|
|
|
+class Ball(RuntimeClassBase):
|
|
|
+ def __init__(self, controller, canvas_id, x, y):
|
|
|
+ RuntimeClassBase.__init__(self, controller)
|
|
|
+
|
|
|
+ self.inports["ball_ui"] = controller.addInputPort("ball_ui", self)
|
|
|
+
|
|
|
+ self.semantics.big_step_maximality = StatechartSemantics.TakeMany
|
|
|
+ self.semantics.internal_event_lifeline = StatechartSemantics.Queue
|
|
|
+ self.semantics.input_event_lifeline = StatechartSemantics.FirstComboStep
|
|
|
+ self.semantics.priority = StatechartSemantics.SourceParent
|
|
|
+ self.semantics.concurrency = StatechartSemantics.Single
|
|
|
+
|
|
|
+ # build Statechart structure
|
|
|
+ self.build_statechart_structure()
|
|
|
+
|
|
|
+ # user defined attributes
|
|
|
+ self.canvas_id = None
|
|
|
+ self.pos = None
|
|
|
+
|
|
|
+ # call user defined constructor
|
|
|
+ Ball.user_defined_constructor(self, canvas_id, x, y)
|
|
|
+
|
|
|
+ def user_defined_constructor(self, canvas_id, x, y):
|
|
|
+ self.canvas_id = canvas_id;
|
|
|
+ self.r = 5.0;
|
|
|
+ self.vel = {'x': random.uniform(-5.0, 5.0), 'y': random.uniform(-5.0, 5.0)};
|
|
|
+ self.pos = {'x': x, 'y': y};
|
|
|
+ self.smooth = 0.6; # value between 0 and 1
|
|
|
+
|
|
|
+ def user_defined_destructor(self):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+ # builds Statechart structure
|
|
|
+ def build_statechart_structure(self):
|
|
|
+
|
|
|
+ # state <root>
|
|
|
+ self.states[""] = State(0, "", self)
|
|
|
+
|
|
|
+ # state /main_behaviour
|
|
|
+ self.states["/main_behaviour"] = State(1, "/main_behaviour", self)
|
|
|
+
|
|
|
+ # state /main_behaviour/initializing
|
|
|
+ self.states["/main_behaviour/initializing"] = State(2, "/main_behaviour/initializing", self)
|
|
|
+
|
|
|
+ # state /main_behaviour/creating_circle
|
|
|
+ self.states["/main_behaviour/creating_circle"] = State(3, "/main_behaviour/creating_circle", self)
|
|
|
+ self.states["/main_behaviour/creating_circle"].setEnter(self._main_behaviour_creating_circle_enter)
|
|
|
+
|
|
|
+ # state /main_behaviour/bouncing
|
|
|
+ self.states["/main_behaviour/bouncing"] = State(4, "/main_behaviour/bouncing", self)
|
|
|
+ self.states["/main_behaviour/bouncing"].setEnter(self._main_behaviour_bouncing_enter)
|
|
|
+ self.states["/main_behaviour/bouncing"].setExit(self._main_behaviour_bouncing_exit)
|
|
|
+
|
|
|
+ # state /main_behaviour/dragging
|
|
|
+ self.states["/main_behaviour/dragging"] = State(5, "/main_behaviour/dragging", self)
|
|
|
+
|
|
|
+ # state /main_behaviour/selected
|
|
|
+ self.states["/main_behaviour/selected"] = State(6, "/main_behaviour/selected", self)
|
|
|
+
|
|
|
+ # state /deleted
|
|
|
+ self.states["/deleted"] = State(7, "/deleted", self)
|
|
|
+
|
|
|
+ # add children
|
|
|
+ self.states[""].addChild(self.states["/main_behaviour"])
|
|
|
+ self.states[""].addChild(self.states["/deleted"])
|
|
|
+ self.states["/main_behaviour"].addChild(self.states["/main_behaviour/initializing"])
|
|
|
+ self.states["/main_behaviour"].addChild(self.states["/main_behaviour/creating_circle"])
|
|
|
+ self.states["/main_behaviour"].addChild(self.states["/main_behaviour/bouncing"])
|
|
|
+ self.states["/main_behaviour"].addChild(self.states["/main_behaviour/dragging"])
|
|
|
+ self.states["/main_behaviour"].addChild(self.states["/main_behaviour/selected"])
|
|
|
+ self.states[""].fixTree()
|
|
|
+ self.states[""].default_state = self.states["/main_behaviour"]
|
|
|
+ self.states["/main_behaviour"].default_state = self.states["/main_behaviour/initializing"]
|
|
|
+
|
|
|
+ # transition /main_behaviour/initializing
|
|
|
+ _main_behaviour_initializing_0 = Transition(self, self.states["/main_behaviour/initializing"], [self.states["/main_behaviour/creating_circle"]])
|
|
|
+ _main_behaviour_initializing_0.setAction(self._main_behaviour_initializing_0_exec)
|
|
|
+ _main_behaviour_initializing_0.setTrigger(Event("set_association_name", None))
|
|
|
+ self.states["/main_behaviour/initializing"].addTransition(_main_behaviour_initializing_0)
|
|
|
+
|
|
|
+ # transition /main_behaviour/creating_circle
|
|
|
+ _main_behaviour_creating_circle_0 = Transition(self, self.states["/main_behaviour/creating_circle"], [self.states["/main_behaviour/bouncing"]])
|
|
|
+ _main_behaviour_creating_circle_0.setAction(self._main_behaviour_creating_circle_0_exec)
|
|
|
+ _main_behaviour_creating_circle_0.setTrigger(Event("circle_created", None))
|
|
|
+ self.states["/main_behaviour/creating_circle"].addTransition(_main_behaviour_creating_circle_0)
|
|
|
+
|
|
|
+ # transition /main_behaviour/bouncing
|
|
|
+ _main_behaviour_bouncing_0 = Transition(self, self.states["/main_behaviour/bouncing"], [self.states["/main_behaviour/bouncing"]])
|
|
|
+ _main_behaviour_bouncing_0.setAction(self._main_behaviour_bouncing_0_exec)
|
|
|
+ _main_behaviour_bouncing_0.setTrigger(Event("_0after"))
|
|
|
+ self.states["/main_behaviour/bouncing"].addTransition(_main_behaviour_bouncing_0)
|
|
|
+ _main_behaviour_bouncing_1 = Transition(self, self.states["/main_behaviour/bouncing"], [self.states["/main_behaviour/selected"]])
|
|
|
+ _main_behaviour_bouncing_1.setAction(self._main_behaviour_bouncing_1_exec)
|
|
|
+ _main_behaviour_bouncing_1.setTrigger(Event("mouse_press", self.getInPortName("ball_ui")))
|
|
|
+ _main_behaviour_bouncing_1.setGuard(self._main_behaviour_bouncing_1_guard)
|
|
|
+ self.states["/main_behaviour/bouncing"].addTransition(_main_behaviour_bouncing_1)
|
|
|
+ _main_behaviour_bouncing_2 = Transition(self, self.states["/main_behaviour/bouncing"], [self.states["/main_behaviour/bouncing"]])
|
|
|
+ _main_behaviour_bouncing_2.setAction(self._main_behaviour_bouncing_2_exec)
|
|
|
+ _main_behaviour_bouncing_2.setTrigger(Event("update_bounds", None))
|
|
|
+ self.states["/main_behaviour/bouncing"].addTransition(_main_behaviour_bouncing_2)
|
|
|
+
|
|
|
+ # transition /main_behaviour/dragging
|
|
|
+ _main_behaviour_dragging_0 = Transition(self, self.states["/main_behaviour/dragging"], [self.states["/main_behaviour/dragging"]])
|
|
|
+ _main_behaviour_dragging_0.setAction(self._main_behaviour_dragging_0_exec)
|
|
|
+ _main_behaviour_dragging_0.setTrigger(Event("mouse_move", self.getInPortName("ball_ui")))
|
|
|
+ self.states["/main_behaviour/dragging"].addTransition(_main_behaviour_dragging_0)
|
|
|
+ _main_behaviour_dragging_1 = Transition(self, self.states["/main_behaviour/dragging"], [self.states["/main_behaviour/bouncing"]])
|
|
|
+ _main_behaviour_dragging_1.setAction(self._main_behaviour_dragging_1_exec)
|
|
|
+ _main_behaviour_dragging_1.setTrigger(Event("mouse_release", self.getInPortName("ball_ui")))
|
|
|
+ self.states["/main_behaviour/dragging"].addTransition(_main_behaviour_dragging_1)
|
|
|
+
|
|
|
+ # transition /main_behaviour/selected
|
|
|
+ _main_behaviour_selected_0 = Transition(self, self.states["/main_behaviour/selected"], [self.states["/main_behaviour/dragging"]])
|
|
|
+ _main_behaviour_selected_0.setAction(self._main_behaviour_selected_0_exec)
|
|
|
+ _main_behaviour_selected_0.setTrigger(Event("mouse_press", self.getInPortName("ball_ui")))
|
|
|
+ _main_behaviour_selected_0.setGuard(self._main_behaviour_selected_0_guard)
|
|
|
+ self.states["/main_behaviour/selected"].addTransition(_main_behaviour_selected_0)
|
|
|
+ _main_behaviour_selected_1 = Transition(self, self.states["/main_behaviour/selected"], [self.states["/deleted"]])
|
|
|
+ _main_behaviour_selected_1.setAction(self._main_behaviour_selected_1_exec)
|
|
|
+ _main_behaviour_selected_1.setTrigger(Event("delete_self", None))
|
|
|
+ self.states["/main_behaviour/selected"].addTransition(_main_behaviour_selected_1)
|
|
|
+
|
|
|
+ def _main_behaviour_creating_circle_enter(self):
|
|
|
+ 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']]))
|
|
|
+
|
|
|
+ def _main_behaviour_bouncing_enter(self):
|
|
|
+ self.addTimer(0, 0.02)
|
|
|
+
|
|
|
+ def _main_behaviour_bouncing_exit(self):
|
|
|
+ self.removeTimer(0)
|
|
|
+
|
|
|
+ def _main_behaviour_initializing_0_exec(self, parameters):
|
|
|
+ association_name = parameters[0]
|
|
|
+ self.association_name = association_name
|
|
|
+
|
|
|
+ def _main_behaviour_creating_circle_0_exec(self, parameters):
|
|
|
+ canvas_id = parameters[0]
|
|
|
+ circle_id = parameters[1]
|
|
|
+ self.circle_id = circle_id
|
|
|
+ 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']]))
|
|
|
+ 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']]))
|
|
|
+ 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']]))
|
|
|
+
|
|
|
+ def _main_behaviour_bouncing_0_exec(self, parameters):
|
|
|
+ # Invert velocity when colliding with canvas border:
|
|
|
+ if self.pos['x']-self.r <= self.rect_pos['x'] - (self.rect_dim['x'] / 2) or self.pos['x']+self.r >= self.rect_pos['x'] + (self.rect_dim['x'] / 2):
|
|
|
+ self.vel['x'] = -self.vel['x'] + self.rect_vel['x'];
|
|
|
+ if self.pos['y']-self.r <= self.rect_pos['y'] - (self.rect_dim['y'] / 2) or self.pos['y']+self.r >= self.rect_pos['y'] + (self.rect_dim['y'] / 2):
|
|
|
+ self.vel['y'] = -self.vel['y'] + self.rect_vel['y'];
|
|
|
+ self.big_step.outputEvent(Event("move_element", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, self.vel['x'], self.vel['y']]))
|
|
|
+ self.pos['x'] += self.vel['x']
|
|
|
+ self.pos['y'] += self.vel['y']
|
|
|
+
|
|
|
+ def _main_behaviour_bouncing_1_exec(self, parameters):
|
|
|
+ x = parameters[0]
|
|
|
+ y = parameters[1]
|
|
|
+ button = parameters[2]
|
|
|
+ self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, '#ff0']))
|
|
|
+
|
|
|
+ def _main_behaviour_bouncing_1_guard(self, parameters):
|
|
|
+ x = parameters[0]
|
|
|
+ y = parameters[1]
|
|
|
+ button = parameters[2]
|
|
|
+ return button == ui.MOUSE_BUTTONS.LEFT
|
|
|
+
|
|
|
+ def _main_behaviour_bouncing_2_exec(self, parameters):
|
|
|
+ pos = parameters[0]
|
|
|
+ dim = parameters[1]
|
|
|
+ vel = parameters[2]
|
|
|
+ self.rect_pos = pos
|
|
|
+ self.rect_dim = dim
|
|
|
+ self.rect_vel = vel
|
|
|
+
|
|
|
+ def _main_behaviour_dragging_0_exec(self, parameters):
|
|
|
+ x = parameters[0]
|
|
|
+ y = parameters[1]
|
|
|
+ button = parameters[2]
|
|
|
+ # Always keep ball within canvas:
|
|
|
+ x = min(max(0+self.r, x), CANVAS_WIDTH-self.r)
|
|
|
+ y = min(max(0+self.r, y), CANVAS_HEIGHT-self.r)
|
|
|
+
|
|
|
+ dx = x - self.pos['x']
|
|
|
+ dy = y - self.pos['y']
|
|
|
+
|
|
|
+ self.vel = {
|
|
|
+ 'x': (1-self.smooth)*dx + self.smooth*self.vel['x'],
|
|
|
+ 'y': (1-self.smooth)*dy + self.smooth*self.vel['y']
|
|
|
+ }
|
|
|
+
|
|
|
+ self.pos = {'x': x, 'y': y}
|
|
|
+ self.big_step.outputEvent(Event("set_element_pos", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, x-self.r, y-self.r]))
|
|
|
+
|
|
|
+ def _main_behaviour_dragging_1_exec(self, parameters):
|
|
|
+ x = parameters[0]
|
|
|
+ y = parameters[1]
|
|
|
+ self.big_step.outputEvent(Event("set_element_color", self.getOutPortName("ui"), [self.canvas_id, self.circle_id, '#f00']))
|
|
|
+
|
|
|
+ def _main_behaviour_selected_0_exec(self, parameters):
|
|
|
+ x = parameters[0]
|
|
|
+ y = parameters[1]
|
|
|
+ button = parameters[2]
|
|
|
+ self.mouse_pos = {'x':x, 'y':y};
|
|
|
+
|
|
|
+ def _main_behaviour_selected_0_guard(self, parameters):
|
|
|
+ x = parameters[0]
|
|
|
+ y = parameters[1]
|
|
|
+ button = parameters[2]
|
|
|
+ return button == ui.MOUSE_BUTTONS.LEFT
|
|
|
+
|
|
|
+ def _main_behaviour_selected_1_exec(self, parameters):
|
|
|
+ self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'parent', Event("delete_ball", None, [self.association_name])]))
|
|
|
+ self.big_step.outputEvent(Event("destroy_element", self.getOutPortName("ui"), [self.canvas_id, self.element_id]))
|
|
|
+
|
|
|
+ def initializeStatechart(self):
|
|
|
+ # enter default state
|
|
|
+ self.default_targets = self.states["/main_behaviour"].getEffectiveTargetStates()
|
|
|
+ RuntimeClassBase.initializeStatechart(self)
|
|
|
+
|
|
|
+class ObjectManager(ObjectManagerBase):
|
|
|
+ def __init__(self, controller):
|
|
|
+ ObjectManagerBase.__init__(self, controller)
|
|
|
+
|
|
|
+ def instantiate(self, class_name, construct_params):
|
|
|
+ if class_name == "MainApp":
|
|
|
+ instance = MainApp(self.controller)
|
|
|
+ instance.associations = {}
|
|
|
+ instance.associations["elevator"] = Association("Elevator", 0, -1)
|
|
|
+ elif class_name == "Elevator":
|
|
|
+ instance = Elevator(self.controller, construct_params[0])
|
|
|
+ instance.associations = {}
|
|
|
+ instance.associations["balls"] = Association("Ball", 0, -1)
|
|
|
+ instance.associations["parent"] = Association("MainApp", 1, 1)
|
|
|
+ elif class_name == "Ball":
|
|
|
+ instance = Ball(self.controller, construct_params[0], construct_params[1], construct_params[2])
|
|
|
+ instance.associations = {}
|
|
|
+ instance.associations["parent"] = Association("Field", 1, 1)
|
|
|
+ else:
|
|
|
+ raise Exception("Cannot instantiate class " + class_name)
|
|
|
+ return instance
|
|
|
+
|
|
|
+class Controller(EventLoopControllerBase):
|
|
|
+ def __init__(self, event_loop_callbacks, finished_callback = None, behind_schedule_callback = None):
|
|
|
+ if finished_callback == None: finished_callback = None
|
|
|
+ if behind_schedule_callback == None: behind_schedule_callback = None
|
|
|
+ EventLoopControllerBase.__init__(self, ObjectManager(self), event_loop_callbacks, finished_callback, behind_schedule_callback)
|
|
|
+ self.addInputPort("ui")
|
|
|
+ self.addOutputPort("ui")
|
|
|
+ self.object_manager.createInstance("MainApp", [])
|