include "primitives.alh" include "modelling.alh" include "object_operations.alh" include "utils.alh" Boolean function main(model : Element): Element elements String class Element attrs Element attr_keys String attr_key String group String elem Integer loc_x Integer loc_y Integer text_loc loc_x = 10 loc_y = 10 Element to_remove String elem_to_remove Element groups Element class_types Element metamodel metamodel = model["metamodel"] String class_type // Construct our own kind of tracability Element cs_to_as Element as_to_cs String asid cs_to_as = dict_create() as_to_cs = dict_create() groups = allInstances(model, "rendered/Group") while (set_len(groups) > 0): group = set_pop(groups) asid = read_attribute(model, group, "__asid") dict_add(cs_to_as, group, "abstract/" + asid) dict_add(as_to_cs, "abstract/" + asid, group) // Now render everything groups = dict_create() class_types = allInstances(metamodel, "Class") while (set_len(class_types) > 0): class_type = set_pop(class_types) if (string_startswith(class_type, "abstract/")): elements = allInstances(model, class_type) while (set_len(elements) > 0): class = set_pop(elements) if (is_edge(model["model"][class])): continue! Integer x Integer y x = loc_x y = loc_y // Check if there is already an associated element if (dict_in(as_to_cs, class)): // Yes, but is it still clean? Element related_groups group = as_to_cs[class] if (bool_not(read_attribute(model, group, "dirty"))): dict_add(groups, class, group) continue! else: group = as_to_cs[class] to_remove = allAssociationDestinations(model, group, "rendered/contains") x = create_value(read_attribute(model, group, "x")) y = create_value(read_attribute(model, group, "y")) while (set_len(to_remove) > 0): elem_to_remove = set_pop(to_remove) if (read_type(model, elem_to_remove) == "rendered/Group"): set_add(to_remove, elem_to_remove) else: model_delete_element(model, elem_to_remove) model_delete_element(model, group) dict_delete(as_to_cs, class) if (dict_in(groups, class)): // Already rendered this, so skip continue! text_loc = 5 group = instantiate_node(model, "rendered/Group", "") instantiate_attribute(model, group, "x", x) instantiate_attribute(model, group, "y", y) instantiate_attribute(model, group, "__asid", list_read(string_split_nr(class, "/", 1), 1)) instantiate_attribute(model, group, "layer", 0) dict_add(groups, class, group) loc_x = loc_x + 250 if (loc_x > 2000): loc_x = 10 loc_y = loc_y + 300 elem = instantiate_node(model, "rendered/Rectangle", "") instantiate_attribute(model, elem, "x", 0) instantiate_attribute(model, elem, "y", 0) instantiate_attribute(model, elem, "height", 40 + set_len(getAttributes(model, class)) * 20) instantiate_attribute(model, elem, "width", 200) instantiate_attribute(model, elem, "lineWidth", 2) instantiate_attribute(model, elem, "lineColour", "black") instantiate_attribute(model, elem, "fillColour", "white") instantiate_attribute(model, elem, "layer", 1) instantiate_link(model, "rendered/contains", "", group, elem) elem = instantiate_node(model, "rendered/Text", "") instantiate_attribute(model, elem, "x", 5) instantiate_attribute(model, elem, "y", 3) instantiate_attribute(model, elem, "lineWidth", 1) instantiate_attribute(model, elem, "lineColour", "black") 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)))) instantiate_attribute(model, elem, "layer", 2) instantiate_link(model, "rendered/contains", "", group, elem) elem = instantiate_node(model, "rendered/Line", "") instantiate_attribute(model, elem, "x", 0) instantiate_attribute(model, elem, "y", 20) instantiate_attribute(model, elem, "targetX", 200) instantiate_attribute(model, elem, "targetY", 20) instantiate_attribute(model, elem, "lineWidth", 1) instantiate_attribute(model, elem, "lineColour", "black") instantiate_attribute(model, elem, "arrow", False) instantiate_attribute(model, elem, "layer", 2) instantiate_link(model, "rendered/contains", "", group, elem) attrs = getAttributes(model, class) attr_keys = dict_keys(attrs) while (dict_len(attr_keys) > 0): attr_key = set_pop(attr_keys) elem = instantiate_node(model, "rendered/Text", "") instantiate_attribute(model, elem, "x", 5) instantiate_attribute(model, elem, "y", text_loc + 20) instantiate_attribute(model, elem, "lineWidth", 1) instantiate_attribute(model, elem, "lineColour", "black") instantiate_attribute(model, elem, "text", (attr_key + " = ") + cast_value(attrs[attr_key])) instantiate_attribute(model, elem, "layer", 2) instantiate_link(model, "rendered/contains", "", group, elem) text_loc = text_loc + 15 // Flush all associations elements = allInstances(model, "rendered/ConnectingLine") while (set_len(elements) > 0): class = set_pop(elements) model_delete_element(model, class) // Rerender associations Element to_render to_render = set_create() class_types = allInstances(metamodel, "Association") while (set_len(class_types) > 0): class_type = set_pop(class_types) log("Checking type " + class_type) if (string_startswith(class_type, "abstract/")): elements = allInstances(model, class_type) log(" Checking instance " + class) while (set_len(elements) > 0): class = set_pop(elements) if (is_edge(model["model"][class])): if (bool_not(set_in(to_render, class))): set_add(to_render, class) log("Added!") to_render = set_to_list(to_render) Element delayed_elements Integer num_to_render delayed_elements = list_create() while (list_len(to_render) > 0): num_to_render = list_len(to_render) while (list_len(to_render) > 0): class = list_pop_final(to_render) attr_keys = dict_keys(getAttributes(model, class)) if (bool_not(bool_and(dict_in(groups, readAssociationSource(model, class)), dict_in(groups, readAssociationDestination(model, class))))): list_append(delayed_elements, class) continue! elem = instantiate_link(model, "rendered/ConnectingLine", "", groups[readAssociationSource(model, class)], groups[readAssociationDestination(model, class)]) dict_add(groups, class, elem) if (is_edge(model["model"][readAssociationSource(model, class)])): instantiate_attribute(model, elem, "offsetSourceX", 0) instantiate_attribute(model, elem, "offsetSourceY", 0) else: instantiate_attribute(model, elem, "offsetSourceX", 100) instantiate_attribute(model, elem, "offsetSourceY", 30) if (is_edge(model["model"][readAssociationDestination(model, class)])): instantiate_attribute(model, elem, "offsetTargetX", 0) instantiate_attribute(model, elem, "offsetTargetY", 0) else: instantiate_attribute(model, elem, "offsetTargetX", 100) instantiate_attribute(model, elem, "offsetTargetY", 30) instantiate_attribute(model, elem, "lineWidth", 3) instantiate_attribute(model, elem, "lineColour", "black") instantiate_attribute(model, elem, "arrow", True) instantiate_attribute(model, elem, "__asid", list_read(string_split_nr(class, "/", 1), 1)) instantiate_attribute(model, elem, "layer", 0) instantiate_link(model, "rendered/contains", "", group, elem) if (num_to_render == list_len(delayed_elements)): log("Could not decrease number of rendered elements anymore... Giving up!") return True! else: to_render = delayed_elements delayed_elements = list_create() return True!