render_OD.alc 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. include "primitives.alh"
  2. include "modelling.alh"
  3. include "object_operations.alh"
  4. include "utils.alh"
  5. Boolean function main(model : Element):
  6. Element elements
  7. String class
  8. Element attrs
  9. Element attr_keys
  10. String attr_key
  11. String group
  12. String elem
  13. Integer loc_x
  14. Integer loc_y
  15. Integer text_loc
  16. loc_x = 10
  17. loc_y = 10
  18. Element to_remove
  19. String elem_to_remove
  20. Element groups
  21. Element class_types
  22. Element metamodel
  23. metamodel = model["metamodel"]
  24. String class_type
  25. // Construct our own kind of tracability
  26. Element cs_to_as
  27. Element as_to_cs
  28. String asid
  29. cs_to_as = dict_create()
  30. as_to_cs = dict_create()
  31. groups = allInstances(model, "rendered/Group")
  32. while (set_len(groups) > 0):
  33. group = set_pop(groups)
  34. asid = read_attribute(model, group, "__asid")
  35. dict_add(cs_to_as, group, "abstract/" + asid)
  36. dict_add(as_to_cs, "abstract/" + asid, group)
  37. // Now render everything
  38. groups = dict_create()
  39. class_types = allInstances(metamodel, "Class")
  40. while (set_len(class_types) > 0):
  41. class_type = set_pop(class_types)
  42. if (string_startswith(class_type, "abstract/")):
  43. elements = allInstances(model, class_type)
  44. while (set_len(elements) > 0):
  45. class = set_pop(elements)
  46. if (is_edge(model["model"][class])):
  47. continue!
  48. Integer x
  49. Integer y
  50. x = loc_x
  51. y = loc_y
  52. // Check if there is already an associated element
  53. if (dict_in(as_to_cs, class)):
  54. // Yes, but is it still clean?
  55. Element related_groups
  56. group = as_to_cs[class]
  57. if (bool_not(read_attribute(model, group, "dirty"))):
  58. dict_add(groups, class, group)
  59. continue!
  60. else:
  61. group = as_to_cs[class]
  62. to_remove = allAssociationDestinations(model, group, "rendered/contains")
  63. x = create_value(read_attribute(model, group, "x"))
  64. y = create_value(read_attribute(model, group, "y"))
  65. while (set_len(to_remove) > 0):
  66. elem_to_remove = set_pop(to_remove)
  67. if (read_type(model, elem_to_remove) == "rendered/Group"):
  68. set_add(to_remove, elem_to_remove)
  69. else:
  70. model_delete_element(model, elem_to_remove)
  71. model_delete_element(model, group)
  72. dict_delete(as_to_cs, class)
  73. if (dict_in(groups, class)):
  74. // Already rendered this, so skip
  75. continue!
  76. text_loc = 5
  77. group = instantiate_node(model, "rendered/Group", "")
  78. instantiate_attribute(model, group, "x", x)
  79. instantiate_attribute(model, group, "y", y)
  80. instantiate_attribute(model, group, "__asid", list_read(string_split_nr(class, "/", 1), 1))
  81. instantiate_attribute(model, group, "layer", 0)
  82. dict_add(groups, class, group)
  83. loc_x = loc_x + 250
  84. if (loc_x > 2000):
  85. loc_x = 10
  86. loc_y = loc_y + 300
  87. elem = instantiate_node(model, "rendered/Rectangle", "")
  88. instantiate_attribute(model, elem, "x", 0)
  89. instantiate_attribute(model, elem, "y", 0)
  90. instantiate_attribute(model, elem, "height", 40 + set_len(getAttributes(model, class)) * 20)
  91. instantiate_attribute(model, elem, "width", 200)
  92. instantiate_attribute(model, elem, "lineWidth", 2)
  93. instantiate_attribute(model, elem, "lineColour", "black")
  94. instantiate_attribute(model, elem, "fillColour", "white")
  95. instantiate_attribute(model, elem, "layer", 1)
  96. instantiate_link(model, "rendered/contains", "", group, elem)
  97. elem = instantiate_node(model, "rendered/Text", "")
  98. instantiate_attribute(model, elem, "x", 5)
  99. instantiate_attribute(model, elem, "y", 3)
  100. instantiate_attribute(model, elem, "lineWidth", 1)
  101. instantiate_attribute(model, elem, "lineColour", "black")
  102. instantiate_attribute(model, elem, "text", string_join(cast_value(list_read(string_split_nr(class, "/", 1), 1)), " : " + cast_value(list_read(string_split_nr(read_type(model, class), "/", 1), 1))))
  103. instantiate_attribute(model, elem, "layer", 2)
  104. instantiate_link(model, "rendered/contains", "", group, elem)
  105. elem = instantiate_node(model, "rendered/Line", "")
  106. instantiate_attribute(model, elem, "x", 0)
  107. instantiate_attribute(model, elem, "y", 20)
  108. instantiate_attribute(model, elem, "targetX", 200)
  109. instantiate_attribute(model, elem, "targetY", 20)
  110. instantiate_attribute(model, elem, "lineWidth", 1)
  111. instantiate_attribute(model, elem, "lineColour", "black")
  112. instantiate_attribute(model, elem, "arrow", False)
  113. instantiate_attribute(model, elem, "layer", 2)
  114. instantiate_link(model, "rendered/contains", "", group, elem)
  115. attrs = getAttributes(model, class)
  116. attr_keys = dict_keys(attrs)
  117. while (dict_len(attr_keys) > 0):
  118. attr_key = set_pop(attr_keys)
  119. elem = instantiate_node(model, "rendered/Text", "")
  120. instantiate_attribute(model, elem, "x", 5)
  121. instantiate_attribute(model, elem, "y", text_loc + 20)
  122. instantiate_attribute(model, elem, "lineWidth", 1)
  123. instantiate_attribute(model, elem, "lineColour", "black")
  124. instantiate_attribute(model, elem, "text", (attr_key + " = ") + cast_value(attrs[attr_key]))
  125. instantiate_attribute(model, elem, "layer", 2)
  126. instantiate_link(model, "rendered/contains", "", group, elem)
  127. text_loc = text_loc + 15
  128. // Flush all associations
  129. elements = allInstances(model, "rendered/ConnectingLine")
  130. while (set_len(elements) > 0):
  131. class = set_pop(elements)
  132. model_delete_element(model, class)
  133. // Rerender associations
  134. Element to_render
  135. to_render = set_create()
  136. class_types = allInstances(metamodel, "Association")
  137. while (set_len(class_types) > 0):
  138. class_type = set_pop(class_types)
  139. log("Checking type " + class_type)
  140. if (string_startswith(class_type, "abstract/")):
  141. elements = allInstances(model, class_type)
  142. log(" Checking instance " + class)
  143. while (set_len(elements) > 0):
  144. class = set_pop(elements)
  145. if (is_edge(model["model"][class])):
  146. if (bool_not(set_in(to_render, class))):
  147. set_add(to_render, class)
  148. log("Added!")
  149. to_render = set_to_list(to_render)
  150. Element delayed_elements
  151. Integer num_to_render
  152. delayed_elements = list_create()
  153. while (list_len(to_render) > 0):
  154. num_to_render = list_len(to_render)
  155. while (list_len(to_render) > 0):
  156. class = list_pop_final(to_render)
  157. attr_keys = dict_keys(getAttributes(model, class))
  158. if (bool_not(bool_and(dict_in(groups, readAssociationSource(model, class)), dict_in(groups, readAssociationDestination(model, class))))):
  159. list_append(delayed_elements, class)
  160. continue!
  161. elem = instantiate_link(model, "rendered/ConnectingLine", "", groups[readAssociationSource(model, class)], groups[readAssociationDestination(model, class)])
  162. dict_add(groups, class, elem)
  163. if (is_edge(model["model"][readAssociationSource(model, class)])):
  164. instantiate_attribute(model, elem, "offsetSourceX", 0)
  165. instantiate_attribute(model, elem, "offsetSourceY", 0)
  166. else:
  167. instantiate_attribute(model, elem, "offsetSourceX", 100)
  168. instantiate_attribute(model, elem, "offsetSourceY", 30)
  169. if (is_edge(model["model"][readAssociationDestination(model, class)])):
  170. instantiate_attribute(model, elem, "offsetTargetX", 0)
  171. instantiate_attribute(model, elem, "offsetTargetY", 0)
  172. else:
  173. instantiate_attribute(model, elem, "offsetTargetX", 100)
  174. instantiate_attribute(model, elem, "offsetTargetY", 30)
  175. instantiate_attribute(model, elem, "lineWidth", 3)
  176. instantiate_attribute(model, elem, "lineColour", "black")
  177. instantiate_attribute(model, elem, "arrow", True)
  178. instantiate_attribute(model, elem, "__asid", list_read(string_split_nr(class, "/", 1), 1))
  179. instantiate_attribute(model, elem, "layer", 0)
  180. instantiate_link(model, "rendered/contains", "", group, elem)
  181. if (num_to_render == list_len(delayed_elements)):
  182. log("Could not decrease number of rendered elements anymore... Giving up!")
  183. return True!
  184. else:
  185. to_render = delayed_elements
  186. delayed_elements = list_create()
  187. return True!