Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Rentz-Reichert2012-02-02 09:42:09 +0000
committerHenrik Rentz-Reichert2012-02-02 09:42:09 +0000
commitb55690aca6ad5d17e699e809af481d1ffd04191e (patch)
tree20d32381f24b1cad365c9b9ec06c8bf1d351fff5 /plugins/org.eclipse.etrice.generator.c/src/org/eclipse
parent0dc402844ba53dbd6afca52e8ec4f7a7dcd196da (diff)
downloadorg.eclipse.etrice-b55690aca6ad5d17e699e809af481d1ffd04191e.tar.gz
org.eclipse.etrice-b55690aca6ad5d17e699e809af481d1ffd04191e.tar.xz
org.eclipse.etrice-b55690aca6ad5d17e699e809af481d1ffd04191e.zip
[core.room, generator, ui.behavior] communication model for protocols
Diffstat (limited to 'plugins/org.eclipse.etrice.generator.c/src/org/eclipse')
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend376
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend516
2 files changed, 446 insertions, 446 deletions
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend
index 44fe509a8..5a19bfc60 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend
@@ -1,189 +1,189 @@
-/*******************************************************************************
- * Copyright (c) 2011 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:
- * Henrik Rentz-Reichert (initial contribution)
- * Thomas Schuetz (changed for C code generator)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.generator.c.gen
-
-import com.google.inject.Inject
-import com.google.inject.Singleton
-import org.eclipse.etrice.core.room.ActorClass
-import org.eclipse.etrice.core.room.Message
-import org.eclipse.etrice.generator.base.ILogger
-import org.eclipse.etrice.generator.etricegen.ExpandedActorClass
-import org.eclipse.etrice.generator.etricegen.Root
-import org.eclipse.xtext.generator.JavaIoFileSystemAccess
-
-import org.eclipse.etrice.generator.extensions.RoomExtensions
-import org.eclipse.etrice.generator.generic.ProcedureHelpers
-import org.eclipse.etrice.generator.generic.TypeHelpers
-
-
-@Singleton
-class ActorClassGen {
-
- @Inject extension JavaIoFileSystemAccess fileAccess
- @Inject extension CExtensions stdExt
- @Inject extension RoomExtensions roomExt
-
- @Inject extension ProcedureHelpers helpers
- @Inject extension TypeHelpers
- @Inject extension StateMachineGen stateMachineGen
- @Inject ILogger logger
-
- def doGenerate(Root root) {
- for (xpac: root.xpActorClasses) {
- var path = xpac.actorClass.generationTargetPath+xpac.actorClass.getPath
-
- // header file
- logger.logInfo("generating ActorClass header '"+xpac.actorClass.getCHeaderFileName+"' in '"+path+"'")
- fileAccess.setOutputPath(path)
- fileAccess.generateFile(xpac.actorClass.getCHeaderFileName, root.generateHeaderFile(xpac, xpac.actorClass))
-
- // header file
- logger.logInfo("generating ActorClass header '"+xpac.actorClass.getCSourceFileName +"' in '"+path+"'")
- fileAccess.setOutputPath(path)
- fileAccess.generateFile(xpac.actorClass.getCSourceFileName , root.generateSourceFile(xpac, xpac.actorClass))
- }
- }
-
- def generateHeaderFile(Root root, ExpandedActorClass xpac, ActorClass ac) {'''
- #ifndef _«xpac.name»_H_
- #define _«xpac.name»_H_
-
- #include "etDatatypes.h"
-
- package «ac.getPackage»;
-
-««« import org.eclipse.etrice.runtime.java.messaging.Address;
-««« import org.eclipse.etrice.runtime.java.messaging.IRTObject;
-««« import org.eclipse.etrice.runtime.java.messaging.IMessageReceiver;
-««« import org.eclipse.etrice.runtime.java.modelbase.ActorClassBase;
-««« import org.eclipse.etrice.runtime.java.modelbase.SubSystemClassBase;
-««« import org.eclipse.etrice.runtime.java.modelbase.InterfaceItemBase;
-««« import org.eclipse.etrice.runtime.java.debugging.DebuggingService;
-
-
- «FOR dataClass : root.getReferencedDataClasses(ac)»#include "«dataClass.name».h"
- «ENDFOR»
-
- «FOR pc : root.getReferencedProtocolClasses(ac)»#include "«pc.name».h"
- «ENDFOR»
-
- «helpers.UserCode(ac.userCode1)»
-
-
- public «IF ac.abstract»abstract «ENDIF»class «ac.name» extends «IF ac.base!=null»«ac.base.name»«ELSE»ActorClassBase«ENDIF» {
-
- «helpers.UserCode(ac.userCode2)»
-
- //--------------------- ports
- «FOR ep : ac.getEndPorts()»
- protected «ep.getPortClassName()» «ep.name» = null;
- «ENDFOR»
- //--------------------- saps
- «FOR sap : ac.strSAPs»
- protected «sap.getPortClassName()» «sap.name» = null;
- «ENDFOR»
- //--------------------- services
- «FOR svc : ac.serviceImplementations»
- protected «svc.getPortClassName()» «svc.spp.name» = null;
- «ENDFOR»
-
- //--------------------- interface item IDs
- «FOR ep : ac.getEndPorts()»
- protected static final int IFITEM_«ep.name» = «xpac.getInterfaceItemLocalId(ep)+1»;
- «ENDFOR»
- «FOR sap : ac.strSAPs»
- protected static final int IFITEM_«sap.name» = «xpac.getInterfaceItemLocalId(sap)+1»;
- «ENDFOR»
- «FOR svc : ac.serviceImplementations»
- protected static final int IFITEM_«svc.spp.name» = «xpac.getInterfaceItemLocalId(svc.spp)+1»;
- «ENDFOR»
-
- «helpers.Attributes(ac.attributes)»
- «helpers.OperationsDeclaration(ac.operations, ac.name)»
-
- //--------------------- construction
- public «ac.name»(IRTObject parent, String name, Address[][] port_addr, Address[][] peer_addr){
- «IF ac.base==null»
- super(parent, name, port_addr[0][0], peer_addr[0][0]);
- «ELSE»
- super(parent, name, port_addr, peer_addr);
- «ENDIF»
- setClassName("«ac.name»");
-
- «ac.attributes.attributeInitialization»
-
- // own ports
- «FOR ep : ac.getEndPorts()»
- «ep.name» = new «ep.getPortClassName()»(this, "«ep.name»", IFITEM_«ep.name», «IF ep.multiplicity==1»0, «ENDIF»port_addr[IFITEM_«ep.name»]«IF ep.multiplicity==1»[0]«ENDIF», peer_addr[IFITEM_«ep.name»]«IF ep.multiplicity==1»[0]«ENDIF»);
- «ENDFOR»
- // own saps
- «FOR sap : ac.strSAPs»
- «sap.name» = new «sap.getPortClassName()»(this, "«sap.name»", IFITEM_«sap.name», 0, port_addr[IFITEM_«sap.name»][0], peer_addr[IFITEM_«sap.name»][0]);
- «ENDFOR»
- // own service implementations
- «FOR svc : ac.serviceImplementations»
- «svc.spp.name» = new «svc.getPortClassName()»(this, "«svc.spp.name»", IFITEM_«svc.spp.name», port_addr[IFITEM_«svc.spp.name»], peer_addr[IFITEM_«svc.spp.name»]);
- «ENDFOR»
- }
-
-
- //--------------------- lifecycle functions
- public void init(){
- initUser();
- }
-
- public void start(){
- startUser();
- }
-
- «IF !ac.overridesStop()»
- public void stop(){
- stopUser();
- }
- «ENDIF»
-
- public void destroy(){
- destroyUser();
- }
-
- «IF ac.stateMachine != null»
- «stateMachineGen.genStateMachine(xpac, ac)»
- «ELSEIF !xpac.hasStateMachine()»
- //--------------------- no state machine
- @Override
- public void receiveEvent(InterfaceItemBase ifitem, int evt, Object data) {
- handleSystemEvent(ifitem, evt, data);
- }
-
- @Override
- public void executeInitTransition(){
- }
- «ENDIF»
- };
-
- #endif /* _«xpac.name»_H_ */
-
- '''
- }
-
- def generateSourceFile(Root root, ExpandedActorClass xpac, ActorClass ac) {'''
- #include "«xpac.getCHeaderFileName»"
-
- '''
- }
-
- def msgArgs(Message msg) {
- '''«IF msg.data!=null»«msg.data.defaultValue()»«ENDIF»'''
- }
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ * Henrik Rentz-Reichert (initial contribution)
+ * Thomas Schuetz (changed for C code generator)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.c.gen
+
+import com.google.inject.Inject
+import com.google.inject.Singleton
+import org.eclipse.etrice.core.room.ActorClass
+import org.eclipse.etrice.core.room.Message
+import org.eclipse.etrice.generator.base.ILogger
+import org.eclipse.etrice.generator.etricegen.ExpandedActorClass
+import org.eclipse.etrice.generator.etricegen.Root
+import org.eclipse.xtext.generator.JavaIoFileSystemAccess
+
+import org.eclipse.etrice.generator.extensions.RoomExtensions
+import org.eclipse.etrice.generator.generic.ProcedureHelpers
+import org.eclipse.etrice.generator.generic.TypeHelpers
+
+
+@Singleton
+class ActorClassGen {
+
+ @Inject extension JavaIoFileSystemAccess fileAccess
+ @Inject extension CExtensions stdExt
+ @Inject extension RoomExtensions roomExt
+
+ @Inject extension ProcedureHelpers helpers
+ @Inject extension TypeHelpers
+ @Inject extension StateMachineGen stateMachineGen
+ @Inject ILogger logger
+
+ def doGenerate(Root root) {
+ for (xpac: root.xpActorClasses) {
+ var path = xpac.actorClass.generationTargetPath+xpac.actorClass.getPath
+
+ // header file
+ logger.logInfo("generating ActorClass header '"+xpac.actorClass.getCHeaderFileName+"' in '"+path+"'")
+ fileAccess.setOutputPath(path)
+ fileAccess.generateFile(xpac.actorClass.getCHeaderFileName, root.generateHeaderFile(xpac, xpac.actorClass))
+
+ // header file
+ logger.logInfo("generating ActorClass header '"+xpac.actorClass.getCSourceFileName +"' in '"+path+"'")
+ fileAccess.setOutputPath(path)
+ fileAccess.generateFile(xpac.actorClass.getCSourceFileName , root.generateSourceFile(xpac, xpac.actorClass))
+ }
+ }
+
+ def generateHeaderFile(Root root, ExpandedActorClass xpac, ActorClass ac) {'''
+ #ifndef _«xpac.name»_H_
+ #define _«xpac.name»_H_
+
+ #include "etDatatypes.h"
+
+ package «ac.getPackage»;
+
+««« import org.eclipse.etrice.runtime.java.messaging.Address;
+««« import org.eclipse.etrice.runtime.java.messaging.IRTObject;
+««« import org.eclipse.etrice.runtime.java.messaging.IMessageReceiver;
+««« import org.eclipse.etrice.runtime.java.modelbase.ActorClassBase;
+««« import org.eclipse.etrice.runtime.java.modelbase.SubSystemClassBase;
+««« import org.eclipse.etrice.runtime.java.modelbase.InterfaceItemBase;
+««« import org.eclipse.etrice.runtime.java.debugging.DebuggingService;
+
+
+ «FOR dataClass : root.getReferencedDataClasses(ac)»#include "«dataClass.name».h"
+ «ENDFOR»
+
+ «FOR pc : root.getReferencedProtocolClasses(ac)»#include "«pc.name».h"
+ «ENDFOR»
+
+ «helpers.UserCode(ac.userCode1)»
+
+
+ public «IF ac.abstract»abstract «ENDIF»class «ac.name» extends «IF ac.base!=null»«ac.base.name»«ELSE»ActorClassBase«ENDIF» {
+
+ «helpers.UserCode(ac.userCode2)»
+
+ //--------------------- ports
+ «FOR ep : ac.getEndPorts()»
+ protected «ep.getPortClassName()» «ep.name» = null;
+ «ENDFOR»
+ //--------------------- saps
+ «FOR sap : ac.strSAPs»
+ protected «sap.getPortClassName()» «sap.name» = null;
+ «ENDFOR»
+ //--------------------- services
+ «FOR svc : ac.serviceImplementations»
+ protected «svc.getPortClassName()» «svc.spp.name» = null;
+ «ENDFOR»
+
+ //--------------------- interface item IDs
+ «FOR ep : ac.getEndPorts()»
+ protected static final int IFITEM_«ep.name» = «xpac.getInterfaceItemLocalId(ep)+1»;
+ «ENDFOR»
+ «FOR sap : ac.strSAPs»
+ protected static final int IFITEM_«sap.name» = «xpac.getInterfaceItemLocalId(sap)+1»;
+ «ENDFOR»
+ «FOR svc : ac.serviceImplementations»
+ protected static final int IFITEM_«svc.spp.name» = «xpac.getInterfaceItemLocalId(svc.spp)+1»;
+ «ENDFOR»
+
+ «helpers.Attributes(ac.attributes)»
+ «helpers.OperationsDeclaration(ac.operations, ac.name)»
+
+ //--------------------- construction
+ public «ac.name»(IRTObject parent, String name, Address[][] port_addr, Address[][] peer_addr){
+ «IF ac.base==null»
+ super(parent, name, port_addr[0][0], peer_addr[0][0]);
+ «ELSE»
+ super(parent, name, port_addr, peer_addr);
+ «ENDIF»
+ setClassName("«ac.name»");
+
+ «ac.attributes.attributeInitialization»
+
+ // own ports
+ «FOR ep : ac.getEndPorts()»
+ «ep.name» = new «ep.getPortClassName()»(this, "«ep.name»", IFITEM_«ep.name», «IF ep.multiplicity==1»0, «ENDIF»port_addr[IFITEM_«ep.name»]«IF ep.multiplicity==1»[0]«ENDIF», peer_addr[IFITEM_«ep.name»]«IF ep.multiplicity==1»[0]«ENDIF»);
+ «ENDFOR»
+ // own saps
+ «FOR sap : ac.strSAPs»
+ «sap.name» = new «sap.getPortClassName()»(this, "«sap.name»", IFITEM_«sap.name», 0, port_addr[IFITEM_«sap.name»][0], peer_addr[IFITEM_«sap.name»][0]);
+ «ENDFOR»
+ // own service implementations
+ «FOR svc : ac.serviceImplementations»
+ «svc.spp.name» = new «svc.getPortClassName()»(this, "«svc.spp.name»", IFITEM_«svc.spp.name», port_addr[IFITEM_«svc.spp.name»], peer_addr[IFITEM_«svc.spp.name»]);
+ «ENDFOR»
+ }
+
+
+ //--------------------- lifecycle functions
+ public void init(){
+ initUser();
+ }
+
+ public void start(){
+ startUser();
+ }
+
+ «IF !ac.overridesStop()»
+ public void stop(){
+ stopUser();
+ }
+ «ENDIF»
+
+ public void destroy(){
+ destroyUser();
+ }
+
+ «IF ac.stateMachine != null»
+ «stateMachineGen.genStateMachine(xpac, ac)»
+ «ELSEIF !xpac.hasStateMachine()»
+ //--------------------- no state machine
+ @Override
+ public void receiveEvent(InterfaceItemBase ifitem, int evt, Object data) {
+ handleSystemEvent(ifitem, evt, data);
+ }
+
+ @Override
+ public void executeInitTransition(){
+ }
+ «ENDIF»
+ };
+
+ #endif /* _«xpac.name»_H_ */
+
+ '''
+ }
+
+ def generateSourceFile(Root root, ExpandedActorClass xpac, ActorClass ac) {'''
+ #include "«xpac.getCHeaderFileName»"
+
+ '''
+ }
+
+ def msgArgs(Message msg) {
+ '''«IF msg.data!=null»«msg.data.defaultValue()»«ENDIF»'''
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend
index 44fdc9e43..d5d802277 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend
@@ -1,258 +1,258 @@
-/*******************************************************************************
- * Copyright (c) 2011 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:
- * Henrik Rentz-Reichert (initial contribution)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.generator.c.gen
-
-import com.google.inject.Inject
-import com.google.inject.Singleton
-import java.util.List
-import org.eclipse.etrice.core.room.ActorClass
-import org.eclipse.etrice.core.room.NonInitialTransition
-import org.eclipse.etrice.core.room.Transition
-import org.eclipse.etrice.core.room.TriggeredTransition
-import org.eclipse.etrice.generator.etricegen.ExpandedActorClass
-import org.eclipse.etrice.generator.etricegen.TransitionChain
-import static extension org.eclipse.etrice.generator.extensions.RoomNameProv.*
-import org.eclipse.etrice.generator.extensions.RoomExtensions
-import org.eclipse.etrice.generator.generic.LanguageGenerator
-
-
-@Singleton
-class StateMachineGen {
-
- @Inject extension CExtensions stdExt
- @Inject extension RoomExtensions roomExt
- @Inject LanguageGenerator languageGen
-
- def genStateMachine(ExpandedActorClass xpac, ActorClass ac) {'''
- //******************************************
- // START of generated code for FSM
- //******************************************
-
- // State IDs for FSM
- «var offset = ac.getNumberOfInheritedBaseStates()»
- «var baseStates = ac.stateMachine.getBaseStateList()»
- «FOR state : baseStates»
- protected static final int «state.getStateId()» = «baseStates.indexOf(state)+2+offset»;
- «ENDFOR»
- protected static final String stateStrings[] = {"<no state>","<top>",«FOR state : ac.getAllBaseStates() SEPARATOR ","»"«state.getStatePathName()»"
- «ENDFOR»};
-
- // history
- // TODOHRR: history defined in ActorClassBase, init in constructor
- // history = new int[5];
- // for (int i = 0; i < history.length; i++) {
- // history[i] = NO_STATE;
- // }
- protected int history[] = {NO_STATE,NO_STATE«FOR state : ac.getAllBaseStates()»,NO_STATE«ENDFOR»};
-
- «var List<TransitionChain> chains = xpac.getOwnTransitionChains()»
- «var offset_tc = xpac.getTransitionChains().size-chains.size»
- // transition chains
- «FOR tc : chains»
- protected static final int «tc.getChainId()» = «chains.indexOf(tc)+1+offset_tc»;
- «ENDFOR»
-
- «var triggers = xpac.getOwnTriggers()»
- // triggers for FSM
- «FOR mif : triggers»protected static final int «xpac.getTriggerCodeName(mif)» = IFITEM_«mif.from.name» + EVT_SHIFT*«xpac.getMessageID(mif)»;
- «ENDFOR»
-
- // receiveEvent contains the main implementation of the FSM
- @Override
- public void receiveEvent(InterfaceItemBase ifitem, int evt, Object generic_data) {
- int trigger = ifitem.getLocalId() + EVT_SHIFT*evt;
- int chain = NOT_CAUGHT;
- int catching_state = NO_STATE;
- boolean is_handler = false;
- boolean skip_entry = false;
-
- if (!handleSystemEvent(ifitem, evt, generic_data)) {
- switch (state) {
- «FOR state : xpac.stateMachine.getLeafStateList()»
- case «state.getStateId()»:
- «var atlist = xpac.getActiveTriggers(state)»
- «IF !atlist.isEmpty»
- switch(trigger) {
- «FOR at : atlist»
- case «xpac.getTriggerCodeName(at.trigger)»:
- «var needData = xpac.hasGuard(at)»
- «IF needData»{ «at.msg.getTypedDataDefinition()»«ENDIF»
- «FOR tt : at.transitions SEPARATOR " else "»
- «var chain = xpac.getChain(tt)»
- «guard(chain.transition, at.trigger, xpac)»
- {
- chain = «chain.getChainId()»;
- catching_state = «chain.getContextId()»;
- «IF chain.isHandler()»is_handler = true;«ENDIF»
- «IF chain.skipEntry»skip_entry = true;«ENDIF»
- }
- «ENDFOR»
- «IF needData»}«ENDIF»
- break;
- «ENDFOR»
- }
- «ENDIF»
- break;
- «ENDFOR»
- }
- }
- if (chain != NOT_CAUGHT) {
- exitTo(state, catching_state, is_handler);
- int next = executeTransitionChain(chain, ifitem, generic_data);
- next = enterHistory(next, is_handler, skip_entry);
- setState(next);
- }
- }
-
- private void setState(int new_state) {
- DebuggingService.getInstance().addActorState(this,stateStrings[new_state]);
- if (stateStrings[new_state]!="Idle") {
- // TODOTS: model switch for activation
- System.out.println(getInstancePath() + " -> " + stateStrings[new_state]);
- }
- this.state = new_state;
- }
-
- @Override
- public void executeInitTransition() {
- «var initt = xpac.stateMachine.getInitTransition()»
- int chain = «xpac.getChain(initt).getChainId()»;
- int next = executeTransitionChain(chain, null, null);
- next = enterHistory(next, false, false);
- setState(next);
- }
-
- /**
- * calls exit codes while exiting from the current state to one of its
- * parent states while remembering the history
- * @param current - the current state
- * @param to - the final parent state
- * @param handler - entry and exit codes are called only if not handler (for handler TransitionPoints)
- */
- private void exitTo(int current, int to, boolean handler) {
- while (current!=to) {
- switch (current) {
- «FOR state : xpac.stateMachine.getBaseStateList()»
- case «state.getStateId()»:
- «IF state.hasExitCode()»if (!handler) «state.getExitCodeOperationName()»();«ENDIF»
- history[«state.getParentStateId()»] = «state.getStateId()»;
- current = «state.getParentStateId()»;
- break;
- «ENDFOR»
- }
- }
- }
- /**
- * calls action, entry and exit codes along a transition chain. The generic data are cast to typed data
- * matching the trigger of this chain. The ID of the final state is returned
- * @param chain - the chain ID
- * @param generic_data - the generic data pointer
- * @return the ID of the final state
- */
- private int executeTransitionChain(int chain, InterfaceItemBase ifitem, Object generic_data) {
- switch (chain) {
- «var allchains = xpac.getTransitionChains()»
- «FOR tc : allchains»
- case «tc.getChainId()»:
- {
- «xpac.getExecuteChainCode(tc)»
- }
- «ENDFOR»
- }
- return NO_STATE;
- }
- /**
- * calls entry codes while entering a state's history. The ID of the final leaf state is returned
- * @param state - the state which is entered
- * @param handler - entry code is executed if not handler
- * @return - the ID of the final leaf state
- */
- private int enterHistory(int state, boolean handler, boolean skip_entry) {
- while (true) {
- switch (state) {
- «FOR state : xpac.stateMachine.getBaseStateList()»
- case «state.getStateId()»:
- «IF state.hasEntryCode()»if (!(skip_entry || handler)) «state.getEntryCodeOperationName()»();«ENDIF»
- «IF state.isLeaf()»
- // in leaf state: return state id
- return «state.getStateId()»;
- «ELSE»
- // state has a sub graph
- «IF state.subgraph.hasInitTransition()»
- // with init transition
- if (history[«state.getStateId()»]==NO_STATE) {
- «var sub_initt = state.subgraph.getInitTransition()»
- state = executeTransitionChain(«xpac.getChain(sub_initt).getChainId()», null, null);
- }
- else {
- state = history[«state.getStateId()»];
- }
- «ELSE»
- // without init transition
- state = history[«state.getStateId()»];
- «ENDIF»
- break;
- «ENDIF»
- «ENDFOR»
- case STATE_TOP:
- state = history[STATE_TOP];
- break;
- }
- skip_entry = false;
- }
- //return NO_STATE; // required by CDT but detected as unreachable by JDT because of while (true)
- }
-
- //*** Entry and Exit Codes
- «FOR state : xpac.stateMachine.getStateList()»
- «IF xpac.isOwnObject(state)»
- «IF state.hasEntryCode()»
- protected void «state.getEntryCodeOperationName()»() {
- «xpac.getEntryCode(state)»
- }
- «ENDIF»
- «IF state.hasExitCode()»
- protected void «state.getExitCodeOperationName()»() {
- «xpac.getExitCode(state)»
- }
- «ENDIF»
- «ENDIF»
- «ENDFOR»
-
- //*** Action Codes
- «FOR tr : xpac.stateMachine.getTransitionList()»
- «IF xpac.isOwnObject(tr) && tr.hasActionCode()»
- protected void «tr.getActionCodeOperationName()»(«IF tr instanceof NonInitialTransition»InterfaceItemBase ifitem«languageGen.getArgumentList(xpac, tr)»«ENDIF») {
- «xpac.getActionCode(tr)»
- }
- «ENDIF»
- «ENDFOR»
-
- //******************************************
- // END of generated code for FSM
- //******************************************
- '''}
-
- def dispatch guard(TriggeredTransition tt, String trigger, ExpandedActorClass ac) {'''
- «var tr = tt.triggers.findFirst(e|ac.isMatching(e, trigger))»
- «IF tr.hasGuard()»
- if («ac.getCode(tr.guard.guard)»)
- «ENDIF»
- '''
- }
-
- def dispatch guard(Transition t, String trigger, ExpandedActorClass ac) {'''
- /* error */
- '''
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2011 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:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.c.gen
+
+import com.google.inject.Inject
+import com.google.inject.Singleton
+import java.util.List
+import org.eclipse.etrice.core.room.ActorClass
+import org.eclipse.etrice.core.room.NonInitialTransition
+import org.eclipse.etrice.core.room.Transition
+import org.eclipse.etrice.core.room.TriggeredTransition
+import org.eclipse.etrice.generator.etricegen.ExpandedActorClass
+import org.eclipse.etrice.generator.etricegen.TransitionChain
+import static extension org.eclipse.etrice.generator.extensions.RoomNameProv.*
+import org.eclipse.etrice.generator.extensions.RoomExtensions
+import org.eclipse.etrice.generator.generic.LanguageGenerator
+
+
+@Singleton
+class StateMachineGen {
+
+ @Inject extension CExtensions stdExt
+ @Inject extension RoomExtensions roomExt
+ @Inject LanguageGenerator languageGen
+
+ def genStateMachine(ExpandedActorClass xpac, ActorClass ac) {'''
+ //******************************************
+ // START of generated code for FSM
+ //******************************************
+
+ // State IDs for FSM
+ «var offset = ac.getNumberOfInheritedBaseStates()»
+ «var baseStates = ac.stateMachine.getBaseStateList()»
+ «FOR state : baseStates»
+ protected static final int «state.getStateId()» = «baseStates.indexOf(state)+2+offset»;
+ «ENDFOR»
+ protected static final String stateStrings[] = {"<no state>","<top>",«FOR state : ac.getAllBaseStates() SEPARATOR ","»"«state.getStatePathName()»"
+ «ENDFOR»};
+
+ // history
+ // TODOHRR: history defined in ActorClassBase, init in constructor
+ // history = new int[5];
+ // for (int i = 0; i < history.length; i++) {
+ // history[i] = NO_STATE;
+ // }
+ protected int history[] = {NO_STATE,NO_STATE«FOR state : ac.getAllBaseStates()»,NO_STATE«ENDFOR»};
+
+ «var List<TransitionChain> chains = xpac.getOwnTransitionChains()»
+ «var offset_tc = xpac.getTransitionChains().size-chains.size»
+ // transition chains
+ «FOR tc : chains»
+ protected static final int «tc.getChainId()» = «chains.indexOf(tc)+1+offset_tc»;
+ «ENDFOR»
+
+ «var triggers = xpac.getOwnTriggers()»
+ // triggers for FSM
+ «FOR mif : triggers»protected static final int «xpac.getTriggerCodeName(mif)» = IFITEM_«mif.from.name» + EVT_SHIFT*«xpac.getMessageID(mif)»;
+ «ENDFOR»
+
+ // receiveEvent contains the main implementation of the FSM
+ @Override
+ public void receiveEvent(InterfaceItemBase ifitem, int evt, Object generic_data) {
+ int trigger = ifitem.getLocalId() + EVT_SHIFT*evt;
+ int chain = NOT_CAUGHT;
+ int catching_state = NO_STATE;
+ boolean is_handler = false;
+ boolean skip_entry = false;
+
+ if (!handleSystemEvent(ifitem, evt, generic_data)) {
+ switch (state) {
+ «FOR state : xpac.stateMachine.getLeafStateList()»
+ case «state.getStateId()»:
+ «var atlist = xpac.getActiveTriggers(state)»
+ «IF !atlist.isEmpty»
+ switch(trigger) {
+ «FOR at : atlist»
+ case «xpac.getTriggerCodeName(at.trigger)»:
+ «var needData = xpac.hasGuard(at)»
+ «IF needData»{ «at.msg.getTypedDataDefinition()»«ENDIF»
+ «FOR tt : at.transitions SEPARATOR " else "»
+ «var chain = xpac.getChain(tt)»
+ «guard(chain.transition, at.trigger, xpac)»
+ {
+ chain = «chain.getChainId()»;
+ catching_state = «chain.getContextId()»;
+ «IF chain.isHandler()»is_handler = true;«ENDIF»
+ «IF chain.skipEntry»skip_entry = true;«ENDIF»
+ }
+ «ENDFOR»
+ «IF needData»}«ENDIF»
+ break;
+ «ENDFOR»
+ }
+ «ENDIF»
+ break;
+ «ENDFOR»
+ }
+ }
+ if (chain != NOT_CAUGHT) {
+ exitTo(state, catching_state, is_handler);
+ int next = executeTransitionChain(chain, ifitem, generic_data);
+ next = enterHistory(next, is_handler, skip_entry);
+ setState(next);
+ }
+ }
+
+ private void setState(int new_state) {
+ DebuggingService.getInstance().addActorState(this,stateStrings[new_state]);
+ if (stateStrings[new_state]!="Idle") {
+ // TODOTS: model switch for activation
+ System.out.println(getInstancePath() + " -> " + stateStrings[new_state]);
+ }
+ this.state = new_state;
+ }
+
+ @Override
+ public void executeInitTransition() {
+ «var initt = xpac.stateMachine.getInitTransition()»
+ int chain = «xpac.getChain(initt).getChainId()»;
+ int next = executeTransitionChain(chain, null, null);
+ next = enterHistory(next, false, false);
+ setState(next);
+ }
+
+ /**
+ * calls exit codes while exiting from the current state to one of its
+ * parent states while remembering the history
+ * @param current - the current state
+ * @param to - the final parent state
+ * @param handler - entry and exit codes are called only if not handler (for handler TransitionPoints)
+ */
+ private void exitTo(int current, int to, boolean handler) {
+ while (current!=to) {
+ switch (current) {
+ «FOR state : xpac.stateMachine.getBaseStateList()»
+ case «state.getStateId()»:
+ «IF state.hasExitCode()»if (!handler) «state.getExitCodeOperationName()»();«ENDIF»
+ history[«state.getParentStateId()»] = «state.getStateId()»;
+ current = «state.getParentStateId()»;
+ break;
+ «ENDFOR»
+ }
+ }
+ }
+ /**
+ * calls action, entry and exit codes along a transition chain. The generic data are cast to typed data
+ * matching the trigger of this chain. The ID of the final state is returned
+ * @param chain - the chain ID
+ * @param generic_data - the generic data pointer
+ * @return the ID of the final state
+ */
+ private int executeTransitionChain(int chain, InterfaceItemBase ifitem, Object generic_data) {
+ switch (chain) {
+ «var allchains = xpac.getTransitionChains()»
+ «FOR tc : allchains»
+ case «tc.getChainId()»:
+ {
+ «xpac.getExecuteChainCode(tc)»
+ }
+ «ENDFOR»
+ }
+ return NO_STATE;
+ }
+ /**
+ * calls entry codes while entering a state's history. The ID of the final leaf state is returned
+ * @param state - the state which is entered
+ * @param handler - entry code is executed if not handler
+ * @return - the ID of the final leaf state
+ */
+ private int enterHistory(int state, boolean handler, boolean skip_entry) {
+ while (true) {
+ switch (state) {
+ «FOR state : xpac.stateMachine.getBaseStateList()»
+ case «state.getStateId()»:
+ «IF state.hasEntryCode()»if (!(skip_entry || handler)) «state.getEntryCodeOperationName()»();«ENDIF»
+ «IF state.isLeaf()»
+ // in leaf state: return state id
+ return «state.getStateId()»;
+ «ELSE»
+ // state has a sub graph
+ «IF state.subgraph.hasInitTransition()»
+ // with init transition
+ if (history[«state.getStateId()»]==NO_STATE) {
+ «var sub_initt = state.subgraph.getInitTransition()»
+ state = executeTransitionChain(«xpac.getChain(sub_initt).getChainId()», null, null);
+ }
+ else {
+ state = history[«state.getStateId()»];
+ }
+ «ELSE»
+ // without init transition
+ state = history[«state.getStateId()»];
+ «ENDIF»
+ break;
+ «ENDIF»
+ «ENDFOR»
+ case STATE_TOP:
+ state = history[STATE_TOP];
+ break;
+ }
+ skip_entry = false;
+ }
+ //return NO_STATE; // required by CDT but detected as unreachable by JDT because of while (true)
+ }
+
+ //*** Entry and Exit Codes
+ «FOR state : xpac.stateMachine.getStateList()»
+ «IF xpac.isOwnObject(state)»
+ «IF state.hasEntryCode()»
+ protected void «state.getEntryCodeOperationName()»() {
+ «xpac.getEntryCode(state)»
+ }
+ «ENDIF»
+ «IF state.hasExitCode()»
+ protected void «state.getExitCodeOperationName()»() {
+ «xpac.getExitCode(state)»
+ }
+ «ENDIF»
+ «ENDIF»
+ «ENDFOR»
+
+ //*** Action Codes
+ «FOR tr : xpac.stateMachine.getTransitionList()»
+ «IF xpac.isOwnObject(tr) && tr.hasActionCode()»
+ protected void «tr.getActionCodeOperationName()»(«IF tr instanceof NonInitialTransition»InterfaceItemBase ifitem«languageGen.getArgumentList(xpac, tr)»«ENDIF») {
+ «xpac.getActionCode(tr)»
+ }
+ «ENDIF»
+ «ENDFOR»
+
+ //******************************************
+ // END of generated code for FSM
+ //******************************************
+ '''}
+
+ def dispatch guard(TriggeredTransition tt, String trigger, ExpandedActorClass ac) {'''
+ «var tr = tt.triggers.findFirst(e|ac.isMatching(e, trigger))»
+ «IF tr.hasGuard()»
+ if («ac.getCode(tr.guard.guard)»)
+ «ENDIF»
+ '''
+ }
+
+ def dispatch guard(Transition t, String trigger, ExpandedActorClass ac) {'''
+ /* error */
+ '''
+ }
+}

Back to the top