Esempio n. 1
0
    def assign_notification_root_state_after(self, model, prop_name, info):
        """
        This method is called, when any state, transition, data flow, etc. within the state machine modifications. This
        then typically requires a redraw of the graphical editor, to display these modifications immediately.
        :param model: The state machine model
        :param prop_name: The property that was changed
        :param info: Information about the change
        """
        # execution_status-changes are not observed
        if self.busy or info.method_name in BY_EXECUTION_TRIGGERED_OBSERVABLE_STATE_METHODS:
            return
        else:
            overview = NotificationOverview(info)

            # handle interrupts of action caused by exceptions
            if overview.get_result() == "CRASH in FUNCTION" or isinstance(
                    overview.get_result(), Exception):
                if self.count_before == 1:
                    return self._interrupt_active_action(info)
                pass

            # modifications of parent are not observed
            if overview.get_cause() == 'parent':
                return

            # decrease counter and finish action when reaching count=0
            if self.locked:
                self.after_count()
                if self.count_before == 0:
                    self.finish_new_action(overview)
            else:
                logger.error(
                    "HISTORY after not count [root_state] -> For every before there should be a after."
                )
Esempio n. 2
0
    def action_signal_after_complex_action(self, model, prop_name, info):
        if self.busy:  # if proceeding undo or redo
            return
        if isinstance(model, AbstractStateModel) and isinstance(info['arg'], ActionSignalMsg) and \
                info['arg'].after and info['arg'].action in ['change_root_state_type', 'change_state_type',
                                                             'paste', 'cut',
                                                             'substitute_state', 'group_states', 'ungroup_state']:

            overview = NotificationOverview(info)
            if info['arg'].action in [
                    'change_state_type', 'paste', 'cut', 'substitute_state',
                    'group_states', 'ungroup_state'
            ]:

                if self.__buffered_root_state_model is not model:
                    self.relieve_model(model)

            if isinstance(info['arg'].result, Exception):
                if self.count_before == 1:
                    return self._interrupt_active_action(info)
                else:
                    logger.warning("Count is wrong 1 != {0}".format(
                        self.count_before))

            # decrease counter and finish action if count_before = 0
            if self.locked:
                self.after_count()
                if self.count_before == 0:
                    self.finish_new_action(overview)
                    if info['arg'].action == 'change_root_state_type':
                        self._re_initiate_observation()
            else:
                logger.error(
                    "HISTORY after not count to 0 [action signal] -> For every before there should be a after."
                    "{0}".format(NotificationOverview(info)))
Esempio n. 3
0
    def assign_notification_states_before(self, model, prop_name, info):
        if self.busy:  # if proceeding undo or redo
            return
        else:
            # avoid to vast computation time
            if 'kwargs' in info and 'method_name' in info['kwargs'] and \
                    info['kwargs']['method_name'] in BY_EXECUTION_TRIGGERED_OBSERVABLE_STATE_METHODS:
                return

            overview = NotificationOverview(info)

            # skipped state modifications
            if not overview.get_change(
            ) == 'state_change' or overview.get_cause() == 'parent':
                return

            # increase counter and generate new action if not locked by action that is performed
            if self.locked:
                self.before_count()
            else:
                if self.start_new_action(overview):
                    self.before_count()
                else:
                    logger.error(
                        "FAILED to start NEW HISTORY ELEMENT [states]")
Esempio n. 4
0
 def before_notification_state_machine_observation_control(
         self, model, prop_name, info):
     """Check for multi-actions and set respective no update flags. """
     overview = NotificationOverview(info)
     if not overview.caused_modification():
         return
     # do not update while multi-actions
     self.check_info_on_no_update_flags(info)
Esempio n. 5
0
    def check_no_update_flags_and_return_combined_flag(self, prop_name, info):
        # avoid updates because of execution status updates
        overview = NotificationOverview(info)
        if not overview.caused_modification():
            return

        self.check_info_on_no_update_flags(info)

        # avoid updates while remove or multi-actions
        if self.no_update or self.no_update_state_destruction or self.no_update_self_or_parent_state_destruction:
            return True
