def substitute_state_as(target_state_m, state, as_template, keep_name=False): """ Substitute a target state with a handed state The method generates a state model for the state to be inserted and use function substitute_state to finally substitute the state. In case the state to be inserted is a LibraryState it can be chosen to be inserted as template. It can be chosen that the inserted state keeps the name of the target state. :param rafcon.gui.models.state.AbstractStateModel target_state_m: State model of the state to be substituted :param rafcon.core.states.State state: State to be inserted :param bool as_template: The flag determines if a handed state of type LibraryState is insert as template :param bool keep_name: The flag to keep the name of the target state :return: """ state_m = get_state_model_class_for_state(state)(state) # If inserted as template, we have to extract the state_copy and model otherwise keep original name if as_template: assert isinstance(state_m, LibraryStateModel) state_m = state_m.state_copy state_m.state.parent = None if keep_name: state_m.state.name = target_state_m.state.name assert target_state_m.parent.states[ target_state_m.state.state_id] is target_state_m substitute_state(target_state_m, state_m, as_template)
def add_state(container_state_m, state_type): """Add a state to a container state Adds a state of type state_type to the given container_state :param rafcon.gui.models.container_state.ContainerState container_state_m: A model of a container state to add the new state to :param rafcon.core.enums.StateType state_type: The type of state that should be added :return: True if successful, False else """ if container_state_m is None: logger.error("Cannot add a state without a parent.") return False if not isinstance(container_state_m, StateModel) or \ (isinstance(container_state_m, StateModel) and not isinstance(container_state_m, ContainerStateModel)): logger.error("Parent state must be a container, for example a Hierarchy State." + str(container_state_m)) return False state_class = state_type_to_state_class_dict.get(state_type, None) if state_class is None: logger.error("Cannot create state of type {0}".format(state_type)) return False new_state = state_class() from rafcon.gui.models.abstract_state import get_state_model_class_for_state new_state_m = get_state_model_class_for_state(new_state)(new_state) gui_helper_meta_data.put_default_meta_on_state_m(new_state_m, container_state_m) container_state_m.expected_future_models.add(new_state_m) container_state_m.state.add_state(new_state) return True
def create_state_model_for_state(new_state, meta, state_element_models): """Create a new state model with the defined properties A state model is created for a state of the type of new_state. All child models in state_element_models ( model list for port, connections and states) are added to the new model. :param StateModel new_state: The new state object with the correct type :param Vividict meta: Meta data for the state model :param list state_element_models: All state element and child state models of the original state model :return: New state model for new_state with all childs of state_element_models """ from rafcon.gui.models.abstract_state import get_state_model_class_for_state state_m_class = get_state_model_class_for_state(new_state) new_state_m = state_m_class(new_state, meta=meta, load_meta_data=False, expected_future_models=state_element_models) error_msg = "New state has not re-used all handed expected future models." check_expected_future_model_list_is_empty(new_state_m, msg=error_msg) return new_state_m
def insert_state_as(target_state_m, state, as_template): """ Add a state into a target state In case the state to be insert is a LibraryState it can be chosen to be insert as template. :param rafcon.gui.models.container_state.ContainerStateModel target_state_m: State model of the target state :param rafcon.core.states.State state: State to be insert as template or not :param bool as_template: The flag determines if a handed state of type LibraryState is insert as template :return: """ if not isinstance(target_state_m, ContainerStateModel) or \ not isinstance(target_state_m.state, ContainerState): logger.error("States can only be inserted in container states") return False state_m = get_state_model_class_for_state(state)(state) if not as_template: gui_helper_meta_data.put_default_meta_on_state_m( state_m, target_state_m) # If inserted as template, we have to extract the state_copy and respective model else: assert isinstance(state, LibraryState) old_lib_state_m = state_m state_m = state_m.state_copy previous_state_size = state_m.get_meta_data_editor()['size'] gui_helper_meta_data.put_default_meta_on_state_m( state_m, target_state_m) # TODO check if the not as template case maybe has to be run with the prepare call prepare_state_m_for_insert_as(state_m, previous_state_size) old_lib_state_m.prepare_destruction(recursive=False) # explicit secure that there is no state_id conflict within target state child states while state_m.state.state_id in target_state_m.state.states: state_m.state.change_state_id() target_state_m.expected_future_models.add(state_m) target_state_m.state.add_state(state_m.state) # secure possible missing models to be generated update_models_recursively(state_m, expected=False)