Ejemplo n.º 1
0
    def _execute(self, execute_inputs, execute_outputs, backward_execution=False):
        """Calls the custom execute function of the script.py of the state"""

        plugins.run_hook('pre_script')
        outcome_item = self._script.execute(self, execute_inputs, execute_outputs, backward_execution)
        plugins.run_hook('post_script')

        # in the case of backward execution the outcome is not relevant
        if backward_execution:
            return

        # If the state was preempted, the state must be left on the preempted outcome
        if self.preempted:
            return Outcome(-2, "preempted")

        # Outcome id was returned
        if outcome_item in self.outcomes:
            return self.outcomes[outcome_item]

        # Outcome name was returned
        for outcome_id, outcome in self.outcomes.items():
            if outcome.name == outcome_item:
                return self.outcomes[outcome_id]

        logger.error("Returned outcome of {0} not existing: {1}".format(self, outcome_item))
        return Outcome(-1, "aborted")
Ejemplo n.º 2
0
def signal_handler(signal, frame):
    global _user_abort

    state_machine_execution_engine = core_singletons.state_machine_execution_engine
    core_singletons.shut_down_signal = signal

    logger.info("Shutting down ...")

    try:
        if not state_machine_execution_engine.finished_or_stopped():
            state_machine_execution_engine.stop()
            state_machine_execution_engine.join(
                3)  # Wait max 3 sec for the execution to stop
    except Exception:
        logger.exception("Could not stop state machine")

    _user_abort = True

    # shutdown twisted correctly
    if reactor_required():
        from twisted.internet import reactor
        if reactor.running:
            plugins.run_hook("pre_destruction")
            reactor.callFromThread(reactor.stop)

    logging.shutdown()
Ejemplo n.º 3
0
    def prepare_destruction(self):
        """Saves current configuration of windows and panes to the runtime config file, before RAFCON is closed."""
        plugins.run_hook("pre_destruction")

        logger.debug("Saving runtime config to {0}".format(
            global_runtime_config.config_file_path))

        # store pane last positions
        for key, widget_name in constants.PANE_ID.items():
            global_runtime_config.store_widget_properties(
                self.view[widget_name], key.replace('_POS', ''))

        # store hidden or undocked widget flags correctly -> make them independent for restoring
        for window_key in constants.UNDOCKABLE_WINDOW_KEYS:
            hidden = False
            if not global_runtime_config.get_config_value(window_key +
                                                          "_WINDOW_UNDOCKED"):
                hidden = getattr(self, window_key.lower() + '_hidden')
            global_runtime_config.set_config_value(window_key + '_HIDDEN',
                                                   hidden)

        global_runtime_config.save_configuration()

        # state-editor will relieve it's model => it won't observe the state machine manager any more
        self.get_controller('states_editor_ctrl').prepare_destruction(
        )  # avoid new state editor TODO tbd (deleted)
        rafcon.core.singleton.state_machine_manager.delete_all_state_machines()
        rafcon.core.singleton.library_manager.prepare_destruction()

        # Recursively destroys the main window
        self.destroy()
        from rafcon.gui.clipboard import global_clipboard
        global_clipboard.destroy()
        gui_singletons.main_window_controller = None
Ejemplo n.º 4
0
def stop_reactor_on_state_machine_finish(state_machine):
    """ Wait for a state machine to be finished and stops the reactor

    :param state_machine: the state machine to synchronize with
    """
    wait_for_state_machine_finished(state_machine)
    from twisted.internet import reactor
    if reactor.running:
        plugins.run_hook("pre_destruction")
        reactor.callFromThread(reactor.stop)
