Pārlūkot izejas kodu

Semi-working object diagrams visualization

Yentl Van Tendeloo 8 gadi atpakaļ
vecāks
revīzija
682ddafc54

+ 1 - 0
classes/canvas/canvas.xml

@@ -98,6 +98,7 @@
                     target_y = self.group_location[element['__target']][1] + element['offsetTargetY']
                     middle_x = (source_x + target_x) / 2
                     middle_y = (source_y + target_y) / 2
+                    self.group_location[element['id']] = (middle_x, middle_y)
 
                     self.connecting_lines.setdefault(element['__source'], []).append(element)
                     self.connecting_lines.setdefault(element['__target'], []).append(element)

+ 3 - 0
classes/canvas/canvas_element.xml

@@ -141,6 +141,9 @@
                     <raise event="start_instance" scope="cd">
                         <parameter expr="name"/>
                     </raise>
+                    <script>
+                        self.remaining_responses = 0
+                    </script>
                 </transition>
             </state>
 

+ 8 - 1
classes/window/main_window.xml

@@ -159,6 +159,8 @@
                             self.context = context
                         </script>
                     </transition>
+
+                    <transition event="mv_exception" target="../../idle"/>
                 </state>
 
                 <state id="modify_render_OD" initial="exit">
@@ -181,7 +183,12 @@
                             </raise>
                         </onentry>
 
-                        <transition event="mv_response" target="../../../open_model/search_CS_mappers"/>
+                        <transition event="mv_response" target="../../../open_model/search_CS_mappers">
+                            <script>
+                                global current_mapper
+                                current_mapper = 'models/render_OD/' + current_metamodel
+                            </script>
+                        </transition>
                     </state>
                 </state>
             </state>

+ 11 - 1
frontend.py

@@ -1,7 +1,7 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-Date:   Thu Oct  5 10:31:58 2017
+Date:   Thu Oct  5 14:27:18 2017
 
 Model author: Yentl Van Tendeloo
 Model name:   Modelverse Visual Editor - Tkinter Version 
@@ -4382,9 +4382,13 @@ class MainWindow(RuntimeClassBase, tk.Toplevel, SCCDWidget):
         _running_add_object_diagrams_init_0.setAction(self._running_add_object_diagrams_init_0_exec)
         _running_add_object_diagrams_init_0.setTrigger(Event("mv_response", None))
         self.states["/running/add_object_diagrams/init"].addTransition(_running_add_object_diagrams_init_0)
+        _running_add_object_diagrams_init_1 = Transition(self, self.states["/running/add_object_diagrams/init"], [self.states["/running/idle"]])
+        _running_add_object_diagrams_init_1.setTrigger(Event("mv_exception", None))
+        self.states["/running/add_object_diagrams/init"].addTransition(_running_add_object_diagrams_init_1)
         
         # transition /running/add_object_diagrams/modify_render_OD/exit
         _running_add_object_diagrams_modify_render_OD_exit_0 = Transition(self, self.states["/running/add_object_diagrams/modify_render_OD/exit"], [self.states["/running/open_model/search_CS_mappers"]])
+        _running_add_object_diagrams_modify_render_OD_exit_0.setAction(self._running_add_object_diagrams_modify_render_OD_exit_0_exec)
         _running_add_object_diagrams_modify_render_OD_exit_0.setTrigger(Event("mv_response", None))
         self.states["/running/add_object_diagrams/modify_render_OD/exit"].addTransition(_running_add_object_diagrams_modify_render_OD_exit_0)
         
@@ -4886,6 +4890,10 @@ class MainWindow(RuntimeClassBase, tk.Toplevel, SCCDWidget):
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'progress_bar', Event("update_status", None, [25, 'Switching contexts...'])]))
         self.context = context
     
+    def _running_add_object_diagrams_modify_render_OD_exit_0_exec(self, parameters):
+        global current_mapper
+        current_mapper = 'models/render_OD/' + current_metamodel
+    
     def _running_upload_MVC_load_code_0_exec(self, parameters):
         self.big_step.outputEventOM(Event("broad_cast", None, [self, Event("mv_request", None, ['model_overwrite', [current_model, open(self.filename, 'r').read()]])]))
         self.big_step.outputEventOM(Event("narrow_cast", None, [self, 'progress_bar', Event("update_status", None, [10, 'Uploading model...'])]))