Esempio n. 6
0
 def register_new_state_machines(self, model, prop_name, info):
     """ The method register self as observer newly added StateMachineModels after those were added to the list of
     state_machines hold by observed StateMachineMangerModel. The method register as observer of observable
     StateMachineMangerModel.state_machines."""
     if info['method_name'] == '__setitem__':
         self.observe_model(info['args'][1])
         self.logger.info(NotificationOverview(info))
     elif info['method_name'] == '__delitem__':
         pass
     else:
         self.logger.warning(NotificationOverview(info))
Esempio n. 7
0
    def states_update_before(self, model, prop_name, info):

        if is_execution_status_update_notification_from_state_machine_model(prop_name, info):
            return

        overview = NotificationOverview(info, False, self.__class__.__name__)

        if overview['prop_name'][-1] == 'state' and \
                overview.get_cause() in ["change_state_type"]:
            changed_model = self._selected_sm_model.get_state_model_by_path(overview['args'][-1][1].get_path())
            self.observe_model(changed_model)
Esempio n. 8
0
 def relieve_state_machines(self, model, prop_name, info):
     """ The method relieves observed models before those get removed from the list of state_machines hold by
     observed StateMachineMangerModel. The method register as observer of observable
     StateMachineMangerModel.state_machines."""
     if info['method_name'] == '__setitem__':
         pass
     elif info['method_name'] == '__delitem__':
         self.relieve_model(self.state_machine_manager_model.state_machines[info['args'][0]])
         self.logger.info(NotificationOverview(info))
     else:
         self.logger.warning(NotificationOverview(info))
Esempio n. 9
0
 def notify_state_name_change(self, model, prop_name, info):
     """Checks whether the name of a state was changed and change the tab label accordingly
     """
     overview = NotificationOverview(info)
     # avoid updates or checks because of execution status updates
     if not overview.caused_modification():
         return
     changed_model = overview.get_affected_model()
     method_name = overview.get_cause()
     if isinstance(changed_model, AbstractStateModel) and method_name in ['name', 'script_text']:
         self.update_tab_label(changed_model)
Esempio n. 10
0
    def notify_state_name_change(self, model, prop_name, info):
        """Checks whether the name of a state was changed and change the tab label accordingly
        """
        # avoid updates or checks because of execution status updates
        if is_execution_status_update_notification_from_state_machine_model(prop_name, info):
            return

        overview = NotificationOverview(info, False, self.__class__.__name__)
        changed_model = overview['model'][-1]
        method_name = overview.get_cause()
        if isinstance(changed_model, AbstractStateModel) and method_name in ['name', 'script_text']:
            self.update_tab_label(changed_model)
Esempio n. 11
0
    def states_update(self, model, prop_name, info):
        overview = NotificationOverview(info)
        if not overview.caused_modification():
            return

        if overview.get_affected_property() == 'state' and \
                overview.get_cause() in ["name"]:  # , "add_state", "remove_state"]:
            self.update_tree_store_row(overview.get_affected_model())
        # TODO check the work around for get_library_root_state -> maybe the notifications can be avoided if upper lib
        elif overview.get_affected_property() == 'state' and not overview.get_affected_model().state.get_next_upper_library_root_state() and \
                overview.get_cause() in ["add_state", "remove_state"]:
            self.update(overview.get_affected_model())
Esempio n. 12
0
    def states_update_before(self, model, prop_name, info):

        if is_execution_status_update_notification_from_state_machine_model(
                prop_name, info):
            return

        overview = NotificationOverview(info)

        if overview.get_affected_property() == 'state' and \
                overview.get_cause() in ["change_state_type"]:
            changed_model = self._selected_sm_model.get_state_model_by_path(
                overview.get_method_args()[1].get_path())
            self.observe_model(changed_model)
