浏览代码

Semi-working transformation_execute and transformation_add

Yentl Van Tendeloo 7 年之前
父节点
当前提交
64872119dd

二进制
bootstrap/bootstrap.m.gz


+ 101 - 69
bootstrap/core_algorithm.alc

@@ -704,14 +704,10 @@ Element function execute_operation(operation_id : String, input_models : Element
 		while (get_entry_id(model_name) != ""):
 		while (get_entry_id(model_name) != ""):
 			model_name = ".tmp/" + random_string(20)
 			model_name = ".tmp/" + random_string(20)
 		model_create(merged_model, model_name, merged_metamodel_id, "Model")
 		model_create(merged_model, model_name, merged_metamodel_id, "Model")
-		output("Operating on: " + cast_string(model_name))
+		log("Transforming...")
 		// We want to modify, so modify
 		// We want to modify, so modify
-		if (modify(merged_model, True)):
-			// Overwrite the merged model
-			model_overwrite(merged_model, get_entry_id(model_name), merged_metamodel_id)
-		else:
-			// Reload the merged model
-			merged_model = get_full_model(get_entry_id(model_name), merged_metamodel_id)
+		do_spawn_modify(model_name, True)
+		merged_model = get_full_model(get_entry_id(model_name), merged_metamodel_id)
 		//model_delete(get_entry_id(model_name))
 		//model_delete(get_entry_id(model_name))
 		result = True
 		result = True
 	elif (exact_type == "ActionLanguage"):
 	elif (exact_type == "ActionLanguage"):
@@ -949,9 +945,6 @@ Void function enact_PM(pm : Element, mapping : Element):
 				// Execute a transformation
 				// Execute a transformation
 				// This the difficult part!
 				// This the difficult part!
 
 
-				//result = enact_action(pm, element, mapping)
-				//output("Success")
-
 				Element args
 				Element args
 				String taskname
 				String taskname
 				args = list_create()
 				args = list_create()
@@ -1346,6 +1339,97 @@ String function cmd_model_render(model_name : String, mapper_name : String, rend
 	else:
 	else:
 		return "Model not found: " + model_name!
 		return "Model not found: " + model_name!
 
 
+Boolean function do_spawn_modify(model_name : String, write : Boolean):
+	log("Spawned task for " + model_name)
+	log("Taskname: " + get_taskname())
+	output("Please edit this model before sending next input: " + model_name)
+	log("OK, waiting for input")
+	input()
+	log("SPAWN MODIFY ENDED")
+	return False!
+
+Boolean function do_spawn_activity(transformation_id : String, tracability_name : String, inputs : Element, outputs : Element, output_map : Element):
+	Element lst
+	Element returnvalue
+	String taskname
+
+	lst = list_create()
+	returnvalue = set_create()
+	list_append(lst, returnvalue)
+	list_append(lst, transformation_id)
+	list_append(lst, tracability_name)
+	list_append(lst, inputs)
+	list_append(lst, outputs)
+	list_append(lst, output_map)
+	taskname = spawn(spawn_activity, lst)
+
+	output("Spawned activity on task: " + taskname)
+	log("Spawned activity")
+
+	while (set_len(returnvalue) == 0):
+		sleep(0.1)
+
+	log("Activity terminated!")
+	output("Finished task: " + taskname)
+	return cast_boolean(set_pop(returnvalue))!
+
+Void function spawn_activity(returnvalue : Element, transformation_id : String, tracability_name : String, inputs : Element, outputs : Element, output_map : Element):
+	Element result
+	Element keys
+	String key
+
+	if (read_type(core, transformation_id) == "ActionLanguage"):
+		output("Success: ready for AL execution")
+	elif (read_type(core, transformation_id) == "ManualOperation"):
+		output("Success: ready for MANUAL execution")
+	else:
+		output("Success: ready for MT execution")
+
+	// Do tracability
+	Element tracability_model
+	if (tracability_name != ""):
+		// Check if exists
+		if (get_entry_id(tracability_name) == ""):
+			// No, so create
+			tracability_model = instantiate_model(get_full_model(get_entry_id("formalisms/Tracability"), get_entry_id("formalisms/SimpleClassDiagrams")))
+			model_create(tracability_model, tracability_name, get_entry_id("formalisms/Tracability"), "Model")
+		else:
+			// Yes, so read out
+			tracability_model = get_full_model(get_entry_id(tracability_name), get_entry_id("formalisms/Tracability"))
+	else:
+		tracability_model = read_root()
+
+	result = execute_operation(transformation_id, inputs, tracability_model)
+
+	// Flush tracability again, just to be sure
+	if (tracability_name != ""):
+		model_overwrite(tracability_model, get_entry_id(tracability_name), get_entry_id("formalisms/Tracability"))
+
+	// Now write out the models again
+	if (element_eq(result, read_root())):
+		// Something went wrong!
+		set_add(returnvalue, False)
+		output("Failure")
+	else:
+		keys = dict_keys(outputs)
+		while (set_len(keys) > 0):
+			key = set_pop(keys)
+			log("Writing away model with key " + cast_string(key))
+			log("Output map: " + dict_to_string(output_map))
+			log("Outputs: " + dict_to_string(outputs))
+			
+			if (get_entry_id(outputs[key]) == ""):
+				// New model
+				model_create(result[key], outputs[key], get_entry_id(output_map[key]), "Model")
+			else:
+				model_overwrite(result[key], get_entry_id(outputs[key]), get_entry_id(output_map[key]))
+
+		set_add(returnvalue, True)
+		output("Success")
+
+	sleep(5)
+	return!
+
 String function cmd_transformation_execute(transformation_name : String, source_models : Element, target_models : Element, tracability_name : String):
 String function cmd_transformation_execute(transformation_name : String, source_models : Element, target_models : Element, tracability_name : String):
 	// Execute a transformation, whatever type it is
 	// Execute a transformation, whatever type it is
 	// First we detect the type, so we know how to prepare for invocation
 	// First we detect the type, so we know how to prepare for invocation
@@ -1362,9 +1446,6 @@ String function cmd_transformation_execute(transformation_name : String, source_
 	String target_model_name
 	String target_model_name
 	String source_model_name
 	String source_model_name
 	String source_model_ID
 	String source_model_ID
-	Element result
-	Element keys
-	String key
 	String assoc_name
 	String assoc_name
 
 
 	transformation_id = get_entry_id(transformation_name)
 	transformation_id = get_entry_id(transformation_name)
@@ -1421,54 +1502,10 @@ String function cmd_transformation_execute(transformation_name : String, source_
 							else:
 							else:
 								return "Permission denied to model: " + target_model_name!
 								return "Permission denied to model: " + target_model_name!
 
 
-				if (read_type(core, transformation_id) == "ActionLanguage"):
-					output("Success: ready for AL execution")
-				elif (read_type(core, transformation_id) == "ManualOperation"):
-					output("Success: ready for MANUAL execution")
-				else:
-					output("Success: ready for MT execution")
-
-				// Do tracability
-				Element tracability_model
-				if (tracability_name != ""):
-					// Check if exists
-					if (get_entry_id(tracability_name) == ""):
-						// No, so create
-						tracability_model = instantiate_model(get_full_model(get_entry_id("formalisms/Tracability"), get_entry_id("formalisms/SimpleClassDiagrams")))
-						model_create(tracability_model, tracability_name, get_entry_id("formalisms/Tracability"), "Model")
-					else:
-						// Yes, so read out
-						tracability_model = get_full_model(get_entry_id(tracability_name), get_entry_id("formalisms/Tracability"))
+				if (do_spawn_activity(transformation_id, tracability_name, inputs, outputs, output_map)):
+					return "Success"!
 				else:
 				else:
-					tracability_model = read_root()
-
-				result = execute_operation(transformation_id, inputs, tracability_model)
-
-				// Flush tracability again, just to be sure
-				if (tracability_name != ""):
-					model_overwrite(tracability_model, get_entry_id(tracability_name), get_entry_id("formalisms/Tracability"))
-
-				// Now write out the models again
-				if (element_eq(result, read_root())):
-					// Something went wrong!
 					return "Failure"!
 					return "Failure"!
-				else:
-					keys = dict_keys(outputs)
-					while (set_len(keys) > 0):
-						key = set_pop(keys)
-						log("Writing away model with key " + cast_string(key))
-						log("Output map: " + dict_to_string(output_map))
-						log("Outputs: " + dict_to_string(outputs))
-						
-						if (get_entry_id(outputs[key]) == ""):
-							// New model
-							log("New model!")
-							model_create(result[key], outputs[key], get_entry_id(output_map[key]), "Model")
-						else:
-							log("Existing model!")
-							model_overwrite(result[key], get_entry_id(outputs[key]), get_entry_id(output_map[key]))
-
-					return "Success"!
 			else:
 			else:
 				return "Model is not executable: " + transformation_name!
 				return "Model is not executable: " + transformation_name!
 		else:
 		else:
@@ -1518,6 +1555,7 @@ String function cmd_model_overwrite(model_name : String, metamodel_name : String
 				if (element_eq(mm, read_root())):
 				if (element_eq(mm, read_root())):
 					return "Metamodel does not conform to formalisms/SimpleClassDiagrams: " + metamodel_name!
 					return "Metamodel does not conform to formalisms/SimpleClassDiagrams: " + metamodel_name!
 
 
+				log("Overwriting...")
 				output("Waiting for model constructors...")
 				output("Waiting for model constructors...")
 				new_model = compile_model(input(), mm)
 				new_model = compile_model(input(), mm)
 
 
@@ -1730,11 +1768,8 @@ String function transformation_add(source_models : Element, target_models : Elem
 		if (dict_len(source_models) + dict_len(target_models) > 0):
 		if (dict_len(source_models) + dict_len(target_models) > 0):
 			merged_formalism = model_fuse(formalism_map)
 			merged_formalism = model_fuse(formalism_map)
 			model_create(merged_formalism, "merged/" + operation_name, get_entry_id("formalisms/SimpleClassDiagrams"), "Model")
 			model_create(merged_formalism, "merged/" + operation_name, get_entry_id("formalisms/SimpleClassDiagrams"), "Model")
-			output("Operating on: merged/" + operation_name)
-			if (modify(merged_formalism, True)):
-				model_overwrite(merged_formalism, get_entry_id("merged/" + operation_name), get_entry_id("formalisms/SimpleClassDiagrams"))
-			else:
-				merged_formalism = get_full_model(get_entry_id("merged/" + operation_name), get_entry_id("formalisms/SimpleClassDiagrams"))
+			do_spawn_modify("merged/" + operation_name, True)
+			merged_formalism = get_full_model(get_entry_id("merged/" + operation_name), get_entry_id("formalisms/SimpleClassDiagrams"))
 
 
 		if (operation_type == "manual"):
 		if (operation_type == "manual"):
 			if (dict_len(source_models) + dict_len(target_models) == 0):
 			if (dict_len(source_models) + dict_len(target_models) == 0):
@@ -1880,11 +1915,8 @@ String function cmd_transformation_add_MT(source_models : Element, target_models
 
 
 	merged_formalism = model_fuse(to_ramify)
 	merged_formalism = model_fuse(to_ramify)
 	model_create(merged_formalism, "merged/" + operation_name, get_entry_id("formalisms/SimpleClassDiagrams"), "Model")
 	model_create(merged_formalism, "merged/" + operation_name, get_entry_id("formalisms/SimpleClassDiagrams"), "Model")
-	output("Operating on: merged/" + operation_name)
-	if (modify(merged_formalism, True)):
-		model_overwrite(merged_formalism, get_entry_id("merged/" + operation_name), get_entry_id("formalisms/SimpleClassDiagrams"))
-	else:
-		merged_formalism = get_full_model(get_entry_id("merged/" + operation_name), get_entry_id("formalisms/SimpleClassDiagrams"))
+	do_spawn_modify("merged/" + operation_name, True)
+	merged_formalism = get_full_model(get_entry_id("merged/" + operation_name), get_entry_id("formalisms/SimpleClassDiagrams"))
 	model_overwrite(merged_formalism, get_entry_id("merged/" + operation_name), get_entry_id("formalisms/SimpleClassDiagrams"))
 	model_overwrite(merged_formalism, get_entry_id("merged/" + operation_name), get_entry_id("formalisms/SimpleClassDiagrams"))
 
 
 	ramified_metamodel = ramify(merged_formalism)
 	ramified_metamodel = ramify(merged_formalism)

+ 0 - 1
bootstrap/random.alc

@@ -24,7 +24,6 @@ Integer function random_interval(a : Integer, b : Integer):
 	if (a == b):
 	if (a == b):
 		return a!
 		return a!
 	else:
 	else:
-		log("Random gives us: " + cast_value(random()))
 		return cast_integer(random() * cast_float(b - a + 1) + cast_float(a))!
 		return cast_integer(random() * cast_float(b - a + 1) + cast_float(a))!
 
 
 Element function random_choice(list : Element):
 Element function random_choice(list : Element):

+ 1 - 0
scripts/run_local_modelverse.py

@@ -32,6 +32,7 @@ try:
     server = subprocess.Popen(program_to_execute)
     server = subprocess.Popen(program_to_execute)
 
 
     server.wait()
     server.wait()
+
 finally:
 finally:
     # Stop the server
     # Stop the server
     try:
     try:

+ 8 - 2
unit/log_output.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:   Fri Nov 10 08:52:06 2017
+Date:   Mon Nov 13 12:46:02 2017
 
 
 Model author: Yentl Van Tendeloo
 Model author: Yentl Van Tendeloo
 Model name:   Logging
 Model name:   Logging
@@ -65,6 +65,7 @@ class Logging(RuntimeClassBase):
         _init_1.setTrigger(Event("_0after"))
         _init_1.setTrigger(Event("_0after"))
         self.states["/init"].addTransition(_init_1)
         self.states["/init"].addTransition(_init_1)
         _init_2 = Transition(self, self.states["/init"], [self.states["/finished"]])
         _init_2 = Transition(self, self.states["/init"], [self.states["/finished"]])
+        _init_2.setAction(self._init_2_exec)
         _init_2.setTrigger(Event("terminate", "inp"))
         _init_2.setTrigger(Event("terminate", "inp"))
         self.states["/init"].addTransition(_init_2)
         self.states["/init"].addTransition(_init_2)
     
     
@@ -77,6 +78,10 @@ class Logging(RuntimeClassBase):
     def _init_0_exec(self, parameters):
     def _init_0_exec(self, parameters):
         value = parameters[0]
         value = parameters[0]
         self.log.append(value)
         self.log.append(value)
+        print("Logging " + str(value))
+    
+    def _init_2_exec(self, parameters):
+        print("Got terminate")
     
     
     def initializeStatechart(self):
     def initializeStatechart(self):
         # enter default state
         # enter default state
@@ -102,4 +107,5 @@ class Controller(ThreadsControllerBase):
         ThreadsControllerBase.__init__(self, ObjectManager(self), keep_running, behind_schedule_callback)
         ThreadsControllerBase.__init__(self, ObjectManager(self), keep_running, behind_schedule_callback)
         self.addInputPort("inp")
         self.addInputPort("inp")
         self.addOutputPort("outp")
         self.addOutputPort("outp")
-        self.object_manager.createInstance("Logging", [log])
+        self.object_manager.createInstance("Logging", [log])
+        print("Start SC at " + str(self))

+ 7 - 1
unit/log_output.xml

@@ -14,18 +14,24 @@
                 self.log = log
                 self.log = log
             </body>
             </body>
         </constructor>
         </constructor>
+
         <scxml initial="init">
         <scxml initial="init">
             <state id="init">
             <state id="init">
                 <transition event="input" port="inp" target=".">
                 <transition event="input" port="inp" target=".">
                     <parameter name="value"/>
                     <parameter name="value"/>
                     <script>
                     <script>
+                        print("Logging " + str(value))
                         self.log.append(value)
                         self.log.append(value)
                     </script>
                     </script>
                 </transition>
                 </transition>
 
 
                 <transition after="0.1" target="."/>
                 <transition after="0.1" target="."/>
 
 
-                <transition event="terminate" port="inp" target="../finished"/>
+                <transition event="terminate" port="inp" target="../finished">
+                    <script>
+                        print("Got terminate")
+                    </script>
+                </transition>
             </state>
             </state>
 
 
             <state id="finished"/>
             <state id="finished"/>

+ 29 - 27
unit/test_all.py

@@ -173,38 +173,39 @@ class TestModelverse(unittest.TestCase):
     def test_operations(self):
     def test_operations(self):
         log = []
         log = []
 
 
-        def manual_callback(context):
-            p1 = instantiate(None, "PetriNet_Runtime/Place", context=context)
-            attr_assign(None, p1, "tokens", 1, context=context)
-            attr_assign(None, p1, "name", "p1", context=context)
-            p2 = instantiate(None, "PetriNet_Runtime/Place", context=context)
-            attr_assign(None, p2, "tokens", 2, context=context)
-            attr_assign(None, p2, "name", "p2", context=context)
-            p3 = instantiate(None, "PetriNet_Runtime/Place", context=context)
-            attr_assign(None, p3, "tokens", 3, context=context)
-            attr_assign(None, p3, "name", "p3", context=context)
-            t1 = instantiate(None, "PetriNet_Runtime/Transition", context=context)
-            attr_assign(None, t1, "name", "t1", context=context)
-            attr_assign(None, t1, "executing", False, context=context)
-            p2t1 = instantiate(None, "PetriNet_Runtime/P2T", (p1, t1), context=context)
-            attr_assign(None, p2t1, "weight", 1, context=context)
-            p2t2 = instantiate(None, "PetriNet_Runtime/P2T", (p2, t1), context=context)
-            attr_assign(None, p2t2, "weight", 1, context=context)
-            t2p1 = instantiate(None, "PetriNet_Runtime/T2P", (t1, p3), context=context)
-            attr_assign(None, t2p1, "weight", 2, context=context)
+        def manual_callback(model):
+            print("Got in manual callback")
+            p1 = instantiate(model, "PetriNet_Runtime/Place")
+            p2 = instantiate(model, "PetriNet_Runtime/Place")
+            p3 = instantiate(model, "PetriNet_Runtime/Place")
+            t1 = instantiate(model, "PetriNet_Runtime/Transition")
+            p2t1 = instantiate(model, "PetriNet_Runtime/P2T", (p1, t1))
+            p2t2 = instantiate(model, "PetriNet_Runtime/P2T", (p2, t1))
+            t2p1 = instantiate(model, "PetriNet_Runtime/T2P", (t1, p3))
+            attr_assign(model, p1, "tokens", 1)
+            attr_assign(model, p1, "name", "p1")
+            attr_assign(model, p2, "tokens", 2)
+            attr_assign(model, p2, "name", "p2")
+            attr_assign(model, p3, "tokens", 3)
+            attr_assign(model, p3, "name", "p3")
+            attr_assign(model, t1, "name", "t1")
+            attr_assign(model, t1, "executing", False)
+            attr_assign(model, p2t1, "weight", 1)
+            attr_assign(model, p2t2, "weight", 1)
+            attr_assign(model, t2p1, "weight", 2)
 
 
         model_add("test/PetriNet", "formalisms/SimpleClassDiagrams", open("integration/code/pn_design.mvc", "r").read())
         model_add("test/PetriNet", "formalisms/SimpleClassDiagrams", open("integration/code/pn_design.mvc", "r").read())
         model_add("test/PetriNet_Runtime", "formalisms/SimpleClassDiagrams", open("integration/code/pn_runtime.mvc", "r").read())
         model_add("test/PetriNet_Runtime", "formalisms/SimpleClassDiagrams", open("integration/code/pn_runtime.mvc", "r").read())
 
 
         model_add("test/my_pn", "test/PetriNet", open("integration/code/pn_design_model.mvc", "r").read())
         model_add("test/my_pn", "test/PetriNet", open("integration/code/pn_design_model.mvc", "r").read())
 
 
-        def add_tracability_D2R(context):
-            instantiate(None, "Association", ("PetriNet/Place", "PetriNet_Runtime/Place"), ID="D2R_PlaceLink", context=context)
-            instantiate(None, "Association", ("PetriNet/Transition", "PetriNet_Runtime/Transition"), ID="D2R_TransitionLink", context=context)
+        def add_tracability_D2R(model):
+            instantiate(model, "Association", ("PetriNet/Place", "PetriNet_Runtime/Place"), ID="D2R_PlaceLink")
+            instantiate(model, "Association", ("PetriNet/Transition", "PetriNet_Runtime/Transition"), ID="D2R_TransitionLink")
 
 
-        def add_tracability_R2D(context):
-            instantiate(None, "Association", ("PetriNet_Runtime/Place", "PetriNet/Place"), ID="R2D_PlaceLink", context=context)
-            instantiate(None, "Association", ("PetriNet_Runtime/Transition", "PetriNet/Transition"), ID="R2D_TransitionLink", context=context)
+        def add_tracability_R2D(model):
+            instantiate(model, "Association", ("PetriNet_Runtime/Place", "PetriNet/Place"), ID="R2D_PlaceLink")
+            instantiate(model, "Association", ("PetriNet_Runtime/Transition", "PetriNet/Transition"), ID="R2D_TransitionLink")
 
 
         transformation_add_MT({"PetriNet": "test/PetriNet"}, {}, "test/print_pn", open("integration/code/pn_print.mvc").read())
         transformation_add_MT({"PetriNet": "test/PetriNet"}, {}, "test/print_pn", open("integration/code/pn_print.mvc").read())
         transformation_add_MANUAL({"PetriNet": "test/PetriNet"}, {"PetriNet_Runtime": "test/PetriNet_Runtime"}, "test/pn_design_to_runtime", add_tracability_D2R)
         transformation_add_MANUAL({"PetriNet": "test/PetriNet"}, {"PetriNet_Runtime": "test/PetriNet_Runtime"}, "test/pn_design_to_runtime", add_tracability_D2R)
@@ -218,10 +219,11 @@ class TestModelverse(unittest.TestCase):
         thrd.daemon = True
         thrd.daemon = True
         thrd.start()
         thrd.start()
 
 
-        assert transformation_execute_MT("test/print_pn", {"PetriNet": "test/my_pn"}, {}, (ctrl, "inp", "outp")) == None
+        assert transformation_execute_MT("test/print_pn", {"PetriNet": "test/my_pn"}, {}, (ctrl, "inp", "outp")) == True
         print("Joining")
         print("Joining")
         thrd.join()
         thrd.join()
         print("Joined")
         print("Joined")
+        print("Got log: " + str(log))
         assert set(log) == set(['"p1" --> 1',
         assert set(log) == set(['"p1" --> 1',
                                 '"p2" --> 2',
                                 '"p2" --> 2',
                                 '"p3" --> 3'])
                                 '"p3" --> 3'])
@@ -239,7 +241,7 @@ class TestModelverse(unittest.TestCase):
         thrd.daemon = True
         thrd.daemon = True
         thrd.start()
         thrd.start()
 
 
-        assert transformation_execute_MT("test/print_pn", {"PetriNet": "test/my_pn"}, {}, (ctrl, "inp", "outp")) == None
+        assert transformation_execute_MT("test/print_pn", {"PetriNet": "test/my_pn"}, {}, (ctrl, "inp", "outp")) == True
         thrd.join()
         thrd.join()
         assert set(log) == set(['"p1" --> 0',
         assert set(log) == set(['"p1" --> 0',
                                 '"p2" --> 1',
                                 '"p2" --> 1',

+ 1 - 0
unit/utils.py

@@ -78,5 +78,6 @@ def flush_data(address, data):
 def start_mvc():
 def start_mvc():
     port = getFreePort()
     port = getFreePort()
     address = "127.0.0.1:%s" % port
     address = "127.0.0.1:%s" % port
+    print("Execute run local MV")
     proc = execute("run_local_modelverse", [str(port)], wait=False)
     proc = execute("run_local_modelverse", [str(port)], wait=False)
     return proc, address
     return proc, address

+ 147 - 141
wrappers/classes/modelverse.xml

@@ -9,6 +9,7 @@
             action = self.actions[context].pop(0)
             action = self.actions[context].pop(0)
             self.parameters = action["parameters"]
             self.parameters = action["parameters"]
             self.current_ID = action["ID"]
             self.current_ID = action["ID"]
+            self.action_name = action["name"]
         </body>
         </body>
     </method>
     </method>
 
 
@@ -76,6 +77,8 @@
         <parameter name="context"/>
         <parameter name="context"/>
         <parameter name="expected"/>
         <parameter name="expected"/>
         <body>
         <body>
+            if context not in self.inputs:
+                return False
             if isinstance(expected, list):
             if isinstance(expected, list):
                 return self.inputs[context] and self.inputs[context][0]["name"] in expected
                 return self.inputs[context] and self.inputs[context][0]["name"] in expected
             else:
             else:
@@ -84,8 +87,9 @@
     </method>
     </method>
 
 
     <constructor>
     <constructor>
+        <parameter name="taskname" default="None"/>
         <body>
         <body>
-            self.controller.taskname = None
+            self.controller.taskname = taskname
             self.actions = {None: []}
             self.actions = {None: []}
             self.responses = []
             self.responses = []
             self.http_clients = []
             self.http_clients = []
@@ -168,7 +172,7 @@
                         </raise>
                         </raise>
                         <script>
                         <script>
                             self.responses.append(json.loads(data))
                             self.responses.append(json.loads(data))
-                            #print("Got data: " + str(json.loads(data)))
+                            print("Got data at %s: %s" % (self.controller.taskname, str(json.loads(data))))
                         </script>
                         </script>
                     </transition>
                     </transition>
 
 
@@ -196,7 +200,14 @@
                             self.address = (self.address[0], int(self.address[1]))
                             self.address = (self.address[0], int(self.address[1]))
 
 
                             self.i = 0
                             self.i = 0
-                            self.controller.taskname = self.taskname = str(uuid.uuid4())
+                            taskname = self.controller.taskname
+                            if taskname is None:
+                                taskname = str(uuid.uuid4())
+                                self.skip_init = False
+                            else:
+                                self.skip_init = True
+                            
+                            self.controller.taskname = self.taskname = taskname
                         </script>
                         </script>
                     </onentry>
                     </onentry>
 
 
@@ -223,7 +234,13 @@
                     </state>
                     </state>
 
 
                     <state id="waiting_http_client">
                     <state id="waiting_http_client">
-                        <transition event="http_client_ready" target="../wait_for_taskname_ack">
+                        <transition event="http_client_ready" cond="self.skip_init" target="../connect_http_client">
+                            <script>
+                                self.i += 1
+                            </script>
+                        </transition>
+
+                        <transition event="http_client_ready" cond="not self.skip_init" target="../wait_for_taskname_ack">
                             <!-- Request the task to be created -->
                             <!-- Request the task to be created -->
                             <raise event="request_raw">
                             <raise event="request_raw">
                                 <parameter expr="self.taskname"/>
                                 <parameter expr="self.taskname"/>
@@ -577,119 +594,51 @@
                         </transition>
                         </transition>
                     </state>
                     </state>
 
 
-                    <state id="store_on_scripted" initial="transformation_add_MT">
-                        <state id="transformation_add_MT" initial="send_metadata">
+                    <state id="store_on_scripted" initial="transformation_add">
+                        <state id="transformation_add" initial="send_metadata">
                             <state id="send_metadata">
                             <state id="send_metadata">
                                 <onentry>
                                 <onentry>
                                     <raise event="request">
                                     <raise event="request">
-                                        <parameter expr="['transformation_add_MT'] + self.dict_to_list(self.parameters[0]) + self.dict_to_list(self.parameters[1]) + [self.parameters[2]]"/>
+                                        <parameter expr="[self.action_name] + self.dict_to_list(self.parameters[0]) + self.dict_to_list(self.parameters[1]) + [self.parameters[2]]"/>
                                     </raise>
                                     </raise>
+                                </onentry>
 
 
+                                <transition cond="self.expect_response_partial('Please edit this model before sending next input: ', pop=False)" target="../wait_for_user">
                                     <script>
                                     <script>
-                                        self.context = str(uuid.uuid4())
-                                        self.actions[self.context] = []
-                                        self.code = self.parameters[3]
+                                        model = self.responses.pop(0).split(": ", 1)[1]
+                                        print("Got model to edit: " + str(model))
                                     </script>
                                     </script>
-
-                                </onentry>
-
-                                <transition cond="self.expect_response_partial('Operating on: ')" target="../edit_metamodel">
-                                    <raise event="result">
-                                        <parameter expr="[self.context, self.responses.pop(0).split(': ', 1)[1]]"/>
-                                    </raise>
-                                </transition>
-                            </state>
-
-                            <state id="edit_metamodel">
-                                <transition cond="self.expect_response('Model loaded, ready for commands!')" target="../../../../going_scripted"/>
-                                <transition cond="self.expect_response('Waiting for model constructors...')" target="../send_model"/>
-                            </state>
-
-                            <state id="send_model">
-                                <onentry>
-                                    <raise event="request">
-                                        <parameter expr="self.code"/>
-                                    </raise>
-                                </onentry>
-
-                                <transition cond="self.expect_response('Success')" target="../../../../wait_for_action/megamodelling">
                                     <raise event="result">
                                     <raise event="result">
-                                        <parameter expr="None"/>
+                                        <parameter expr="model"/>
                                     </raise>
                                     </raise>
                                 </transition>
                                 </transition>
                             </state>
                             </state>
 
 
-                            <transition cond="self.expect_response_partial('', pop=False)" target="../../../wait_for_action/history">
-                                <script>
-                                    print("UNKNOWN RESPONSE received: " + str(self.responses.pop(0)))
-                                </script>
-                            </transition>
-                        </state>
-
-                        <state id="transformation_add_AL" initial="send_metadata">
-                            <state id="send_metadata">
-                                <onentry>
-                                    <raise event="request">
-                                        <parameter expr="['transformation_add_AL'] + self.dict_to_list(self.parameters[0]) + self.dict_to_list(self.parameters[1]) + [self.parameters[2]]"/>
-                                    </raise>
-
+                            <state id="wait_for_user">
+                                <transition cond="None in self.inputs and self.inputs[None]" target="../upload_changes">
                                     <script>
                                     <script>
-                                        self.context = str(uuid.uuid4())
-                                        self.actions[self.context] = []
-                                        self.code = self.parameters[3]
+                                        self.inputs[None].pop(0)
+                                        print("POP input indicating readyness")
                                     </script>
                                     </script>
-                                </onentry>
-
-                                <transition cond="self.expect_response_partial('Operating on: ')" target="../edit_metamodel">
-                                    <raise event="result">
-                                        <parameter expr="[self.context, self.responses.pop(0).split(': ', 1)[1]]"/>
+                                    <raise event="request">
+                                        <parameter expr="True"/>
                                     </raise>
                                     </raise>
                                 </transition>
                                 </transition>
                             </state>
                             </state>
 
 
-                            <state id="edit_metamodel">
-                                <transition cond="self.expect_response('Model loaded, ready for commands!')" target="../../../../going_scripted"/>
-                            </state>
-                               
-                            <state id="send_model">
-                                <onentry>
+                            <state id="upload_changes">
+                                <transition cond="self.expect_response('Waiting for code constructors...')" target=".">
                                     <raise event="request">
                                     <raise event="request">
-                                        <parameter expr="self.code"/>
-                                    </raise>
-                                </onentry>
-
-                                <transition cond="self.expect_response('Success')" target="../../../../wait_for_action/megamodelling">
-                                    <raise event="result">
-                                        <parameter expr="None"/>
+                                        <parameter expr="self.parameters[3]"/>
                                     </raise>
                                     </raise>
                                 </transition>
                                 </transition>
-                            </state>
-
-                            <transition cond="self.expect_response('Waiting for code constructors...')" target="send_model"/>
-                        </state>
 
 
-                        <state id="transformation_add_MANUAL" initial="send_metadata">
-                            <state id="send_metadata">
-                                <onentry>
+                                <transition cond="self.expect_response('Waiting for model constructors...')" target=".">
                                     <raise event="request">
                                     <raise event="request">
-                                        <parameter expr="['transformation_add_MANUAL'] + self.dict_to_list(self.parameters[0]) + self.dict_to_list(self.parameters[1]) + [self.parameters[2]]"/>
-                                    </raise>
-
-                                    <script>
-                                        self.context = str(uuid.uuid4())
-                                        self.actions[self.context] = []
-                                    </script>
-                                </onentry>
-
-                                <transition cond="self.expect_response_partial('Operating on: ')" target="../edit_metamodel">
-                                    <raise event="result">
-                                        <parameter expr="[self.context, self.responses.pop(0).split(': ', 1)[1]]"/>
+                                        <parameter expr="self.parameters[3]"/>
                                     </raise>
                                     </raise>
                                 </transition>
                                 </transition>
-                            </state>
 
 
-                            <state id="edit_metamodel">
-                                <transition cond="self.expect_response('Model loaded, ready for commands!')" target="../../../../going_scripted"/>
                                 <transition cond="self.expect_response('Success')" target="../../../../wait_for_action/megamodelling">
                                 <transition cond="self.expect_response('Success')" target="../../../../wait_for_action/megamodelling">
                                     <raise event="result">
                                     <raise event="result">
                                         <parameter expr="None"/>
                                         <parameter expr="None"/>
@@ -711,58 +660,31 @@
                                     </script>
                                     </script>
                                 </onentry>
                                 </onentry>
 
 
-                                <transition cond="self.expect_response('Success: ready for MANUAL execution', pop=True)" target="../edit_model">
+                                <transition cond="self.expect_response_partial('Spawned activity on task: ', pop=False)" target="../waiting">
                                     <script>
                                     <script>
-                                        self.context = str(uuid.uuid4())
-                                        self.actions[self.context] = []
+                                        self.sub_sc_taskname = self.responses.pop(0).split(": ", 1)[1]
                                     </script>
                                     </script>
-                                </transition>
-                                <transition cond="self.expect_response('Success: ready for AL execution', pop=True) or self.expect_response('Success: ready for MT execution', pop=True)" target="../dialog">
-                                    <script>
-                                        self.input_context = str(uuid.uuid4())
-                                        self.inputs[self.input_context] = []
-                                    </script>
-                                    <raise event="result">
-                                        <parameter expr="['SC', self.parameters[0], self.input_context]"/>
-                                    </raise>
-                                </transition>
-                            </state>
-
-                            <state id="dialog">
-                                <transition cond="self.expect_response('Success', pop=False) or self.expect_response('Failure', pop=False)" target="../../../../wait_for_action/history">
                                     <raise event="result">
                                     <raise event="result">
-                                        <parameter expr="True if self.responses.pop(0) == 'Success' else False"/>
-                                    </raise>
-                                </transition>
-
-                                <transition cond="not (self.expect_response('Success', pop=False) or self.expect_response('Failure', pop=False)) and self.expect_response_partial('', pop=False)" target=".">
-                                    <raise event="data_output">
-                                        <parameter expr="self.responses.pop(0)"/>
-                                    </raise>
-                                </transition>
-
-                                <transition cond="self.expect_input(self.input_context, 'data_input')" target=".">
-                                    <raise event="request">
-                                        <parameter expr="self.inputs[self.input_context].pop(0)['parameters']"/>
+                                        <parameter expr="self.sub_sc_taskname"/>
                                     </raise>
                                     </raise>
                                 </transition>
                                 </transition>
                             </state>
                             </state>
 
 
-                            <state id="edit_model">
-                                <transition cond="self.expect_response_partial('Please perform manual operation ', pop=True)" target="."/>
-                                <transition cond="self.expect_response_partial('Operating on: ', pop=False)" target=".">
+                            <state id="waiting">
+                                <onentry>
                                     <script>
                                     <script>
-                                        model = self.responses.pop(0).split(": ", 1)[1]
+                                        print("Waiting on task " + self.sub_sc_taskname)
                                     </script>
                                     </script>
+                                </onentry>
+
+                                <transition cond="self.expect_response('Finished task: ' + self.sub_sc_taskname)" target="."/>
+                                <transition cond="self.expect_response('Success', pop=False) or self.expect_response('Failure', pop=False)" target="../../../../wait_for_action/megamodelling">
                                     <raise event="result">
                                     <raise event="result">
-                                        <parameter expr="['OP', self.parameters[0], self.context, model]"/>
-                                    </raise>
-                                </transition>
-                                <transition cond="self.expect_response('Model loaded, ready for commands!')" target="../../../../going_scripted"/>
-                                <transition cond="self.expect_response('Success')" target="../../../../wait_for_action/megamodelling">
-                                    <raise event="result">
-                                        <parameter expr="True"/>
+                                        <parameter expr="self.responses.pop(0) == 'Success'"/>
                                     </raise>
                                     </raise>
+                                    <script>
+                                        print("FINISHED")
+                                    </script>
                                 </transition>
                                 </transition>
                             </state>
                             </state>
                         </state>
                         </state>
@@ -1434,15 +1356,18 @@
                         </transition>
                         </transition>
                     </state>
                     </state>
 
 
-                    <state id="save">
+                    <state id="exit_save">
                         <onentry>
                         <onentry>
                             <raise event="request">
                             <raise event="request">
-                                <parameter expr="['exit', 'model_modify', self.current_model]"/>
+                                <parameter expr="['exit']"/>
                             </raise>
                             </raise>
                         </onentry>
                         </onentry>
 
 
-                        <transition cond="self.expect_response('Success')" target="."/>
-                        <transition cond="self.expect_response('Model loaded, ready for commands!')" target="../../wait_for_action/modelling/recognized/manual"/>
+                        <transition cond="self.expect_response('Success')" target="../../wait_for_action/megamodelling">
+                            <raise event="result">
+                                <parameter expr="None"/>
+                            </raise>
+                        </transition>
                     </state>
                     </state>
 
 
                     <state id="service_register">
                     <state id="service_register">
@@ -1524,6 +1449,86 @@
                                 self.load_action(None)
                                 self.load_action(None)
                             </script>
                             </script>
                         </transition>
                         </transition>
+
+                        <transition cond="self.expect_response('Success: ready for AL execution')" target="../activity/SC"/>
+                        <transition cond="self.expect_response('Success: ready for MT execution')" target="../activity/SC"/>
+                        <transition cond="self.expect_response('Success: ready for MANUAL execution')" target="../activity/OP"/>
+                    </state>
+
+                    <state id="activity" initial="SC">
+                        <state id="SC">
+                            <onentry>
+                                <script>
+                                    print("SC EXEC!")
+                                </script>
+                                <raise event="result">
+                                    <parameter expr="'SC'"/>
+                                </raise>
+                            </onentry>
+
+                            <state id="forwarding">
+                                <transition cond="self.expect_response('Success', pop=False) or self.expect_response('Failure', pop=False)" target="../../../history">
+                                    <raise event="result">
+                                        <parameter expr="True if self.responses.pop(0) == 'Success' else False"/>
+                                    </raise>
+                                    <script>
+                                        print("FINISHED")
+                                    </script>
+                                </transition>
+
+                                <transition cond="not (self.expect_response('Success', pop=False) or self.expect_response('Failure', pop=False)) and self.expect_response_partial('', pop=False)" target=".">
+                                    <raise event="data_output">
+                                        <parameter expr="self.responses.pop(0)"/>
+                                    </raise>
+                                </transition>
+
+                                <transition cond="self.expect_input(None, 'data_input')" target=".">
+                                    <raise event="request">
+                                        <parameter expr="self.inputs[None].pop(0)['parameters']"/>
+                                    </raise>
+                                </transition>
+                            </state>
+                        </state>
+
+                        <state id="OP">
+                            <onentry>
+                                <script>
+                                    print("OP EXEC on " + str(self.controller.taskname))
+                                </script>
+                                <raise event="result">
+                                    <parameter expr="'OP'"/>
+                                </raise>
+                            </onentry>
+
+                            <onexit>
+                                <script>
+                                    print("LEAVING")
+                                </script>
+                            </onexit>
+
+                            <state id="forwarding">
+                                <transition cond="self.expect_response_partial('Please perform manual operation ', pop=True)" target="."/>
+
+                                <transition cond="self.expect_response_partial('Please edit this model before sending next input: ', pop=False)" target=".">
+                                    <raise event="result">
+                                        <parameter expr="self.responses.pop(0).split(': ')[1]"/>
+                                    </raise>
+                                    <script>
+                                        print("EDITING...")
+                                    </script>
+                                </transition>
+
+                                <transition cond="None in self.inputs and self.inputs[None]" target="../../../history">
+                                    <script>
+                                        print("GOT DATA INPUT")
+                                        self.inputs[None].pop(0)
+                                    </script>
+                                    <raise event="request">
+                                        <parameter expr="0"/>
+                                    </raise>
+                                </transition>
+                            </state>
+                        </state>
                     </state>
                     </state>
 
 
                     <state id="megamodelling">
                     <state id="megamodelling">
@@ -1617,19 +1622,19 @@
                             </script>
                             </script>
                         </transition>
                         </transition>
 
 
-                        <transition cond="self.expect_action(None, 'transformation_add_MT')" target="../../operations/store_on_scripted/transformation_add_MT">
+                        <transition cond="self.expect_action(None, 'transformation_add_MT')" target="../../operations/store_on_scripted/transformation_add">
                             <script>
                             <script>
                                 self.load_action(None)
                                 self.load_action(None)
                             </script>
                             </script>
                         </transition>
                         </transition>
 
 
-                        <transition cond="self.expect_action(None, 'transformation_add_AL')" target="../../operations/store_on_scripted/transformation_add_AL">
+                        <transition cond="self.expect_action(None, 'transformation_add_AL')" target="../../operations/store_on_scripted/transformation_add">
                             <script>
                             <script>
                                 self.load_action(None)
                                 self.load_action(None)
                             </script>
                             </script>
                         </transition>
                         </transition>
 
 
-                        <transition cond="self.expect_action(None, 'transformation_add_MANUAL')" target="../../operations/store_on_scripted/transformation_add_MANUAL">
+                        <transition cond="self.expect_action(None, 'transformation_add_MANUAL')" target="../../operations/store_on_scripted/transformation_add">
                             <script>
                             <script>
                                 self.load_action(None)
                                 self.load_action(None)
                             </script>
                             </script>
@@ -1937,7 +1942,7 @@
                                 </script>
                                 </script>
                             </transition>
                             </transition>
 
 
-                            <transition cond="self.expect_action(self.context, 'save')" target="../../../operations/save">
+                            <transition cond="self.expect_action(self.context, 'exit_save')" target="../../../operations/exit_save">
                                 <script>
                                 <script>
                                     self.load_action(self.context)
                                     self.load_action(self.context)
                                 </script>
                                 </script>
@@ -2117,7 +2122,8 @@
                         <parameter name="value"/>
                         <parameter name="value"/>
                         <parameter name="context_ID"/>
                         <parameter name="context_ID"/>
                         <script>
                         <script>
-                            self.inputs[context_ID].append({"name": "data_input", "parameters": value})
+                            print("Got data_input in MV")
+                            self.inputs.setdefault(context_ID, []).append({"name": "data_input", "parameters": value})
                         </script>
                         </script>
                     </transition>
                     </transition>
                 </state>
                 </state>

+ 124 - 44
wrappers/modelverse.py

@@ -52,38 +52,108 @@ def _next_ID():
     ID += 1
     ID += 1
     return ID
     return ID
 
 
-def _process_SC(statechart, port_sc, context):
-    print("Context: " + str(context))
+def __run_new_modelverse(address, username, password, callback, model):
+    print("RUN NEW")
+    init(address)
+    login(username, password)
+    print("LOGIN OK")
+    if callback is not None:
+        callback(model)
+    exit_save(model)
+    print("CALLBACK DONE")
+
+def __run_new_modelverse_activity(address, username, password, taskname, pipe, callback):
+    print("Run MV activity")
+    init(address, taskname=taskname)
+    controller.username = username
+    controller.password = password
+    print("INIT OK")
+    t = OUTPUT()
+    print("Got type: " + str(t))
+
+    if t == "OP":
+        print("Requesting model...")
+        model = OUTPUT()
+        print("Do manual operations on " + str(model))
+        __invoke(callback, model)
+        print("Invocation OK")
+        controller.addInput(Event("data_input", "action_in", [None, None]))
+        print("Waiting on output")
+        # TODO fix this to something using OUTPUT or so
+        time.sleep(5)
+    elif t == "SC":
+        while 1:
+            empty = True
+
+            # Fetch output from the MV
+            response = responses.fetch(0)
+            if response is not None:
+                print("Output of MV to SC: " + str(response))
+                if response.name == "data_output":
+                    # Got output of MV, so forward to SCCD
+                    pipe.send(("input", response.parameters))
+                elif response.name == "result":
+                    # Finished execution, so continue and return result
+                    pipe.send(("terminate", []))
+                    pipe.close()
+                    return response.parameters[1]
+                else:
+                    raise Exception("Unknown data from MV to SC: " + str(response))
+                empty = False
+
+            # Fetch output from the SC
+            if pipe.poll():
+                response = pipe.recv()
+
+                if response.name == "output":
+                    controller.addInput(Event("data_input", "action_in", [response.parameters, context]))
+                else:
+                    raise Exception("Unknown data from SC to MV: " + str(response))
+                empty = False
+
+            if empty:
+                time.sleep(0.05)
+
+def __invoke(callback, model):
+    import multiprocessing
+    print("Invoked action!")
+    p = multiprocessing.Process(target=__run_new_modelverse, args=[controller.address, controller.username, controller.password, callback, model])
+    p.start()
+    p.join()
+    print("Invocation done")
+
+def _process_SC(statechart, port_sc, taskname):
+    import multiprocessing
+    p2c_pipe, c2p_pipe = multiprocessing.Pipe()
+    p = multiprocessing.Process(target=__run_new_modelverse_activity, args=[controller.address, controller.username, controller.password, taskname, c2p_pipe, None])
+    p.start()
     while 1:
     while 1:
         empty = True
         empty = True
 
 
-        # Fetch output from the MV
-        response = responses.fetch(0)
-        if response is not None:
-            print("Output of MV to SC")
-            if response.name == "data_output":
-                # Got output of MV, so forward to SCCD
-                statechart[0].addInput(Event("input", statechart[1], response.parameters))
-            elif response.name == "result":
-                # Finished execution, so continue and return result
-                statechart[0].addInput(Event("terminate", statechart[1], []))
-                return response.parameters[1]
-            else:
-                raise Exception("Unknown data from MV to SC: " + str(response))
+        if p2c_pipe.poll():
+            response = p2c_pipe.recv()
+            statechart[0].addInput(Event(response[0], statechart[1], response[1]))
+            
+            if response[0] == "terminate":
+                p2c_pipe.close()
+                break
             empty = False
             empty = False
 
 
-        # Fetch output from the SC
         response = port_sc.fetch(0)
         response = port_sc.fetch(0)
         if response is not None:
         if response is not None:
-            print("Output of SC to MV")
-            if response.name == "output":
-                controller.addInput(Event("data_input", "action_in", [response.parameters, context]))
-            else:
-                raise Exception("Unknown data from SC to MV: " + str(response))
+            p2c_pipe.send(response)
             empty = False
             empty = False
 
 
         if empty:
         if empty:
-            time.sleep(0.5)
+            time.sleep(0.05)
+    p.join()
+
+def _process_OP(callback, taskname):
+    import multiprocessing
+    print("Running remote operation for taskname " + taskname)
+    p = multiprocessing.Process(target=__run_new_modelverse_activity, args=[controller.address, controller.username, controller.password, taskname, None, callback])
+    p.start()
+    p.join()
 
 
 def INPUT(action, context, parameters):
 def INPUT(action, context, parameters):
     controller.addInput(Event("action", "action_in", [action, _next_ID(), context, parameters]))
     controller.addInput(Event("action", "action_in", [action, _next_ID(), context, parameters]))
@@ -102,12 +172,12 @@ def OUTPUT():
                 print("Unknown error: " + str(response.parameters))
                 print("Unknown error: " + str(response.parameters))
                 raise UnknownError()
                 raise UnknownError()
 
 
-def init(address_param="127.0.0.1:8001", timeout=20.0):
+def init(address_param="127.0.0.1:8001", timeout=20.0, taskname=None):
     global controller
     global controller
     global ID
     global ID
     global responses
     global responses
 
 
-    controller = modelverse_SCCD.Controller()
+    controller = modelverse_SCCD.Controller(taskname)
     socket2event.boot_translation_service(controller)
     socket2event.boot_translation_service(controller)
 
 
     ID = 0
     ID = 0
@@ -124,6 +194,8 @@ def init(address_param="127.0.0.1:8001", timeout=20.0):
     return OUTPUT()
     return OUTPUT()
 
 
 def login(username, password):
 def login(username, password):
+    controller.username = username
+    controller.password = password
     INPUT("login", None, [username, password])
     INPUT("login", None, [username, password])
     return OUTPUT()
     return OUTPUT()
 
 
@@ -173,31 +245,36 @@ def transformation_between(sources, targets):
 
 
 def transformation_add_MT(source_metamodels, target_metamodels, operation_name, code, callback=None):
 def transformation_add_MT(source_metamodels, target_metamodels, operation_name, code, callback=None):
     INPUT("transformation_add_MT", None, [source_metamodels, target_metamodels, operation_name, code, True])
     INPUT("transformation_add_MT", None, [source_metamodels, target_metamodels, operation_name, code, True])
-    context, model = OUTPUT()
+    model = OUTPUT()
+
     if callback is not None:
     if callback is not None:
-        callback(context)
-    INPUT("exit", context, [])
+        __invoke(callback, model)
+    controller.addInput(Event("data_input", "action_in", [None, None]))
+
     return OUTPUT()
     return OUTPUT()
 
 
 def transformation_add_AL(source_metamodels, target_metamodels, operation_name, code, callback=None):
 def transformation_add_AL(source_metamodels, target_metamodels, operation_name, code, callback=None):
     INPUT("transformation_add_AL", None, [source_metamodels, target_metamodels, operation_name, code, True])
     INPUT("transformation_add_AL", None, [source_metamodels, target_metamodels, operation_name, code, True])
-    context, model = OUTPUT()
+    model = OUTPUT()
 
 
-    if context is None:
+    if model is None:
         # In case the source and target metamodels are empty, the context will be None, indicating that we are finished already (no callbacks allowed)
         # In case the source and target metamodels are empty, the context will be None, indicating that we are finished already (no callbacks allowed)
         return
         return
 
 
     if callback is not None:
     if callback is not None:
-        callback(context)
-    INPUT("exit", context, [])
+        __invoke(callback, model)
+    controller.addInput(Event("data_input", "action_in", [None, None]))
+
     return OUTPUT()
     return OUTPUT()
 
 
 def transformation_add_MANUAL(source_metamodels, target_metamodels, operation_name, callback=None):
 def transformation_add_MANUAL(source_metamodels, target_metamodels, operation_name, callback=None):
     INPUT("transformation_add_MANUAL", None, [source_metamodels, target_metamodels, operation_name, True])
     INPUT("transformation_add_MANUAL", None, [source_metamodels, target_metamodels, operation_name, True])
-    context, model = OUTPUT()
+    model = OUTPUT()
+
     if callback is not None:
     if callback is not None:
-        callback(context)
-    INPUT("exit", context, [])
+        __invoke(callback, model)
+    controller.addInput(Event("data_input", "action_in", [None, None]))
+
     return OUTPUT()
     return OUTPUT()
 
 
 def __transformation_execute(operation_name, input_models_dict, output_models_dict, statechart, tracability_model, fetch_output):
 def __transformation_execute(operation_name, input_models_dict, output_models_dict, statechart, tracability_model, fetch_output):
@@ -205,13 +282,10 @@ def __transformation_execute(operation_name, input_models_dict, output_models_di
         port_sc = statechart[0].addOutputListener(statechart[2])
         port_sc = statechart[0].addOutputListener(statechart[2])
 
 
     INPUT("transformation_execute", None, [operation_name, input_models_dict, output_models_dict, tracability_model, fetch_output])
     INPUT("transformation_execute", None, [operation_name, input_models_dict, output_models_dict, tracability_model, fetch_output])
-    op, name, context = OUTPUT()
+    taskname = OUTPUT()
     if statechart is not None:
     if statechart is not None:
-        threading.Thread(target=_process_SC, args=[statechart, port_sc, context]).start()
-    else:
-        val = OUTPUT()
-        print("Transformation result: " + str(val))
-        return val
+        threading.Thread(target=_process_SC, args=[statechart, port_sc, taskname]).start()
+    return OUTPUT()
 
 
 def transformation_execute_MT(operation_name, input_models_dict, output_models_dict, statechart=None, tracability_model="", fetch_output=True):
 def transformation_execute_MT(operation_name, input_models_dict, output_models_dict, statechart=None, tracability_model="", fetch_output=True):
     return __transformation_execute(operation_name, input_models_dict, output_models_dict, statechart, tracability_model, fetch_output)
     return __transformation_execute(operation_name, input_models_dict, output_models_dict, statechart, tracability_model, fetch_output)
@@ -221,10 +295,12 @@ def transformation_execute_AL(operation_name, input_models_dict, output_models_d
 
 
 def transformation_execute_MANUAL(operation_name, input_models_dict, output_models_dict, callback=None, tracability_model=""):
 def transformation_execute_MANUAL(operation_name, input_models_dict, output_models_dict, callback=None, tracability_model=""):
     INPUT("transformation_execute", None, [operation_name, input_models_dict, output_models_dict, tracability_model])
     INPUT("transformation_execute", None, [operation_name, input_models_dict, output_models_dict, tracability_model])
-    op, name, context, model = OUTPUT()
-    if callback is not None:
-        callback(context)
-    INPUT("exit", context, [])
+    taskname = OUTPUT()
+
+    print("Running manual task at " + str(taskname))
+    _process_OP(callback, taskname)
+    print("Process OP called")
+
     return OUTPUT()
     return OUTPUT()
 
 
 def transformation_signature(operation_name):
 def transformation_signature(operation_name):
@@ -439,6 +515,10 @@ def get_taskname():
     """Fetch the taskname of the current connection."""
     """Fetch the taskname of the current connection."""
     return controller.taskname
     return controller.taskname
 
 
+def exit_save(model_name):
+    INPUT("exit_save", None, [model_name])
+    return OUTPUT()
+
 """ Some hardcoded functions... Way easier to express them with code than with statecharts!"""
 """ Some hardcoded functions... Way easier to express them with code than with statecharts!"""
 import json
 import json
 import urllib
 import urllib

文件差异内容过多而无法显示
+ 364 - 397
wrappers/modelverse_SCCD.py


+ 1 - 1
wrappers/poll_print.xml

@@ -35,7 +35,7 @@
 
 
             <state id="finished">
             <state id="finished">
                 <script>
                 <script>
-                    print("FINISHED")
+                    print("FINISHED SC")
                 </script>
                 </script>
             </state>
             </state>
         </scxml>
         </scxml>