@@ -7211,6 +7219,7 @@ class Canvas(RuntimeClassBase, tk.Canvas, SCCDWidget):
         target_y = self.group_location[element['__target']][1] + element['offsetTargetY']
         middle_x = (source_x + target_x) / 2
         middle_y = (source_y + target_y) / 2
+        self.group_location[element['id']] = (middle_x, middle_y)
         
         self.connecting_lines.setdefault(element['__source'], []).append(element)
         self.connecting_lines.setdefault(element['__target'], []).append(element)
@@ -7530,6 +7539,7 @@ class CanvasElement(RuntimeClassBase, SCCDWidget):
     def _update_attrs_prompt_0_exec(self, parameters):
         name = parameters[0]
         self.big_step.outputEventOM(Event("start_instance", None, [self, name]))
+        self.remaining_responses = 0
     
     def _update_attrs_wait_for_results_0_exec(self, parameters):
         results = parameters[0]

+ 0 - 1
icons/object_diagrams.png


BIN
icons/object_diagrams.png


+ 143 - 98
models/render_OD.alc

@@ -10,9 +10,11 @@ Boolean function main(model : Element):
 	String attr_key
 	String group
 	String elem
-	Integer loc
+	Integer loc_x
+	Integer loc_y
 	Integer text_loc
-	loc = 10
+	loc_x = 10
+	loc_y = 10
 
 	Element to_remove
 	String elem_to_remove
@@ -41,102 +43,115 @@ Boolean function main(model : Element):
 	while (set_len(class_types) > 0):
 		class_type = set_pop(class_types)
 
-		elements = allInstances(model, class_type)
-
-		while (set_len(elements) > 0):
-			class = set_pop(elements)
-			
-			Integer x
-			Integer y
-			x = loc
-			y = 10
-
-			// Check if there is already an associated element
-			if (dict_in(as_to_cs, class)):
-				// Yes, but is it still clean?
-				Element related_groups
-				Boolean dirty
-				dirty = False
-
-				related_groups = as_to_cs[class]
-				while (set_len(related_groups) > 0):
-					group = set_pop(related_groups)
-					if (value_eq(read_attribute(model, group, "dirty"), True)):
-						// No, so mark all as dirty
-						dirty = True
-						break!
-					else:
-						// Yes, so just ignore this!
-						continue!
+		if (string_startswith(class_type, "abstract/")):
+			elements = allInstances(model, class_type)
+
+			while (set_len(elements) > 0):
+				class = set_pop(elements)
 
-				if (bool_not(dirty)):
-					dict_add(groups, class, group)
+				if (is_edge(model["model"][class])):
+					log("Skipping edge " + class)
 					continue!
-				else:
-					group = as_to_cs[class]
-					group = set_pop(related_groups)
-					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)
+				log("Drawing " + class)
+				
+				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
+					Boolean dirty
+					dirty = False
+
+					related_groups = as_to_cs[class]
+					while (set_len(related_groups) > 0):
+						group = set_pop(related_groups)
+						if (value_eq(read_attribute(model, group, "dirty"), True)):
+							// No, so mark all as dirty
+							dirty = True
+							break!
 						else:
-							model_delete_element(model, elem_to_remove)
-					model_delete_element(model, group)
-
-			attr_keys = dict_keys(getAttributeList(model, class))
-			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(class, "/"), 1))
-			dict_add(groups, class, group)
-			loc = loc + 200
-
-			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(getAttributeList(model, class)) * 20)
-			instantiate_attribute(model, elem, "width", 150)
-			instantiate_attribute(model, elem, "lineWidth", 2) 
-			instantiate_attribute(model, elem, "lineColour", "black")
-			instantiate_attribute(model, elem, "fillColour", "white")
-			instantiate_link(model, "rendered/contains", "", group, elem)
+							// Yes, so just ignore this!
+							continue!
 
