# Statechart compiler by Glenn De Jonghe # # Date: Mon Aug 17 14:45:55 2015 # Model author: Simon Van Mierlo+Joeri Exelmans+Raphael Mannadiar # Model name: Bouncing_Balls # Model description: """ Tkinter frame with bouncing balls in it. """ from python_runtime.statecharts_core import ObjectManagerBase, Event, InstanceWrapper, RuntimeClassBase, Association from python_runtime.libs.ui import * from python_runtime.libs.utils import * class Button(RuntimeClassBase): # Unique IDs for all statechart nodes Root = 0 Root_initializing = 1 Root_running = 2 def commonConstructor(self, controller = None): """Constructor part that is common for all constructors.""" RuntimeClassBase.__init__(self) # User defined input ports self.inports = {} self.controller = controller self.object_manager = controller.getObjectManager() self.current_state = {} self.history_state = {} #Initialize statechart : self.current_state[self.Root] = [] def start(self): super(Button, self).start() self.enter_Root_initializing() #The actual constructor def __init__(self, controller, parent, event_name, button_text): self.commonConstructor(controller) #constructor body (user-defined) self.event_name = event_name button = ui.append_button(parent.field_window, event_name) ui.bind_event(button.element, ui.EVENTS.MOUSE_CLICK, self.controller, 'mouse_click') # Statechart enter/exit action method(s) : def enter_Root_initializing(self): self.current_state[self.Root].append(self.Root_initializing) def exit_Root_initializing(self): self.current_state[self.Root] = [] def enter_Root_running(self): self.current_state[self.Root].append(self.Root_running) def exit_Root_running(self): self.current_state[self.Root] = [] #Statechart transitions : def transition_Root(self, event) : catched = False if not catched : if self.current_state[self.Root][0] == self.Root_initializing: catched = self.transition_Root_initializing(event) elif self.current_state[self.Root][0] == self.Root_running: catched = self.transition_Root_running(event) return catched def transition_Root_initializing(self, event) : catched = False enableds = [] enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_initializing. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : self.exit_Root_initializing() send_event = Event("button_created", parameters = []) self.object_manager.addEvent(Event("narrow_cast", parameters = [self, 'parent' , send_event])) self.enter_Root_running() catched = True return catched def transition_Root_running(self, event) : catched = False enableds = [] if event.name == "mouse_click" and event.getPort() == "ui" : parameters = event.getParameters() x = parameters[0] y = parameters[1] button = parameters[2] if button == ui.MOUSE_BUTTONS.LEFT : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_running. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : parameters = event.getParameters() x = parameters[0] y = parameters[1] button = parameters[2] self.exit_Root_running() send_event = Event("button_pressed", parameters = [self.event_name]) self.object_manager.addEvent(Event("narrow_cast", parameters = [self, 'parent' , send_event])) self.enter_Root_running() catched = True return catched # Execute transitions def transition(self, event = Event("")): self.state_changed = self.transition_Root(event) # inState method for statechart def inState(self, nodes): for actives in self.current_state.itervalues(): nodes = [node for node in nodes if node not in actives] if not nodes : return True return False class Field(RuntimeClassBase): # Unique IDs for all statechart nodes Root = 0 Root_root = 1 Root_root_running = 2 Root_root_running_main_behaviour = 3 Root_root_running_deleting_behaviour = 4 Root_root_running_child_behaviour = 5 Root_root_waiting = 6 Root_root_packing = 7 Root_root_deleting = 8 Root_root_creating = 9 Root_root_initializing = 10 Root_root_deleted = 11 Root_root_running_main_behaviour_running = 12 Root_root_running_main_behaviour_creating = 13 Root_root_running_deleting_behaviour_running = 14 Root_root_running_child_behaviour_listening = 15 def commonConstructor(self, controller = None): """Constructor part that is common for all constructors.""" RuntimeClassBase.__init__(self) # User defined input ports self.inports = {} self.inports["field_ui"] = controller.addInputPort("field_ui", self) # User defined attributes self.field_window = None self.canvas = None self.controller = controller self.object_manager = controller.getObjectManager() self.current_state = {} self.history_state = {} self.timers = {} #Initialize statechart : self.current_state[self.Root] = [] self.current_state[self.Root_root] = [] self.current_state[self.Root_root_running] = [] self.current_state[self.Root_root_running_main_behaviour] = [] self.current_state[self.Root_root_running_deleting_behaviour] = [] self.current_state[self.Root_root_running_child_behaviour] = [] def start(self): super(Field, self).start() self.enterDefault_Root_root() #The actual constructor def __init__(self, controller): self.commonConstructor(controller) #constructor body (user-defined) self.field_window = ui.new_window(400, 450) self.canvas = ui.append_canvas(self.field_window, 400, 400, {'background':'#eee'}) ui.bind_event(self.field_window, ui.EVENTS.WINDOW_CLOSE, self.controller, 'window_close') ui.bind_event(self.field_window, ui.EVENTS.KEY_PRESS, self.controller, 'key_press') ui.bind_event(self.canvas.element, ui.EVENTS.MOUSE_RIGHT_CLICK, self.controller, 'right_click', self.inports['field_ui']) ui.bind_event(self.canvas.element, ui.EVENTS.MOUSE_MOVE, self.controller, 'mouse_move') ui.bind_event(self.canvas.element, ui.EVENTS.MOUSE_RELEASE, self.controller, 'mouse_release') # User defined destructor def __del__(self): ui.close_window(self.field_window) # Statechart enter/exit action method(s) : def enter_Root_root(self): self.current_state[self.Root].append(self.Root_root) def exit_Root_root(self): if self.Root_root_waiting in self.current_state[self.Root_root] : self.exit_Root_root_waiting() if self.Root_root_packing in self.current_state[self.Root_root] : self.exit_Root_root_packing() if self.Root_root_deleting in self.current_state[self.Root_root] : self.exit_Root_root_deleting() if self.Root_root_creating in self.current_state[self.Root_root] : self.exit_Root_root_creating() if self.Root_root_initializing in self.current_state[self.Root_root] : self.exit_Root_root_initializing() if self.Root_root_deleted in self.current_state[self.Root_root] : self.exit_Root_root_deleted() if self.Root_root_running in self.current_state[self.Root_root] : self.exit_Root_root_running() self.current_state[self.Root] = [] def enter_Root_root_running(self): self.current_state[self.Root_root].append(self.Root_root_running) def exit_Root_root_running(self): self.exit_Root_root_running_main_behaviour() self.exit_Root_root_running_deleting_behaviour() self.exit_Root_root_running_child_behaviour() self.current_state[self.Root_root] = [] def enter_Root_root_running_main_behaviour(self): self.current_state[self.Root_root_running].append(self.Root_root_running_main_behaviour) def exit_Root_root_running_main_behaviour(self): if self.Root_root_running_main_behaviour_running in self.current_state[self.Root_root_running_main_behaviour] : self.exit_Root_root_running_main_behaviour_running() if self.Root_root_running_main_behaviour_creating in self.current_state[self.Root_root_running_main_behaviour] : self.exit_Root_root_running_main_behaviour_creating() self.current_state[self.Root_root_running] = [] def enter_Root_root_running_deleting_behaviour(self): self.current_state[self.Root_root_running].append(self.Root_root_running_deleting_behaviour) def exit_Root_root_running_deleting_behaviour(self): if self.Root_root_running_deleting_behaviour_running in self.current_state[self.Root_root_running_deleting_behaviour] : self.exit_Root_root_running_deleting_behaviour_running() self.current_state[self.Root_root_running] = [] def enter_Root_root_running_child_behaviour(self): self.current_state[self.Root_root_running].append(self.Root_root_running_child_behaviour) def exit_Root_root_running_child_behaviour(self): if self.Root_root_running_child_behaviour_listening in self.current_state[self.Root_root_running_child_behaviour] : self.exit_Root_root_running_child_behaviour_listening() self.current_state[self.Root_root_running] = [] def enter_Root_root_waiting(self): self.current_state[self.Root_root].append(self.Root_root_waiting) def exit_Root_root_waiting(self): self.current_state[self.Root_root] = [] def enter_Root_root_packing(self): self.current_state[self.Root_root].append(self.Root_root_packing) def exit_Root_root_packing(self): self.current_state[self.Root_root] = [] def enter_Root_root_deleting(self): self.timers[0] = 0.05 self.current_state[self.Root_root].append(self.Root_root_deleting) def exit_Root_root_deleting(self): self.timers.pop(0, None) self.current_state[self.Root_root] = [] def enter_Root_root_creating(self): self.current_state[self.Root_root].append(self.Root_root_creating) def exit_Root_root_creating(self): self.current_state[self.Root_root] = [] def enter_Root_root_initializing(self): self.current_state[self.Root_root].append(self.Root_root_initializing) def exit_Root_root_initializing(self): self.current_state[self.Root_root] = [] def enter_Root_root_deleted(self): self.current_state[self.Root_root].append(self.Root_root_deleted) def exit_Root_root_deleted(self): self.current_state[self.Root_root] = [] def enter_Root_root_running_main_behaviour_running(self): self.current_state[self.Root_root_running_main_behaviour].append(self.Root_root_running_main_behaviour_running) def exit_Root_root_running_main_behaviour_running(self): self.current_state[self.Root_root_running_main_behaviour] = [] def enter_Root_root_running_main_behaviour_creating(self): self.current_state[self.Root_root_running_main_behaviour].append(self.Root_root_running_main_behaviour_creating) def exit_Root_root_running_main_behaviour_creating(self): self.current_state[self.Root_root_running_main_behaviour] = [] def enter_Root_root_running_deleting_behaviour_running(self): self.current_state[self.Root_root_running_deleting_behaviour].append(self.Root_root_running_deleting_behaviour_running) def exit_Root_root_running_deleting_behaviour_running(self): self.current_state[self.Root_root_running_deleting_behaviour] = [] def enter_Root_root_running_child_behaviour_listening(self): self.current_state[self.Root_root_running_child_behaviour].append(self.Root_root_running_child_behaviour_listening) def exit_Root_root_running_child_behaviour_listening(self): self.current_state[self.Root_root_running_child_behaviour] = [] #Statechart enter/exit default method(s) : def enterDefault_Root_root(self): self.enter_Root_root() self.enter_Root_root_waiting() def enterDefault_Root_root_running(self): self.enter_Root_root_running() self.enterDefault_Root_root_running_main_behaviour() self.enterDefault_Root_root_running_deleting_behaviour() self.enterDefault_Root_root_running_child_behaviour() def enterDefault_Root_root_running_main_behaviour(self): self.enter_Root_root_running_main_behaviour() self.enter_Root_root_running_main_behaviour_running() def enterDefault_Root_root_running_deleting_behaviour(self): self.enter_Root_root_running_deleting_behaviour() self.enter_Root_root_running_deleting_behaviour_running() def enterDefault_Root_root_running_child_behaviour(self): self.enter_Root_root_running_child_behaviour() self.enter_Root_root_running_child_behaviour_listening() #Statechart transitions : def transition_Root(self, event) : catched = False if not catched : if self.current_state[self.Root][0] == self.Root_root: catched = self.transition_Root_root(event) return catched def transition_Root_root(self, event) : catched = False if not catched : if self.current_state[self.Root_root][0] == self.Root_root_waiting: catched = self.transition_Root_root_waiting(event) elif self.current_state[self.Root_root][0] == self.Root_root_packing: catched = self.transition_Root_root_packing(event) elif self.current_state[self.Root_root][0] == self.Root_root_deleting: catched = self.transition_Root_root_deleting(event) elif self.current_state[self.Root_root][0] == self.Root_root_creating: catched = self.transition_Root_root_creating(event) elif self.current_state[self.Root_root][0] == self.Root_root_initializing: catched = self.transition_Root_root_initializing(event) elif self.current_state[self.Root_root][0] == self.Root_root_deleted: catched = self.transition_Root_root_deleted(event) elif self.current_state[self.Root_root][0] == self.Root_root_running: catched = self.transition_Root_root_running(event) return catched def transition_Root_root_waiting(self, event) : catched = False enableds = [] if event.name == "set_association_name" and event.getPort() == "" : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_root_waiting. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : parameters = event.getParameters() association_name = parameters[0] self.exit_Root_root_waiting() self.association_name = association_name self.enter_Root_root_initializing() catched = True return catched def transition_Root_root_packing(self, event) : catched = False enableds = [] if event.name == "button_created" and event.getPort() == "" : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_root_packing. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : self.exit_Root_root_packing() self.enterDefault_Root_root_running() catched = True return catched def transition_Root_root_deleting(self, event) : catched = False enableds = [] if event.name == "_0after" and event.getPort() == "" : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_root_deleting. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : self.exit_Root_root_deleting() send_event = Event("delete_field", parameters = [self.association_name]) self.object_manager.addEvent(Event("narrow_cast", parameters = [self, 'parent' , send_event])) self.enter_Root_root_deleted() catched = True return catched def transition_Root_root_creating(self, event) : catched = False enableds = [] if event.name == "instance_created" and event.getPort() == "" : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_root_creating. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : parameters = event.getParameters() association_name = parameters[0] self.exit_Root_root_creating() self.object_manager.addEvent(Event("start_instance", parameters = [self, association_name])) self.enter_Root_root_packing() catched = True return catched def transition_Root_root_initializing(self, event) : catched = False enableds = [] enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_root_initializing. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : self.exit_Root_root_initializing() self.object_manager.addEvent(Event("create_instance", parameters = [self, 'buttons','Button',self,'create_new_field','Spawn New Window'])) self.enter_Root_root_creating() catched = True return catched def transition_Root_root_deleted(self, event) : catched = False return catched def transition_Root_root_running(self, event) : catched = False enableds = [] if event.name == "window_close" and event.getPort() == "ui" : parameters = event.getParameters() window = parameters[0] if window == self.field_window or window == ui.window : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_root_running. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : parameters = event.getParameters() window = parameters[0] self.exit_Root_root_running() self.object_manager.addEvent(Event("delete_instance", parameters = [self, 'buttons'])) send_event = Event("delete_self", parameters = []) self.object_manager.addEvent(Event("narrow_cast", parameters = [self, 'balls' , send_event])) self.enter_Root_root_deleting() catched = True if not catched : catched = self.transition_Root_root_running_main_behaviour(event) or catched catched = self.transition_Root_root_running_deleting_behaviour(event) or catched catched = self.transition_Root_root_running_child_behaviour(event) or catched return catched def transition_Root_root_running_main_behaviour(self, event) : catched = False if not catched : if self.current_state[self.Root_root_running_main_behaviour][0] == self.Root_root_running_main_behaviour_running: catched = self.transition_Root_root_running_main_behaviour_running(event) elif self.current_state[self.Root_root_running_main_behaviour][0] == self.Root_root_running_main_behaviour_creating: catched = self.transition_Root_root_running_main_behaviour_creating(event) return catched def transition_Root_root_running_main_behaviour_running(self, event) : catched = False enableds = [] if event.name == "right_click" and event.getPort() == "field_ui" : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_root_running_main_behaviour_running. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : parameters = event.getParameters() x = parameters[0] y = parameters[1] button = parameters[2] self.exit_Root_root_running_main_behaviour_running() self.object_manager.addEvent(Event("create_instance", parameters = [self, 'balls','Ball',self.canvas,x,y,self.field_window])) self.enter_Root_root_running_main_behaviour_creating() catched = True return catched def transition_Root_root_running_main_behaviour_creating(self, event) : catched = False enableds = [] if event.name == "instance_created" and event.getPort() == "" : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_root_running_main_behaviour_creating. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : parameters = event.getParameters() association_name = parameters[0] self.exit_Root_root_running_main_behaviour_creating() send_event = Event("set_association_name", parameters = [association_name]) self.object_manager.addEvent(Event("narrow_cast", parameters = [self, association_name , send_event])) self.object_manager.addEvent(Event("start_instance", parameters = [self, association_name])) self.enter_Root_root_running_main_behaviour_running() catched = True return catched def transition_Root_root_running_deleting_behaviour(self, event) : catched = False if not catched : if self.current_state[self.Root_root_running_deleting_behaviour][0] == self.Root_root_running_deleting_behaviour_running: catched = self.transition_Root_root_running_deleting_behaviour_running(event) return catched def transition_Root_root_running_deleting_behaviour_running(self, event) : catched = False enableds = [] if event.name == "delete_ball" and event.getPort() == "" : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_root_running_deleting_behaviour_running. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : parameters = event.getParameters() association_name = parameters[0] self.exit_Root_root_running_deleting_behaviour_running() self.object_manager.addEvent(Event("delete_instance", parameters = [self, association_name])) self.enter_Root_root_running_deleting_behaviour_running() catched = True return catched def transition_Root_root_running_child_behaviour(self, event) : catched = False if not catched : if self.current_state[self.Root_root_running_child_behaviour][0] == self.Root_root_running_child_behaviour_listening: catched = self.transition_Root_root_running_child_behaviour_listening(event) return catched def transition_Root_root_running_child_behaviour_listening(self, event) : catched = False enableds = [] if event.name == "button_pressed" and event.getPort() == "" : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_root_running_child_behaviour_listening. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : parameters = event.getParameters() event_name = parameters[0] self.exit_Root_root_running_child_behaviour_listening() send_event = Event("button_pressed", parameters = [event_name]) self.object_manager.addEvent(Event("narrow_cast", parameters = [self, 'parent' , send_event])) self.enter_Root_root_running_child_behaviour_listening() catched = True return catched # Execute transitions def transition(self, event = Event("")): self.state_changed = self.transition_Root(event) # inState method for statechart def inState(self, nodes): for actives in self.current_state.itervalues(): nodes = [node for node in nodes if node not in actives] if not nodes : return True return False class MainApp(RuntimeClassBase): # Unique IDs for all statechart nodes Root = 0 Root_running = 1 Root_running_root = 2 Root_running_root_main_behaviour = 3 Root_running_root_cd_behaviour = 4 Root_running_stopped = 5 Root_running_root_main_behaviour_initializing = 6 Root_running_root_main_behaviour_running = 7 Root_running_root_cd_behaviour_creating = 8 Root_running_root_cd_behaviour_waiting = 9 Root_running_root_cd_behaviour_check_nr_of_fields = 10 def commonConstructor(self, controller = None): """Constructor part that is common for all constructors.""" RuntimeClassBase.__init__(self) # User defined input ports self.inports = {} self.controller = controller self.object_manager = controller.getObjectManager() self.current_state = {} self.history_state = {} #Initialize statechart : self.current_state[self.Root] = [] self.current_state[self.Root_running] = [] self.current_state[self.Root_running_root] = [] self.current_state[self.Root_running_root_main_behaviour] = [] self.current_state[self.Root_running_root_cd_behaviour] = [] def start(self): super(MainApp, self).start() self.enterDefault_Root_running() #The actual constructor def __init__(self, controller): self.commonConstructor(controller) #constructor body (user-defined) self.nr_of_fields = 0 ui.bind_event(ui.window, ui.EVENTS.WINDOW_CLOSE, self.controller, 'window_close') # Statechart enter/exit action method(s) : def enter_Root_running(self): self.current_state[self.Root].append(self.Root_running) def exit_Root_running(self): if self.Root_running_stopped in self.current_state[self.Root_running] : self.exit_Root_running_stopped() if self.Root_running_root in self.current_state[self.Root_running] : self.exit_Root_running_root() self.current_state[self.Root] = [] def enter_Root_running_root(self): self.current_state[self.Root_running].append(self.Root_running_root) def exit_Root_running_root(self): self.exit_Root_running_root_main_behaviour() self.exit_Root_running_root_cd_behaviour() self.current_state[self.Root_running] = [] def enter_Root_running_root_main_behaviour(self): self.current_state[self.Root_running_root].append(self.Root_running_root_main_behaviour) def exit_Root_running_root_main_behaviour(self): if self.Root_running_root_main_behaviour_initializing in self.current_state[self.Root_running_root_main_behaviour] : self.exit_Root_running_root_main_behaviour_initializing() if self.Root_running_root_main_behaviour_running in self.current_state[self.Root_running_root_main_behaviour] : self.exit_Root_running_root_main_behaviour_running() self.current_state[self.Root_running_root] = [] def enter_Root_running_root_cd_behaviour(self): self.current_state[self.Root_running_root].append(self.Root_running_root_cd_behaviour) def exit_Root_running_root_cd_behaviour(self): if self.Root_running_root_cd_behaviour_creating in self.current_state[self.Root_running_root_cd_behaviour] : self.exit_Root_running_root_cd_behaviour_creating() if self.Root_running_root_cd_behaviour_waiting in self.current_state[self.Root_running_root_cd_behaviour] : self.exit_Root_running_root_cd_behaviour_waiting() if self.Root_running_root_cd_behaviour_check_nr_of_fields in self.current_state[self.Root_running_root_cd_behaviour] : self.exit_Root_running_root_cd_behaviour_check_nr_of_fields() self.current_state[self.Root_running_root] = [] def enter_Root_running_stopped(self): self.current_state[self.Root_running].append(self.Root_running_stopped) def exit_Root_running_stopped(self): self.current_state[self.Root_running] = [] def enter_Root_running_root_main_behaviour_initializing(self): self.current_state[self.Root_running_root_main_behaviour].append(self.Root_running_root_main_behaviour_initializing) def exit_Root_running_root_main_behaviour_initializing(self): self.current_state[self.Root_running_root_main_behaviour] = [] def enter_Root_running_root_main_behaviour_running(self): self.current_state[self.Root_running_root_main_behaviour].append(self.Root_running_root_main_behaviour_running) def exit_Root_running_root_main_behaviour_running(self): self.current_state[self.Root_running_root_main_behaviour] = [] def enter_Root_running_root_cd_behaviour_creating(self): self.current_state[self.Root_running_root_cd_behaviour].append(self.Root_running_root_cd_behaviour_creating) def exit_Root_running_root_cd_behaviour_creating(self): self.current_state[self.Root_running_root_cd_behaviour] = [] def enter_Root_running_root_cd_behaviour_waiting(self): self.current_state[self.Root_running_root_cd_behaviour].append(self.Root_running_root_cd_behaviour_waiting) def exit_Root_running_root_cd_behaviour_waiting(self): self.current_state[self.Root_running_root_cd_behaviour] = [] def enter_Root_running_root_cd_behaviour_check_nr_of_fields(self): self.current_state[self.Root_running_root_cd_behaviour].append(self.Root_running_root_cd_behaviour_check_nr_of_fields) def exit_Root_running_root_cd_behaviour_check_nr_of_fields(self): self.current_state[self.Root_running_root_cd_behaviour] = [] #Statechart enter/exit default method(s) : def enterDefault_Root_running(self): self.enter_Root_running() self.enterDefault_Root_running_root() def enterDefault_Root_running_root(self): self.enter_Root_running_root() self.enterDefault_Root_running_root_main_behaviour() self.enterDefault_Root_running_root_cd_behaviour() def enterDefault_Root_running_root_main_behaviour(self): self.enter_Root_running_root_main_behaviour() self.enter_Root_running_root_main_behaviour_initializing() def enterDefault_Root_running_root_cd_behaviour(self): self.enter_Root_running_root_cd_behaviour() self.enter_Root_running_root_cd_behaviour_waiting() #Statechart transitions : def transition_Root(self, event) : catched = False if not catched : if self.current_state[self.Root][0] == self.Root_running: catched = self.transition_Root_running(event) return catched def transition_Root_running(self, event) : catched = False if not catched : if self.current_state[self.Root_running][0] == self.Root_running_stopped: catched = self.transition_Root_running_stopped(event) elif self.current_state[self.Root_running][0] == self.Root_running_root: catched = self.transition_Root_running_root(event) return catched def transition_Root_running_stopped(self, event) : catched = False return catched def transition_Root_running_root(self, event) : catched = False if not catched : catched = self.transition_Root_running_root_main_behaviour(event) or catched catched = self.transition_Root_running_root_cd_behaviour(event) or catched return catched def transition_Root_running_root_main_behaviour(self, event) : catched = False if not catched : if self.current_state[self.Root_running_root_main_behaviour][0] == self.Root_running_root_main_behaviour_initializing: catched = self.transition_Root_running_root_main_behaviour_initializing(event) elif self.current_state[self.Root_running_root_main_behaviour][0] == self.Root_running_root_main_behaviour_running: catched = self.transition_Root_running_root_main_behaviour_running(event) return catched def transition_Root_running_root_main_behaviour_initializing(self, event) : catched = False enableds = [] enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_running_root_main_behaviour_initializing. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : self.exit_Root_running_root_main_behaviour_initializing() self.addEvent(Event("create_field", parameters = [])) self.enter_Root_running_root_main_behaviour_running() catched = True return catched def transition_Root_running_root_main_behaviour_running(self, event) : catched = False enableds = [] if event.name == "button_pressed" and event.getPort() == "" : parameters = event.getParameters() event_name = parameters[0] if event_name == 'create_new_field' : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_running_root_main_behaviour_running. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : parameters = event.getParameters() event_name = parameters[0] self.exit_Root_running_root_main_behaviour_running() self.addEvent(Event("create_field", parameters = [])) self.enter_Root_running_root_main_behaviour_running() catched = True return catched def transition_Root_running_root_cd_behaviour(self, event) : catched = False if not catched : if self.current_state[self.Root_running_root_cd_behaviour][0] == self.Root_running_root_cd_behaviour_creating: catched = self.transition_Root_running_root_cd_behaviour_creating(event) elif self.current_state[self.Root_running_root_cd_behaviour][0] == self.Root_running_root_cd_behaviour_waiting: catched = self.transition_Root_running_root_cd_behaviour_waiting(event) elif self.current_state[self.Root_running_root_cd_behaviour][0] == self.Root_running_root_cd_behaviour_check_nr_of_fields: catched = self.transition_Root_running_root_cd_behaviour_check_nr_of_fields(event) return catched def transition_Root_running_root_cd_behaviour_creating(self, event) : catched = False enableds = [] if event.name == "instance_created" and event.getPort() == "" : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_running_root_cd_behaviour_creating. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : parameters = event.getParameters() association_name = parameters[0] self.exit_Root_running_root_cd_behaviour_creating() self.object_manager.addEvent(Event("start_instance", parameters = [self, association_name])) send_event = Event("set_association_name", parameters = [association_name]) self.object_manager.addEvent(Event("narrow_cast", parameters = [self, association_name , send_event])) self.nr_of_fields += 1 self.enter_Root_running_root_cd_behaviour_waiting() catched = True return catched def transition_Root_running_root_cd_behaviour_waiting(self, event) : catched = False enableds = [] if event.name == "create_field" and event.getPort() == "" : enableds.append(1) if event.name == "delete_field" and event.getPort() == "" : enableds.append(2) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_running_root_cd_behaviour_waiting. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : self.exit_Root_running_root_cd_behaviour_waiting() self.object_manager.addEvent(Event("create_instance", parameters = [self, 'fields'])) self.enter_Root_running_root_cd_behaviour_creating() elif enabled == 2 : parameters = event.getParameters() association_name = parameters[0] self.exit_Root_running_root_cd_behaviour_waiting() self.object_manager.addEvent(Event("delete_instance", parameters = [self, association_name])) self.nr_of_fields -= 1 self.enter_Root_running_root_cd_behaviour_check_nr_of_fields() catched = True return catched def transition_Root_running_root_cd_behaviour_check_nr_of_fields(self, event) : catched = False enableds = [] if self.nr_of_fields != 0 : enableds.append(1) if self.nr_of_fields == 0 : enableds.append(2) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_running_root_cd_behaviour_check_nr_of_fields. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : self.exit_Root_running_root_cd_behaviour_check_nr_of_fields() self.enter_Root_running_root_cd_behaviour_waiting() elif enabled == 2 : self.exit_Root_running_root() ui.close_window(ui.window) self.enter_Root_running_stopped() catched = True return catched # Execute transitions def transition(self, event = Event("")): self.state_changed = self.transition_Root(event) # inState method for statechart def inState(self, nodes): for actives in self.current_state.itervalues(): nodes = [node for node in nodes if node not in actives] if not nodes : return True return False class Ball(RuntimeClassBase): # Unique IDs for all statechart nodes Root = 0 Root_main_behaviour = 1 Root_main_behaviour_dragging = 2 Root_main_behaviour_selected = 3 Root_main_behaviour_initializing = 4 Root_main_behaviour_bouncing = 5 Root_deleted = 6 def commonConstructor(self, controller = None): """Constructor part that is common for all constructors.""" RuntimeClassBase.__init__(self) # User defined input ports self.inports = {} self.inports["ball_ui"] = controller.addInputPort("ball_ui", self) # User defined attributes self.field_window = None self.canvas = None self.element = None self.controller = controller self.object_manager = controller.getObjectManager() self.current_state = {} self.history_state = {} self.timers = {} #Initialize statechart : self.current_state[self.Root] = [] self.current_state[self.Root_main_behaviour] = [] def start(self): super(Ball, self).start() self.enterDefault_Root_main_behaviour() #The actual constructor def __init__(self, controller, canvas, x, y, field_window): self.commonConstructor(controller) #constructor body (user-defined) self.canvas = canvas self.field_window = field_window self.r = 20.0 self.vel = {'x':utils.random() * 2.0 - 1.0, 'y':utils.random() * 2.0 - 1.0} self.mouse_pos = {'':''} self.smooth = 0.4 circle = self.canvas.add_circle(x, y, self.r, {'fill':'#000'}) ui.bind_event(circle, ui.EVENTS.MOUSE_PRESS, self.controller, 'mouse_press', self.inports['ball_ui']) ui.bind_event(circle, ui.EVENTS.MOUSE_RIGHT_CLICK, self.controller, 'right_click') self.element = circle # User defined destructor def __del__(self): self.canvas.remove_element(self.element) # Statechart enter/exit action method(s) : def enter_Root_main_behaviour(self): self.current_state[self.Root].append(self.Root_main_behaviour) def exit_Root_main_behaviour(self): if self.Root_main_behaviour_dragging in self.current_state[self.Root_main_behaviour] : self.exit_Root_main_behaviour_dragging() if self.Root_main_behaviour_selected in self.current_state[self.Root_main_behaviour] : self.exit_Root_main_behaviour_selected() if self.Root_main_behaviour_initializing in self.current_state[self.Root_main_behaviour] : self.exit_Root_main_behaviour_initializing() if self.Root_main_behaviour_bouncing in self.current_state[self.Root_main_behaviour] : self.exit_Root_main_behaviour_bouncing() self.current_state[self.Root] = [] def enter_Root_main_behaviour_dragging(self): self.current_state[self.Root_main_behaviour].append(self.Root_main_behaviour_dragging) def exit_Root_main_behaviour_dragging(self): self.current_state[self.Root_main_behaviour] = [] def enter_Root_main_behaviour_selected(self): self.current_state[self.Root_main_behaviour].append(self.Root_main_behaviour_selected) def exit_Root_main_behaviour_selected(self): self.current_state[self.Root_main_behaviour] = [] def enter_Root_main_behaviour_initializing(self): self.current_state[self.Root_main_behaviour].append(self.Root_main_behaviour_initializing) def exit_Root_main_behaviour_initializing(self): self.current_state[self.Root_main_behaviour] = [] def enter_Root_main_behaviour_bouncing(self): self.timers[0] = 0.01 self.current_state[self.Root_main_behaviour].append(self.Root_main_behaviour_bouncing) def exit_Root_main_behaviour_bouncing(self): self.timers.pop(0, None) self.current_state[self.Root_main_behaviour] = [] def enter_Root_deleted(self): self.current_state[self.Root].append(self.Root_deleted) def exit_Root_deleted(self): self.current_state[self.Root] = [] #Statechart enter/exit default method(s) : def enterDefault_Root_main_behaviour(self): self.enter_Root_main_behaviour() self.enter_Root_main_behaviour_initializing() #Statechart transitions : def transition_Root(self, event) : catched = False if not catched : if self.current_state[self.Root][0] == self.Root_main_behaviour: catched = self.transition_Root_main_behaviour(event) elif self.current_state[self.Root][0] == self.Root_deleted: catched = self.transition_Root_deleted(event) return catched def transition_Root_main_behaviour(self, event) : catched = False enableds = [] if event.name == "delete_self" and event.getPort() == "" : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_main_behaviour. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : self.exit_Root_main_behaviour() send_event = Event("delete_ball", parameters = [self.association_name]) self.object_manager.addEvent(Event("narrow_cast", parameters = [self, 'parent' , send_event])) self.enter_Root_deleted() catched = True if not catched : if self.current_state[self.Root_main_behaviour][0] == self.Root_main_behaviour_dragging: catched = self.transition_Root_main_behaviour_dragging(event) elif self.current_state[self.Root_main_behaviour][0] == self.Root_main_behaviour_selected: catched = self.transition_Root_main_behaviour_selected(event) elif self.current_state[self.Root_main_behaviour][0] == self.Root_main_behaviour_initializing: catched = self.transition_Root_main_behaviour_initializing(event) elif self.current_state[self.Root_main_behaviour][0] == self.Root_main_behaviour_bouncing: catched = self.transition_Root_main_behaviour_bouncing(event) return catched def transition_Root_main_behaviour_dragging(self, event) : catched = False enableds = [] if event.name == "mouse_release" and event.getPort() == "ui" : enableds.append(1) if event.name == "mouse_move" and event.getPort() == "ui" : enableds.append(2) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_main_behaviour_dragging. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : parameters = event.getParameters() x = parameters[0] y = parameters[1] self.exit_Root_main_behaviour_dragging() self.element.set_color('#f00') self.enter_Root_main_behaviour_bouncing() elif enabled == 2 : parameters = event.getParameters() x = parameters[0] y = parameters[1] button = parameters[2] self.exit_Root_main_behaviour_dragging() dx = x - self.mouse_pos['x'] dy = y - self.mouse_pos['y'] self.element.move(dx, dy) pos = self.element.get_position() if pos.x - self.r <= 0: pos.x = self.r + 1 else: if pos.x + self.r >= self.canvas.width: pos.x = self.canvas.width - self.r - 1 if pos.y - self.r <= 0: pos.y = self.r + 1 else: if pos.y + self.r >= self.canvas.height: pos.y = self.canvas.height - self.r - 1 self.element.set_position(pos.x, pos.y) self.mouse_pos = {'x':x, 'y':y} self.vel = {'x':(1 - self.smooth) * dx + self.smooth * self.vel['x'], 'y':(1 - self.smooth) * dy + self.smooth * self.vel['y']} self.enter_Root_main_behaviour_dragging() catched = True return catched def transition_Root_main_behaviour_selected(self, event) : catched = False enableds = [] if event.name == "mouse_press" and event.getPort() == "ball_ui" : parameters = event.getParameters() x = parameters[0] y = parameters[1] button = parameters[2] if button == ui.MOUSE_BUTTONS.LEFT : enableds.append(1) if event.name == "key_press" and event.getPort() == "ui" : parameters = event.getParameters() key = parameters[0] active_window = parameters[1] if key == ui.KEYCODES.DELETE and active_window == self.field_window : enableds.append(2) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_main_behaviour_selected. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : parameters = event.getParameters() x = parameters[0] y = parameters[1] button = parameters[2] self.exit_Root_main_behaviour_selected() self.mouse_pos = {'x':x, 'y':y} self.enter_Root_main_behaviour_dragging() elif enabled == 2 : parameters = event.getParameters() key = parameters[0] active_window = parameters[1] self.exit_Root_main_behaviour_selected() self.addEvent(Event("delete_self", parameters = [])) self.enter_Root_main_behaviour_selected() catched = True return catched def transition_Root_main_behaviour_initializing(self, event) : catched = False enableds = [] if event.name == "set_association_name" and event.getPort() == "" : enableds.append(1) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_main_behaviour_initializing. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : parameters = event.getParameters() association_name = parameters[0] self.exit_Root_main_behaviour_initializing() self.association_name = association_name self.enter_Root_main_behaviour_bouncing() catched = True return catched def transition_Root_main_behaviour_bouncing(self, event) : catched = False enableds = [] if event.name == "_0after" and event.getPort() == "" : enableds.append(1) if event.name == "mouse_press" and event.getPort() == "ball_ui" : parameters = event.getParameters() x = parameters[0] y = parameters[1] button = parameters[2] if button == ui.MOUSE_BUTTONS.LEFT : enableds.append(2) if len(enableds) > 1 : print "Runtime warning : indeterminism detected in a transition from node Root_main_behaviour_bouncing. Only the first in document order enabled transition is executed." if len(enableds) > 0 : enabled = enableds[0] if enabled == 1 : self.exit_Root_main_behaviour_bouncing() pos = self.element.get_position() if pos.x - self.r <= 0 or pos.x + self.r >= self.canvas.width: self.vel['x'] = -self.vel['x'] if pos.y - self.r <= 0 or pos.y + self.r >= self.canvas.height: self.vel['y'] = -self.vel['y'] self.element.move(self.vel['x'], self.vel['y']) self.enter_Root_main_behaviour_bouncing() elif enabled == 2 : parameters = event.getParameters() x = parameters[0] y = parameters[1] button = parameters[2] self.exit_Root_main_behaviour_bouncing() self.element.set_color('#ff0') self.enter_Root_main_behaviour_selected() catched = True return catched def transition_Root_deleted(self, event) : catched = False return catched # Execute transitions def transition(self, event = Event("")): self.state_changed = self.transition_Root(event) # inState method for statechart def inState(self, nodes): for actives in self.current_state.itervalues(): nodes = [node for node in nodes if node not in actives] if not nodes : return True return False class ObjectManager (ObjectManagerBase): def __init__(self, controller): super(ObjectManager, self).__init__(controller) def instantiate(self, class_name, construct_params): associations = [] if class_name == "Button" : instance = Button(self.controller, *construct_params) associations.append(Association("parent", "Field", 1, 1)) elif class_name == "Field" : instance = Field(self.controller, *construct_params) associations.append(Association("parent", "MainApp", 1, 1)) associations.append(Association("buttons", "Button", 0, -1)) associations.append(Association("balls", "Ball", 0, -1)) elif class_name == "MainApp" : instance = MainApp(self.controller, *construct_params) associations.append(Association("fields", "Field", 0, -1)) elif class_name == "Ball" : instance = Ball(self.controller, *construct_params) associations.append(Association("parent", "Field", 1, 1)) if instance: return InstanceWrapper(instance, associations) else : return None from python_runtime.statecharts_core import GameLoopControllerBase class Controller(GameLoopControllerBase): def __init__(self, keep_running = True): super(Controller, self).__init__(ObjectManager(self), keep_running) self.addInputPort("field_ui") self.addInputPort("ball_ui") self.addInputPort("ui") self.object_manager.createInstance("MainApp", []) def main(): controller = Controller() controller.start() if __name__ == "__main__": main()