This example shows how to implement a state machine generator using EMF and openArchitectureWare. Note that the implementation of the state machine in Java is probably the slowest and clumsiest way to implement a state machine. The focus was not on optimizing the performance of the state machine implementation.
This tutorial does not explain too much, it is rather a guide through the example code. We expect that you know how to work with openArchitectureWare and EMF. If that is not the case, you should read and play with the emfHelloWorld example first (the tutorial entitled Generating Code from EMF Models ).
You need to have openArchitectureWare 4.3 installed. Please consider for details.
You can also install the code for the tutorial. It can be downloaded from the URL above, it is part of the the EMF samples ZIP file. Installing the demos is easy: Just add the projects to your workspace. Note that in the openArchitectureWare preferences (either globally for the workspace, or specific for the sample projects, you have to select EMF metamodels for these examples to work.
In the emf examples package, you can find the following three projects:
oaw4.demo.emf.statemachine
: contains the
metamodel
oaw4.demo.emf.statemachine.generator
:
contains the code generator
oaw4.demo.emf.statemachine.example
:
contains an example state machine as well as a manually written unit
test
The metamodel looks more or less as you would expect from a state
machine metamodel. The following is the representation of the metamodel in
Emfatic syntax. You can find it in the
oaw4.demo.emf.statemachine/model
package.
@namespace(uri="http://oaw/statemachine", prefix="statemachine") package statemachine; abstract class Named { attr String name; } class State extends AbstractState { val Action entryAction; val Action exitAction; } class StartState extends AbstractState { } class StopState extends AbstractState { } class Transition extends Named { ref AbstractState[1] target; val Action action; ref Event event; } class Action extends Named { } class Event extends Named { } class CompositeEvent extends Event { val Event[*] children; } class StateMachine extends Named { val AbstractState[*] states; val Event[*] events; } abstract class AbstractState extends Named { val Transition[*] transition; }
From the .ecore file, you have to generate the implementation classes, as it is usual with EMF.
In the oaw4.demo.emf.statemachine.example/src
folder, you can find an example.statemachine
file
that contains a simple example state machine. You can view it as an EMF
tree view after generating the EMF editors.
To generate code from it, run the example.oaw workflow file right next to it. It looks as follows:
<workflow> <cartridge file="workflow.oaw"> <modelFile value="example.statemachine"/> <srcGenPath value="src-gen"/> <appProject value="oaw4.demo.emf.statemachine.example"/> <srcPath value="man-src"/> </cartridge> </workflow>
As you can see, it only defines a number of parameters and calls another workflow file – the one in the generator project. We will take a look at it below.
... is achieved by running the example.oaw
file. It creates an implementation of the state machine in the
src-gen folder in the example project. Take a look
at the file to understand the implementation of the state
machine.
In the man-src folder, there is a manually written subclass that implements the actions referenced from the state machine. There is also a unit test that you can run to verify that it works. It also shows you how to use the generated state machine.
The workflow file in
oaw4.demo.emf.statemachine.generator/src
has four
steps:
A number of constraints are defined. Take a look at their definition in structure.chk to learn about the constraints check language.
There is a transformation called trafo.ext in
the src
folder which adds an emergency stop
transition to each state.
In src/recipe
, there is an
SMRecipeCreator workflow component that creates
recipes for the manual implementation of the state machine.Recipe
Creation