Browse Source

Refactored

Casper Thule 3 years ago
parent
commit
7f210f63d9

+ 61 - 10
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/tests/CgCppBasicTest.xtend

@@ -24,6 +24,7 @@ import java.io.File
 import java.io.PrintWriter
 import java.nio.file.Files
 import java.io.FileWriter
+import org.eclipse.xtext.junit4.ui.AbstractAutoEditTest
 
 @RunWith(XtextRunner)
 @InjectWith(SemanticAdaptationInjectorProvider)
@@ -33,8 +34,59 @@ class CgCppBasicTest extends AbstractSemanticAdaptationTest {
 	@Inject extension ParseHelper<SemanticAdaptation>
 	@Inject extension  ValidationTestHelper
 
-	
-	@Test def powerwindow_model_only() { __parseNoErrors('test_input/single_folder_spec/window/window_sa_canonical.BASE.sa') }
+	@Test def powerwindow_model_only() {
+//		__parseNoErrors('test_input/single_folder_spec/window/window_sa_canonical.BASE.sa');
+		__parseNoErrorsWithValidation('test_input/single_folder_spec/window',
+			'test_input/single_folder_spec/window/window_sa_canonical.BASE.sa');
+	}
+
+	def __parseNoErrorsWithValidation(String directory, String filename) {
+		val model = __parse(filename);
+		__assertNoParseErrors(model, filename);
+
+		val correctFileDirectory = new File(directory + File.separator + "correct");
+
+		val fsa = new InMemoryFileSystemAccess()
+		val IGeneratorContext ctxt = null;
+		new CppGenerator().doGenerate(model.eResource, fsa, ctxt);
+
+		for (files : fsa.allFiles.entrySet) {
+			val filename2 = files.key.substring(14);
+			val file = new File(correctFileDirectory, filename2);
+			val correctFileContent = Files.readAllLines(file.toPath);
+
+			var path = new File("generated");
+			if (path.exists)
+				path.delete
+			else
+				path.mkdir;
+
+			path = new File(path, files.key.substring(14))
+
+			val FileWriter writer = new FileWriter(path);
+			writer.write(files.value.toString);
+			writer.close;
+
+			val testFileContent = Files.readAllLines(path.toPath);
+
+			if (correctFileContent.size != testFileContent.size) {
+				System.out.println("Error: Lines are of different length in file: " + filename2);
+			} else {
+				val error = false;
+				for (var i = 0; i < testFileContent.size; i++) {
+					val testLine = testFileContent.get(i);
+					val correctLine = correctFileContent.get(i);
+					if (testLine.compareTo(correctLine) != 0) {
+						if (!testLine.contains("guid")) {
+							System.out.println("ERROR: The following lines are not equal: \n" + testLine + "\n" +
+								correctLine);
+						}
+					}
+				}
+			}
+		}
+
+	}
 
 	def __parseNoErrors(String filename) {
 		val model = __parse(filename)
@@ -43,26 +95,25 @@ class CgCppBasicTest extends AbstractSemanticAdaptationTest {
 		val fsa = new InMemoryFileSystemAccess()
 		val IGeneratorContext ctxt = null;
 		new CppGenerator().doGenerate(model.eResource, fsa, ctxt);
-		
-		for(files : fsa.allFiles.entrySet)
-		{
+
+		for (files : fsa.allFiles.entrySet) {
 //			System.out.println("########################")
 //			System.out.println("Filename: " + files.key.substring(14))
 //			System.out.println(files.value)
 			var path = new File("generated");
-			if(path.exists)
+			if (path.exists)
 				path.delete
 			else
 				path.mkdir;
-				
-			path = new File(path, files.key.substring(14))	
-			
+
+			path = new File(path, files.key.substring(14))
+
 			val FileWriter writer = new FileWriter(path);
 			writer.write(files.value.toString);
 			writer.close;
 			System.out.println("Stored file: " + files.key.substring(14) + " at: " + path.absolutePath);
 		}
-		//System.out.println(fsa.allFiles)		
+	// System.out.println(fsa.allFiles)		
 	}
 
 	def __parseNoErrorsPrint(String filename) {

+ 36 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/correct/modelDescription.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?><fmiModelDescription fmiVersion="2.0" guid="71e95519-506e-48ca-9de6-55cb071ea842" modelName="windowSA" variableNamingConvention="flat">
+    <ModelVariables>
+        <ScalarVariable causality="output" name="disp" valueReference="0" variability="continuous">
+            <Real/>
+        </ScalarVariable>
+        <ScalarVariable causality="input" name="displacement" valueReference="1" variability="continuous">
+            <Real start="0.0"/>
+        </ScalarVariable>
+        <ScalarVariable causality="output" name="friction" valueReference="2" variability="continuous">
+            <Real/>
+        </ScalarVariable>
+        <ScalarVariable causality="input" name="reaction_force" valueReference="3" variability="continuous">
+            <Real start="0.0"/>
+        </ScalarVariable>
+        <ScalarVariable causality="input" name="speed" valueReference="4" variability="continuous">
+            <Real start="0.0"/>
+        </ScalarVariable>
+        <ScalarVariable causality="output" name="tau" valueReference="5" variability="continuous">
+            <Real/>
+        </ScalarVariable>
+        <ScalarVariable causality="local" name="v" valueReference="6" variability="continuous">
+            <Real/>
+        </ScalarVariable>
+        <ScalarVariable causality="parameter" name="b" valueReference="7" variability="fixed">
+            <Real start="10.0"/>
+        </ScalarVariable>
+        <ScalarVariable causality="parameter" name="r" valueReference="8" variability="fixed">
+            <Real start="0.11"/>
+        </ScalarVariable>
+    </ModelVariables>
+    <Outputs>
+        <Unknown index="1"/>
+        <Unknown index="3"/>
+        <Unknown index="6"/>
+    </Outputs>
+</fmiModelDescription>

+ 219 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/correct/windowSA.cpp

@@ -0,0 +1,219 @@
+#include "windowSA.h"
+
+windowSA::windowSA(shared_ptr<std::string> resourceLocation) : SemanticAdaptation(createInputRules(),createOutputRules())
+{
+	stored_window_reaction_torque = 0.0;
+	stored_window_height = 0.0;
+	
+	this->stored_windowsa_reaction_force = 0.0;
+	this->stored_windowsa_displacement = 0.0;
+	this->stored_windowsa_speed = 0.0;
+	
+	this->displacement = 0.0;
+	this->reaction_force = 0.0;
+	this->speed = 0.0;
+	this->b = 10.0;
+	this->r = 0.11;
+	
+	const char* path = Fmu::combinePath(resourceLocation, make_shared<string>("Window.fmu"))->c_str();
+	auto windowFmu = make_shared<fmi2::Fmu>(path);
+	windowFmu->initialize();
+	this->window = windowFmu->instantiate("Window",fmi2CoSimulation, "{29e3eae4-7ed5-4ccc-a0e7-7d8198e20bc0}", true, true, make_shared<Callback>()); 
+}
+
+
+windowSA* windowSA::getRuleThis()
+{
+	return this;
+}
+
+
+bool windowSA::in_rule_condition1(){
+	return true;
+}
+void windowSA::in_rule_body1(){
+	if(this->isSetreaction_force){
+		this->stored_windowsa_reaction_force = this->reaction_force;
+	}
+}
+void windowSA::in_rule_flush1(){
+	setValue(window,WINDOWREACTION_FORCE,this->stored_windowsa_reaction_force);
+}
+bool windowSA::in_rule_condition2(){
+	return true;
+}
+void windowSA::in_rule_body2(){
+	if(this->isSetdisplacement){
+		this->stored_windowsa_displacement = this->displacement;
+	}
+}
+void windowSA::in_rule_flush2(){
+	setValue(window,WINDOWDISPLACEMENT,this->stored_windowsa_displacement);
+}
+bool windowSA::in_rule_condition3(){
+	return true;
+}
+void windowSA::in_rule_body3(){
+	if(this->isSetspeed){
+		this->stored_windowsa_speed = this->speed;
+	}
+}
+void windowSA::in_rule_flush3(){
+	setValue(window,WINDOWSPEED,this->stored_windowsa_speed);
+}
+shared_ptr<list<Rule<windowSA>>> windowSA::createInputRules()
+{
+	auto list = make_shared<list<Rule<windowSA>>>()
+	
+	list->push_back(
+		(Rule<windowSA>){
+			&windowSA::bool in_rule_condition1();,
+			&windowSA::void in_rule_body1();
+			&windowSA::void in_rule_flush1();
+		});
+	
+	
+	list->push_back(
+		(Rule<windowSA>){
+			&windowSA::bool in_rule_condition2();,
+			&windowSA::void in_rule_body2();
+			&windowSA::void in_rule_flush2();
+		});
+	
+	
+	list->push_back(
+		(Rule<windowSA>){
+			&windowSA::bool in_rule_condition3();,
+			&windowSA::void in_rule_body3();
+			&windowSA::void in_rule_flush3();
+		});
+	
+	
+	return list;
+	
+}
+
+bool windowSA::out_rule_condition1(){
+	return true;
+}
+void windowSA::out_rule_body1(){
+	this->stored_window_reaction_torque = getValue(window,WINDOWTAU);
+}
+void windowSA::out_rule_flush1(){
+	this->tau = -this->stored_window_reaction_torque;
+}
+bool windowSA::out_rule_condition2(){
+	return true;
+}
+void windowSA::out_rule_body2(){
+	this->stored_window_height = getValue(window,WINDOWDISP);
+}
+void windowSA::out_rule_flush2(){
+	this->disp = this->stored_window_height * 100;
+}
+shared_ptr<list<Rule<windowSA>>> windowSA::createOutputRules()
+{
+	auto list = make_shared<list<Rule<windowSA>>>()
+	
+	list->push_back(
+		(Rule<windowSA>){
+			&windowSA::bool out_rule_condition1();,
+			&windowSA::void out_rule_body1();
+			&windowSA::void out_rule_flush1();
+		});
+	
+	
+	list->push_back(
+		(Rule<windowSA>){
+			&windowSA::bool out_rule_condition2();,
+			&windowSA::void out_rule_body2();
+			&windowSA::void out_rule_flush2();
+		});
+	
+	
+	return list;
+	
+}
+
+void windowSA::executeInternalControlFlow(double h, double dt)
+{
+	this->doStep(window,h,dt);
+}
+double  windowSA::getFmiValueDouble(fmi2ValueReference id)
+{
+	switch (id)
+	{
+		case WINDOWDISP:
+		{
+			return this->disp;
+		}
+		case WINDOWFRICTION:
+		{
+			return this->friction;
+		}
+		case WINDOWTAU:
+		{
+			return this->tau;
+		}
+		default:
+		{
+			return 0.0;
+		}
+	}
+	
+}
+
+String  windowSA::getFmiValueString(fmi2ValueReference id)
+{
+	return "";
+}
+
+int  windowSA::getFmiValueInteger(fmi2ValueReference id)
+{
+	return 0;
+}
+
+bool  windowSA::getFmiValueBool(fmi2ValueReference id)
+{
+	return false;
+}
+
+void windowSA::setFmiValue(fmi2ValueReference id, double value)
+{
+	switch (id)	
+		{
+			case WINDOWDISPLACEMENT:
+			{
+				this->displacement = value;
+				this->isSetdisplacement = true;
+				break;
+			}
+			case WINDOWREACTION_FORCE:
+			{
+				this->reaction_force = value;
+				this->isSetreaction_force = true;
+				break;
+			}
+			case WINDOWSPEED:
+			{
+				this->speed = value;
+				this->isSetspeed = true;
+				break;
+			}
+			default:
+			{
+			}
+		}
+}
+
+void windowSA::setFmiValue(fmi2ValueReference id, String value)
+{
+}
+
+void windowSA::setFmiValue(fmi2ValueReference id, int value)
+{
+}
+
+void windowSA::setFmiValue(fmi2ValueReference id, bool value)
+{
+}

+ 78 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp.tests/test_input/single_folder_spec/window/correct/windowSA.h

@@ -0,0 +1,78 @@
+#define WINDOWDISP 0
+#define WINDOWDISPLACEMENT 1
+#define WINDOWFRICTION 2
+#define WINDOWREACTION_FORCE 3
+#define WINDOWSPEED 4
+#define WINDOWTAU 5
+#define WINDOWV 6
+#define WINDOWB 7
+#define WINDOWR 8
+
+#include "SemanticAdaptation.h"
+#include <memory>
+#include "Fmu.h"
+
+using namespace std;
+using namespace fmi2
+
+class windowSA : public SemanticAdaptation<windowSA>{
+	public:
+		windowSA();
+		virtual ~windowSA();
+		
+		void setFmiValue(fmi2ValueReference id, int value);
+		void setFmiValue(fmi2ValueReference id, bool value);
+		void setFmiValue(fmi2ValueReference id, double value);
+	
+		int getFmiValueInteger(fmi2ValueReference id);
+		bool getFmiValueBoolean(fmi2ValueReference id);
+		double getFmiValueDouble(fmi2ValueReference id);
+	private:
+		
+		windowSA* getRuleThis();
+		
+		/*in rules*/
+		bool in_rule_condition1();
+		void in_rule_body1();
+		void in_rule_flush1();
+		bool in_rule_condition2();
+		void in_rule_body2();
+		void in_rule_flush2();
+		bool in_rule_condition3();
+		void in_rule_body3();
+		void in_rule_flush3();
+		shared_ptr<list<Rule<windowSA>>> createInputRules;
+		
+		/*out rules*/
+		bool out_rule_condition1();
+		void out_rule_body1();
+		void out_rule_flush1();
+		bool out_rule_condition2();
+		void out_rule_body2();
+		void out_rule_flush2();
+		shared_ptr<list<Rule<windowSA>>> createOutputRules;
+		
+		void executeInternalControlFlow(double h, double dt);
+		
+		shared_ptr<Fmu> window;
+		
+		double disp;
+		double displacement;
+		bool isSetdisplacement;								
+		double friction;
+		double reaction_force;
+		bool isSetreaction_force;								
+		double speed;
+		bool isSetspeed;								
+		double tau;
+		double v;
+		double b;
+		double r;
+		
+		double stored_window_reaction_torque;
+		double stored_window_height;
+		
+		double stored_windowsa_reaction_force;
+		double stored_windowsa_displacement;
+		double stored_windowsa_speed;
+}

+ 245 - 228
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/CppGenerator.xtend

@@ -41,7 +41,17 @@ class CppGenerator extends SemanticAdaptationGenerator {
 			var String genSource = "";
 			var ModelDescription md;
 			// Load Model Description file
-			for (fmu : type.inner.eAllContents.toIterable.filter(InnerFMU)) {
+			val innerFmus = type.inner.eAllContents.toList.filter(InnerFMU);
+			if(innerFmus.size > 1)
+			{
+				throw new IncorrectAmountOfElementsException("Only one InnerFmu is supported.")
+			}
+			if(innerFmus.isEmpty)
+			{
+				throw new IncorrectAmountOfElementsException("The adaptation does not contain any InnerFMUs.")
+			}
+			
+			for (fmu : type.inner.eAllContents.toList.filter(InnerFMU)) {
 				// TODO: Merge this with ModelDescriptionCreator
 				md = new ModelDescription(fmu.name, fmu.type.name, new File(fmu.path.replace('\"', '')));
 				fmus.add(fmu.name -> fmu.type.name);
@@ -54,13 +64,13 @@ class CppGenerator extends SemanticAdaptationGenerator {
 			}
 
 			// Compile the in rules
-			val inRuleResult = compileInRuleBlock(adaptation.eAllContents.toIterable.filter(InRulesBlock), svDefs,
-				type.name);
+			val inRuleResult = compileInOutRuleBlocks(InputOutputType.Input, adaptation.eAllContents.toIterable.filter(
+				InRulesBlock).map[x|x as InOutRules], svDefs, type.name);
 			genSource += inRuleResult.generatedCpp;
 
 			// Compile the out rules
-			val outRuleResult = compileOutRuleBlock(adaptation.eAllContents.toIterable.filter(OutRulesBlock), svDefs,
-				type.name);
+			val outRuleResult = compileInOutRuleBlocks(InputOutputType.Output, adaptation.eAllContents.toIterable.
+				filter(OutRulesBlock).map[x|x as InOutRules], svDefs, type.name);
 			genSource += outRuleResult.generatedCpp;
 
 			// Generate the Control Rules
@@ -70,8 +80,8 @@ class CppGenerator extends SemanticAdaptationGenerator {
 
 			// Compile the includes and constructor 
 			val String include = '''#include "«type.name».h"''';
-			val String constructor = compileConstructor(type.name, outRuleResult, inRuleResult, sVars, fmus.head.key, fmus.head.value,
-				md.guid);
+			val String constructor = compileConstructor(type.name, outRuleResult, inRuleResult, sVars, fmus.head.key,
+				fmus.head.value, md.guid);
 			val String getRuleThis = compileGetRuleThis(type.name);
 			genSource = include + "\n\n" + constructor + "\n\n" + getRuleThis + "\n\n" + genSource;
 
@@ -96,261 +106,268 @@ class CppGenerator extends SemanticAdaptationGenerator {
 		}
 	}
 
-	def String compileHeader(String name, InOutRulesBlockResult inRulesResult, InOutRulesBlockResult outRulesResult,
-		RulesBlockResult crtlRulesResult, ArrayList<Pair<String, String>> fmus,
+	/*
+	 * Compiles the header file
+	 */
+	def String compileHeader(String adaptationName, InOutRulesBlockResult inRulesResult,
+		InOutRulesBlockResult outRulesResult, RulesBlockResult crtlRulesResult, ArrayList<Pair<String, String>> fmus,
 		LinkedHashMap<String, ScalarVariable> sVars) {
-			return '''
-				#include "SemanticAdaptation.h"
-				#include <memory>
-				#include "Fmu.h"
-				
-				using namespace std;
-				using namespace fmi2
+		return '''
+			#include "SemanticAdaptation.h"
+			#include <memory>
+			#include "Fmu.h"
+			
+			using namespace std;
+			using namespace fmi2
+			
+			class «adaptationName» : public SemanticAdaptation<«adaptationName»>{
+				public:
+					«adaptationName»();
+					virtual ~«adaptationName»();
+					
+					void setFmiValue(fmi2ValueReference id, int value);
+					void setFmiValue(fmi2ValueReference id, bool value);
+					void setFmiValue(fmi2ValueReference id, double value);
 				
-				class «name» : public SemanticAdaptation<«name»>{
-					public:
-						«name»();
-						virtual ~«name»();
-						
-						void setFmiValue(fmi2ValueReference id, int value);
-						void setFmiValue(fmi2ValueReference id, bool value);
-						void setFmiValue(fmi2ValueReference id, double value);
+					int getFmiValueInteger(fmi2ValueReference id);
+					bool getFmiValueBoolean(fmi2ValueReference id);
+					double getFmiValueDouble(fmi2ValueReference id);
+				private:
 					
-						int getFmiValueInteger(fmi2ValueReference id);
-						bool getFmiValueBoolean(fmi2ValueReference id);
-						double getFmiValueDouble(fmi2ValueReference id);
-					private:
-						
-						«name»* getRuleThis();
-						
-						/*in rules*/
-						«inRulesResult.functionSignatures.join("\n")»
-						
-						/*out rules*/
-						«outRulesResult.functionSignatures.join("\n")»
-						
-						«crtlRulesResult.functionSignatures.join("\n")»
-						
-						«FOR fmu : fmus»
-							shared_ptr<Fmu> «fmu.key»;
-						«ENDFOR»
-						
-						«FOR sv : sVars.entrySet»
-							«Conversions.fmiTypeToCppType(sv.value.type)» «sv.value.name»;
-							«IF sv.value.causality == SVCausality.input»
-								bool isSet«sv.value.name»;								
-							«ENDIF»
-						«ENDFOR»
-						
-						«FOR v : outRulesResult.globalVars.entrySet»
-							«Conversions.fmiTypeToCppType(v.value.key)» «v.key»;
-						«ENDFOR»
-						
-						«FOR v : inRulesResult.globalVars.entrySet»
-							«Conversions.fmiTypeToCppType(v.value.key)» «v.key»;
-						«ENDFOR»
-				}
-			''';
-		}
-
-		def compileConstructor(String name, InOutRulesBlockResult outRuleResult, InOutRulesBlockResult inRuleResult,
-			LinkedHashMap<String, ScalarVariable> sVars, String fmuName, String fmuTypeName, String guid) {
-			return '''
-				«name»::«name»(shared_ptr<std::string> resourceLocation) : SemanticAdaptation(createInputRules(),createOutputRules())
-				{
-					«FOR v : outRuleResult.globalVars.entrySet»
-						«(v.key)» = «v.value.value»;
-					«ENDFOR»
+					«adaptationName»* getRuleThis();
+					
+					/*in rules*/
+					«inRulesResult.functionSignatures.join("\n")»
 					
-					«FOR v : inRuleResult.globalVars.entrySet»
-						this->«(v.key)» = «v.value.value»;
+					/*out rules*/
+					«outRulesResult.functionSignatures.join("\n")»
+					
+					«crtlRulesResult.functionSignatures.join("\n")»
+					
+					«FOR fmu : fmus»
+						shared_ptr<Fmu> «fmu.key»;
 					«ENDFOR»
 					
-					«FOR v : sVars.entrySet»
-						«IF v.value.start !== null»
-							this->«(v.key)» = «v.value.start»;
+					«FOR sv : sVars.entrySet»
+						«Conversions.fmiTypeToCppType(sv.value.type)» «sv.value.name»;
+						«IF sv.value.causality == SVCausality.input»
+							bool isSet«sv.value.name»;								
 						«ENDIF»
 					«ENDFOR»
 					
-					const char* path = Fmu::combinePath(resourceLocation, make_shared<string>("«fmuTypeName».fmu"))->c_str();
-					auto «fmuName»Fmu = make_shared<fmi2::Fmu>(path);
-					«fmuName»Fmu->initialize();
-					this->«fmuName» = «fmuName»Fmu->instantiate("«fmuTypeName»",fmi2CoSimulation, "«guid»", true, true, make_shared<Callback>()); 
-				}
-			''';
-		}
-
-		def compileGetRuleThis(String name) {
-			return '''
-				«name»* «name»::getRuleThis()
-				{
-					return this;
-				}
-			'''
-		}
-
-		def compileGetFmuValueCppFuncSig(String adaptationName, SVType type) {
-			return '''«Conversions.fmiTypeToCppType(type)»  «adaptationName»::getFmiValue«Conversions.fmiTypeToCppTypeName(type)»(fmi2ValueReference id)''';
-		}
+					«FOR v : outRulesResult.globalVars.entrySet»
+						«Conversions.fmiTypeToCppType(v.value.key)» «v.key»;
+					«ENDFOR»
+					
+					«FOR v : inRulesResult.globalVars.entrySet»
+						«Conversions.fmiTypeToCppType(v.value.key)» «v.key»;
+					«ENDFOR»
+			}
+		''';
+	}
 
-		def compileGetFmuValueCppFuncReturn(SVType type) {
-			return '''return «Conversions.fmiTypeToCppDefaultValue(type)»''';
-		}
+	/*
+	 * Compiles the source file constructor 
+	 */
+	def String compileConstructor(String adaptationName, InOutRulesBlockResult outRuleResult,
+		InOutRulesBlockResult inRuleResult, LinkedHashMap<String, ScalarVariable> sVars, String fmuName,
+		String fmuTypeName, String guid) {
+		return '''
+			«adaptationName»::«adaptationName»(shared_ptr<std::string> resourceLocation) : SemanticAdaptation(createInputRules(),createOutputRules())
+			{
+				«FOR v : outRuleResult.globalVars.entrySet»
+					«(v.key)» = «v.value.value»;
+				«ENDFOR»
+				
+				«FOR v : inRuleResult.globalVars.entrySet»
+					this->«(v.key)» = «v.value.value»;
+				«ENDFOR»
+				
+				«FOR v : sVars.entrySet»
+					«IF v.value.start !== null»
+						this->«(v.key)» = «v.value.start»;
+					«ENDIF»
+				«ENDFOR»
+				
+				const char* path = Fmu::combinePath(resourceLocation, make_shared<string>("«fmuTypeName».fmu"))->c_str();
+				auto «fmuName»Fmu = make_shared<fmi2::Fmu>(path);
+				«fmuName»Fmu->initialize();
+				this->«fmuName» = «fmuName»Fmu->instantiate("«fmuTypeName»",fmi2CoSimulation, "«guid»", true, true, make_shared<Callback>()); 
+			}
+		''';
+	}
 
-		def compileGetFmuValue(String adaptationName, LinkedHashMap<String, ScalarVariable> sVars,
-			LinkedHashMap<String, Pair<String, Integer>> sVarDefs) {
-			var ArrayList<String> cpp = newArrayList();
-			var sVarsOrdered = sVars.entrySet.filter[value.causality === SVCausality.output].groupBy[value.type];
+	/*
+	 * Compiles the source file function getRuleThis
+	 */
+	def String compileGetRuleThis(String adaptationName) {
+		return '''
+			«adaptationName»* «adaptationName»::getRuleThis()
+			{
+				return this;
+			}
+		'''
+	}
 
-			for (SVType type : SVType.values) {
-				if (sVarsOrdered.containsKey(type)) {
-					cpp.add(
-						'''
-							«compileGetFmuValueCppFuncSig(adaptationName,type)»
+	/*
+	 * Compiles the source file functions getFmiValue<double, int, string, bool>
+	 */
+	def String compileGetFmuValue(String adaptationName, LinkedHashMap<String, ScalarVariable> sVars,
+		LinkedHashMap<String, Pair<String, Integer>> sVarDefs) {
+		var ArrayList<String> cpp = newArrayList();
+		var sVarsOrdered = sVars.entrySet.filter[value.causality === SVCausality.output].groupBy[value.type];
+
+		for (SVType type : SVType.values) {
+			val functionSignature = '''«Conversions.fmiTypeToCppType(type)»  «adaptationName»::getFmiValue«Conversions.fmiTypeToCppTypeName(type)»(fmi2ValueReference id)''';
+			val functionReturn = '''return «Conversions.fmiTypeToCppDefaultValue(type)»''';
+			if (sVarsOrdered.containsKey(type)) {
+				cpp.add(
+					'''
+						«functionSignature»
+						{
+							switch (id)
 							{
-								switch (id)
-								{
-									«FOR svInner : sVarsOrdered.get(type)»
-										case «sVarDefs.get(svInner.value.owner + svInner.value.name).key»:
-										{
-											return this->«svInner.key»;
-										}
-									«ENDFOR»
-									default:
+								«FOR svInner : sVarsOrdered.get(type)»
+									case «sVarDefs.get(svInner.value.owner + svInner.value.name).key»:
 									{
-										«compileGetFmuValueCppFuncReturn(type)»;
+										return this->«svInner.key»;
 									}
+								«ENDFOR»
+								default:
+								{
+									«functionReturn»;
 								}
-								
 							}
-						'''
-					);
-				} else {
-					cpp.add(
-						'''
-							«compileGetFmuValueCppFuncSig(adaptationName,type)»
-							{
-								«compileGetFmuValueCppFuncReturn(type)»;
-							}
-						'''
-					);
-				}
-			}
-
-			return cpp.join("\n");
-		}
-
-		def compileSetFmuValueCppFuncSig(String adaptationName, SVType type) {
-			return '''«Conversions.fmiTypeToCppType(type)»  «adaptationName»::getFmiValue«Conversions.fmiTypeToCppTypeName(type)»(fmi2ValueReference id)''';
-		}
-
-		def compileSetFmuValue(String adaptationName, LinkedHashMap<String, ScalarVariable> sVars,
-			LinkedHashMap<String, Pair<String, Integer>> sVarDefs) {
-			var ArrayList<String> cpp = newArrayList();
-			var sVarsOrdered = sVars.entrySet.filter[value.causality === SVCausality.input].groupBy[value.type];
-
-			for (SVType type : SVType.values) {
-
+							
+						}
+					'''
+				);
+			} else {
 				cpp.add(
 					'''
-						void «adaptationName»::setFmiValue(fmi2ValueReference id, «Conversions.fmiTypeToCppType(type)» value)
+						«functionSignature»
 						{
-							«IF sVarsOrdered.containsKey(type)»
-								switch (id)	
-									{
-										«FOR svInner : sVarsOrdered.get(type)»
-											case «sVarDefs.get(svInner.value.owner + svInner.value.name).key»:
-											{
-												this->«svInner.key» = value;
-												this->isSet«svInner.key» = true;
-												break;
-											}
-										«ENDFOR»
-										default:
-										{
-										}
-									}
-							«ENDIF»
+							«functionReturn»;
 						}
 					'''
 				);
-
 			}
-
-			return cpp.join("\n");
 		}
 
-		def RulesBlockResult compileControlRuleBlock(Iterable<ControlRuleBlock> crtlRuleBlocks, String name,
-			LinkedHashMap<String, Pair<String, Integer>> svDefs) {
-			var cpp = "";
-			val visitor = new ControlConditionSwitch(name, svDefs);
-			for (crtlRule : crtlRuleBlocks) {
-				cpp += visitor.doSwitch(crtlRule);
-			}
+		return cpp.join("\n");
+	}
 
-			return new RulesBlockResult(cpp, visitor.functionSignatures);
-		}
+	/*
+	 * Compiles the source file functions setFmiValue<double, int, string, bool>*
+	 */
+	def String compileSetFmuValue(String adaptationName, LinkedHashMap<String, ScalarVariable> sVars,
+		LinkedHashMap<String, Pair<String, Integer>> sVarDefs) {
+		var ArrayList<String> cpp = newArrayList();
+		var sVarsOrdered = sVars.entrySet.filter[value.causality === SVCausality.input].groupBy[value.type];
+
+		for (SVType type : SVType.values) {
+
+			cpp.add(
+				'''
+					void «adaptationName»::setFmiValue(fmi2ValueReference id, «Conversions.fmiTypeToCppType(type)» value)
+					{
+						«IF sVarsOrdered.containsKey(type)»
+							switch (id)	
+								{
+									«FOR svInner : sVarsOrdered.get(type)»
+										case «sVarDefs.get(svInner.value.owner + svInner.value.name).key»:
+										{
+											this->«svInner.key» = value;
+											this->isSet«svInner.key» = true;
+											break;
+										}
+									«ENDFOR»
+									default:
+									{
+									}
+								}
+						«ENDIF»
+					}
+				'''
+			);
 
-		def InOutRulesBlockResult compileOutRuleBlock(Iterable<OutRulesBlock> rulesBlocks,
-			LinkedHashMap<String, Pair<String, Integer>> svDefs, String name) {
-			return compileInOutRuleBlocks(new OutRulesConditionSwitch(name, svDefs), rulesBlocks.map[x|x as InOutRules],
-				svDefs, name, "createOutputRules");
 		}
 
-		def InOutRulesBlockResult compileInRuleBlock(Iterable<InRulesBlock> rulesBlocks,
-			LinkedHashMap<String, Pair<String, Integer>> svDefs, String name) {
-			return compileInOutRuleBlocks(new InRulesConditionSwitch(name, svDefs), rulesBlocks.map[x|x as InOutRules],
-				svDefs, name, "createInputRules");
+		return cpp.join("\n");
+	}
+
+	/*
+	 * Compiles the source file function executeInternalControlFlow.
+	 * Calculates necessary information on function signatures necessary for generation of the header file.
+	 */
+	def RulesBlockResult compileControlRuleBlock(Iterable<ControlRuleBlock> crtlRuleBlocks, String name,
+		LinkedHashMap<String, Pair<String, Integer>> svDefs) {
+		var cpp = "";
+		val visitor = new ControlConditionSwitch(name, svDefs);
+		for (crtlRule : crtlRuleBlocks) {
+			cpp += visitor.doSwitch(crtlRule);
 		}
 
-		def InOutRulesBlockResult compileInOutRuleBlocks(InOutRulesConditionSwitch visitor,
-			Iterable<InOutRules> rulesBlocks, LinkedHashMap<String, Pair<String, Integer>> svDefs, String name,
-			String functionName) {
-				var String cpp = "";
-				val ruleBlock = rulesBlocks.head;
-				if (ruleBlock !== null) {
-					cpp += visitor.doSwitch(ruleBlock);
-					if (!visitor.functionSignatures.empty) {
-						var ArrayList<String> createRulesFunction = newArrayList();
-						for (var int i = 0; i < (visitor.functionSignatures.length); i += 3) {
-							createRulesFunction.add( 
+		return new RulesBlockResult(cpp, visitor.functionSignatures);
+	}
+
+	/*
+	 * Compiles the source file functions <in/out>_rule_<condition, body, flush>.
+	 * Calculates necessary information on global in/out variables necessary for generation of the header file.
+	 * Calculates necessary information on function signatures necessary for generation of the header file.
+	 */
+	def InOutRulesBlockResult compileInOutRuleBlocks(InputOutputType ioType, Iterable<InOutRules> rulesBlocks,
+		LinkedHashMap<String, Pair<String, Integer>> svDefs, String name) {
+		val visitor = if(ioType == InputOutputType.Input) new InRulesConditionSwitch(name,
+				svDefs) else new OutRulesConditionSwitch(name, svDefs);
+		val functionName = "create" + ioType + "Rules";
+		var String cpp = "";
+		val ruleBlock = rulesBlocks.head;
+		if (ruleBlock !== null) {
+			cpp += visitor.doSwitch(ruleBlock);
+			if (!visitor.functionSignatures.empty) {
+				var ArrayList<String> createRulesFunction = newArrayList();
+				for (var int i = 0; i < (visitor.functionSignatures.length); i += 3) {
+					createRulesFunction.add( 
 					'''
-								list->push_back(
-									(Rule<«name»>){
-										&«name»::«visitor.functionSignatures.get(i)»,
-										&«name»::«visitor.functionSignatures.get(i+1)»
-										&«name»::«visitor.functionSignatures.get(i+2)»
-									});
-								
-							''');
-						}
-						val functionPrefix = '''shared_ptr<list<Rule<«name»>>>''';
-						visitor.functionSignatures.add(functionPrefix + " " + functionName + ";")
-						cpp += '''
-							«functionPrefix» «name»::«functionName»()
-							{
-								auto list = make_shared<list<Rule<«name»>>>()
-								
-								«createRulesFunction.join("\n")»
-								
-								return list;
-								
-							}
-							
-						'''
-					}
+						list->push_back(
+							(Rule<«name»>){
+								&«name»::«visitor.functionSignatures.get(i)»,
+								&«name»::«visitor.functionSignatures.get(i+1)»
+								&«name»::«visitor.functionSignatures.get(i+2)»
+							});
+						
+					''');
 				}
-				return new InOutRulesBlockResult(cpp, visitor.functionSignatures, visitor.globalVars);
+				val functionPrefix = '''shared_ptr<list<Rule<«name»>>>''';
+				visitor.functionSignatures.add(functionPrefix + " " + functionName + ";")
+				cpp += '''
+					«functionPrefix» «name»::«functionName»()
+					{
+						auto list = make_shared<list<Rule<«name»>>>()
+						
+						«createRulesFunction.join("\n")»
+						
+						return list;
+						
+					}
+					
+				'''
 			}
+		}
+		return new InOutRulesBlockResult(cpp, visitor.functionSignatures, visitor.globalVars);
+	}
 
-			def calcDefines(LinkedHashMap<String, Pair<String, Integer>> svDefs) {
-				// Create Defines for the scalar values
-				var defines = newArrayList();
-				for (scalar : svDefs.entrySet) {
-					val definition = scalar.value;
-					defines.add("#define " + definition.key + " " + definition.value);
-				}
-				return defines;
-			}
+	/*
+	 * Calculates defines for accessing scalar variables via value references. 
+	 */
+	def ArrayList<String> calcDefines(LinkedHashMap<String, Pair<String, Integer>> svDefs) {
+		// Create Defines for the scalar values
+		var defines = newArrayList();
+		for (scalar : svDefs.entrySet) {
+			val definition = scalar.value;
+			defines.add("#define " + definition.key + " " + definition.value);
 		}
-		
+		return defines;
+	}
+}

+ 8 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/IncorrectAmountOfElementsException.java

@@ -0,0 +1,8 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp;
+
+public class IncorrectAmountOfElementsException extends Exception {
+	
+	public IncorrectAmountOfElementsException(String arg0) {
+		super(arg0);
+	}
+}

+ 6 - 0
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/InputOutputType.java

@@ -0,0 +1,6 @@
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp;
+
+public enum InputOutputType {
+	Input,
+	Output
+}

+ 0 - 8
DSL_SemanticAdaptation/be.uantwerpen.ansymo.semanticadaptation.cg.cpp/src/be/uantwerpen/ansymo/semanticadaptation/cg/cpp/TooManyRulesException.java

@@ -1,8 +0,0 @@
-package be.uantwerpen.ansymo.semanticadaptation.cg.cpp;
-
-public class TooManyRulesException extends Exception {
-	
-	public TooManyRulesException(String arg0) {
-		super(arg0);
-	}
-}