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." )
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)