Ejemplo n.º 5
0
    def prepare_destruction(self):
        """Saves current configuration of windows and panes to the runtime config file, before RAFCON is closed."""
        plugins.run_hook("pre_destruction")

        logger.debug("Saving runtime config to {0}".format(
            global_runtime_config.config_file_path))

        # store pane last positions
        for key, widget_name in constants.PANE_ID.items():
            global_runtime_config.store_widget_properties(
                self.view[widget_name], key.replace('_POS', ''))

        # store hidden or undocked widget flags correctly -> make them independent for restoring
        for window_key in constants.UNDOCKABLE_WINDOW_KEYS:
            hidden = False
            if not global_runtime_config.get_config_value(window_key +
                                                          "_WINDOW_UNDOCKED"):
                hidden = getattr(self, window_key.lower() + '_hidden')
            global_runtime_config.set_config_value(window_key + '_HIDDEN',
                                                   hidden)

        global_runtime_config.save_configuration()

        # state-editor will relieve it's model => it won't observe the state machine manager any more
        self.get_controller('states_editor_ctrl').prepare_destruction(
        )  # avoid new state editor TODO tbd (deleted)
        rafcon.core.singleton.state_machine_manager.delete_all_state_machines()
        rafcon.core.singleton.library_manager.prepare_destruction()

        # gtkmvc installs a global glade custom handler that holds a reference to the last created View class,
        # preventing it from being destructed. By installing a dummy callback handler, after all views have been
        # created, the old handler is being removed and with it the reference, allowing all Views to be destructed.

        # Gtk TODO: check if necessary and search for replacement
        # try:
        #     from gtk import glade
        #     def dummy(*args, **kwargs):
        #         pass
        #     glade.set_custom_handler(dummy)
        # except ImportError:
        #     pass

        # Recursively destroys the main window
        self.destroy()
        from rafcon.gui.clipboard import global_clipboard
        global_clipboard.destroy()
        gui_singletons.main_window_controller = None
Ejemplo n.º 6
0
 def __init__(self, root_state_name):
     self.consumers = dict()
     # Queue with infinite space
     self.execution_history_item_queue = Queue()
     self.condition = threading.Condition()
     self.interrupt = False
     self._consumers_exist = False
     self._file_system_consumer_exists = False
     if global_config.get_config_value("FILE_SYSTEM_EXECUTION_HISTORY_ENABLE", False):
         self.register_consumer(self.FILE_SYSTEM_CONSUMER_NAME, FileSystemConsumer(root_state_name))
         self._file_system_consumer_exists = True
     plugins.run_hook("register_execution_history_consumer", self)
     # Only have one thread here that will call the notify function of each consumer
     # The advantage it that the consumer authors don't have to care about threading
     # and don't have to care about when an item is popped from the queue
     self.worker_thread = threading.Thread(target=self._feed_consumers)
     self.worker_thread.start()
Ejemplo n.º 7
0
def main():
    register_signal_handlers(signal_handler)

    logger.info("initialize RAFCON ... ")

    pre_setup_plugins()

    setup_environment()

    logger.info("parse arguments ... ")
    parser = setup_argument_parser()
    user_input = parser.parse_args()
    if not user_input.state_machine_path:
        logger.error("You have to specify a valid state machine path")
        exit(-1)

    setup_configuration(user_input.config_path)

    post_setup_plugins(user_input)

    first_sm = None
    for sm_path in user_input.state_machine_path:
        sm = open_state_machine(sm_path)
        if first_sm is None:
            first_sm = sm

    if not user_input.remote:
        start_state_machine(first_sm, user_input.start_state_path)

    if reactor_required():
        from twisted.internet import reactor

        # Blocking call, return when state machine execution finishes
        reactor.run()

    if not user_input.remote:
        wait_for_state_machine_finished(first_sm)
    else:
        while not _user_abort:
            time.sleep(1)

    logger.info("State machine execution finished!")
    plugins.run_hook("post_destruction")
    logging.shutdown()
Ejemplo n.º 8
0
def post_gui_destruction():
    plugins.run_hook("post_destruction")

    if global_gui_config.get_config_value('AUTO_RECOVERY_LOCK_ENABLED'):
        rafcon.gui.models.auto_backup.remove_rafcon_instance_lock_file()