Esempio n. 13
0
    def after_notification_of_parent_or_state_from_lists(self, model, prop_name, info):

        # avoid updates because of execution status updates or while multi-actions
        if self.check_no_update_flags_and_return_combined_flag(prop_name, info):
            return

        overview = NotificationOverview(info)

        # avoid updates because of unimportant methods
        if overview.get_cause() not in ['name', 'append', '__setitem__',  # '__delitem__', 'remove',
                                        'group_states', 'ungroup_state', 'change_data_type',
                                        'from_key', 'to_key', 'from_state', 'to_state',
                                        'modify_origin', 'modify_target']:
            if self.model.parent:
                # check for a sibling port change
                if prop_name == 'states' and overview.get_affected_core_element() is self.model.parent.state and \
                        (overview.get_affected_core_element() in self.model.parent.state.states and
                         overview.get_cause() in ['add_input_data_port', 'add_output_data_port'] or
                         overview.get_affected_property() in ['data_port', 'scoped_variable'] and
                         overview.get_cause() in ['name', 'change_data_type']):
                    pass
                else:
                    return
            else:
                return

        try:
            self.update(initiator=str(overview))
        except Exception as e:
            if self.debug_log:
                import traceback
                self.store_debug_log_file(str(overview))
                self.store_debug_log_file(str(traceback.format_exc()))
            logger.error("update of data_flow widget fails while detecting change in state %s %s" %
                         (self.model.state.name, self.model.state.state_id))
Esempio n. 14
0
 def model_changed(self, model, prop_name, info):
     overview = NotificationOverview(info)
     if overview.operation_finished() and self.child_model_changed(
             overview):
         # The only operations allowed are setting the parent of the state_copy and
         # changing the state_execution_status
         if not (info["instance"] == self.state_copy.state
                 and info["method_name"] == "parent"
                 or info["method_name"] == "state_execution_status"):
             if not self.is_about_to_be_destroyed_recursively:
                 logger.warning(
                     "You have modified core property of an inner state of a library state."
                 )
     super(LibraryStateModel, self).model_changed(model, prop_name, info)
Esempio n. 15
0
    def check_info_on_no_update_flags(self, info):
        """Stop updates while multi-actions"""
        # TODO that could need a second clean up
        # avoid updates because of state destruction
        if 'before' in info and info['method_name'] == "remove_state":
            if info.instance is self.model.state:
                self.no_update_state_destruction = True
            else:
                # if the state it self is removed lock the widget to never run updates and relieve all models
                removed_state_id = info.args[1] if len(
                    info.args) > 1 else info.kwargs['state_id']
                if removed_state_id == self.model.state.state_id or \
                        not self.model.state.is_root_state and removed_state_id == self.model.parent.state.state_id:
                    self.no_update_self_or_parent_state_destruction = True
                    self.relieve_all_models()

        elif 'after' in info and info['method_name'] == "remove_state":
            if info.instance.state_id == self.model.state.state_id:
                self.no_update_state_destruction = False

        # reduce NotificationOverview generations by the fact that after could cause False and before could cause True
        if not self.no_update_state_destruction and not self.no_update_self_or_parent_state_destruction and \
                (not self.no_update and 'before' in info or 'after' in info and self.no_update):
            return
        overview = NotificationOverview(info)

        # The method causing the change raised an exception, thus nothing was changed and updates are allowed
        if 'after' in info and isinstance(overview.get_result(), Exception):
            self.no_update = False
            self.no_update_state_destruction = False
            # self.no_update_self_or_parent_state_destruction = False
            return

        if overview.get_cause() in [
                'group_states', 'ungroup_state', "change_state_type",
                "change_root_state_type"
        ]:
            instance_is_self = self.model.state is overview.get_affected_core_element(
            )
            instance_is_parent = self.model.parent and self.model.parent.state is overview.get_affected_core_element(
            )
            instance_is_parent_parent = self.model.parent and self.model.parent.parent and self.model.parent.parent.state is overview.get_affected_core_element(
            )
            # print("no update flag: ", True if 'before' in info and (instance_is_self or instance_is_parent or instance_is_parent_parent) else False)
            if instance_is_self or instance_is_parent or instance_is_parent_parent:
                self.no_update = True if 'before' in info else False

            if overview.get_affected_property() == 'state' and overview.get_cause() in ["change_state_type"] and \
                    self.model.get_state_machine_m() is not None:
                changed_model = self.model.get_state_machine_m(
                ).get_state_model_by_path(
                    overview.get_method_args()[1].get_path())
                if changed_model not in self._model_observed:
                    self.observe_model(changed_model)
