Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Karlitschek2012-12-05 08:58:06 +0000
committerPeter Karlitschek2012-12-05 08:58:06 +0000
commit0ee43bf8f13c5d7d1d0db600ddf1875abb105477 (patch)
tree10294dc924f4f26cd80bee7b6f2f34cd35339eda /plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen
parent84afe757e7b94d028acfe3fb1076985526abce2e (diff)
parent73b4a1693e646cffb9691ccd231801e961bb9257 (diff)
downloadorg.eclipse.etrice-0ee43bf8f13c5d7d1d0db600ddf1875abb105477.tar.gz
org.eclipse.etrice-0ee43bf8f13c5d7d1d0db600ddf1875abb105477.tar.xz
org.eclipse.etrice-0ee43bf8f13c5d7d1d0db600ddf1875abb105477.zip
Merge branch 'master' of http://git.eclipse.org/gitroot/etrice/org.eclipse.etrice.git
Diffstat (limited to 'plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen')
-rw-r--r--plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ActorClassGen.xtend33
-rw-r--r--plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ConfigGenAddon.xtend286
-rw-r--r--plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/DataClassGen.xtend2
-rw-r--r--plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/Initialization.xtend130
-rw-r--r--plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaExtensions.xtend28
-rw-r--r--plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ProtocolClassGen.xtend2
-rw-r--r--plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/SubSystemClassGen.xtend69
-rw-r--r--plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/SubSystemRunnerGen.xtend11
-rw-r--r--plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/VariableServiceGen.xtend513
9 files changed, 604 insertions, 470 deletions
diff --git a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ActorClassGen.xtend b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ActorClassGen.xtend
index f9a08f30b..e6418cdf0 100644
--- a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ActorClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ActorClassGen.xtend
@@ -21,10 +21,10 @@ import org.eclipse.etrice.core.genmodel.etricegen.Root
import org.eclipse.xtext.generator.JavaIoFileSystemAccess
import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
import org.eclipse.etrice.generator.base.AbstractGenerator
-import org.eclipse.etrice.generator.generic.ConfigExtension
import org.eclipse.etrice.generator.generic.RoomExtensions
import org.eclipse.etrice.generator.generic.ProcedureHelpers
import org.eclipse.etrice.generator.generic.GenericActorClassGenerator
+import org.eclipse.etrice.generator.base.IDataConfiguration
@Singleton
class ActorClassGen extends GenericActorClassGenerator {
@@ -32,8 +32,8 @@ class ActorClassGen extends GenericActorClassGenerator {
@Inject JavaIoFileSystemAccess fileAccess
@Inject extension JavaExtensions
@Inject extension RoomExtensions
- @Inject extension ConfigExtension
- @Inject ConfigGenAddon configAddon
+ @Inject IDataConfiguration dataConfigExt
+ @Inject ConfigGenAddon configGenAddon
@Inject extension ProcedureHelpers
@Inject extension Initialization
@@ -53,14 +53,14 @@ class ActorClassGen extends GenericActorClassGenerator {
def generate(Root root, ExpandedActorClass xpac, ActorClass ac) {
val ctor = ac.operations.filter(op|op.constructor).head
val dtor = ac.operations.filter(op|op.destructor).head
- val dynConfigReadAttributes = ac.getDynConfigAttributes(true, false)
- val dynConfigWriteAttributes = ac.getDynConfigAttributes(false, true)
'''
package «ac.getPackage»;
- «IF !dynConfigReadAttributes.empty»import org.eclipse.etrice.runtime.java.config.DynConfigLock;«ENDIF»
- «IF !dynConfigReadAttributes.empty || !dynConfigWriteAttributes.empty»import org.eclipse.etrice.runtime.java.config.VariableService;«ENDIF»
+ «IF !dataConfigExt.getDynConfigReadAttributes(ac).empty»
+ import org.eclipse.etrice.runtime.java.config.DynConfigLock;«ENDIF»
+ «IF !dataConfigExt.getDynConfigReadAttributes(ac).empty || !dataConfigExt.getDynConfigWriteAttributes(ac).empty»
+ import org.eclipse.etrice.runtime.java.config.VariableService;«ENDIF»
import org.eclipse.etrice.runtime.java.messaging.Address;
import org.eclipse.etrice.runtime.java.messaging.IRTObject;
import org.eclipse.etrice.runtime.java.messaging.IMessageReceiver;
@@ -85,7 +85,7 @@ class ActorClassGen extends GenericActorClassGenerator {
«ac.userCode(2)»
- «IF !dynConfigWriteAttributes.empty»
+ «IF !dataConfigExt.getDynConfigWriteAttributes(ac).empty»
private VariableService variableService;
«ENDIF»
@@ -107,9 +107,9 @@ class ActorClassGen extends GenericActorClassGenerator {
//--------------------- interface item IDs
«genInterfaceItemConstants(xpac, ac)»
- «configAddon.genMinMaxConstants(ac)»
+ «configGenAddon.genMinMaxConstants(ac)»
«ac.attributes.attributes»
- «FOR a : dynConfigReadAttributes»
+ «FOR a : dataConfigExt.getDynConfigReadAttributes(ac)»
private DynConfigLock lock_«a.name»;
«ENDFOR»
«ac.operationsImplementation»
@@ -123,7 +123,7 @@ class ActorClassGen extends GenericActorClassGenerator {
«ENDIF»
setClassName("«ac.name»");
- «ac.attributes.attributeInitialization(false)»
+ «ac.attributes.attributeInitialization(ac, false)»
// own ports
«FOR ep : ac.getEndPorts()»
@@ -148,22 +148,22 @@ class ActorClassGen extends GenericActorClassGenerator {
«ENDIF»
}
- «IF !dynConfigReadAttributes.empty || !dynConfigWriteAttributes.empty»
+ «IF !dataConfigExt.getDynConfigReadAttributes(ac).empty || !dataConfigExt.getDynConfigWriteAttributes(ac).empty»
public «ac.name»(IRTObject parent, String name, Address[][] port_addr, Address[][] peer_addr, VariableService variableService){
this(parent, name, port_addr, peer_addr);
- «IF !dynConfigWriteAttributes.empty»
+ «IF !dataConfigExt.getDynConfigWriteAttributes(ac).empty»
this.variableService = variableService;
«ENDIF»
- «FOR a : dynConfigReadAttributes»
+ «FOR a : dataConfigExt.getDynConfigReadAttributes(ac)»
lock_«a.name» = new DynConfigLock();
«ENDFOR»
}
«ENDIF»
- «attributeSettersGettersImplementation(ac.attributes.minus(dynConfigReadAttributes.toList), ac.name)»
+ «attributeSettersGettersImplementation(ac.attributes.minus(dataConfigExt.getDynConfigReadAttributes(ac)), ac.name)»
- «configAddon.genDynConfigGetterSetter(ac)»
+ «configGenAddon.genDynConfigGetterSetter(ac)»
//--------------------- port getters
«FOR ep : ac.getEndPorts()»
@@ -213,4 +213,5 @@ class ActorClassGen extends GenericActorClassGenerator {
};
'''
}
+
}
diff --git a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ConfigGenAddon.xtend b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ConfigGenAddon.xtend
index c7fb05a5f..d2f075813 100644
--- a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ConfigGenAddon.xtend
+++ b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ConfigGenAddon.xtend
@@ -1,121 +1,179 @@
-/*******************************************************************************
- * Copyright (c) 2012 Juergen Haug
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Juergen Haug
- *
- *******************************************************************************/
-
+/*******************************************************************************
+ * Copyright (c) 2012 Juergen Haug
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Juergen Haug
+ *
+ *******************************************************************************/
+
package org.eclipse.etrice.generator.java.gen
import com.google.inject.Inject
+import java.util.ArrayList
import java.util.List
-import org.eclipse.etrice.core.config.AttrInstanceConfig
+import org.eclipse.etrice.core.genmodel.etricegen.ActorInstance
import org.eclipse.etrice.core.room.ActorClass
+import org.eclipse.etrice.core.room.Attribute
+import org.eclipse.etrice.core.room.DataClass
+import org.eclipse.etrice.core.room.GeneralProtocolClass
+import org.eclipse.etrice.core.room.InterfaceItem
import org.eclipse.etrice.core.room.PrimitiveType
-import org.eclipse.etrice.generator.generic.ConfigExtension
+import org.eclipse.etrice.core.room.ProtocolClass
+import org.eclipse.etrice.generator.base.IDataConfiguration
import org.eclipse.etrice.generator.generic.ProcedureHelpers
-import org.eclipse.etrice.generator.generic.TypeHelpers
-
-
-class ConfigGenAddon {
-
- @Inject extension JavaExtensions stdExt
- @Inject extension TypeHelpers typeHelpers
- @Inject extension ProcedureHelpers helpers
- @Inject extension ConfigExtension configExt
-
- // For SubSystemClassGen
-
- def public applyInstanceConfig(String instance, String className, List<AttrInstanceConfig> attrConfigs){'''
- «FOR attrConfig : attrConfigs»
- «var a = attrConfig.attribute»
- «var aType = a.refType.type»
- «IF aType.primitive»
- «var values = attrConfig.value?.values»
- «IF values == null»
- «ELSEIF a.size == 0 || aType.characterType»
- «instance».«a.name.invokeSetter(className, (aType as PrimitiveType).toValueLiteral(values.get(0)))»;
- «ELSEIF a.size == values.size»
- «instance».«a.name.invokeSetter(className, "new "+aType.typeName+"[]"+(aType as PrimitiveType).toArrayValueLiteral(values))»;
- «ELSE»
- {
- «aType.typeName»[] array = «instance».«a.name.invokeGetter(className)»;
- for (int i=0;i<«a.size»;i++){
- array[i] = «(aType as PrimitiveType).toValueLiteral(values.get(0))»;
- }
- }
- «ENDIF»
- «ELSEIF aType.dataClass»
- «(instance+"."+a.name.invokeGetter(className)).applyInstanceConfig(aType.typeName, attrConfig.attributes)»
- «ENDIF»
- «ENDFOR»
- '''}
-
- // For ActorClassGen
-
- def public genDynConfigGetterSetter(ActorClass ac){'''
- «FOR a : ac.getDynConfigAttributes(true, false)»
- public «a.refType.type.typeName»«IF a.size>0»[]«ENDIF» get«a.name.toFirstUpper»(){
- if(lock_«a.name» == null)
- return «a.name»;
- else
- synchronized(lock_«a.name»){
- return «a.name»;
- }
- }
- public void set«a.name.toFirstUpper»(«a.refType.type.typeName»«IF a.size>0»[]«ENDIF» «a.name»){
- if(lock_«a.name» == null)
- this.«a.name» = «a.name»;
- else
- synchronized(lock_«a.name»){
- this.«a.name» = «a.name»;
- }
- }
- public DynConfigLock get«a.name.toFirstUpper»Lock(){
- return lock_«a.name»;
- }
- «ENDFOR»
- «FOR a : ac.getDynConfigAttributes(false, true)»
- public void setAndWrite«a.name.toFirstUpper»(«a.refType.type.typeName»«IF a.size>0»[]«ENDIF» «a.name»){
- set«a.name.toFirstUpper»(«a.name»);
- variableService.write(this.getInstancePath()+"/«a.name»", «a.name»);
- }
- «ENDFOR»
- '''}
-
- def public genMinMaxConstants(ActorClass ac){
- var attrConfigs = ac.allAttrConfigFlat.filter(c | c.min != null || c.max != null)
- '''
- «IF !attrConfigs.empty»
- //--------------------- attribute specifications
- «ENDIF»
-
- «FOR c : attrConfigs»
- «var aType = (c.attribute.refType.type as PrimitiveType)»
- «IF c.min != null»
- public static «aType.minMaxType» MIN«c.getPath(false, false, true, true).toPath("_")» = «aType.toValueLiteral(c.min.value)»;
- «ENDIF»
- «IF c.max != null»
- public static «aType.minMaxType» MAX«c.getPath(false, false, true, true).toPath("_")» = «aType.toValueLiteral(c.max.value)»;
- «ENDIF»
- «ENDFOR»
- '''
- }
-
- def private getMinMaxType(PrimitiveType type){
- switch(type.typeName){
- case "byte":
- return "int"
- case "short":
- return "int"
- case "float":
- return "double"
- }
- return type.typeName
- }
-} \ No newline at end of file
+import org.eclipse.etrice.generator.generic.RoomExtensions
+import org.eclipse.etrice.generator.generic.TypeHelpers
+import org.eclipse.etrice.core.room.ExternalType
+
+class ConfigGenAddon {
+
+ @Inject extension JavaExtensions stdExt
+ @Inject extension TypeHelpers typeHelpers
+ @Inject extension ProcedureHelpers helpers
+ @Inject IDataConfiguration dataConfigExt
+ @Inject extension RoomExtensions
+
+ // For SubSystemClassGen
+
+ def public genActorInstanceConfig(ActorInstance ai, String aiVariableName){'''
+ «FOR a : ai.actorClass.attributes»
+ «applyInstanceConfig(ai, null, aiVariableName, new ArrayList<Attribute>().union(a))»
+ «ENDFOR»
+ «FOR p : ai.actorClass.allEndPorts»
+ «FOR a : getAttributes(p.protocol, !p.conjugated)»
+ «applyInstanceConfig(ai, p, aiVariableName+"."+invokeGetter(p.name, null), new ArrayList<Attribute>().union(a))»
+ «ENDFOR»
+ «ENDFOR»
+ «FOR sap : ai.actorClass.allSAPs»
+ «FOR a : getAttributes(sap.protocol, true)»
+ «applyInstanceConfig(ai, sap, aiVariableName+"."+invokeGetter(sap.name, null), new ArrayList<Attribute>().union(a))»
+ «ENDFOR»
+ «ENDFOR»
+ '''
+ }
+
+ def private List<Attribute> getAttributes(GeneralProtocolClass gpc, boolean regular){
+ var result = new ArrayList<Attribute>
+ if(gpc instanceof ProtocolClass){
+ var protocol = gpc as ProtocolClass
+ if(regular && protocol.regular?.attributes != null)
+ result.addAll(protocol.regular.attributes)
+ else if(!regular && protocol.conjugate?.attributes != null)
+ result.addAll(protocol.conjugate.attributes)
+ }
+ return result
+ }
+
+ def private applyInstanceConfig(ActorInstance ai, InterfaceItem port, String invokes, List<Attribute> path){
+ var a = path.last
+ var aType = a.refType.type
+ if(aType.primitive){
+ var value = if(port==null)dataConfigExt.getAttrInstanceConfigValue(ai, path)
+ else dataConfigExt.getAttrInstanceConfigValue(ai, port, path)
+ if(value == null)
+ ''''''
+ else if(a.size == 0 || aType.characterType)
+ '''«invokes».«a.name.invokeSetter(null, (aType as PrimitiveType).toValueLiteral(value))»;'''
+ else if(a.size == value.split(",").size){
+ var arrayExpr = '''{ «FOR s : value.split(",") SEPARATOR ', '»«(aType as PrimitiveType).toValueLiteral(s.trim)»«ENDFOR» }'''
+ '''«invokes».«a.name.invokeSetter(null, '''new «aType.typeName»[] «arrayExpr»'''.toString)»;'''
+ } else '''
+ {
+ «aType.typeName»[] array = «invokes».«a.name.invokeGetter(null)»;
+ for (int i=0;i<«a.size»;i++){
+ array[i] = «(aType as PrimitiveType).toValueLiteral(value)»;
+ }'''
+ }
+ else if (aType.dataClass)'''
+ «FOR e : (aType as DataClass).attributes»
+ «applyInstanceConfig(ai, port, invokes+"."+a.name.invokeGetter(null), path.union(e))»
+ «ENDFOR»
+ '''
+ }
+
+ // For ActorClassGen
+
+ def public genDynConfigGetterSetter(ActorClass ac){'''
+ «FOR a : dataConfigExt.getDynConfigReadAttributes(ac)»
+ public «a.refType.type.typeName»«IF a.size>0»[]«ENDIF» get«a.name.toFirstUpper»(){
+ if(lock_«a.name» == null)
+ return «a.name»;
+ else
+ synchronized(lock_«a.name»){
+ return «a.name»;
+ }
+ }
+ public void set«a.name.toFirstUpper»(«a.refType.type.typeName»«IF a.size>0»[]«ENDIF» «a.name»){
+ if(lock_«a.name» == null)
+ this.«a.name» = «a.name»;
+ else
+ synchronized(lock_«a.name»){
+ this.«a.name» = «a.name»;
+ }
+ }
+ public DynConfigLock get«a.name.toFirstUpper»Lock(){
+ return lock_«a.name»;
+ }
+ «ENDFOR»
+ «FOR a : dataConfigExt.getDynConfigWriteAttributes(ac)»
+ public void setAndWrite«a.name.toFirstUpper»(«a.refType.type.typeName»«IF a.size>0»[]«ENDIF» «a.name»){
+ set«a.name.toFirstUpper»(«a.name»);
+ variableService.write(this.getInstancePath()+"/«a.name»", «a.name»);
+ }
+ «ENDFOR»
+ '''}
+
+ def public genMinMaxConstants(ActorClass ac){
+ var result = '''
+ «FOR a : ac.attributes»
+ «genMinMaxConstantsRec(ac, a.name, new ArrayList<Attribute>().union(a))»
+ «ENDFOR»
+ '''
+ if(result.length != 0)
+ result = result+'''//--------------------- Attribute Specifications'''
+ return result
+ }
+
+ def private genMinMaxConstantsRec(ActorClass ac, String varNamePath, List<Attribute> path){
+ var temp = null as String
+ if (path.last.refType.type.dataClass)
+ '''
+ «FOR e : (path.last.refType.type as DataClass).allAttributes»
+ «genMinMaxConstantsRec(ac, varNamePath+"_"+e.name, path.union(e))»
+ «ENDFOR»
+ '''
+ else if (path.last.refType.type instanceof ExternalType) {
+ // do nothing
+ }
+ else
+ {
+ var aType = (path.last.refType.type as PrimitiveType)
+ '''
+ «IF (temp = dataConfigExt.getAttrClassConfigMinValue(ac, path)) != null»
+ public static «aType.minMaxType» MIN_«varNamePath» = «aType.toValueLiteral(temp)»;
+ «ENDIF»
+ «IF (temp = dataConfigExt.getAttrClassConfigMaxValue(ac, path)) != null»
+ public static «aType.minMaxType» MAX_«varNamePath» = «aType.toValueLiteral(temp)»;
+ «ENDIF»
+ '''
+ }
+ }
+
+ def private getMinMaxType(PrimitiveType type){
+ return switch(type.typeName){
+ case "byte":
+ "int"
+ case "short":
+ "int"
+ case "float":
+ "double"
+ default:
+ type.typeName
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/DataClassGen.xtend b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/DataClassGen.xtend
index 6c8c44c6d..327c4f459 100644
--- a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/DataClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/DataClassGen.xtend
@@ -74,7 +74,7 @@ class DataClassGen {
public «dc.name»() {
super();
- «dc.attributes.attributeInitialization(true)»
+ «dc.attributes.attributeInitialization(dc, true)»
«IF ctor!=null»
{
diff --git a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/Initialization.xtend b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/Initialization.xtend
index 5ae8109b5..f3484e9cb 100644
--- a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/Initialization.xtend
+++ b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/Initialization.xtend
@@ -12,56 +12,122 @@
package org.eclipse.etrice.generator.java.gen
-import org.eclipse.etrice.core.room.Attribute
-import java.util.List
import com.google.inject.Inject
-import org.eclipse.etrice.generator.generic.ConfigExtension
-import org.eclipse.etrice.generator.generic.TypeHelpers
+import com.google.inject.Singleton
+import java.util.ArrayList
+import java.util.List
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.etrice.core.room.ActorClass
+import org.eclipse.etrice.core.room.Attribute
import org.eclipse.etrice.core.room.ComplexType
+import org.eclipse.etrice.core.room.DataClass
+import org.eclipse.etrice.core.room.PortClass
+import org.eclipse.etrice.core.room.PrimitiveType
+import org.eclipse.etrice.core.room.ProtocolClass
+import org.eclipse.etrice.generator.base.IDataConfiguration
import org.eclipse.etrice.generator.generic.ILanguageExtension
-import com.google.inject.Singleton
+import org.eclipse.etrice.generator.generic.ProcedureHelpers
+import org.eclipse.etrice.generator.generic.RoomExtensions
+import org.eclipse.etrice.generator.generic.TypeHelpers
@Singleton
class Initialization {
- @Inject extension ConfigExtension
@Inject extension TypeHelpers
+ @Inject extension RoomExtensions
@Inject ILanguageExtension languageExt
+ @Inject IDataConfiguration dataConfigExt
+ @Inject ProcedureHelpers procedureHelpers
- def attributeInitialization(List<Attribute> attribs, boolean useClassDefaultsOnly) {
+ def attributeInitialization(List<Attribute> attribs, EObject roomClass, boolean useClassDefaultsOnly) {
+ var tmp = ''''''
'''
// initialize attributes
«FOR a : attribs»
- «var aType = a.refType.type»
- «var value = a.initValueLiteral»
- «IF value!=null»
- «IF a.size == 0 || aType.characterType»
- «a.name» = «value»;
- «ELSEIF value.startsWith("{")»
- «a.name» = new «aType.typeName»[] «value»;
- «ELSE»
- «a.name» = new «aType.typeName»[«a.size»];
+ «tmp = dataConfigurationInit(roomClass, new ArrayList<Attribute>.union(a))»
+ «IF tmp.length==0»«(tmp = valueInit(new ArrayList<Attribute>.union(a), getRoomDefaulValue(a)))»«ENDIF»
+ «IF tmp.length==0»«defaultInit(a, useClassDefaultsOnly)»«ENDIF»
+ «ENDFOR»
+ '''
+ }
+ def private dataConfigurationInit(EObject roomClass, List<Attribute> path){
+ var a = path.last
+ var aType = a.refType.type
+ if(aType.dataClass){
+ return '''
+ «FOR e : (aType as DataClass).attributes»
+ «dataConfigurationInit(roomClass, path.union(e))»
+ «ENDFOR»
+ '''
+ }
+ else if(aType.primitive)
+ return valueInit(path, getDataConfigValue(roomClass, path))
+ ''''''
+ }
+
+ def private valueInit(List<Attribute> path, String literalValue){
+ if(literalValue == null) return ''''''
+ var a = path.last
+ var aType = a.refType.type
+ var getter = if(path.size > 1)procedureHelpers.invokeGetters(path.take(path.size-1), null)+"." else ""
+ '''
+ «IF a.size == 0 || aType.characterType»
+ «getter»«procedureHelpers.invokeSetter(a.name,null,literalValue)»;
+ «ELSEIF literalValue.startsWith("{")»
+ «getter»«procedureHelpers.invokeSetter(a.name,null, '''new «aType.typeName»[] «literalValue»''')»;
+ «ELSE»
+ {
+ «aType.typeName»[] _«a.name» = new «aType.typeName»[«a.size»];
for (int i=0;i<«a.size»;i++){
- «a.name»[i] = «value»;
+ _«a.name»[i] = «literalValue»;
}
- «ENDIF»
- «ELSEIF aType instanceof ComplexType || a.size>1 || !useClassDefaultsOnly»
- «IF a.size==0»
- «IF a.refType.isRef»
- «a.name» = «languageExt.nullPointer()»;
- «ELSE»
- «a.name» = «languageExt.defaultValue(aType)»;
- «ENDIF»
+ «getter»«procedureHelpers.invokeSetter(a.name,null,"_"+a.name)»;
+ }
+ «ENDIF»
+ '''
+ }
+
+ def private defaultInit(Attribute a, boolean useClassDefaultsOnly){
+ '''
+ «IF a.refType.type instanceof ComplexType || a.size>1 || !useClassDefaultsOnly»
+ «IF a.size==0»
+ «IF a.refType.isRef»
+ «a.name» = «languageExt.nullPointer()»;
«ELSE»
- «a.name» = new «aType.typeName»[«a.size»];
- «IF !useClassDefaultsOnly»
- for (int i=0;i<«a.size»;i++){
- «a.name»[i] = «IF a.refType.isRef»«languageExt.nullPointer()»«ELSE»«languageExt.defaultValue(aType)»«ENDIF»;
- }
- «ENDIF»
+ «a.name» = «languageExt.defaultValue(a.refType.type)»;
+ «ENDIF»
+ «ELSE»
+ «a.name» = new «a.refType.type.typeName»[«a.size»];
+ «IF !useClassDefaultsOnly»
+ for (int i=0;i<«a.size»;i++){
+ «a.name»[i] = «IF a.refType.isRef»«languageExt.nullPointer()»«ELSE»«languageExt.defaultValue(a.refType.type)»«ENDIF»;
+ }
«ENDIF»
«ENDIF»
- «ENDFOR»
+ «ENDIF»
'''
}
+
+ def String getRoomDefaulValue(Attribute a){
+ if(a.refType.type.primitive && a.defaultValueLiteral != null)
+ languageExt.toValueLiteral(a.refType.type as PrimitiveType, a.defaultValueLiteral)
+ }
+
+ def private String getDataConfigValue(EObject roomClass, List<Attribute> path){
+ var a = path.last
+ if(a.refType.type.primitive){
+ var aType = a.refType.type as PrimitiveType
+ var result = switch roomClass {
+ ActorClass: dataConfigExt.getAttrClassConfigValue(roomClass, path)
+ PortClass:
+ if(roomClass.eContainer instanceof ProtocolClass){
+ var pc = roomClass.eContainer as ProtocolClass
+ dataConfigExt.getAttrClassConfigValue(pc, pc.regular.equals(roomClass), path)
+ }
+ }
+ if(result != null)
+ return languageExt.toValueLiteral(aType, result)
+ }
+ }
+
} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaExtensions.xtend b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaExtensions.xtend
index e461a45fd..d76f23f5a 100644
--- a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaExtensions.xtend
+++ b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaExtensions.xtend
@@ -100,13 +100,27 @@ class JavaExtensions implements ILanguageExtension {
override String destructorReturnType() {
"void"
}
- override String toCharArrayExpr(String s){
- "\"" + s + "\".toCharArray()"
- }
+
override String superCall(String baseClassName, String method, String args) {
"super."+method+"("+args+");"
}
- override String toValueLiteral(PrimitiveType type, String value){
+
+ override toValueLiteral(PrimitiveType type, String value) {
+ switch(type.targetName){
+ case "char":
+ castValue(type, value)
+ case "string":
+ castValue(type, value)
+ case value.contains(','):{
+ var singleValues = value.replace('{', '').replace('}', '').trim.split(',')
+ '''{ «FOR v: singleValues SEPARATOR ', '»«castValue(type, v.trim)»«ENDFOR» }'''.toString
+ }
+ default:
+ castValue(type, value)
+ }
+ }
+
+ def private castValue(PrimitiveType type, String value){
switch(type.targetName){
case "boolean":
return value
@@ -126,10 +140,10 @@ class JavaExtensions implements ILanguageExtension {
if(value.length == 1)
return "'"+value+"'"
else
- return value.toCharArrayExpr
+ return "\""+value.replace("\\", "\\\\").replace("\"", "\\\"")+"\".toCharArray()"
}
case "String":
- return "\""+value+"\""
+ return "\""+value.replace("\\", "\\\\").replace("\"", "\\\"")+"\""
}
throw new UnsupportedOperationException(type.targetName)
@@ -183,4 +197,6 @@ class JavaExtensions implements ILanguageExtension {
return newArrayList(dataArg, typedData, typedArgList);
}
+
+
}
diff --git a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ProtocolClassGen.xtend b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ProtocolClassGen.xtend
index 0626b628c..69889bc26 100644
--- a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ProtocolClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/ProtocolClassGen.xtend
@@ -112,7 +112,7 @@ class ProtocolClassGen extends GenericProtocolClassGenerator {
public «portClassName»(IEventReceiver actor, String name, int localId, int idx, Address addr, Address peerAddress) {
super(actor, name, localId, idx, addr, peerAddress);
«IF pclass!=null»
- «pclass.attributes.attributeInitialization(true)»
+ «pclass.attributes.attributeInitialization(pclass, true)»
«ENDIF»
DebuggingService.getInstance().addPortInstance(this);
}
diff --git a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/SubSystemClassGen.xtend b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/SubSystemClassGen.xtend
index b704c9c76..f17978ef4 100644
--- a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/SubSystemClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/SubSystemClassGen.xtend
@@ -17,14 +17,13 @@ import com.google.inject.Singleton
import org.eclipse.etrice.core.genmodel.base.ILogger
import org.eclipse.etrice.core.genmodel.etricegen.Root
import org.eclipse.etrice.core.genmodel.etricegen.SubSystemInstance
-import org.eclipse.etrice.core.room.SubSystemClass
-import org.eclipse.etrice.generator.generic.ConfigExtension
import org.eclipse.etrice.generator.generic.ProcedureHelpers
import org.eclipse.etrice.generator.generic.RoomExtensions
import org.eclipse.xtext.generator.JavaIoFileSystemAccess
import static extension org.eclipse.etrice.generator.base.Indexed.*
-
+import org.eclipse.etrice.generator.base.IDataConfiguration
+import org.eclipse.etrice.core.room.LogicalThread
@Singleton
class SubSystemClassGen {
@@ -32,8 +31,8 @@ class SubSystemClassGen {
@Inject JavaIoFileSystemAccess fileAccess
@Inject extension JavaExtensions
@Inject extension RoomExtensions
- @Inject extension ConfigExtension
- @Inject ConfigGenAddon configAddon
+ @Inject IDataConfiguration dataConfigExt
+ @Inject ConfigGenAddon configGenAddon
@Inject extension ProcedureHelpers
@Inject VariableServiceGen varService
@@ -45,16 +44,18 @@ class SubSystemClassGen {
var file = ssi.subSystemClass.getJavaFileName
logger.logInfo("generating SubSystemClass implementation: '"+file+"' in '"+path+"'")
fileAccess.setOutputPath(path)
- fileAccess.generateFile(file, root.generate(ssi, ssi.subSystemClass))
- if(ssi.subSystemClass.hasVariableService)
+ fileAccess.generateFile(file, root.generate(ssi))
+ if(dataConfigExt.hasVariableService(ssi.subSystemClass))
varService.doGenerate(root, ssi);
}
}
- def generate(Root root, SubSystemInstance comp, SubSystemClass cc) {'''
+ def generate(Root root, SubSystemInstance comp) {
+ val cc = comp.subSystemClass
+ '''
package «cc.getPackage()»;
- «IF cc.hasVariableService»import org.eclipse.etrice.runtime.java.config.VariableService;«ENDIF»
+ «IF dataConfigExt.hasVariableService(cc)»import org.eclipse.etrice.runtime.java.config.VariableService;«ENDIF»
import org.eclipse.etrice.runtime.java.messaging.MessageService;
import org.eclipse.etrice.runtime.java.messaging.RTServices;
import org.eclipse.etrice.runtime.java.messaging.Address;
@@ -69,11 +70,15 @@ class SubSystemClassGen {
«cc.userCode(1)»
- public class «comp.name» extends SubSystemClassBase{
+ public class «cc.name» extends SubSystemClassBase {
+ public final int THREAD__DEFAULT = 0;
+ «FOR thread : cc.threads.indexed»
+ public final int «thread.value.threadId» = «thread.index1»;
+ «ENDFOR»
«cc.userCode(2)»
- public «comp.name»(String name) {
+ public «cc.name»(String name) {
super(name);
}
@@ -84,9 +89,9 @@ class SubSystemClassGen {
@Override
public void instantiateMessageServices(){
- RTServices.getInstance().getMsgSvcCtrl().addMsgSvc(new MessageService(this, new Address(0, 0, 0),"MessageService_Main"));
+ RTServices.getInstance().getMsgSvcCtrl().addMsgSvc(new MessageService(this, new Address(THREAD__DEFAULT, 0, 0),"MessageService_Main"));
«FOR thread : cc.threads»
- RTServices.getInstance().getMsgSvcCtrl().addMsgSvc(new MessageService(this, new Address(0, «cc.threads.indexOf(thread)+1», 0),"MessageService_«thread.name»", «thread.prio»));
+ RTServices.getInstance().getMsgSvcCtrl().addMsgSvc(new MessageService(this, new Address(0, «thread.threadId», 0),"MessageService_«thread.name»" /*, thread_prio */));
«ENDFOR»
}
@@ -95,23 +100,24 @@ class SubSystemClassGen {
// all addresses
// Addresses for the Subsystem Systemport
- «FOR ai : comp.allContainedInstances.indexed(comp.maxObjId)»
- Address addr_item_SystemPort_«comp.allContainedInstances.indexOf(ai.value)» = new Address(0,0,«ai.index1»);
+ «FOR ai : comp.allContainedInstances»
+ Address addr_item_SystemPort_«comp.allContainedInstances.indexOf(ai)» = getFreeAddress(THREAD__DEFAULT);
«ENDFOR»
«FOR ai : comp.allContainedInstances»
+ «val threadId = if (ai.threadId==0) "THREAD__DEFAULT" else cc.threads.get(ai.threadId-1).threadId»
// actor instance «ai.path» itself => Systemport Address
««« // TODOTJ: For each Actor, multiple addresses should be generated (actor?, systemport, debugport)
- Address addr_item_«ai.path.getPathName()» = new Address(0,«ai.threadId»,«ai.objId»);
+ Address addr_item_«ai.path.getPathName()» = getFreeAddress(«threadId»);
// interface items of «ai.path»
«FOR pi : ai.orderedIfItemInstances»
«IF pi.replicated»
«FOR peer : pi.peers»
«var i = pi.peers.indexOf(peer)»
- Address addr_item_«pi.path.getPathName()»_«i» = new Address(0,«ai.threadId»,«pi.objId+i»);
+ Address addr_item_«pi.path.getPathName()»_«i» = getFreeAddress(«threadId»);
«ENDFOR»
«ELSE»
- Address addr_item_«pi.path.getPathName()» = new Address(0,«ai.threadId»,«pi.objId»);
+ Address addr_item_«pi.path.getPathName()» = getFreeAddress(«threadId»);
«ENDIF»
«ENDFOR»
«ENDFOR»
@@ -168,21 +174,19 @@ class SubSystemClassGen {
«ENDIF»
«ENDFOR»
}
- «IF ai.configAttributes.exists(c | c.dynConfig)»
+ «IF !dataConfigExt.getDynConfigWriteAttributes(ai.path).empty»
, variableService
«ENDIF»
);
«ENDFOR»
// apply instance attribute configurations
- «FOR ai : comp.allContainedInstances»
- «IF !(ai.configAttributes.empty && ai.getConfigPorts.empty)»
- {
+ «FOR ai: comp.allContainedInstances»
+ «val cfg = configGenAddon.genActorInstanceConfig(ai, "inst")»
+ «IF cfg.length>0»
+ {
«ai.actorClass.name» inst = («ai.actorClass.name») instances[«comp.allContainedInstances.indexOf(ai)»];
- «configAddon.applyInstanceConfig("inst", ai.actorClass.name, ai.configAttributes)»
- «FOR portConfig : ai.configPorts»
- «configAddon.applyInstanceConfig(("inst."+portConfig.item.name.invokeGetter(ai.actorClass.name)), portConfig.item.portClassName, portConfig.attributes)»
- «ENDFOR»
+ «cfg»
}
«ENDIF»
«ENDFOR»
@@ -204,17 +208,17 @@ class SubSystemClassGen {
});
}
- «IF cc.hasVariableService»
+ «IF dataConfigExt.hasVariableService(cc)»
private VariableService variableService;
«ENDIF»
@Override
public void init(){
- «IF cc.hasVariableService»
- variableService = new «comp.name»VariableService(this);
+ «IF dataConfigExt.hasVariableService(cc)»
+ variableService = new «cc.name»VariableService(this);
«ENDIF»
super.init();
- «IF cc.hasVariableService»
+ «IF dataConfigExt.hasVariableService(cc)»
variableService.init();
«ENDIF»
}
@@ -222,7 +226,7 @@ class SubSystemClassGen {
@Override
public void stop(){
super.stop();
- «IF cc.hasVariableService»
+ «IF dataConfigExt.hasVariableService(cc)»
variableService.stop();
«ENDIF»
}
@@ -231,4 +235,7 @@ class SubSystemClassGen {
'''
}
+ def private getThreadId(LogicalThread thread) {
+ "THREAD_"+thread.name.toUpperCase
+ }
}
diff --git a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/SubSystemRunnerGen.xtend b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/SubSystemRunnerGen.xtend
index c0cc6cc1f..3a3057f5d 100644
--- a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/SubSystemRunnerGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/SubSystemRunnerGen.xtend
@@ -14,7 +14,6 @@ package org.eclipse.etrice.generator.java.gen
import com.google.inject.Inject
import com.google.inject.Singleton
-import org.eclipse.etrice.core.room.SubSystemClass
import org.eclipse.etrice.core.genmodel.etricegen.Root
import org.eclipse.etrice.core.genmodel.etricegen.SubSystemInstance
import org.eclipse.xtext.generator.JavaIoFileSystemAccess
@@ -29,11 +28,13 @@ class SubSystemRunnerGen {
def doGenerate(Root root) {
for (sc: root.subSystemInstances) {
fileAccess.setOutputPath(sc.subSystemClass.generationTargetPath+sc.subSystemClass.getPath)
- fileAccess.generateFile( sc.name+"Runner.java", root.generate(sc, sc.subSystemClass))
+ fileAccess.generateFile(sc.subSystemClass.name+"Runner.java", root.generate(sc))
}
}
- def generate(Root root, SubSystemInstance ssc, SubSystemClass cc) {'''
+ def generate(Root root, SubSystemInstance ssc) {
+ val cc = ssc.subSystemClass
+ '''
/**
* @author generated by eTrice
*
@@ -45,7 +46,7 @@ class SubSystemRunnerGen {
import org.eclipse.etrice.runtime.java.modelbase.SubSystemRunnerBase;
- class «ssc.name+"Runner"» extends SubSystemRunnerBase {
+ class «cc.name+"Runner"» extends SubSystemRunnerBase {
/**
* main function
@@ -53,7 +54,7 @@ class SubSystemRunnerGen {
*/
public static void main(String[] args) {
// instantiate the main component
- «ssc.name» main_component = new «ssc.name»("«ssc.name»");
+ «cc.name» main_component = new «cc.name»("«ssc.name»");
run(main_component, args);
}
diff --git a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/VariableServiceGen.xtend b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/VariableServiceGen.xtend
index abc225481..568111467 100644
--- a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/VariableServiceGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/VariableServiceGen.xtend
@@ -1,15 +1,15 @@
-/*******************************************************************************
- * Copyright (c) 2012 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Juergen Haug
- *
- *******************************************************************************/
-
+/*******************************************************************************
+ * Copyright (c) 2012 Juergen Haug
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Juergen Haug
+ *
+ *******************************************************************************/
+
package org.eclipse.etrice.generator.java.gen
import com.google.inject.Inject
@@ -19,10 +19,6 @@ import java.util.HashMap
import java.util.HashSet
import java.util.LinkedList
import java.util.List
-import java.util.Map
-import org.eclipse.etrice.core.config.ActorClassConfig
-import org.eclipse.etrice.core.config.ActorInstanceConfig
-import org.eclipse.etrice.core.config.AttrInstanceConfig
import org.eclipse.etrice.core.genmodel.base.ILogger
import org.eclipse.etrice.core.genmodel.etricegen.ActorInstance
import org.eclipse.etrice.core.genmodel.etricegen.Root
@@ -30,254 +26,243 @@ import org.eclipse.etrice.core.genmodel.etricegen.SubSystemInstance
import org.eclipse.etrice.core.room.Attribute
import org.eclipse.etrice.core.room.DataClass
import org.eclipse.etrice.core.room.RoomModel
-import org.eclipse.etrice.core.room.SubSystemClass
-import org.eclipse.etrice.generator.generic.ConfigExtension
+import org.eclipse.etrice.generator.base.IDataConfiguration
import org.eclipse.etrice.generator.generic.ProcedureHelpers
import org.eclipse.etrice.generator.generic.RoomExtensions
import org.eclipse.etrice.generator.generic.TypeHelpers
-import org.eclipse.xtext.generator.JavaIoFileSystemAccess
-
-@Singleton
-class VariableServiceGen {
-
- @Inject extension JavaIoFileSystemAccess fileAccess
- @Inject extension JavaExtensions stdExt
- @Inject extension RoomExtensions roomExt
- @Inject extension ConfigExtension configExt
- @Inject extension ProcedureHelpers helpers
- @Inject extension TypeHelpers
- @Inject ILogger logger
-
- def doGenerate(Root root, SubSystemInstance ssi) {
- var path = ssi.subSystemClass.generationTargetPath+ssi.subSystemClass.getPath
- var file = ssi.subSystemClass.name+"VariableService.java"
- logger.logInfo("generating VariableService implementation: '"+file+"' in '"+path+"'")
- fileAccess.setOutputPath(path)
- fileAccess.generateFile(file, root.generate(ssi, ssi.subSystemClass))
- }
-
- def private generate(Root root, SubSystemInstance comp, SubSystemClass cc) {'''
- «val dynConfig = cc.subSystemConfig.dynConfig»
-
- package «cc.getPackage()»;
-
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.Map;
- import org.eclipse.etrice.runtime.java.config.VariableService;
- «IF dynConfig.userCode1 != null»
- «dynConfig.userCode1»;
- «ELSE»
- import org.eclipse.etrice.runtime.java.config.ConfigSourceFile;
- «ENDIF»
- «var ais = dynConfigsAIs(comp)»
- «FOR model : ais.roomModels»
- import «model.name».*;
- «ENDFOR»
-
-
- public class «comp.name+"VariableService"» extends VariableService{
-
- private «cc.name» subSystem;
-
- // Actor instances
- «FOR ai : ais»
- private «ai.actorClass.name» «ai.path.split("/").drop(2).toPath("_")»;
- «ENDFOR»
-
- public «comp.name+"VariableService"»(«cc.name» subSystem) {
- super(«IF dynConfig.filePath != null»new ConfigSourceFile("«dynConfig.filePath»")«ELSE»«dynConfig.userCode2»«ENDIF»);
- this.subSystem = subSystem;
- }
-
- @Override
- protected void initInstances(){
- «FOR ai : ais»
- «ai.path.split("/").drop(2).toPath("_")» = («ai.actorClass.name»)subSystem.getInstance("«ai.path»");
- «ENDFOR»
- }
-
-
- @Override
- protected void setAttributeValues(Map<String, Object> values) {
- Object object;
- String id = null;
- «FOR attrConfig : cc.getAttrDynConfigs(true, false)»
- «var aiName = (attrConfig.eContainer as ActorInstanceConfig).path.refs.toPath("_")»
- try{
- boolean changed = false;
- «FOR entry : attrConfig.allAttributes.entrySet»
- «var a = entry.key»
- «var aPath = attrConfig.getPath(true, true, true, false).toPath("/")+entry.value.toPath("/")+"/"+a.name»
- id = "«aPath»";
- «IF a.size==0»«a.refType.type.typeName.toWrapper»«ELSE»«a.refType.type.typeName»[]«ENDIF» _«a.name» = null;
- object = values.get(id);
- if(object != null){
- _«a.name» = ensure«a.refType.type.typeName.toFirstUpper»«IF a.size>0»Array«ENDIF»(object«IF a.size>0», «a.size»«ENDIF»);
- «genMinMaxCheck(attrConfig, (attrConfig.eContainer as ActorInstanceConfig).actorClassConfig)»
- if(!«IF a.size==0»_«a.name».equals(«ELSE»Arrays.equals(_«a.name», «ENDIF»(«IF a.size==0»«a.refType.type.typeName.toWrapper»«ELSE»«a.refType.type.typeName»[]«ENDIF»)getDiffMap().get(id)))
- changed = true;
- } else
- warning(id, "is missing");
- «ENDFOR»
- if(changed)
- synchronized(«aiName».«invokeGetter(attrConfig.attribute.name+"Lock", null)»){
- if(«aiName».«invokeGetter(attrConfig.attribute.name+"Lock", null)».isUpdate()){
- «FOR entry : attrConfig.allAttributes.entrySet»
- if(_«entry.key.name» != null){
- «aiName»«entry.value.toInvoke».«invokeSetter(entry.key.name, null, "_"+entry.key.name)»;
- getDiffMap().put("«attrConfig.getPath(true, true, true, false).toPath("/")+entry.value.toPath("/")+"/"+entry.key.name»", _«entry.key.name»);
- }
- «ENDFOR»
- }
- }
- }catch(IllegalArgumentException e){
- error(id, e);
- }
- «ENDFOR»
- }
-
- @Override
- protected Map<String, Object> getAttributeValues(){
- Map<String, Object> values = new HashMap<String, Object>();
- «FOR attrConfig : cc.getAttrDynConfigs(true, false)»
- «var aiName = (attrConfig.eContainer as ActorInstanceConfig).path.refs.toPath("_")»
- «FOR entry : attrConfig.allAttributes.entrySet»
- «var array = entry.key.size>0»
- «var aPath = attrConfig.getPath(true, true, true, false).toPath("/")+entry.value.toPath("/")+"/"+entry.key.name»
- values.put("«aPath»", «IF array»toObjectArray(«ENDIF»«aiName»«entry.value.toInvoke».«invokeGetter(entry.key.name, null)»«IF array»)«ENDIF»);
- «ENDFOR»
- «ENDFOR»
-
- return values;
- }
-
- @Override
- public void writeDataClass(String id, Object dcObject, Map<String, Object> writeMap) {
- «FOR dc : comp.dynDataClasses»
- if(dcObject.getClass().equals(«dc.typeName».class))
- writeDataClass(id, («dc.typeName») dcObject, writeTasks);
- «ENDFOR»
- }
-
- // DataClasses write operations
-
- «FOR dc : comp.allDynDataClasses»
- private void writeDataClass(String id, «dc.typeName» object, Map<String, Object> map){
- «FOR a : dc.attributes»
- «IF a.refType.type.primitive»
- map.put(id+"/«a.name»", «IF a.size>0»toObjectArray(«ENDIF»object.«invokeGetter(a.name, null)»«IF a.size>0»)«ENDIF»);
- «ELSE»
- writeDataClass(id+"/«a.name»", object.«invokeGetter(a.name, null)», map);
- «ENDIF»
- «ENDFOR»
- }
- «ENDFOR»
-
- @Override
- protected int getPollingTimerUser(){
- return «dynConfig.polling»;
- }
-
- }
- '''}
-
- def private genMinMaxCheck(AttrInstanceConfig instConf, ActorClassConfig acConf){
- var config = acConf?.resolve(instConf.getPath(false, false, true, true))
- if(config?.min == null && config?.max == null)
- return ''''''
- var path = config.getPath(false, false, true, true).toPath("_")
- var acName = (config.eContainer as ActorClassConfig).actor.name
- '''
- checkMinMax(_«config.attribute.name», «IF config.min != null»«acName».MIN«path»«ELSE»null«ENDIF», «IF config.max != null»«acName».MAX«path»«ELSE»null«ENDIF»);
- '''
- }
-
- def private Map<Attribute, List<String>> getAllAttributes(AttrInstanceConfig config){
- var map = new HashMap<Attribute, List<String>>()
- if(config.attribute.refType.type.primitive)
- map.put(config.attribute, new ArrayList<String>())
- else
- config.attribute.getAllAttributes(new LinkedList<String>(), map)
-
- return map
- }
-
- def private void getAllAttributes(Attribute attribute, List<String> path, Map<Attribute, List<String>> map){
- if(attribute.refType.type.primitive)
- map.put(attribute, path)
- else if (attribute.refType.type.dataClass){
- var new_path = new ArrayList<String>(path)
- new_path.add(attribute.name)
- for(dc : (attribute.refType.type as DataClass).allAttributes)
- dc.getAllAttributes(new_path, map)
- }
- }
-
- def private String toInvoke(List<String> path){
- var builder = new StringBuilder()
- for(p : path)
- builder.append("."+p.invokeGetter(null))
-
- return builder.toString
- }
-
- def private List<ActorInstance> dynConfigsAIs(SubSystemInstance comp){
- val aiPaths = new HashSet<String>();
- for(attrConfig : comp.subSystemClass.getAttrDynConfigs(true, false))
- aiPaths.add(attrConfig.getPath(true, true, false, false).toPath("/"))
-
- var ais = new ArrayList<ActorInstance>();
- for(ai : comp.allContainedInstances)
- if(aiPaths.contains(ai.path))
- ais.add(ai);
-
- return ais
- }
-
-
- def private getDynDataClasses(SubSystemInstance comp){
- var dcs = new HashSet<DataClass>()
- for(config : comp.subSystemClass.getAttrDynConfigs(false, true))
- if(config.attribute.refType.type.dataClass)
- dcs.add(config.attribute.refType.type as DataClass)
-
- return dcs
- }
-
- def private getAllDynDataClasses(SubSystemInstance comp){
- var dcs = new HashSet<DataClass>()
- var stack = new LinkedList<DataClass>()
- stack.addAll(comp.dynDataClasses)
- dcs.addAll(stack)
- while(!stack.empty){
- var dc = stack.pop
- for(a : dc.allAttributes)
- if(a.refType.type.dataClass){
- dcs.add(a.refType.type as DataClass)
- stack.push(a.refType.type as DataClass);
- }
- }
-
- return dcs
- }
-
- def private resolve(ActorClassConfig config, String[] path){
- var result = config.attributes.findFirst(c | c.attribute.name.equals(path.head))
- for (String ref : path.tail) {
- result = result?.attributes.findFirst(c | c.attribute.name.equals(ref))
- if (result == null)
- return null
- }
-
- return result
- }
-
- def private getRoomModels(List<ActorInstance> ais){
- val models = new HashSet<RoomModel>
- ais.forEach(ai | models.add(ai.actorClass.eContainer as RoomModel))
- return models
- }
-
-
-} \ No newline at end of file
+import org.eclipse.xtext.generator.JavaIoFileSystemAccess
+import org.eclipse.etrice.core.room.ActorClass
+import java.util.Collection
+
+@Singleton
+class VariableServiceGen {
+
+ @Inject extension JavaIoFileSystemAccess fileAccess
+ @Inject extension JavaExtensions stdExt
+ @Inject extension RoomExtensions roomExt
+ @Inject IDataConfiguration configExt
+ @Inject extension ProcedureHelpers helpers
+ @Inject extension TypeHelpers
+ @Inject ILogger logger
+
+ def doGenerate(Root root, SubSystemInstance ssi) {
+ var path = ssi.subSystemClass.generationTargetPath+ssi.subSystemClass.getPath
+ var file = ssi.subSystemClass.name+"VariableService.java"
+ logger.logInfo("generating VariableService implementation: '"+file+"' in '"+path+"'")
+ fileAccess.setOutputPath(path)
+ fileAccess.generateFile(file, root.generate(ssi))
+ }
+
+ def private generate(Root root, SubSystemInstance comp) {
+ val cc = comp.subSystemClass
+ val aisAttrMap = new HashMap<ActorInstance, List<Attribute>>
+ comp.allContainedInstances.forEach(ai | if(!configExt.getDynConfigReadAttributes(ai.path).empty)aisAttrMap.put(ai, configExt.getDynConfigReadAttributes(ai.path)))
+ '''
+
+ package «cc.getPackage()»;
+
+ import java.util.Arrays;
+ import java.util.HashMap;
+ import java.util.Map;
+ import org.eclipse.etrice.runtime.java.config.VariableService;
+ «configExt.getUserCode1(cc)»
+ «FOR model : aisAttrMap.keySet.roomModels»
+ import «model.name».*;
+ «ENDFOR»
+
+
+ public class «cc.name+"VariableService"» extends VariableService{
+
+ private «cc.name» subSystem;
+
+ // Actor instances
+ «FOR ai : aisAttrMap.keySet»
+ private «ai.actorClass.name» «ai.varName»;
+ «ENDFOR»
+
+ public «cc.name+"VariableService"»(«cc.name» subSystem) {
+ super(«configExt.getUserCode2(cc)»);
+ this.subSystem = subSystem;
+ }
+
+ @Override
+ protected void initInstances(){
+ «FOR ai : aisAttrMap.keySet»
+ «ai.varName» = («ai.actorClass.name»)subSystem.getInstance("«ai.path»");
+ «ENDFOR»
+ }
+
+
+ @Override
+ protected void setAttributeValues(Map<String, Object> values) {
+ Object object;
+ String id = null;
+
+ «FOR ai : aisAttrMap.keySet»
+ «FOR a : aisAttrMap.get(ai)»
+ try{
+ boolean changed = false;
+ «genSetAttributeValues1(new ArrayList<Attribute>.union(a), ai)»
+ if(changed)
+ synchronized(«ai.varName».«invokeGetter(a.name+"Lock", null)»){
+ if(«ai.varName».«invokeGetter(a.name+"Lock", null)».isUpdate()){
+ «genSetAttributeValues2(new ArrayList<Attribute>.union(a), ai)»
+ }
+ }
+ }catch(IllegalArgumentException e){
+ error(id, e);
+ }
+ «ENDFOR»
+ «ENDFOR»
+ }
+
+ @Override
+ protected Map<String, Object> getAttributeValues(){
+ Map<String, Object> values = new HashMap<String, Object>();
+ «FOR ai : aisAttrMap.keySet»
+ «FOR a : aisAttrMap.get(ai)»
+ «genGetAttributeValues(new ArrayList<Attribute>.union(a), ai)»
+ «ENDFOR»
+ «ENDFOR»
+
+ return values;
+ }
+
+ @Override
+ public void writeDataClass(String id, Object dcObject, Map<String, Object> writeMap) {
+ «var dataClasses = aisAttrMap.keySet.dynConfigDataClasses»
+ «FOR dc : dataClasses»
+ if(dcObject.getClass().equals(«dc.typeName».class))
+ writeDataClass(id, («dc.typeName») dcObject, writeTasks);
+ «ENDFOR»
+ }
+
+ // DataClasses write operations
+
+ «FOR dc : getAllDataClasses(dataClasses)»
+ private void writeDataClass(String id, «dc.typeName» object, Map<String, Object> map){
+ «FOR a : dc.attributes»
+ «IF a.refType.type.primitive»
+ map.put(id+"/«a.name»", «IF a.size>0»toObjectArray(«ENDIF»object.«invokeGetter(a.name, null)»«IF a.size>0»)«ENDIF»);
+ «ELSE»
+ writeDataClass(id+"/«a.name»", object.«invokeGetter(a.name, null)», map);
+ «ENDIF»
+ «ENDFOR»
+ }
+ «ENDFOR»
+
+ @Override
+ protected int getPollingTimerUser(){
+ return «configExt.getPollingTimerUser(cc)»;
+ }
+
+ }
+ '''}
+
+ def private genMinMaxCheck(List<Attribute> path, ActorClass ac){
+ var aVarName = path.toAbsolutePath("_")
+ var min = configExt.getAttrClassConfigMinValue(ac, path) != null
+ var max = configExt.getAttrClassConfigMaxValue(ac, path) != null
+ if(min || max)
+ '''
+ checkMinMax(«aVarName», «IF min»«ac.name».MIN«aVarName»«ELSE»null«ENDIF», «IF max»«ac.name».MAX«aVarName»«ELSE»null«ENDIF»);
+ '''
+ else
+ ''''''
+ }
+
+ def private getDynConfigDataClasses(Iterable<ActorInstance> ais){
+ val result = new HashSet<DataClass>
+ ais.forEach(ai | configExt.getDynConfigReadAttributes(ai.path).
+ forEach(a | if(a.refType.type.dataClass)result.add(a.refType.type as DataClass)
+ ))
+ return result
+ }
+
+ def private getAllDataClasses(Iterable<DataClass> dcs){
+ val result = new HashSet<DataClass>
+ result.addAll(dcs)
+ val visit = new LinkedList<DataClass>
+ visit.addAll(dcs)
+ while(!visit.empty){
+ var dc = visit.pop
+ dc.allAttributes.forEach(a | if(a.refType.type.dataClass)visit.add(a.refType.type as DataClass))
+ }
+ return result
+ }
+
+ def private getRoomModels(Collection<ActorInstance> ais){
+ val models = new HashSet<RoomModel>
+ ais.forEach(ai | models.add(ai.actorClass.eContainer as RoomModel))
+ return models
+ }
+
+ def private toAbsolutePath(List<Attribute> path, String pathDelim){
+ '''«FOR p : path»«pathDelim»«p.name»«ENDFOR»'''.toString
+ }
+
+ def private getVarName(ActorInstance ai){
+ '''«FOR p : ai.path.split('/').drop(2) SEPARATOR '_'»«p»«ENDFOR»'''
+ }
+
+ def private genGetAttributeValues(List<Attribute> path, ActorInstance ai){
+ var a = path.last
+ if(a.refType.type.primitive){'''
+ values.put("«ai.path»«path.toAbsolutePath('/')»", «IF a.size>0»toObjectArray(«ENDIF»«ai.varName».«path.invokeGetters(null)»«IF a.size>0»)«ENDIF»);
+ '''
+ } else if(a.refType.type.dataClass){
+ var dataClass = (a.refType.type as DataClass)
+ '''
+ «FOR at : dataClass.allAttributes»
+ «genGetAttributeValues(path.union(at), ai)»
+ «ENDFOR»
+ '''
+ }
+ }
+
+ def private genSetAttributeValues1(List<Attribute> path, ActorInstance ai){
+ var a = path.last
+ var aVarName = path.toAbsolutePath("_")
+ if(a.refType.type.primitive){'''
+ id = "«ai.path»«path.toAbsolutePath("/")»";
+ «IF a.size==0»«a.refType.type.typeName.toWrapper»«ELSE»«a.refType.type.typeName»[]«ENDIF» «aVarName» = null;
+ object = values.get(id);
+ if(object != null){
+ «aVarName» = ensure«a.refType.type.typeName.toFirstUpper»«IF a.size>0»Array«ENDIF»(object«IF a.size>0», «a.size»«ENDIF»);
+ «genMinMaxCheck(path, ai.actorClass)»
+ if(!«IF a.size==0»«aVarName».equals(«ELSE»Arrays.equals(«aVarName», «ENDIF»(«IF a.size==0»«a.refType.type.typeName.toWrapper»«ELSE»«a.refType.type.typeName»[]«ENDIF»)getDiffMap().get(id)))
+ changed = true;
+ } else
+ warning(id, "is missing");
+ '''
+ } else if(a.refType.type.dataClass){
+ var dataClass = (a.refType.type as DataClass)
+ '''
+ «FOR at : dataClass.allAttributes»
+ «genSetAttributeValues1(path.union(at), ai)»
+ «ENDFOR»
+ '''
+ }
+ }
+
+ def private genSetAttributeValues2(List<Attribute> path, ActorInstance ai){
+ var a = path.last
+ var aVarName = path.toAbsolutePath("_")
+ if(a.refType.type.primitive){
+ var getters = if(path.size>1)path.take(path.size-1).invokeGetters(null)+"." else ""
+ '''
+ if(«aVarName» != null){
+ «ai.varName».«getters»«invokeSetter(a.name, null, aVarName)»;
+ getDiffMap().put("«ai.path»«path.toAbsolutePath("/")»", «aVarName»);
+ }
+ '''
+ } else if(a.refType.type.dataClass){
+ var dataClass = (a.refType.type as DataClass)
+ '''
+ «FOR at : dataClass.allAttributes»
+ «genSetAttributeValues2(path.union(at), ai)»
+ «ENDFOR»
+ '''
+ }
+ }
+}

Back to the top