Ejemplo n.º 9
0
    def register_view(self, view):
        super(MainWindowController, self).register_view(view)
        self.register_actions(self.shortcut_manager)

        self.view.get_top_widget().connect("key-press-event",
                                           self._on_key_press)
        self.view.get_top_widget().connect("key-release-event",
                                           self._on_key_release)

        # using helper function to connect functions to GUI elements to be able to access the handler id later on

        self.connect_button_to_function(
            'main_window', "delete_event",
            self.get_controller('menu_bar_controller').on_quit_activate)

        # connect left bar, right bar and console hide buttons' signals to their corresponding methods
        self.connect_button_to_function('left_bar_hide_button', "clicked",
                                        self.on_left_bar_hide_clicked)
        self.connect_button_to_function('right_bar_hide_button', "clicked",
                                        self.on_right_bar_hide_clicked)
        self.connect_button_to_function('console_hide_button', "clicked",
                                        self.on_console_hide_clicked)

        # Connect left bar, right bar and console return buttons' signals to their corresponding methods
        self.connect_button_to_function('left_bar_return_button', "clicked",
                                        self.on_left_bar_return_clicked)
        self.connect_button_to_function('right_bar_return_button', "clicked",
                                        self.on_right_bar_return_clicked)
        self.connect_button_to_function('console_return_button', "clicked",
                                        self.on_console_return_clicked)

        # Connect undock buttons signals
        for window_key in constants.UNDOCKABLE_WINDOW_KEYS:
            self.connect_button_to_function(
                'undock_{}_button'.format(window_key.lower()), "clicked",
                partial(self.undock_sidebar, window_key))

        # Connect collapse button for trees
        self.connect_button_to_function('collapse_tree_button', "clicked",
                                        self.on_collapse_button_clicked)

        # Connect Shortcut buttons' signals to their corresponding methods
        self.connect_button_to_function('button_start_shortcut', "toggled",
                                        self.on_button_start_shortcut_toggled)
        self.connect_button_to_function('button_stop_shortcut', "clicked",
                                        self.on_button_stop_shortcut_clicked)
        self.connect_button_to_function('button_pause_shortcut', "toggled",
                                        self.on_button_pause_shortcut_toggled)
        self.connect_button_to_function(
            'button_start_from_shortcut', "clicked",
            self.on_button_start_from_shortcut_clicked)
        self.connect_button_to_function('button_run_to_shortcut', "clicked",
                                        self.on_button_run_to_shortcut_clicked)
        self.connect_button_to_function(
            'button_step_mode_shortcut', "toggled",
            self.on_button_step_mode_shortcut_toggled)
        self.connect_button_to_function(
            'button_step_in_shortcut', "clicked",
            self.on_button_step_in_shortcut_clicked)
        self.connect_button_to_function(
            'button_step_over_shortcut', "clicked",
            self.on_button_step_over_shortcut_clicked)
        self.connect_button_to_function(
            'button_step_out_shortcut', "clicked",
            self.on_button_step_out_shortcut_clicked)
        self.connect_button_to_function(
            'button_step_backward_shortcut', "clicked",
            self.on_button_step_backward_shortcut_clicked)

        view['upper_notebook'].connect('switch-page',
                                       self.on_notebook_tab_switch,
                                       view['upper_notebook_title'],
                                       view.left_bar_window, 'upper')
        view['lower_notebook'].connect('switch-page',
                                       self.on_notebook_tab_switch,
                                       view['lower_notebook_title'],
                                       view.left_bar_window, 'lower')

        view.get_top_widget().connect("configure-event",
                                      self.update_widget_runtime_config,
                                      "MAIN_WINDOW")
        view.left_bar_window.get_top_widget().connect(
            "configure-event", self.update_widget_runtime_config,
            "LEFT_BAR_WINDOW")
        view.right_bar_window.get_top_widget().connect(
            "configure-event", self.update_widget_runtime_config,
            "RIGHT_BAR_WINDOW")
        view.console_window.get_top_widget().connect(
            "configure-event", self.update_widget_runtime_config,
            "CONSOLE_WINDOW")

        # save pane positions in the runtime config on every change
        view['top_level_h_pane'].connect("button-release-event",
                                         self.update_widget_runtime_config,
                                         "LEFT_BAR_DOCKED")
        view['right_h_pane'].connect("button-release-event",
                                     self.update_widget_runtime_config,
                                     "RIGHT_BAR_DOCKED")
        view['central_v_pane'].connect("button-release-event",
                                       self.update_widget_runtime_config,
                                       "CONSOLE_DOCKED")

        # hide not usable buttons
        self.view['step_buttons'].hide()

        # Initializing Main Window Size & Position
        # secure un maximize in initial condition to restore correct position and size
        view.get_top_widget().unmaximize()
        gui_helper_label.set_window_size_and_position(view.get_top_widget(),
                                                      'MAIN')

        wait_for_gui()

        # Initializing Pane positions
        for config_id in constants.PANE_ID:
            self.set_pane_position(config_id)

        # set the hidden status of all bars
        for window_key in constants.UNDOCKABLE_WINDOW_KEYS:
            if global_runtime_config.get_config_value(window_key + '_HIDDEN'):
                func = getattr(self,
                               'on_{}_hide_clicked'.format(window_key.lower()))
                func(None)

        # restore undock state of bar windows
        if gui_config.get_config_value("RESTORE_UNDOCKED_SIDEBARS"):
            for window_key in constants.UNDOCKABLE_WINDOW_KEYS:
                if global_runtime_config.get_config_value(window_key +
                                                          "_WINDOW_UNDOCKED"):
                    self.undock_sidebar(window_key)

        # secure maximized state
        if global_runtime_config.get_config_value("MAIN_WINDOW_MAXIMIZED"):
            wait_for_gui()
            view.get_top_widget().maximize()

        # check for auto backups
        if gui_config.get_config_value(
                'AUTO_BACKUP_ENABLED') and gui_config.get_config_value(
                    'AUTO_RECOVERY_CHECK'):
            import rafcon.gui.models.auto_backup as auto_backup
            auto_backup.check_for_crashed_rafcon_instances()

        plugins.run_hook("main_window_setup", self)

        wait_for_gui()
        # Ensure that the next message is being printed (needed for LN manager to detect finished startup)
        level = logger.level
        logger.setLevel(logging.INFO)
        logger.info("Ready")
        logger.setLevel(level)