Esempio n. 16
0
    def states_update(self, model, prop_name, info):

        if is_execution_status_update_notification_from_state_machine_model(prop_name, info) or \
                self._ongoing_complex_actions:
            return

        overview = NotificationOverview(info, False, self.__class__.__name__)

        if overview['prop_name'][-1] == 'state' and \
                overview.get_cause() in ["name"]:  # , "add_state", "remove_state"]:
            self.update_tree_store_row(overview['model'][-1])
        # TODO check the work around for get_library_root_state -> maybe the notifications can be avoided if upper lib
        elif overview['prop_name'][-1] == 'state' and not overview['model'][-1].state.get_next_upper_library_root_state() and \
                overview.get_cause() in ["add_state", "remove_state"]:
            self.update(overview['model'][-1])
Esempio n. 17
0
    def model_changed(self, model, prop_name, info):
        """This method notifies the model lists and the parent state about changes

        The method is called each time, the model is changed. This happens, when the state itself changes or one of
        its children (states, transitions, data flows) changes. Changes of the children cannot be observed directly,
        therefore children notify their parent about their changes by calling this method.
        This method then checks, what has been changed by looking at the model that is passed to it. In the following it
        notifies the list in which the change happened about the change.
        E.g. one child state changes its name. The model of that state observes itself and notifies the parent (
        i.e. this state model) about the change by calling this method with the information about the change. This
        method recognizes that the model is of type StateModel and therefore triggers a notify on the list of state
        models.
        "_notify_method_before" is used as trigger method when the changing function is entered and
        "_notify_method_after" is used when the changing function returns. This changing function in the example
        would be the setter of the property name.
        :param model: The model that was changed
        :param prop_name: The property that was changed
        :param info: Information about the change (e.g. the name of the changing function)
        """
        overview = NotificationOverview(info)
        # if info.method_name == 'change_state_type':  # Handled in method 'change_state_type'
        #     return

        # If this model has been changed (and not one of its child states), then we have to update all child models
        # This must be done before notifying anybody else, because other may relay on the updated models
        if not self.child_model_changed(overview):
            if overview.operation_finished():
                self.update_child_models(model, prop_name, info)
                # if there is and exception set is_about_to_be_destroyed_recursively flag to False again
                if info.method_name in ["remove_state"] and isinstance(
                        info.result, Exception):
                    state_id = info.kwargs[
                        'state_id'] if 'state_id' in info.kwargs else info.args[
                            1]
                    self.states[
                        state_id].is_about_to_be_destroyed_recursively = False
            elif overview.operation_started():
                # while before notification mark all states which get destroyed recursively
                if info.method_name in ["remove_state"] and \
                        info.kwargs.get('destroy', True) and info.kwargs.get('recursive', True):
                    state_id = info.kwargs[
                        'state_id'] if 'state_id' in info.kwargs else info.args[
                            1]
                    self.states[
                        state_id].is_about_to_be_destroyed_recursively = True

        # Finally call the method of the base class, to forward changes in ports and outcomes
        super(ContainerStateModel, self).model_changed(model, prop_name, info)
Esempio n. 18
0
    def state_action_signal(self, model, prop_name, info):
        if self.busy:  # if proceeding undo or redo
            return
        if isinstance(model, StateMachineModel) and isinstance(info['arg'], ActionSignalMsg) and \
                not info['arg'].after and info['arg'].action in ['change_root_state_type', 'change_state_type',
                                                                 'paste', 'cut',
                                                                 'substitute_state', 'group_states', 'ungroup_state']:

            overview = NotificationOverview(info)

            if info['arg'].action == 'change_root_state_type':
                assert info['arg'].action_parent_m is self.state_machine_model
                self.active_action = StateMachineAction(
                    parent_path=info['arg'].action_parent_m.root_state.state.
                    get_path(),
                    state_machine_model=info['arg'].action_parent_m,
                    overview=overview)
            else:
                self.active_action = StateAction(
                    parent_path=info['arg'].action_parent_m.state.get_path(),
                    state_machine_model=self.state_machine_model,
                    overview=overview)

            self.before_count()
            if info['arg'].action in ['group_states', 'paste', 'cut']:
                self.observe_model(info['arg'].action_parent_m)
            else:
                self.observe_model(info['arg'].affected_models[0])
