Esempio n. 1
0
    def configure_gtk(self):
        if not resource_exists(__name__, self.get_assets_path("gtk-2.0", "gtkrc")):
            raise ValueError("GTK theme does not exist")
        gtkrc_file_path = resource_filename(__name__, self.get_assets_path("gtk-2.0", "gtkrc"))
        filename = resource_filename(__name__, self.get_assets_path(
            "icons", "RAFCON_figurative_mark_negative.svg", for_theme=False))
        gtk.window_set_default_icon_from_file(filename)

        # wait for all gtk events being processed before parsing the gtkrc file
        wait_for_gui()
        gtk.rc_parse(gtkrc_file_path)
Esempio n. 2
0
def execute(self, inputs, outputs, gvm):
    self.logger.debug("Insert state")
    #libary_path = "unit_test_state_machines/bake_libraries"
    #libary_name = "bake_library1"
    libary_path = inputs["library_path"]
    libary_name = inputs["library_name"]
    s = LibraryState(libary_path,
                     libary_name,
                     name=libary_name,
                     state_id="test_state")
    call_gui_callback(self.parent.add_state, s)
    wait_for_gui()
    call_gui_callback(self.parent.add_transition, self.state_id, 0, s.state_id,
                      None)
    wait_for_gui()
    call_gui_callback(self.parent.add_transition, s.state_id, 0, "CXVBON",
                      None)
    wait_for_gui()
    parent_id = None
    for d_id, d in self.parent.input_data_ports.items():
        if d.name == "str_variable":
            parent_id = d_id
    call_gui_callback(self.parent.add_data_flow, self.parent.state_id,
                      parent_id, s.state_id, 0)
    wait_for_gui()
    outputs["generated_state_id"] = s.state_id
    time.sleep(1.0)
    return 0
Esempio n. 3
0
def stop_gtk():
    # shutdown twisted correctly
    if reactor_required():
        from twisted.internet import reactor
        if reactor.running:
            reactor.callFromThread(reactor.stop)
        # Twisted can be imported without the reactor being used
        # => check if GTK main loop is running
        elif gtk.main_level() > 0:
            glib.idle_add(gtk.main_quit)
    else:
        glib.idle_add(gtk.main_quit)

    # Run the GTK loop until no more events are being generated and thus the GUI is fully destroyed
    wait_for_gui()
Esempio n. 4
0
def start_stop_state_machine(state_machine, start_state_path, quit_flag):
    wait_for_gui()

    state_machine_execution_engine = core_singletons.state_machine_execution_engine
    state_machine_execution_engine.execute_state_machine_from_path(
        state_machine=state_machine,
        start_state_path=start_state_path,
        wait_for_execution_finished=True)
    if reactor_required():
        from twisted.internet import reactor
        reactor.callFromThread(reactor.stop)

    if quit_flag:
        gui_singletons.main_window_controller.get_controller(
            'menu_bar_controller').on_quit_activate(None, None)
Esempio n. 5
0
 def __call__(self, *args, **kwargs):
     from rafcon.gui.utils import wait_for_gui
     if self.with_gui:
         from rafcon.utils.gui_functions import call_gui_callback
         return_values = call_gui_callback(*args, **kwargs)
         call_gui_callback(wait_for_gui)
         return return_values
     else:
         func = args[0]
         result = func(*args[1:], **kwargs)
         # Now we manually need to run the GTK main loop to handle all asynchronous notifications
         # E.g., when a state machine is added to the manager (in the core), the models are in certain cases created
         # asynchronously, depending in which thread the manager model was created.
         wait_for_gui()
         return result
Esempio n. 6
0
    def print_filtered_buffer(self):
        # remember cursor position
        self.view.store_cursor_position()

        # update text buffer
        self.view.clean_buffer()

        for entry in self._log_entries:
            level = entry[0]
            message = entry[1]
            self.print_message(message, level, new=False)

        # restore cursor position
        wait_for_gui()
        self.view.restore_cursor_position()

        self.view.scroll_to_cursor_onscreen()
