diff options
author | Peter Karlitschek | 2012-12-05 08:58:06 +0000 |
---|---|---|
committer | Peter Karlitschek | 2012-12-05 08:58:06 +0000 |
commit | 0ee43bf8f13c5d7d1d0db600ddf1875abb105477 (patch) | |
tree | 10294dc924f4f26cd80bee7b6f2f34cd35339eda /plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen | |
parent | 84afe757e7b94d028acfe3fb1076985526abce2e (diff) | |
parent | 73b4a1693e646cffb9691ccd231801e961bb9257 (diff) | |
download | org.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')
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» + ''' + } + } +} |