Esempio n. 19
0
 def execution_change(self, model, prop_name, info):
     from rafcon.gui.utils.notification_overview import NotificationOverview
     overview = NotificationOverview(info)
     if overview['method_name'][-1] == 'state_execution_status':
         # print("CURRENT STATE: {0}".format(overview['model'][-1].state.get_path()))
         self.last_execution_change_at_state = overview['model'][
             -1].state.get_path()
Esempio n. 20
0
    def on_state_execution_status_changed_after(self, model, prop_name, info):
        """ Show current execution status in the widget

        This function specifies what happens if the state machine execution status of a state changes
        
        :param model: the model of the state that has changed (most likely its execution status)
        :param prop_name: property name that has been changed
        :param info: notification info dictionary
        :return:
        """
        from rafcon.gui.utils.notification_overview import NotificationOverview
        from rafcon.core.states.state import State

        def name_and_next_state(state):
            assert isinstance(state, State)
            if state.is_root_state_of_library:
                return state.parent.parent, state.parent.name
            else:
                return state.parent, state.name

        def create_path(state, n=3, separator='/'):
            next_parent, name = name_and_next_state(state)
            path = separator + name
            n -= 1
            while n > 0 and isinstance(next_parent, State):
                next_parent, name = name_and_next_state(next_parent)
                path = separator + name + path
                n -= 1
            if isinstance(next_parent, State):
                path = separator + '..' + path
            return path

        if 'kwargs' in info and 'method_name' in info['kwargs']:
            overview = NotificationOverview(info)
            if overview.get_cause() == 'state_execution_status':
                active_state = overview.get_affected_model().state
                assert isinstance(active_state, State)

                path_depth = rafcon.gui.singleton.global_gui_config.get_config_value(
                    "EXECUTION_TICKER_PATH_DEPTH", 3)

                message = self._fix_text_of_label + create_path(
                    active_state, path_depth)
                if rafcon.gui.singleton.main_window_controller.view is not None:
                    self.ticker_text_label.set_text(message)
                else:
                    logger.warning("Not initialized yet")
Esempio n. 21
0
 def all_after_notification(self, model, prop_name, info):
     """ The method logs all changes that notified recursively trough the hierarchies of the states after the change
     occurs in the rafcon.core object. The method register as observer of observable
     StateMachineModel.state_machine of any observed StateMachineModel.
     :param model: StateMachineModel that is represents the state_machine which has been changed
     :param prop_name: Name of property that notifies -> here always 'state_machine'
     :param info: Dictionary that hold recursive notification information like models, property and method names
     :return:
     """
     self.logger.debug(NotificationOverview(info))
Esempio n. 22
0
    def model_changed(self, model, prop_name, info):
        """This method notifies the model lists and the parent state about changes

        The method is called each time, the model is changed. This happens, when the state itself changes or one of
        its children (outcomes, ports) changes. Changes of the children cannot be observed directly,
        therefore children notify their parent about their changes by calling this method.
        This method then checks, what has been changed by looking at the method that caused the change. In the
        following, it notifies the list in which the change happened about the change.
        E.g. one input data port changes its name. The model of the port observes itself and notifies the parent (
        i.e. the state model) about the change by calling this method with the information about the change. This
        method recognizes that the method "modify_input_data_port" caused the change and therefore triggers a notify
        on the list if input data port models.
        "_notify_method_before" is used as trigger method when the changing function is entered and
        "_notify_method_after" is used when the changing function returns. This changing function in the example
        would be "modify_input_data_port".

        :param model: The model that was changed
        :param prop_name: The property that was changed
        :param info: Information about the change (e.g. the name of the changing function)
        """
        overview = NotificationOverview(info)

        # If this model has been changed (and not one of its child states), then we have to update all child models
        # This must be done before notifying anybody else, because other may rely on the updated models
        if overview.operation_finished(
        ) and not self.child_model_changed(overview):
            self.update_models(model, prop_name, info)

        cause, changed_list = self.get_cause_and_affected_model_list(model)

        if not (cause is None or cause is "income_change"
                or changed_list is None):
            if overview.operation_started():
                changed_list._notify_method_before(self.state, cause,
                                                   (self.state, ), info)
            else:
                changed_list._notify_method_after(self.state, cause, None,
                                                  (self.state, ), info)

        # Notifies parent state
        super(StateModel, self).model_changed(model, prop_name, info)