Esempio n. 7
0
def execute(self, inputs, outputs, gvm):
    self.logger.debug("Delete state")
    state_id = inputs["generated_state_id"]
    # the target state is the hierarchy state, which holds this library state as child state
    target_state = self.parent.parent

    call_gui_callback(target_state.remove_state, state_id)
    # do not call this with idle_add, otherwise the oberserver will be triggered asynchronously
    # i.e. the before notification will be handled after the whole operation already happend
    #GLib.idle_add(target_state.remove_state, state_id)

    while state_id in target_state.states.keys():
        time.sleep(0.1)

    wait_for_gui()

    #call_gui_callback(wait_for_gui)

    #time.sleep(2.0)
    return 0
Esempio n. 8
0
def execute(self, inputs, outputs, gvm):
    self.logger.debug("Insert library state")
    #libary_path = "unit_test_state_machines/bake_libraries"
    #libary_name = "bake_library1"
    libary_path = "unit_test_state_machines/dynamic_library_insertion_libraries"
    libary_name = "test_library"
    e = call_gui_callback(LibraryState,
                          libary_path,
                          libary_name,
                          name="test_library_state")
    call_gui_callback(self.parent.add_state, e)
    call_gui_callback(self.parent.add_transition, self.state_id, 0, e.state_id,
                      None)
    call_gui_callback(self.parent.add_transition, e.state_id, 0,
                      self.parent.state_id, 0)
    wait_for_gui()
    parent_id = None
    for d_id, d in self.parent.output_data_ports.items():
        if d.name == "output_0":
            parent_id = d_id
    call_gui_callback(self.parent.add_data_flow, e.state_id, 2,
                      self.parent.state_id, parent_id)
    wait_for_gui()
    return 0
Esempio n. 9
0
def main():

    # check if all env variables are set
    if not os.environ.get("HOME", False):
        logger.error(
            "For starting RAFCON in GUI mode, the HOME environment variable has to be set!"
        )
        return

    register_signal_handlers(signal_handler)

    splash_screen = SplashScreen(contains_image=True, width=530, height=350)
    splash_screen.rotate_image(random_=True)
    splash_screen.set_text(_("Starting RAFCON..."))
    while gtk.events_pending():
        gtk.main_iteration()

    setup_installation()
    setup_l10n()
    setup_l10n_gtk()

    splash_screen.set_text("Setting up logger...")
    setup_gtkmvc_logger()

    splash_screen.set_text("Initializing plugins...")
    pre_setup_plugins()

    splash_screen.set_text("Setting up environment...")
    setup_mvc_environment()

    parser = setup_argument_parser()
    user_input = parser.parse_args()

    splash_screen.set_text("Loading configurations...")
    setup_mvc_configuration(user_input.config_path, user_input.gui_config_path,
                            user_input.gui_config_path)

    # create lock file -> keep behavior for hole instance
    if global_gui_config.get_config_value('AUTO_RECOVERY_LOCK_ENABLED'):
        rafcon.gui.models.auto_backup.generate_rafcon_instance_lock_file()

    # setup the gui before loading the state machine as then the debug console shows the errors that emerged during
    # loading the state state machine
    splash_screen.set_text("Loading GUI...")
    setup_gui()

    wait_for_gui()

    post_setup_plugins(user_input)

    state_machine = None
    if user_input.state_machine_paths:
        state_machine = open_state_machines(user_input.state_machine_paths)

    if user_input.new:
        create_new_state_machine()

    # initiate stored session # TODO think about a controller for this
    if not user_input.new and not user_input.state_machine_paths \
            and rafcon.gui.singleton.global_gui_config.get_config_value("SESSION_RESTORE_ENABLED"):
        glib.idle_add(backup_session.restore_session_from_runtime_config,
                      priority=glib.PRIORITY_LOW)

    if state_machine and (user_input.start_state_machine_flag
                          or state_machine.get_state_by_path(
                              user_input.start_state_path)):
        start_state_machine(state_machine, user_input.start_state_path,
                            user_input.quit_flag)

    splash_screen.destroy()
    try:
        start_gtk()

        logger.info(_("Main window was closed"))

    finally:
        post_gui_destruction()

    if core_singletons.state_machine_execution_engine.status.execution_mode == StateMachineExecutionStatus.STARTED:
        logger.info(_("Waiting for the state machine execution to finish"))
        core_singletons.state_machine_execution_engine.join()
        logger.info(_("State machine execution has finished"))

    logger.info(_("Exiting ..."))