Ejemplo n.º 10
0
    def register_view(self, view):
        """Called when the View was registered

        Can be used e.g. to connect signals. Here, the destroy signal is connected to close the application
        """
        super(StateEditorController, self).register_view(view)
        view.prepare_the_labels(
        )  # the preparation of the labels is done here to take into account plugin hook changes
        view['add_input_port_button'].connect('clicked',
                                              self.inputs_ctrl.on_add)
        view['add_output_port_button'].connect('clicked',
                                               self.outputs_ctrl.on_add)
        if isinstance(self.model, ContainerStateModel):
            view['add_scoped_variable_button'].connect('clicked',
                                                       self.scopes_ctrl.on_add)

        view['remove_input_port_button'].connect('clicked',
                                                 self.inputs_ctrl.on_remove)
        view['remove_output_port_button'].connect('clicked',
                                                  self.outputs_ctrl.on_remove)
        if isinstance(self.model, ContainerStateModel):
            view['remove_scoped_variable_button'].connect(
                'clicked', self.scopes_ctrl.on_remove)

        if isinstance(
                self.model, LibraryStateModel
        ) or self.model.state.get_next_upper_library_root_state():
            view['add_input_port_button'].set_sensitive(False)
            view['remove_input_port_button'].set_sensitive(False)
            view['add_output_port_button'].set_sensitive(False)
            view['remove_output_port_button'].set_sensitive(False)
            view['add_scoped_variable_button'].set_sensitive(False)
            view['remove_scoped_variable_button'].set_sensitive(False)

        view.inputs_view.show()
        view.outputs_view.show()
        view.scopes_view.show()
        view.outcomes_view.show()
        view.transitions_view.show()
        view.data_flows_view.show()

        # show scoped variables if show content is enabled -> if disabled the tab stays and indicates a container state
        if isinstance(self.model,
                      LibraryStateModel) and not self.model.show_content():
            view.scopes_view.hide()
            view.linkage_overview.scope_view.hide()

        # Container states do not have a source editor and library states does not show there source code
        # Thus, for those states we do not have to add the source controller and can hide the source code tab
        # logger.info("init state: {0}".format(model))
        lib_with_and_ES_as_root = isinstance(self.model, LibraryStateModel) and \
                                  not isinstance(self.model.state_copy, ContainerStateModel)
        if not isinstance(self.model, ContainerStateModel) and not isinstance(self.model, LibraryStateModel) or \
                lib_with_and_ES_as_root:
            view.source_view.show()
            if isinstance(self.model,
                          LibraryStateModel) and not self.model.show_content():
                view.remove_source_tab()
            view.remove_scoped_variables_tab()
        else:
            view.scopes_view.show()
            if isinstance(self.model, LibraryStateModel) and \
                    (not self.model.show_content() or not isinstance(self.model.state_copy, ContainerStateModel)):
                view.remove_scoped_variables_tab()
            view.remove_source_tab()

        if global_gui_config.get_config_value("SEMANTIC_DATA_MODE", False):
            view.bring_tab_to_the_top('Semantic Data')
        else:
            if isinstance(self.model.state, LibraryState):
                view.bring_tab_to_the_top('Description')
            else:
                view.bring_tab_to_the_top('Linkage Overview')

        if isinstance(self.model, ContainerStateModel):
            self.scopes_ctrl.reload_scoped_variables_list_store()

        plugins.run_hook("post_state_editor_register_view", self)