Esempio n. 23
0
    def meta_changed_notify_after(self, changed_model, prop_name, info):
        if not self.with_meta_data_actions:
            return
        overview = NotificationOverview(info)
        if self.busy:
            return
        if overview.get_signal_message().origin == 'load_meta_data':
            return

        if self.active_action is None or overview.get_signal_message(
        ).change in ['append_initial_change']:
            # update last actions after_state_image -> meta-data
            self.re_initiate_meta_data()
        elif self.active_action is None or \
                overview.get_signal_message().change in ['append_to_last_change'] or \
                overview.get_signal_message().origin in ['group_states', 'ungroup_state', 'substitute_state']:
            # update last actions after_state_image -> meta-data
            self.active_action.after_state_image = self.active_action.get_state_image(
            )
            self.update_internal_tmp_storage()
        else:
            if isinstance(overview.get_affected_model(), AbstractStateModel):
                changed_parent_model = overview.get_affected_model()
            else:
                changed_parent_model = overview.get_affected_model().parent
            changed_parent_state_path = changed_parent_model.state.get_path()

            # TODO think about to remove this work around again
            # ignore meta data changes inside of library states
            changed_parent_state = self.state_machine_model.get_state_model_by_path(
                changed_parent_state_path).state
            if changed_parent_state.get_next_upper_library_root_state():
                return

            if self.count_before == 0:
                self.active_action = MetaDataAction(
                    changed_parent_model.state.get_path(),
                    state_machine_model=self.state_machine_model,
                    overview=overview)
                meta_data = self.get_state_element_meta_from_internal_tmp_storage(
                    changed_parent_state_path)
                state_image = StateImage(meta_data=meta_data)
                self.active_action.before_state_image = state_image

                self.finish_new_action(overview)
            else:
                logger.info(
                    'Meta data change signal was emitted while other action was is performed. \n{0}'
                    .format(overview))
Esempio n. 24
0
    def assign_notification_root_state_before(self, model, prop_name, info):
        # execution_status-changes are not observed
        if self.busy or info.method_name in BY_EXECUTION_TRIGGERED_OBSERVABLE_STATE_METHODS:
            return
        # first element should be prop_name="state_machine", instance=StateMachine and model=StateMachineModel
        # second element should be Prop_name="states" if root_state child elements are changed
        # --- for root_state elements it has to be prop_name in ["data_flows", "transitions", "input_data_ports",
        #                                                        "output_data_ports", "scoped_variables"]
        # third (and last element) should be prop_name in ["data_flow", "transition", ...
        else:
            overview = NotificationOverview(info)
            # modifications of parent are not observed
            if overview.get_cause() == 'parent':
                return

            # increase counter and generate new action if not locked by action that is performed
            if self.locked:
                self.before_count()
            else:
                if self.start_new_action(overview):
                    self.before_count()
                else:
                    logger.error(
                        "FAILED to start NEW HISTORY ELEMENT [root_state]")
Esempio n. 25
0
    def after_notification_state(self, model, prop_name, info):

        # avoid updates because of execution status updates or while multi-actions
        # logger.info("after_notification_state: ".format(NotificationOverview(info)))
        if self.check_no_update_flags_and_return_combined_flag(prop_name, info):
            return

        overview = NotificationOverview(info, False, self.__class__.__name__)
        # logger.info("after_notification_state: OK")

        if overview['method_name'][-1] == 'parent' and overview['instance'][-1] is self.model.state or \
                overview['instance'][-1] in [self.model.state, self.model.state.parent] and \
                overview['method_name'][-1] in ['name', 'group_states', 'ungroup_state', 'change_data_type',
                                                "remove_outcome", "remove_transition"]:
            # logger.info("after_notification_state: UPDATE")
            self.update(initiator=str(overview))
