|
@@ -1,27 +1,36 @@
|
|
-package be.uantwerpen.ansymo.semanticadaptation.cg.cpp
|
|
|
|
|
|
+package be.uantwerpen.ansymo.semanticadaptation.cg.cpp.generation
|
|
|
|
|
|
import be.uantwerpen.ansymo.semanticadaptation.generator.SemanticAdaptationGenerator
|
|
import be.uantwerpen.ansymo.semanticadaptation.generator.SemanticAdaptationGenerator
|
|
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
|
|
|
|
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.ControlRuleBlock
|
|
|
|
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InOutRules
|
|
|
|
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InRulesBlock
|
|
|
|
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InnerFMU
|
|
|
|
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.OutRulesBlock
|
|
|
|
|
|
+import org.eclipse.xtext.generator.IFileSystemAccess2
|
|
|
|
+
|
|
|
|
+import org.eclipse.xtext.generator.IGeneratorContext
|
|
import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
|
|
import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
|
|
-import java.io.File
|
|
|
|
|
|
+import org.eclipse.emf.ecore.resource.Resource
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
|
|
import java.util.ArrayList
|
|
import java.util.ArrayList
|
|
import java.util.LinkedHashMap
|
|
import java.util.LinkedHashMap
|
|
-import org.eclipse.emf.ecore.resource.Resource
|
|
|
|
-import org.eclipse.xtext.generator.IFileSystemAccess2
|
|
|
|
-import org.eclipse.xtext.generator.IGeneratorContext
|
|
|
|
-import java.util.Collection
|
|
|
|
-import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Port
|
|
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.MappedScalarVariable
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InnerFMU
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.exceptions.IncorrectAmountOfElementsException
|
|
|
|
+import java.io.File
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SAScalarVariable
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.InputOutputType
|
|
import org.eclipse.emf.common.util.EList
|
|
import org.eclipse.emf.common.util.EList
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Port
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVCausality
|
|
|
|
+import java.util.Collection
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InOutRules
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InRulesBlock
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.InOutRulesBlockResult
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.OutRulesBlock
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.GlobalInOutVariable
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.ControlRuleBlock
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.RulesBlockResult
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.ScalarVariable
|
|
|
|
+import java.util.List
|
|
|
|
+import be.uantwerpen.ansymo.semanticadaptation.cg.cpp.data.SVType
|
|
|
|
|
|
class CppGenerator extends SemanticAdaptationGenerator {
|
|
class CppGenerator extends SemanticAdaptationGenerator {
|
|
-
|
|
|
|
- var ModelDescriptionCreator mdCreator = new ModelDescriptionCreator()
|
|
|
|
-
|
|
|
|
private var IFileSystemAccess2 fsa;
|
|
private var IFileSystemAccess2 fsa;
|
|
|
|
|
|
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
|
|
override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
|
|
@@ -32,22 +41,25 @@ class CppGenerator extends SemanticAdaptationGenerator {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-// TODO: Verify adaptation.name is not a C++ keyword
|
|
|
|
-// TODO: Add initial value to inputs in the model description file
|
|
|
|
|
|
+ // TODO: Verify adaptation.name is not a C++ keyword
|
|
def void compile(SemanticAdaptation adaptation) {
|
|
def void compile(SemanticAdaptation adaptation) {
|
|
for (Adaptation type : adaptation.elements.filter(Adaptation)) {
|
|
for (Adaptation type : adaptation.elements.filter(Adaptation)) {
|
|
|
|
+ // Value used for scoping variables in the .sa file
|
|
val adapInteralRefName = type.name;
|
|
val adapInteralRefName = type.name;
|
|
|
|
+
|
|
|
|
+ // The CPP class name
|
|
val adapClassName = type.name.toFirstUpper;
|
|
val adapClassName = type.name.toFirstUpper;
|
|
|
|
+
|
|
|
|
+ // This is the external name used in the model description file for the semantic adaptation FMU.
|
|
val adapExternalName = type.type.name;
|
|
val adapExternalName = type.type.name;
|
|
- var LinkedHashMap<String, Pair<String, Integer>> svDefs = newLinkedHashMap();
|
|
|
|
|
|
+
|
|
|
|
+ // List of FMUs with a pairing between its name and its type.name.
|
|
var ArrayList<Pair<String, String>> fmus = newArrayList();
|
|
var ArrayList<Pair<String, String>> fmus = newArrayList();
|
|
- var LinkedHashMap<String, ScalarVariable> sVars = newLinkedHashMap();
|
|
|
|
- var String genSource = "";
|
|
|
|
- var ModelDescription md;
|
|
|
|
- var LinkedHashMap<String, Collection<ScalarVariable>> scalarVariables = newLinkedHashMap();
|
|
|
|
- var LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mappedScalarVariables = newLinkedHashMap();
|
|
|
|
|
|
|
|
- // Load Model Description file
|
|
|
|
|
|
+ // The scalar variables above with additional data
|
|
|
|
+ var LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mappedScalarVariables = newLinkedHashMap();
|
|
|
|
+
|
|
|
|
+ // TODO: Currently only 1 inner fmu is supported
|
|
val innerFmus = type.inner.eAllContents.toList.filter(InnerFMU);
|
|
val innerFmus = type.inner.eAllContents.toList.filter(InnerFMU);
|
|
if (innerFmus.size > 1) {
|
|
if (innerFmus.size > 1) {
|
|
throw new IncorrectAmountOfElementsException("Only one InnerFmu is supported.")
|
|
throw new IncorrectAmountOfElementsException("Only one InnerFmu is supported.")
|
|
@@ -56,95 +68,136 @@ class CppGenerator extends SemanticAdaptationGenerator {
|
|
throw new IncorrectAmountOfElementsException("The adaptation does not contain any InnerFMUs.")
|
|
throw new IncorrectAmountOfElementsException("The adaptation does not contain any InnerFMUs.")
|
|
}
|
|
}
|
|
|
|
|
|
- var LinkedHashMap<String,SAScalarVariable> SASVs = calcSASVsFromInportsOutports(adapInteralRefName, type.inports, type.outports)
|
|
|
|
-
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Loading the FMU defined in InnerFMU, the related model description file and its scalar variables.
|
|
|
|
+ * This is stored in a map of fmuName -> (SVName -> mappedSV)
|
|
|
|
+ * where the mappedSV contains the original scalar variable and some extra data such as define name.
|
|
|
|
+ */
|
|
|
|
+ // TODO: Currently only 1 model description is supported
|
|
|
|
+ var ModelDescription md;
|
|
for (fmu : type.inner.eAllContents.toList.filter(InnerFMU)) {
|
|
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('\"', '')));
|
|
md = new ModelDescription(fmu.name, fmu.type.name, new File(fmu.path.replace('\"', '')));
|
|
fmus.add(fmu.name -> fmu.type.name);
|
|
fmus.add(fmu.name -> fmu.type.name);
|
|
- svDefs.putAll(md.svDef);
|
|
|
|
- sVars.putAll(md.sv);
|
|
|
|
- scalarVariables.put(fmu.name, md.sv.values);
|
|
|
|
-
|
|
|
|
- mdCreator.name = adapExternalName;
|
|
|
|
- mdCreator.CalcContent(md);
|
|
|
|
- fsa.generateFile("modelDescription.xml", mdCreator.modelDescription);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * We might have conflicting scalar variables,
|
|
|
|
- * and therefore the scalar variables cannot be directly mapped to the mdCreator.
|
|
|
|
- * mappedScalarVariables is therefore: HashMap (fmuName -> HashMap(SVName->mappedSV))
|
|
|
|
- */
|
|
|
|
- for (mdSv : scalarVariables.entrySet) {
|
|
|
|
- val LinkedHashMap<String, MappedScalarVariable> msv = newLinkedHashMap();
|
|
|
|
- for (sv : mdSv.value) {
|
|
|
|
|
|
+ val LinkedHashMap<String, MappedScalarVariable> mSV = newLinkedHashMap();
|
|
|
|
+ for (sv : md.sv.values) {
|
|
var mappedSv = new MappedScalarVariable(sv);
|
|
var mappedSv = new MappedScalarVariable(sv);
|
|
mappedSv.define = (mappedSv.mappedSv.owner + mappedSv.mappedSv.name).toUpperCase;
|
|
mappedSv.define = (mappedSv.mappedSv.owner + mappedSv.mappedSv.name).toUpperCase;
|
|
- msv.put(mappedSv.mappedSv.name, mappedSv);
|
|
|
|
|
|
+ mSV.put(mappedSv.mappedSv.name, mappedSv);
|
|
}
|
|
}
|
|
- mappedScalarVariables.put(mdSv.key, msv);
|
|
|
|
|
|
+ mappedScalarVariables.put(fmu.name, mSV);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ // Defines for accessing FMU scalar variables.
|
|
|
|
+ val String fmusDefines = calcDefines2(mappedScalarVariables);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * This map contains all the ScalarVariables for the semantic adaptation.
|
|
|
|
+ * The are not populated yet, but they will be during the compilation of the in and out rule blocks.
|
|
|
|
+ */
|
|
|
|
+ var LinkedHashMap<String, SAScalarVariable> SASVs = calcSASVsFromInportsOutports(adapInteralRefName,
|
|
|
|
+ type.inports, type.outports)
|
|
|
|
+
|
|
|
|
+ // Generate defines for the scalar variables of the semantic adaptation
|
|
|
|
+ val String SADefines = calcSADefines(SASVs.values);
|
|
|
|
+
|
|
// Compile the in rules
|
|
// Compile the in rules
|
|
val inRuleResult = compileInOutRuleBlocks(InputOutputType.Input, adaptation.eAllContents.toIterable.filter(
|
|
val inRuleResult = compileInOutRuleBlocks(InputOutputType.Input, adaptation.eAllContents.toIterable.filter(
|
|
InRulesBlock).map[x|x as InOutRules], adapClassName, adapInteralRefName, mappedScalarVariables, SASVs);
|
|
InRulesBlock).map[x|x as InOutRules], adapClassName, adapInteralRefName, mappedScalarVariables, SASVs);
|
|
- genSource += inRuleResult.generatedCpp;
|
|
|
|
|
|
|
|
// Compile the out rules
|
|
// Compile the out rules
|
|
val outRuleResult = compileInOutRuleBlocks(InputOutputType.Output, adaptation.eAllContents.toIterable.
|
|
val outRuleResult = compileInOutRuleBlocks(InputOutputType.Output, adaptation.eAllContents.toIterable.
|
|
- filter(OutRulesBlock).map[x|x as InOutRules], adapClassName, adapInteralRefName, mappedScalarVariables, SASVs);
|
|
|
|
- genSource += outRuleResult.generatedCpp;
|
|
|
|
|
|
+ filter(OutRulesBlock).map[x|x as InOutRules], adapClassName, adapInteralRefName, mappedScalarVariables,
|
|
|
|
+ SASVs);
|
|
|
|
+
|
|
|
|
+ // Merge the global variables
|
|
|
|
+ // TODO: Check for duplicates
|
|
|
|
+ var LinkedHashMap<String, GlobalInOutVariable> globalVariables = newLinkedHashMap();
|
|
|
|
+ globalVariables.putAll(outRuleResult.globalVars2);
|
|
|
|
+ globalVariables.putAll(inRuleResult.globalVars2);
|
|
|
|
+
|
|
|
|
+ // Compile the Control Rules
|
|
|
|
+ val crtlRuleResult = compileControlRuleBlock(adaptation.eAllContents.toIterable.filter(ControlRuleBlock),
|
|
|
|
+ adapClassName, adapInteralRefName, SASVs);
|
|
|
|
|
|
/*
|
|
/*
|
|
- * We now have the explicit input and output values determined in the SA.
|
|
|
|
- * This along with the model descriptions should be enough to create a model description for the SA FMU.
|
|
|
|
|
|
+ * As the in and out rules have populated the semantic adaptation scalar variables we can generate the getFmiValue* and setFmiValue functions.
|
|
*/
|
|
*/
|
|
- // Generate the Control Rules
|
|
|
|
- val crtlRuleResult = compileControlRuleBlock(adaptation.eAllContents.toIterable.filter(ControlRuleBlock),
|
|
|
|
- adapClassName, adapInteralRefName, svDefs, SASVs);
|
|
|
|
- genSource += crtlRuleResult.generatedCpp;
|
|
|
|
-
|
|
|
|
- // Compile the source file includes, namespace and constructor
|
|
|
|
- val String include = '''#include "«adapClassName.toFirstLower».h"''';
|
|
|
|
- val String constructor = compileDeAndConstructor(adapClassName, outRuleResult, inRuleResult, sVars,
|
|
|
|
- fmus.head.key, fmus.head.value, md.guid);
|
|
|
|
- val String getRuleThis = compileGetRuleThis(adapClassName);
|
|
|
|
-
|
|
|
|
- // Compile the get functions
|
|
|
|
- val String getFuncs = compileGetFmuValue(adapClassName, sVars, svDefs);
|
|
|
|
-
|
|
|
|
- // Compile the set functions
|
|
|
|
- val String setFuncs = compileSetFmuValue(adapClassName, sVars, svDefs);
|
|
|
|
-
|
|
|
|
- // Generate the source file for the SA
|
|
|
|
- val source = compileSource(
|
|
|
|
- include,
|
|
|
|
- constructor,
|
|
|
|
- getRuleThis,
|
|
|
|
- getFuncs,
|
|
|
|
- setFuncs,
|
|
|
|
|
|
+ val String getFuncsSource = compileGetFmiValueFunctions(adapClassName, SASVs);
|
|
|
|
+ val String setFuncsSource = compileSetFmiValueFunctions(adapClassName, SASVs);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Compile the de and constructors
|
|
|
|
+ */
|
|
|
|
+ val String deAndConstructorSource = compileDeAndConstructor(adapClassName, globalVariables, fmus.head.key,
|
|
|
|
+ fmus.head.value, md.guid);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Compile getRuleThis function
|
|
|
|
+ */
|
|
|
|
+ val String getRuleThisSource = compileGetRuleThis(adapClassName);
|
|
|
|
+
|
|
|
|
+ // Compile the source file
|
|
|
|
+ val String sourceInclude = '''#include "«adapClassName.toFirstLower».h"''';
|
|
|
|
+ val sourceFile = compileSource(
|
|
|
|
+ sourceInclude,
|
|
|
|
+ deAndConstructorSource,
|
|
|
|
+ getRuleThisSource,
|
|
|
|
+ getFuncsSource,
|
|
|
|
+ setFuncsSource,
|
|
inRuleResult.generatedCpp,
|
|
inRuleResult.generatedCpp,
|
|
- crtlRuleResult.generatedCpp,
|
|
|
|
- outRuleResult.generatedCpp
|
|
|
|
|
|
+ outRuleResult.generatedCpp,
|
|
|
|
+ crtlRuleResult.generatedCpp
|
|
|
|
+ );
|
|
|
|
+ fsa.generateFile(adapClassName.toFirstLower + ".cpp", sourceFile);
|
|
|
|
+
|
|
|
|
+ // Compile the header file
|
|
|
|
+ val headerFile = compileHeader(
|
|
|
|
+ adapClassName,
|
|
|
|
+ fmusDefines,
|
|
|
|
+ SADefines,
|
|
|
|
+ inRuleResult.functionSignatures,
|
|
|
|
+ outRuleResult.functionSignatures,
|
|
|
|
+ crtlRuleResult.functionSignatures,
|
|
|
|
+ globalVariables,
|
|
|
|
+ fmus,
|
|
|
|
+ SASVs.values.map[CalcSVar()].toList
|
|
);
|
|
);
|
|
|
|
+ fsa.generateFile(adapClassName.toFirstLower + ".h", headerFile);
|
|
|
|
+
|
|
|
|
+ // Compile the model description file
|
|
|
|
+ val modelDescCreator = new ModelDescriptionCreator(adapExternalName);
|
|
|
|
+ val modelDescription = modelDescCreator.generateModelDescription(SASVs.values);
|
|
|
|
+ fsa.generateFile("modelDescription.xml", modelDescription);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ def calcSADefines(Collection<SAScalarVariable> variables) {
|
|
|
|
+ var ArrayList<String> defines = newArrayList();
|
|
|
|
+
|
|
|
|
+ for (SASV : variables) {
|
|
|
|
+ defines.add("#define " + SASV.defineName + " " + SASV.valueReference);
|
|
|
|
+ }
|
|
|
|
|
|
- fsa.generateFile(adapClassName.toFirstLower + ".cpp", source);
|
|
|
|
|
|
+ return defines.join("\n");
|
|
|
|
+ }
|
|
|
|
|
|
- // Compile defines for the scalar variables
|
|
|
|
- var genDef = calcDefines(svDefs).join("\n");
|
|
|
|
- // Compile the class definition file for the SA
|
|
|
|
- val String header = compileHeader(adapClassName, inRuleResult, outRuleResult, crtlRuleResult, fmus, sVars,
|
|
|
|
- genDef);
|
|
|
|
|
|
+ def calcDefines2(LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> map) {
|
|
|
|
+ var ArrayList<String> defines = newArrayList();
|
|
|
|
|
|
- // Generate the header file for the SA
|
|
|
|
- fsa.generateFile(adapClassName.toLowerCase + ".h", header);
|
|
|
|
|
|
+ for (fmuEntries : map.entrySet) {
|
|
|
|
+ for (MappedScalarVariable mSV : fmuEntries.value.values) {
|
|
|
|
+ defines.add("#define " + mSV.define + " " + mSV.valueReference);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ return defines.join("\n");
|
|
}
|
|
}
|
|
|
|
|
|
// Compiles the final source file
|
|
// Compiles the final source file
|
|
def String compileSource(String include, String constructor, String getRuleThis, String getFunctions,
|
|
def String compileSource(String include, String constructor, String getRuleThis, String getFunctions,
|
|
- String setFunctions, String inFunctions, String controlFunction, String outFunctions) {
|
|
|
|
|
|
+ String setFunctions, String inFunctions, String outFunctions, String controlFunction) {
|
|
return '''
|
|
return '''
|
|
«include»
|
|
«include»
|
|
|
|
|
|
@@ -173,9 +226,10 @@ class CppGenerator extends SemanticAdaptationGenerator {
|
|
* Compiles the header file split into two: The first part contains the includes and using namespace definitions and start the ,
|
|
* Compiles the header file split into two: The first part contains the includes and using namespace definitions and start the ,
|
|
* the second part contains the class
|
|
* the second part contains the class
|
|
*/
|
|
*/
|
|
- def String compileHeader(String adaptationName, InOutRulesBlockResult inRulesResult,
|
|
|
|
- InOutRulesBlockResult outRulesResult, RulesBlockResult crtlRulesResult, ArrayList<Pair<String, String>> fmus,
|
|
|
|
- LinkedHashMap<String, ScalarVariable> sVars, String defines) {
|
|
|
|
|
|
+ def String compileHeader(String adapClassName, String fmusDefines, String SADefines, List<String> inRulesFuncSig,
|
|
|
|
+ List<String> outRulesFuncSig, List<String> crtlRulesFuncSig,
|
|
|
|
+ LinkedHashMap<String, GlobalInOutVariable> globalVariables, ArrayList<Pair<String, String>> fmus,
|
|
|
|
+ Collection<ScalarVariable> sVars) {
|
|
return '''
|
|
return '''
|
|
#include "SemanticAdaptation.h"
|
|
#include "SemanticAdaptation.h"
|
|
#include <memory>
|
|
#include <memory>
|
|
@@ -186,11 +240,15 @@ class CppGenerator extends SemanticAdaptationGenerator {
|
|
|
|
|
|
namespace adaptation
|
|
namespace adaptation
|
|
{
|
|
{
|
|
|
|
+
|
|
|
|
+ «fmusDefines»
|
|
|
|
+
|
|
|
|
+ «SADefines»
|
|
|
|
|
|
- class «adaptationName» : public SemanticAdaptation<«adaptationName»>{
|
|
|
|
|
|
+ class «adapClassName» : public SemanticAdaptation<«adapClassName»>{
|
|
public:
|
|
public:
|
|
- «adaptationName»(shared_ptr<string> resourceLocation);
|
|
|
|
- virtual ~«adaptationName»();
|
|
|
|
|
|
+ «adapClassName»(shared_ptr<string> resourceLocation);
|
|
|
|
+ virtual ~«adapClassName»();
|
|
|
|
|
|
void setFmiValue(fmi2ValueReference id, int value);
|
|
void setFmiValue(fmi2ValueReference id, int value);
|
|
void setFmiValue(fmi2ValueReference id, bool value);
|
|
void setFmiValue(fmi2ValueReference id, bool value);
|
|
@@ -201,33 +259,29 @@ class CppGenerator extends SemanticAdaptationGenerator {
|
|
double getFmiValueDouble(fmi2ValueReference id);
|
|
double getFmiValueDouble(fmi2ValueReference id);
|
|
private:
|
|
private:
|
|
|
|
|
|
- «adaptationName»* getRuleThis();
|
|
|
|
|
|
+ «adapClassName»* getRuleThis();
|
|
|
|
|
|
/*in rules*/
|
|
/*in rules*/
|
|
- «inRulesResult.functionSignatures.join("\n")»
|
|
|
|
|
|
+ «inRulesFuncSig.join("\n")»
|
|
|
|
|
|
/*out rules*/
|
|
/*out rules*/
|
|
- «outRulesResult.functionSignatures.join("\n")»
|
|
|
|
|
|
+ «outRulesFuncSig.join("\n")»
|
|
|
|
|
|
- «crtlRulesResult.functionSignatures.join("\n")»
|
|
|
|
|
|
+ «crtlRulesFuncSig.join("\n")»
|
|
|
|
|
|
«FOR fmu : fmus»
|
|
«FOR fmu : fmus»
|
|
shared_ptr<FmuComponent> «fmu.key»;
|
|
shared_ptr<FmuComponent> «fmu.key»;
|
|
«ENDFOR»
|
|
«ENDFOR»
|
|
|
|
|
|
- «FOR sv : sVars.entrySet»
|
|
|
|
- «Conversions.fmiTypeToCppType(sv.value.type)» «sv.value.name»;
|
|
|
|
- «IF sv.value.causality == SVCausality.input»
|
|
|
|
- bool isSet«sv.value.name»;
|
|
|
|
|
|
+ «FOR sv : sVars»
|
|
|
|
+ «Conversions.fmiTypeToCppType(sv.type)» «sv.name»;
|
|
|
|
+ «IF sv.causality == SVCausality.input»
|
|
|
|
+ bool isSet«sv.name»;
|
|
«ENDIF»
|
|
«ENDIF»
|
|
«ENDFOR»
|
|
«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»;
|
|
|
|
|
|
+ «FOR v : globalVariables.entrySet»
|
|
|
|
+ «Conversions.fmiTypeToCppType(v.value.type)» «v.key»;
|
|
«ENDFOR»
|
|
«ENDFOR»
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -237,32 +291,21 @@ class CppGenerator extends SemanticAdaptationGenerator {
|
|
/*
|
|
/*
|
|
* Compiles the source file constructor and destructor
|
|
* Compiles the source file constructor and destructor
|
|
*/
|
|
*/
|
|
- def String compileDeAndConstructor(String adaptationName, InOutRulesBlockResult outRuleResult,
|
|
|
|
- InOutRulesBlockResult inRuleResult, LinkedHashMap<String, ScalarVariable> sVars, String fmuName,
|
|
|
|
- String fmuTypeName, String guid) {
|
|
|
|
|
|
+ def String compileDeAndConstructor(String adapClassName, LinkedHashMap<String, GlobalInOutVariable> globalVariables,
|
|
|
|
+ String fmuName, String fmuTypeName, String guid) {
|
|
return '''
|
|
return '''
|
|
- «adaptationName»::«adaptationName»(shared_ptr<string> resourceLocation) : SemanticAdaptation(createInputRules(),createOutputRules())
|
|
|
|
|
|
+ «adapClassName»::«adapClassName»(shared_ptr<string> resourceLocation) : SemanticAdaptation(createInputRules(),createOutputRules())
|
|
{
|
|
{
|
|
- «FOR v : outRuleResult.globalVars.entrySet»
|
|
|
|
- «(v.key)» = «v.value.value»;
|
|
|
|
- «ENDFOR»
|
|
|
|
-
|
|
|
|
- «FOR v : inRuleResult.globalVars.entrySet»
|
|
|
|
|
|
+ «FOR v : globalVariables.entrySet»
|
|
this->«(v.key)» = «v.value.value»;
|
|
this->«(v.key)» = «v.value.value»;
|
|
«ENDFOR»
|
|
«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();
|
|
const char* path = Fmu::combinePath(resourceLocation, make_shared<string>("«fmuTypeName».fmu"))->c_str();
|
|
auto «fmuName»Fmu = make_shared<fmi2::Fmu>(path);
|
|
auto «fmuName»Fmu = make_shared<fmi2::Fmu>(path);
|
|
«fmuName»Fmu->initialize();
|
|
«fmuName»Fmu->initialize();
|
|
- this->«fmuName» = «fmuName»Fmu->instantiate("«fmuTypeName»",fmi2CoSimulation, "«guid»", true, true, make_shared<Callback>());
|
|
|
|
|
|
+ this->«fmuName» = «fmuName»Fmu->instantiate("«fmuName»",fmi2CoSimulation, "«guid»", true, true, make_shared<Callback>());
|
|
}
|
|
}
|
|
- «adaptationName»::~«adaptationName»()
|
|
|
|
|
|
+ «adapClassName»::~«adapClassName»()
|
|
{
|
|
{
|
|
}
|
|
}
|
|
''';
|
|
''';
|
|
@@ -283,25 +326,25 @@ class CppGenerator extends SemanticAdaptationGenerator {
|
|
/*
|
|
/*
|
|
* Compiles the source file functions getFmiValue<double, int, string, bool>
|
|
* 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) {
|
|
|
|
|
|
+ def String compileGetFmiValueFunctions(String adaptationName, LinkedHashMap<String, SAScalarVariable> variables) {
|
|
var ArrayList<String> cpp = newArrayList();
|
|
var ArrayList<String> cpp = newArrayList();
|
|
- var sVarsOrdered = sVars.entrySet.filter[value.causality === SVCausality.output].groupBy[value.type];
|
|
|
|
|
|
+ var List<ScalarVariable> convertedSASVs = variables.values.map[CalcSVar()].toList;
|
|
|
|
+ var convertedSASVsOrdered = convertedSASVs.filter[causality === SVCausality.output].groupBy[type];
|
|
|
|
|
|
for (SVType type : SVType.values) {
|
|
for (SVType type : SVType.values) {
|
|
- val functionSignature = '''«Conversions.fmiTypeToCppType(type)» «adaptationName»::getFmiValue«type.toString»(fmi2ValueReference id)''';
|
|
|
|
|
|
+ val functionSignature = '''«Conversions.fmiTypeToCppType(type)» «adaptationName»::getFmiValue«type.toString»(fmi2ValueReference id)''';
|
|
val functionReturn = '''return «Conversions.fmiTypeToCppDefaultValue(type)»''';
|
|
val functionReturn = '''return «Conversions.fmiTypeToCppDefaultValue(type)»''';
|
|
- if (sVarsOrdered.containsKey(type)) {
|
|
|
|
|
|
+ if (convertedSASVsOrdered.containsKey(type)) {
|
|
cpp.add(
|
|
cpp.add(
|
|
'''
|
|
'''
|
|
«functionSignature»
|
|
«functionSignature»
|
|
{
|
|
{
|
|
switch (id)
|
|
switch (id)
|
|
{
|
|
{
|
|
- «FOR svInner : sVarsOrdered.get(type)»
|
|
|
|
- case «sVarDefs.get(svInner.value.owner + svInner.value.name).key»:
|
|
|
|
|
|
+ «FOR svInner : convertedSASVsOrdered.get(type)»
|
|
|
|
+ case «variables.get(svInner.name).defineName»:
|
|
{
|
|
{
|
|
- return this->«svInner.key»;
|
|
|
|
|
|
+ return this->«svInner.name»;
|
|
}
|
|
}
|
|
«ENDFOR»
|
|
«ENDFOR»
|
|
default:
|
|
default:
|
|
@@ -331,25 +374,26 @@ class CppGenerator extends SemanticAdaptationGenerator {
|
|
/*
|
|
/*
|
|
* Compiles the source file functions setFmiValue<double, int, string, bool>*
|
|
* 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) {
|
|
|
|
|
|
+ def String compileSetFmiValueFunctions(String adapClassName, LinkedHashMap<String, SAScalarVariable> variables) {
|
|
var ArrayList<String> cpp = newArrayList();
|
|
var ArrayList<String> cpp = newArrayList();
|
|
- var sVarsOrdered = sVars.entrySet.filter[value.causality === SVCausality.input].groupBy[value.type];
|
|
|
|
|
|
+ var List<ScalarVariable> convertedSASVs = variables.values.map[CalcSVar()].filter [
|
|
|
|
+ causality === SVCausality.input
|
|
|
|
+ ].toList;
|
|
|
|
+ var convertedSASVsOrdered = convertedSASVs.groupBy[type];
|
|
|
|
|
|
for (SVType type : SVType.values) {
|
|
for (SVType type : SVType.values) {
|
|
-
|
|
|
|
cpp.add(
|
|
cpp.add(
|
|
'''
|
|
'''
|
|
- void «adaptationName»::setFmiValue(fmi2ValueReference id, «Conversions.fmiTypeToCppType(type)» value)
|
|
|
|
|
|
+ void «adapClassName»::setFmiValue(fmi2ValueReference id, «Conversions.fmiTypeToCppType(type)» value)
|
|
{
|
|
{
|
|
- «IF sVarsOrdered.containsKey(type)»
|
|
|
|
|
|
+ «IF convertedSASVsOrdered.containsKey(type)»
|
|
switch (id)
|
|
switch (id)
|
|
{
|
|
{
|
|
- «FOR svInner : sVarsOrdered.get(type)»
|
|
|
|
- case «sVarDefs.get(svInner.value.owner + svInner.value.name).key»:
|
|
|
|
|
|
+ «FOR svInner : convertedSASVsOrdered.get(type)»
|
|
|
|
+ case «variables.get(svInner.name).defineName»:
|
|
{
|
|
{
|
|
- this->«svInner.key» = value;
|
|
|
|
- this->isSet«svInner.key» = true;
|
|
|
|
|
|
+ this->«svInner.name» = value;
|
|
|
|
+ this->isSet«svInner.name» = true;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
«ENDFOR»
|
|
«ENDFOR»
|
|
@@ -372,11 +416,11 @@ class CppGenerator extends SemanticAdaptationGenerator {
|
|
* Calculates necessary information on function signatures necessary for generation of the header file.
|
|
* Calculates necessary information on function signatures necessary for generation of the header file.
|
|
*/
|
|
*/
|
|
def RulesBlockResult compileControlRuleBlock(Iterable<ControlRuleBlock> crtlRuleBlocks, String adaptationClassName,
|
|
def RulesBlockResult compileControlRuleBlock(Iterable<ControlRuleBlock> crtlRuleBlocks, String adaptationClassName,
|
|
- String adaptationName, LinkedHashMap<String, Pair<String, Integer>> svDefs, LinkedHashMap<String, SAScalarVariable> SASVs) {
|
|
|
|
|
|
+ String adaptationName, LinkedHashMap<String, SAScalarVariable> SASVs) {
|
|
var cpp = "";
|
|
var cpp = "";
|
|
- val visitor = new ControlConditionSwitch(adaptationClassName, adaptationName, svDefs, SASVs);
|
|
|
|
|
|
+ val visitor = new ControlConditionSwitch(adaptationClassName, adaptationName, SASVs);
|
|
for (crtlRule : crtlRuleBlocks) {
|
|
for (crtlRule : crtlRuleBlocks) {
|
|
- cpp += visitor.doSwitch(crtlRule);
|
|
|
|
|
|
+ cpp += visitor.doSwitch(crtlRule).code;
|
|
}
|
|
}
|
|
|
|
|
|
return new RulesBlockResult(cpp, visitor.functionSignatures);
|
|
return new RulesBlockResult(cpp, visitor.functionSignatures);
|
|
@@ -393,18 +437,19 @@ class CppGenerator extends SemanticAdaptationGenerator {
|
|
*/
|
|
*/
|
|
def InOutRulesBlockResult compileInOutRuleBlocks(InputOutputType ioType, Iterable<InOutRules> rulesBlocks,
|
|
def InOutRulesBlockResult compileInOutRuleBlocks(InputOutputType ioType, Iterable<InOutRules> rulesBlocks,
|
|
String adaptationClassName, String adaptationName,
|
|
String adaptationClassName, String adaptationName,
|
|
- LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars, LinkedHashMap<String,SAScalarVariable> SASVs) {
|
|
|
|
-
|
|
|
|
|
|
+ LinkedHashMap<String, LinkedHashMap<String, MappedScalarVariable>> mSVars,
|
|
|
|
+ LinkedHashMap<String, SAScalarVariable> SASVs) {
|
|
|
|
+
|
|
val visitor = if (ioType == InputOutputType.Input)
|
|
val visitor = if (ioType == InputOutputType.Input)
|
|
new InRulesConditionSwitch(adaptationClassName, adaptationName, mSVars, SASVs)
|
|
new InRulesConditionSwitch(adaptationClassName, adaptationName, mSVars, SASVs)
|
|
else
|
|
else
|
|
new OutRulesConditionSwitch(adaptationClassName, adaptationName, mSVars, SASVs);
|
|
new OutRulesConditionSwitch(adaptationClassName, adaptationName, mSVars, SASVs);
|
|
-
|
|
|
|
|
|
+
|
|
val functionName = "create" + ioType + "Rules()";
|
|
val functionName = "create" + ioType + "Rules()";
|
|
var String cpp = "";
|
|
var String cpp = "";
|
|
val ruleBlock = rulesBlocks.head;
|
|
val ruleBlock = rulesBlocks.head;
|
|
if (ruleBlock !== null) {
|
|
if (ruleBlock !== null) {
|
|
- cpp += visitor.doSwitch(ruleBlock);
|
|
|
|
|
|
+ cpp += visitor.doSwitch(ruleBlock).code;
|
|
if (!visitor.functionSignatures.empty) {
|
|
if (!visitor.functionSignatures.empty) {
|
|
var ArrayList<String> createRulesFunction = newArrayList();
|
|
var ArrayList<String> createRulesFunction = newArrayList();
|
|
for (var int i = 0; i < (visitor.functionSignatures.length); i += 3) {
|
|
for (var int i = 0; i < (visitor.functionSignatures.length); i += 3) {
|
|
@@ -435,25 +480,17 @@ class CppGenerator extends SemanticAdaptationGenerator {
|
|
'''
|
|
'''
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- return new InOutRulesBlockResult(cpp, visitor.functionSignatures, visitor.globalVars);
|
|
|
|
|
|
+ return new InOutRulesBlockResult(cpp, visitor.functionSignatures, visitor.vars, visitor.getGlobalVars);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
- * Calculates defines for accessing scalar variables via value references.
|
|
|
|
|
|
+ * Calculates the semantic adaptation scalar variables via input ports and output ports.
|
|
|
|
+ * Note: These a not fully populated yet as the in rules and out rules must be compiled first.
|
|
*/
|
|
*/
|
|
- 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;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- def LinkedHashMap<String, SAScalarVariable> calcSASVsFromInportsOutports(String definePrefix, EList<Port> inports, EList<Port> outports) {
|
|
|
|
|
|
+ def LinkedHashMap<String, SAScalarVariable> calcSASVsFromInportsOutports(String definePrefix, EList<Port> inports,
|
|
|
|
+ EList<Port> outports) {
|
|
var LinkedHashMap<String, SAScalarVariable> saSVs = newLinkedHashMap();
|
|
var LinkedHashMap<String, SAScalarVariable> saSVs = newLinkedHashMap();
|
|
-
|
|
|
|
|
|
+
|
|
var int valueReference = 0;
|
|
var int valueReference = 0;
|
|
for (inport : inports) {
|
|
for (inport : inports) {
|
|
var saSV = new SAScalarVariable();
|
|
var saSV = new SAScalarVariable();
|
|
@@ -472,7 +509,7 @@ class CppGenerator extends SemanticAdaptationGenerator {
|
|
saSV.causality = SVCausality.output;
|
|
saSV.causality = SVCausality.output;
|
|
saSVs.put(saSV.name, saSV);
|
|
saSVs.put(saSV.name, saSV);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
return saSVs;
|
|
return saSVs;
|
|
}
|
|
}
|
|
}
|
|
}
|