Ejemplo n.º 11
0
def main(optional_args=None):

    register_signal_handlers(signal_handler)

    logger.info("initialize RAFCON ... ")

    pre_setup_plugins()

    setup_environment()

    logger.info("parse arguments ... ")
    parser = setup_argument_parser()

    if optional_args:
        user_input = parser.parse_args(optional_args)
    else:
        user_input = parser.parse_args()
    if not user_input.state_machine_path:
        logger.error("You have to specify a valid state machine path")
        exit(-1)

    if user_input.memory_profiling:
        tracemalloc.start()
        memory_profiling_args = {
            'memory_profiling_path': user_input.memory_profiling_path,
            'memory_profiling_interval': user_input.memory_profiling_interval,
            'memory_profiling_print': user_input.memory_profiling_print,
            'stop': False,
        }
        memory_profiling_thread = threading.Thread(target=profiling.memory_profiling, args=(memory_profiling_args,))
        memory_profiling_thread.start()

    setup_configuration(user_input.config_path)

    post_setup_plugins(user_input)

    first_sm = None
    for sm_path in user_input.state_machine_path:
        sm = open_state_machine(sm_path)
        if first_sm is None:
            first_sm = sm

    if not user_input.remote:
        start_state_machine(first_sm, user_input.start_state_path)

    if reactor_required():
        from twisted.internet import reactor

        # Blocking call, return when state machine execution finishes
        reactor.run()

    if not user_input.remote:
        wait_for_state_machine_finished(first_sm)
    else:
        while not _user_abort:
            time.sleep(1)

    logger.info("State machine execution finished!")
    plugins.run_hook("post_destruction")
    logging.shutdown()

    if user_input.memory_profiling:
        memory_profiling_args['stop'] = True
        memory_profiling_thread.join()