Esempio n. 26
0
    def after_notification_of_parent_or_state_from_lists(
            self, model, prop_name, info):
        """ Activates the update after update if outcomes, transitions or states list has been changed.
        """
        # avoid updates because of execution status updates or while multi-actions
        if self.check_no_update_flags_and_return_combined_flag(
                prop_name, info):
            return

        overview = NotificationOverview(info)
        if overview.get_cause() not in [
                'name',
                'append',
                '__setitem__',  # '__delitem__', 'remove'
                'from_outcome',
                'to_outcome',
                'from_state',
                'to_state',
                'modify_origin',
                'modify_target'
        ]:
            if self.model.parent:
                # check for sibling port change
                if prop_name == 'states' and overview.get_affected_core_element() is self.model.parent.state and \
                        (overview.get_affected_core_element() in self.model.parent.state.states and
                         overview.get_cause() in ['add_outcome'] or
                         overview.get_affected_property() in ['outcome'] and
                         overview.get_cause() in ['name']):
                    pass
                else:
                    return
            else:
                return

        try:
            self.update(initiator=str(overview))
        except KeyError as e:
            if self.debug_log:
                import traceback
                self.store_debug_log_file(str(overview))
                self.store_debug_log_file(str(traceback.format_exc()))
            logger.error(
                "update of transition widget fails while detecting list change of state %s %s %s\n%s"
                % (self.model.state.name, self.model.state.state_id, e, self))
Esempio n. 27
0
    def after_notification_of_parent_or_state_from_lists(
            self, model, prop_name, info):
        """ Activates the update after update if outcomes, transitions or states list has been changed.
        """
        # avoid updates because of execution status updates or while multi-actions
        # logger.info("after_notification_of_parent_or_state_from_lists: ".format(NotificationOverview(info)))
        if self.check_no_update_flags_and_return_combined_flag(
                prop_name, info):
            return

        overview = NotificationOverview(info, False, self.__class__.__name__)
        # print(self, self.model.state.get_path(), overview)
        # logger.info("after_notification_of_parent_or_state_from_lists: OK")

        if overview['prop_name'][0] in ['states', 'outcomes', 'transitions'] and \
                overview['method_name'][-1] not in ['name', 'append', '__setitem__',  # '__delitem__', 'remove'
                                                    'from_outcome', 'to_outcome', 'from_state', 'to_state',
                                                    'modify_origin', 'modify_target']:
            if self.model.parent:
                # check for sibling port change
                if overview['prop_name'][0] == 'states' and overview['instance'][0] is self.model.parent.state and \
                        (overview['instance'][-1] in self.model.parent.state.states and
                         overview['method_name'][-1] in ['add_outcome'] or
                         overview['prop_name'][-1] in ['outcome'] and
                         overview['method_name'][-1] in ['name']):
                    pass
                else:
                    return
            else:
                return
        # print("TUPDATE ", self, overview)

        try:
            # logger.info("after_notification_of_parent_or_state_from_lists: UPDATE")
            self.update(initiator=str(overview))
        except KeyError as e:
            if self.debug_log:
                import traceback
                self.store_debug_log_file(str(overview))
                self.store_debug_log_file(str(traceback.format_exc()))
            logger.error(
                "update of transition widget fails while detecting list change of state %s %s %s\n%s"
                % (self.model.state.name, self.model.state.state_id, e, self))
Esempio n. 28
0
    def after_notification_of_parent_or_state(self, model, prop_name, info):

        # avoid updates because of execution status updates or while multi-actions
        if self.check_no_update_flags_and_return_combined_flag(prop_name, info):
            return

        overview = NotificationOverview(info)

        if overview.get_cause() == 'parent' and overview.get_affected_core_element() is self.model.state or \
                overview.get_affected_core_element() in [self.model.state, self.model.state.parent] and \
                overview.get_cause() in ['name', 'group_states', 'ungroup_state', 'change_data_type',
                                                "remove_input_data_port", "remove_output_data_port",
                                                "remove_scoped_variable", "remove_data_flow"]:
            self.update(initiator=str(overview))
