Browse Source

Semi-working object diagrams visualization

Yentl Van Tendeloo 8 years ago
parent
commit
682ddafc54

+ 1 - 0
classes/canvas/canvas.xml

@@ -98,6 +98,7 @@
                     target_y = self.group_location[element['__target']][1] + element['offsetTargetY']
                     target_y = self.group_location[element['__target']][1] + element['offsetTargetY']
                     middle_x = (source_x + target_x) / 2
                     middle_x = (source_x + target_x) / 2
                     middle_y = (source_y + target_y) / 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['__source'], []).append(element)
                     self.connecting_lines.setdefault(element['__target'], []).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">
                     <raise event="start_instance" scope="cd">
                         <parameter expr="name"/>
                         <parameter expr="name"/>
                     </raise>
                     </raise>
+                    <script>
+                        self.remaining_responses = 0
+                    </script>
                 </transition>
                 </transition>
             </state>
             </state>
 
 

+ 8 - 1
classes/window/main_window.xml

@@ -159,6 +159,8 @@
                             self.context = context
                             self.context = context
                         </script>
                         </script>
                     </transition>
                     </transition>
+
+                    <transition event="mv_exception" target="../../idle"/>
                 </state>
                 </state>
 
 
                 <state id="modify_render_OD" initial="exit">
                 <state id="modify_render_OD" initial="exit">
@@ -181,7 +183,12 @@
                             </raise>
                             </raise>
                         </onentry>
                         </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>
                 </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)
 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 author: Yentl Van Tendeloo
 Model name:   Modelverse Visual Editor - Tkinter Version 
 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.setAction(self._running_add_object_diagrams_init_0_exec)
         _running_add_object_diagrams_init_0.setTrigger(Event("mv_response", None))
         _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)
         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
         # 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 = 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))
         _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)
         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.big_step.outputEventOM(Event("narrow_cast", None, [self, 'progress_bar', Event("update_status", None, [25, 'Switching contexts...'])]))
         self.context = context
         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):
     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("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...'])]))
         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']
         target_y = self.group_location[element['__target']][1] + element['offsetTargetY']
         middle_x = (source_x + target_x) / 2
         middle_x = (source_x + target_x) / 2
         middle_y = (source_y + target_y) / 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['__source'], []).append(element)
         self.connecting_lines.setdefault(element['__target'], []).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):
     def _update_attrs_prompt_0_exec(self, parameters):
         name = parameters[0]
         name = parameters[0]
         self.big_step.outputEventOM(Event("start_instance", None, [self, name]))
         self.big_step.outputEventOM(Event("start_instance", None, [self, name]))
+        self.remaining_responses = 0
     
     
     def _update_attrs_wait_for_results_0_exec(self, parameters):
     def _update_attrs_wait_for_results_0_exec(self, parameters):
         results = parameters[0]
         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 attr_key
 	String group
 	String group
 	String elem
 	String elem
-	Integer loc
+	Integer loc_x
+	Integer loc_y
 	Integer text_loc
 	Integer text_loc
-	loc = 10
+	loc_x = 10
+	loc_y = 10
 
 
 	Element to_remove
 	Element to_remove
 	String elem_to_remove
 	String elem_to_remove
@@ -41,102 +43,115 @@ Boolean function main(model : Element):
 	while (set_len(class_types) > 0):
 	while (set_len(class_types) > 0):
 		class_type = set_pop(class_types)
 		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!
 					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:
 						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", "")
 				elem = instantiate_node(model, "rendered/Text", "")
 				instantiate_attribute(model, elem, "x", 5)
 				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, "lineWidth", 1)
 				instantiate_attribute(model, elem, "lineColour", "black")
 				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)
 				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
 	// Flush all associations
 	elements = allInstances(model, "rendered/ConnectingLine")
 	elements = allInstances(model, "rendered/ConnectingLine")
@@ -145,25 +160,55 @@ Boolean function main(model : Element):
 		model_delete_element(model, class)
 		model_delete_element(model, class)
 
 
 	// Rerender associations
 	// 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):
 	while (set_len(class_types) > 0):
 		class_type = set_pop(class_types)
 		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)])
 			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, "lineColour", "black")
 			instantiate_attribute(model, elem, "arrow", True)
 			instantiate_attribute(model, elem, "arrow", True)
 			instantiate_attribute(model, elem, "__asid", list_read(string_split(class, "/"), 1))
 			instantiate_attribute(model, elem, "__asid", list_read(string_split(class, "/"), 1))
 			instantiate_link(model, "rendered/contains", "", group, elem)
 			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!
 	return True!