import sys sys.path.append("../wrappers") from wrappers import modelverse as mv import commons class NodeAdd(object): def __init__(self): self._node_type = "" def execute(self, model, node_type, local): """ Add a new node with type node_type to model. If local is true, the node is only added to the model. If local is false, the node will be added to all example models. """ self._node_type = node_type if local: mv.transformation_execute_MANUAL("graph_ops/add_node", {"gm":model}, {"gm":model}, callback=self._callback) else: for m in commons.all_example_models(): self.execute(m, node_type, local=True) def _callback(self, model): node_id = mv.instantiate(model, "gm/Node") mv.attr_assign(model, node_id, "typeID", self._node_type) def repair(self): """ Check if the node add invalidated any instance models by making a type mandatory. If yes, repair by adding a node of the same type to it. """ if commons.is_type_mandatory(self._node_type): for im in commons.all_instance_models(): if not commons.all_nodes_with_type(im, self._node_type): print("Adding mandatory type {} to model {}".format(self._node_type, im)) self.execute(im, self._node_type, local=True) class NodeDelete(object): def __init__(self): self._node = "" self._node_type = "" self.was_last = False def execute(self, model, node, local): self._node = node self._node_type = commons.get_node_type(model, node) if local: mv.transformation_execute_MANUAL("graph_ops/del_node", {"gm":model}, {"gm":model}, callback=self._callback) else: for m in commons.all_example_models(): nodes_to_delete = commons.all_nodes_with_type(m, self._node_type) for node in nodes_to_delete: self.execute(m, node, local=True) def _callback(self, model): mv.delete_element(model, "gm/"+self._node) def repair(self): """ Check if this operation invalidated any instance model by leaving a node untyped. If yes, delete untyped node as well. """ remaining_instances = 0 for exm in commons.all_example_models(): remaining_instances += len(commons.all_nodes_with_type(exm, self._node_type)) if remaining_instances == 0: self.was_last = True print("Type {} became unavailable, deleting from all instance models ...".format(self._node_type)) for im in commons.all_instance_models(): nodes_to_delete = commons.all_nodes_with_type(im, self._node_type) for node in nodes_to_delete: self.execute(im, node, local=True) class NodeRetype(object): def __init__(self): self._node = "" self._old_type = "" self._new_type = "" self._scope = "" def execute(self, model, node, new_type, local): """ Retype the node in model to new_type. If local is true, new_type must already exist and the change only affects the given node. If local is false, all nodes in all example models are renamed to a new type (which must not exist yet). """ self._node = node self._new_type = new_type self._old_type = commons.get_node_type(model, node) if local: self._scope = "Local" else: self._scope = "Global" if local: mv.transformation_execute_MANUAL("graph_ops/retype_node", {"gm":model}, {"gm":model}, callback=self._callback) else: for exm in commons.all_example_models(): for node in commons.all_nodes_with_type(exm, self._old_type): print("NodeRetype: retyping {} in {}".format(node, exm)) self.execute(exm, node, new_type, local=True) def _callback(self, model): mv.attr_assign(model, "gm/"+self._node, "typeID", self._new_type) def repair(self): """ Check if this operation invalidated any instance models. Depends on the scope: if local, need to retype all instance model nodes with the old type as well """ if self._scope == "Global": for im in commons.all_instance_models(): for node in commons.all_nodes_with_type(im, self._old_type): self.execute(im, node, self._new_type, local=True) else: pass # TODO implement