Esempio n. 29
0
    def after_notification_of_parent_or_state_from_lists(self, model, prop_name, info):

        # avoid updates because of execution status updates or while multi-actions
        # logger.info("after_notification_of_parent_or_state_from_lists: {1}\n{0}".format(NotificationOverview(info),
        #                                                                                 self.model.state.get_path()))
        if self.check_no_update_flags_and_return_combined_flag(prop_name, info):
            return

        overview = NotificationOverview(info, False, self.__class__.__name__)
        # print self, self.model.state.get_path(), overview
        # logger.info("after_notification_of_parent_or_state_from_lists: OK")

        # avoid updates because of unimportant methods
        if overview['prop_name'][0] in ['states', 'input_data_ports', 'output_data_ports', 'scoped_variables', 'data_flows'] and \
                overview['method_name'][-1] not in ['name', 'append', '__setitem__',  # '__delitem__', 'remove',
                                                    'group_states', 'ungroup_state', 'change_data_type',
                                                    'from_key', 'to_key', 'from_state', 'to_state',
                                                    'modify_origin', 'modify_target']:
            if self.model.parent:
                # check for a sibling port change
                if overview['prop_name'][0] == 'states' and overview['instance'][0] is self.model.parent.state and \
                        (overview['instance'][-1] in self.model.parent.state.states and
                         overview['method_name'][-1] in ['add_input_data_port', 'add_output_data_port'] or
                         overview['prop_name'][-1] in ['data_port', 'scoped_variable'] and
                         overview['method_name'][-1] in ['name', 'change_data_type']):
                    pass
                else:
                    return
            else:
                return
        # print "DUPDATE ", self, overview

        try:
            # logger.info("after_notification_of_parent_or_state_from_lists: UPDATE")
            self.update(initiator=str(overview))
        except Exception as e:
            if self.debug_log:
                import traceback
                self.store_debug_log_file(str(overview))
                self.store_debug_log_file(str(traceback.format_exc()))
            logger.error("update of data_flow widget fails while detecting change in state %s %s" %
                         (self.model.state.name, self.model.state.state_id))
Esempio n. 30
0
    def model_changed(self, model, prop_name, info):
        if isinstance(info['result'], Exception):
            from rafcon.gui.utils.notification_overview import NotificationOverview
            logger.exception("An '{0}' exception was raised in the core. "
                             "Details about the origin:\n{1}"
                             "".format(
                                 type(info['result']).__name__,
                                 NotificationOverview(info)))
            return

        if info["method_name"] == "add_state_machine":
            logger.debug("Add new state machine model ... ")
            sm_id = info['result']
            if sm_id in self.state_machine_manager.state_machines and sm_id not in self.state_machines:
                logger.debug(
                    "Create new state machine model for state machine with id %s",
                    sm_id)
                sm = self.state_machine_manager.state_machines[sm_id]
                with sm.modification_lock():
                    self.state_machines[sm_id] = StateMachineModel(sm)
                    from rafcon.gui.models.abstract_state import AbstractStateModel
                    logger.verbose("Number of created state models {}".format(
                        AbstractStateModel.state_counter))
                    self.selected_state_machine_id = sm_id
            else:
                logger.error(
                    "Model of state machine {0} is supposed to not exist but the state machine object should."
                    "".format(sm_id))

        elif info["method_name"] == "remove_state_machine":
            sm_id_to_delete = info['result'].state_machine_id
            if sm_id_to_delete is not None:
                logger.debug(
                    "Delete state machine model for state machine with id %s",
                    sm_id_to_delete)
                if self.selected_state_machine_id == sm_id_to_delete:
                    self.selected_state_machine_id = None
                sm_m = self.state_machines[sm_id_to_delete]
                sm_m.prepare_destruction()
                del self.state_machines[sm_id_to_delete]
                sm_m.destroy()