node_ops.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import sys
  2. sys.path.append("../wrappers")
  3. from wrappers import modelverse as mv
  4. import commons
  5. class NodeAdd(object):
  6. def __init__(self):
  7. self._node_type = ""
  8. def execute(self, model, node_type, local, check_if_last=False):
  9. """
  10. Add a new node with type node_type to model model.
  11. If local is true, the node is only added to the model.
  12. If local is false, the node will be added to all models.
  13. """
  14. self._node_type = node_type
  15. if local:
  16. mv.transformation_execute_MANUAL("graph_ops/add_node", {"gm":model}, {"gm":model},
  17. callback=self._callback)
  18. # Local add can make a type mandatory and therefore break conformance
  19. if check_if_last:
  20. if commons.is_type_mandatory(node_type):
  21. print("Type {} became mandatory, adding it to instance models ...".format(node_type))
  22. # local add made type mandatory, so need to add to instance models (if not exists already)
  23. for im in commons.all_instance_models():
  24. if not commons.all_nodes_with_type(im, self._node_type):
  25. self.execute(im, node_type, local=True, check_if_last=False)
  26. else:
  27. for m in commons.all_models():
  28. self.execute(m, node_type, local=True)
  29. def _callback(self, model):
  30. node_id = mv.instantiate(model, "gm/Node")
  31. mv.attr_assign(model, node_id, "typeID", self._node_type)
  32. class NodeDelete(object):
  33. def __init__(self):
  34. self._node = ""
  35. self._node_type = ""
  36. self._was_last = False
  37. def execute(self, model, node, local, check_if_last=False):
  38. self._node = node
  39. self._node_type = commons.get_node_type(model, node)
  40. if local:
  41. mv.transformation_execute_MANUAL("graph_ops/del_node", {"gm":model}, {"gm":model},
  42. callback=self._callback)
  43. if check_if_last:
  44. # check if we just deleted the last instance of the node in all example models
  45. # if yes, delete it in instance models as well to preserve their validity
  46. remaining_instances = 0
  47. for m in commons.all_example_models():
  48. remaining_instances += len(commons.all_nodes_with_type(m, self._node_type))
  49. if remaining_instances == 0:
  50. # it was indeed the last one, delete from instance models
  51. self._was_last = True
  52. for m in commons.all_instance_models():
  53. nodes_to_delete = commons.all_nodes_with_type(m, self._node_type)
  54. for node in nodes_to_delete:
  55. self.execute(m, node, local=True)
  56. else:
  57. for m in commons.all_models():
  58. nodes_to_delete = commons.all_nodes_with_type(m, self._node_type)
  59. for node in nodes_to_delete:
  60. self.execute(m, node, local=True)
  61. def was_last(self):
  62. return self._was_last
  63. def _callback(self, model):
  64. mv.delete_element(model, "gm/"+self._node)
  65. class NodeRetype(object):
  66. def __init__(self):
  67. self._node = ""
  68. self._new_type = ""
  69. def execute(self, model, node, new_type, local):
  70. """
  71. Retype the node in model to new_type.
  72. If local is true, the change only affects the single node.
  73. If local is false, the change affects all nodes in all models.
  74. """
  75. self._node = node
  76. self._new_type = new_type
  77. if local:
  78. mv.transformation_execute_MANUAL("graph_ops/retype_node", {"gm":model}, {"gm":model},
  79. callback=self._callback)
  80. else:
  81. node_type = commons.get_node_type(model, node)
  82. for m in commons.all_models():
  83. for node in commons.all_nodes_with_type(m, node_type):
  84. self.execute(m, node, new_type, local=True)
  85. def _callback(self, model):
  86. mv.attr_assign(model, "gm/"+self._node, "typeID", self._new_type)