Ejemplo 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."
                )
Ejemplo n.º 2
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)