Esempio n. 10
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)
Esempio n. 11
0
def convert(config_path, source_path, target_path=None, gui_config_path=None):
    logger.info("RAFCON launcher")
    rafcon.gui.start.setup_l10n(logger)
    from rafcon.gui.controllers.main_window import MainWindowController
    from rafcon.gui.views.main_window import MainWindowView

    setup_environment()

    gui_config_path = gui_config_path or get_default_config_path()

    setup_config = {}
    setup_config["config_path"] = config_path
    setup_config["gui_config_path"] = gui_config_path
    setup_config["source_path"] = [source_path]
    if not target_path:
        setup_config["target_path"] = [source_path]
    else:
        setup_config["target_path"] = [target_path]

    global_config.load(path=setup_config['config_path'])
    global_gui_config.load(path=setup_config['gui_config_path'])
    global_runtime_config.load(path=setup_config['gui_config_path'])

    # Initialize library
    core_singletons.library_manager.initialize()

    # Create the GUI
    main_window_view = MainWindowView()

    if setup_config['source_path']:
        if len(setup_config['source_path']) > 1:
            logger.error("Only one state machine is supported yet")
            exit(-1)
        for path in setup_config['source_path']:
            try:
                state_machine = gui_helper_state_machine.open_state_machine(
                    path)
            except Exception as e:
                logger.error("Could not load state machine {0}: {1}".format(
                    path, e))
    else:
        logger.error(
            "You need to specify exactly one state machine to be converted!")

    sm_manager_model = gui_singletons.state_machine_manager_model

    main_window_controller = MainWindowController(sm_manager_model,
                                                  main_window_view)

    if not os.getenv("RAFCON_START_MINIMIZED", False):
        main_window = main_window_view.get_top_widget()
        size = global_runtime_config.get_config_value("WINDOW_SIZE", None)
        position = global_runtime_config.get_config_value("WINDOW_POS", None)
        if size:
            main_window.resize(size[0], size[1])
        if position:
            position = (max(0, position[0]), max(0, position[1]))
            screen_width = Gdk.Screen.width()
            screen_height = Gdk.Screen.height()
            if position[0] < screen_width and position[1] < screen_height:
                main_window.move(position[0], position[1])

    wait_for_gui()
    thread = threading.Thread(target=trigger_gui_signals,
                              args=[
                                  sm_manager_model, main_window_controller,
                                  setup_config, state_machine
                              ])
    thread.start()

    Gtk.main()
    logger.debug("Gtk main loop exited!")
    logger.debug("Conversion done")