-			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(class, " : " + cast_v2s(list_read(string_split(read_type(model, class), "/"), 1))))
-			instantiate_link(model, "rendered/contains", "", group, elem)
+					if (bool_not(dirty)):
+						dict_add(groups, class, group)
+						continue!
+					else:
+						group = as_to_cs[class]
+						group = set_pop(related_groups)
+						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)
+
+				if (dict_in(groups, class)):
+					// Already rendered this, so skip
+					continue!
 
-			elem = instantiate_node(model, "rendered/Line", "")
-			instantiate_attribute(model, elem, "x", 0)
-			instantiate_attribute(model, elem, "y", 20)
-			instantiate_attribute(model, elem, "targetX", 150)
-			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_link(model, "rendered/contains", "", group, elem)
+				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(class, "/"), 1))
+				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_link(model, "rendered/contains", "", group, elem)
 
-			attrs = getAttributeList(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, "y", 3)
 				instantiate_attribute(model, elem, "lineWidth", 1)
 				instantiate_attribute(model, elem, "lineColour", "black")
-				instantiate_attribute(model, elem, "text", (attr_key + " = ") + cast_v2s(list_read(string_split(attrs[attr_key], "/"), 1)))
+				instantiate_attribute(model, elem, "text", string_join(cast_v2s(list_read(string_split(class, "/"), 1)), " : " + cast_v2s(list_read(string_split(read_type(model, class), "/"), 1))))
 				instantiate_link(model, "rendered/contains", "", group, elem)
-				text_loc = text_loc + 15
+
+				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_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_v2s(attrs[attr_key]))
+					instantiate_link(model, "rendered/contains", "", group, elem)
+					text_loc = text_loc + 15
 
 	// Flush all associations
 	elements = allInstances(model, "rendered/ConnectingLine")
@@ -145,25 +160,55 @@ Boolean function main(model : Element):
 		model_delete_element(model, class)
 
 	// Rerender associations
-	class_types = allInstances(metamodel, "Association")
+	Element to_render
+	to_render = set_create()
+	class_types = allInstances(metamodel, "Class")
 	while (set_len(class_types) > 0):
 		class_type = set_pop(class_types)
 
-		elements = allInstances(model, "abstract/Association")
-		while (set_len(elements) > 0):
-			class = set_pop(elements)
-
-			attr_keys = dict_keys(getAttributeList(model, class))
+		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])):
+					if (bool_not(set_in(to_render, class))):
+						set_add(to_render, class)
+
+	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))
+
+			log("Association: " + class)
+			log("Connects " + cast_v2s(readAssociationSource(model, class)))
+			log("      to " + cast_v2s(readAssociationDestination(model, class)))
+			if (bool_not(bool_and(dict_in(groups, readAssociationSource(model, class)), dict_in(groups, readAssociationDestination(model, class))))):
+				log("DELAY")
+				list_append(delayed_elements, class)
+				continue!
 
 			elem = instantiate_link(model, "rendered/ConnectingLine", "", groups[readAssociationSource(model, class)], groups[readAssociationDestination(model, class)])
-			instantiate_attribute(model, elem, "offsetSourceX", 0)
-			instantiate_attribute(model, elem, "offsetSourceY", 0)
-			instantiate_attribute(model, elem, "offsetTargetX", 0)
-			instantiate_attribute(model, elem, "offsetTargetY", 0)
-			instantiate_attribute(model, elem, "lineWidth", 1)
+			dict_add(groups, class, elem)
+			instantiate_attribute(model, elem, "offsetSourceX", 100)
+			instantiate_attribute(model, elem, "offsetSourceY", 50)
+			instantiate_attribute(model, elem, "offsetTargetX", 100)
+			instantiate_attribute(model, elem, "offsetTargetY", 50)
+			instantiate_attribute(model, elem, "lineWidth", 4)
 			instantiate_attribute(model, elem, "lineColour", "black")
 			instantiate_attribute(model, elem, "arrow", True)
 			instantiate_attribute(model, elem, "__asid", list_read(string_split(class, "/"), 1))
 			instantiate_link(model, "rendered/contains", "", group, elem)
 
+		if (num_to_render == list_len(delayed_elements)):
+			log("Could not decrease number of rendered elements anymore...")
+			return True!
+		else:
+			to_render = delayed_elements
+			delayed_elements = list_create()
+
 	return True!