Esempio n. 12
0
def restore_session_from_runtime_config():
    """ Restore stored tabs from runtime config

    The method checks if the last status of a state machine is in the backup or in tis original path and loads it
    from there. The original path of these state machines are also insert into the recently opened state machines
    list.
    """
    # TODO add a dirty lock for a crashed rafcon instance also into backup session feature
    # TODO in case a dialog is needed to give the user control
    # TODO combine this and auto-backup in one structure/controller/observer
    from rafcon.gui.singleton import state_machine_manager_model, global_runtime_config, global_gui_config
    from rafcon.gui.models.auto_backup import recover_state_machine_from_backup
    from rafcon.gui.singleton import main_window_controller
    # check if session storage exists
    open_tabs = global_runtime_config.get_config_value('open_tabs', None)
    if open_tabs is None:
        logger.info("No session found for recovery")
        return

    # load and restore state machines like they were opened before
    open_sm = []
    for idx, tab_meta_dict in enumerate(open_tabs):
        start_time = time.time()
        backup_meta_dict = tab_meta_dict['backup_meta']
        from_backup_path = None
        open_sm.append(None)
        # TODO do this decision before storing or maybe store the last stored time in the auto backup?!
        # pick folder name dependent on time, and backup meta data existence
        # problem is that the backup time is maybe not the best choice
        if 'last_backup' in backup_meta_dict:
            last_backup_time = storage_utils.get_float_time_for_string(
                backup_meta_dict['last_backup']['time'])
            if 'last_saved' in backup_meta_dict:
                last_save_time = storage_utils.get_float_time_for_string(
                    backup_meta_dict['last_saved']['time'])
                backup_marked_dirty = backup_meta_dict['last_backup'][
                    'marked_dirty']
                if last_backup_time > last_save_time and backup_marked_dirty:
                    from_backup_path = backup_meta_dict['last_backup'][
                        'file_system_path']
            else:
                from_backup_path = backup_meta_dict['last_backup'][
                    'file_system_path']
        elif 'last_saved' in backup_meta_dict:
            # print("### open last saved", sm_meta_dict['last_saved']['file_system_path'])
            pass
        else:
            logger.error(
                "A tab was stored into session storage dictionary {0} without any recovery path"
                "".format(backup_meta_dict))
            continue

        # check in case that the backup folder is valid or use last saved path
        if from_backup_path is not None and not os.path.isdir(
                from_backup_path):
            logger.warning(
                "The backup of tab {0} from backup path {1} was not possible. "
                "The last saved path will be used for recovery, which could result is loss of changes."
                "".format(idx, from_backup_path))
            from_backup_path = None

        # open state machine
        if from_backup_path is not None:
            # open state machine, recover mark dirty flags, cleans dirty lock files
            logger.info("Restoring from backup {0}".format(from_backup_path))
            state_machine_m = recover_state_machine_from_backup(
                from_backup_path)
        else:
            if 'last_saved' not in backup_meta_dict or backup_meta_dict[
                    'last_saved']['file_system_path'] is None:
                continue
            path = backup_meta_dict['last_saved']['file_system_path']
            if not os.path.isdir(path):
                logger.warning(
                    "The tab can not be open. The backup of tab {0} from common path {1} was not "
                    "possible.".format(idx, path))
                continue
            # logger.info("backup from last saved", path, sm_meta_dict)
            state_machine = storage.load_state_machine_from_path(path)
            state_machine_manager_model.state_machine_manager.add_state_machine(
                state_machine)
            wait_for_gui()
            state_machine_m = state_machine_manager_model.state_machines[
                state_machine.state_machine_id]

        duration = time.time() - start_time
        stat = state_machine_m.state_machine.root_state.get_states_statistics(
            0)
        logger.info(
            "It took {0:.3}s to restore {1} states with {2} hierarchy levels.".
            format(duration, stat[0], stat[1]))

        open_sm[idx] = state_machine_m

    global_runtime_config.extend_recently_opened_by_current_open_state_machines(
    )

    wait_for_gui()

    # restore all state machine selections separate to avoid states-editor and state editor creation problems
    for idx, tab_meta_dict in enumerate(open_tabs):
        state_machine_m = open_sm[idx]
        if state_machine_m is None:  # state machine could not be open
            return

        # restore state machine selection
        selected_model_set = []
        for core_element_identifier in tab_meta_dict['selection']:
            selected_model_set.append(
                state_machine_m.get_state_model_by_path(
                    core_element_identifier))
        state_machine_m.selection.set(selected_model_set)

    # restore backup-ed tab selection
    selected_page_number = global_runtime_config.get_config_value(
        'selected_state_machine_page_number', None)
    if selected_page_number is not None:
        selected_state_machine_page_number = selected_page_number
        if selected_state_machine_page_number is None:
            return
        state_machines_editor_ctrl = main_window_controller.get_controller(
            'state_machines_editor_ctrl')
        if not state_machines_editor_ctrl.view['notebook'].get_n_pages(
        ) >= selected_page_number:
            logger.warning(
                "Page id {0} does not exist so session restore can not re-create selection."
                "".format(selected_page_number))
            return
        notebook = state_machines_editor_ctrl.view['notebook']
        page = state_machines_editor_ctrl.on_switch_page(
            notebook, None, selected_page_number)
        selected_sm_id = state_machine_manager_model.selected_state_machine_id
        if not selected_sm_id == state_machines_editor_ctrl.get_state_machine_id_for_page(
                page):
            logger.warning(
                "Selection of page was not set correctly so session restore can not re-create selection."
            )
            return
Esempio n. 13
0
def main():

    # check if all env variables are set
    if not os.environ.get("HOME", False):
        logger.error("For starting RAFCON in GUI mode, the HOME environment variable has to be set!")
        return

    register_signal_handlers(signal_handler)

    setup_l10n(logger)

    parser = setup_argument_parser()
    user_input = parser.parse_args()

    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_mvc_environment()
    setup_mvc_configuration(user_input.config_path, user_input.gui_config_path,
                            user_input.gui_config_path, user_input.design_config_path)

    splash_screen = create_splash_screen()
    while Gtk.events_pending():
        Gtk.main_iteration()

    splash_screen.set_text("Install missing resources ...")
    setup_installation()

    splash_screen.set_text("Setting up logger...")
    setup_gtkmvc3_logger()

    splash_screen.set_text("Initializing plugins...")
    pre_setup_plugins()

    splash_screen.set_text("Setting up environment...")

    # create lock file -> keep behavior for hole instance
    if global_gui_config.get_config_value('AUTO_RECOVERY_LOCK_ENABLED'):
        import rafcon.gui.models.auto_backup
        rafcon.gui.models.auto_backup.generate_rafcon_instance_lock_file()

    # setup the gui before loading the state machine as then the debug console shows the errors that emerged during
    # loading the state state machine
    splash_screen.set_text("Loading GUI...")
    setup_gui()
    wait_for_gui()

    post_setup_plugins(user_input)

    state_machine = None
    if user_input.state_machine_paths:
        state_machine = open_state_machines(user_input.state_machine_paths)

    if user_input.new:
        create_new_state_machine()

    # initiate stored session # TODO think about a controller for this
    if not user_input.new and not user_input.state_machine_paths \
            and global_gui_config.get_config_value("SESSION_RESTORE_ENABLED"):
        # do in background in order not to block GUI
        GLib.idle_add(backup_session.restore_session_from_runtime_config, priority=GLib.PRIORITY_LOW)

    if state_machine and (user_input.start_state_machine_flag or state_machine.get_state_by_path(user_input.start_state_path)):
        start_state_machine(state_machine, user_input.start_state_path, user_input.quit_flag)

    splash_screen.destroy()
    try:
        start_gtk()

        logger.info(_("Main window was closed"))

    finally:
        post_gui_destruction()

    if core_singletons.state_machine_execution_engine.status.execution_mode == StateMachineExecutionStatus.STARTED:
        logger.info(_("Waiting for the state machine execution to finish"))
        # overwriting signal handlers here does not work either
        import rafcon
        rafcon.core.start.register_signal_handlers(rafcon.core.start.signal_handler)
        core_singletons.state_machine_execution_engine.join()
        logger.info(_("State machine execution has finished"))
        core_singletons.state_machine_manager.delete_all_state_machines()

    logger.info(_("Exiting ..."))
    logging.shutdown()

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