123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- h1. Tasks
- h2. Simulating Operations With Custom Java Code
- To simulate a model with operations it is possible to use custom Java code that mocks the desired behavior or even to simulate against an existing java backend.
- For that to work, it is required to provide one or more custom java classes having a method with a matching signature.
- !images/operationsExample.png!
- To simulate the statechart above, a new Java Class must be created matching the method signature defined in the statechart. This class must be placed onto the classpath of the
- statecharts project.
- Yakindu Statechart Tools default types are mapped to java types as follows:
- table{border:1px solid black}.
- |*SCT Type* | |*Java Type* |
- |integer|=>|long|
- |real|=>|double|
- |boolean|=>|boolean|
- |string|=>|String|
- |void|=>|void|
-
- bc(prettyprint).
- package example;
- public class Calculator {
- public long add(long param1, long param2) {
- return param1 + param2;
- }
- }
- This custom class can be passed to the run configuration as *Operation Class*, shown in the figure below. It is possible to pass multiple java classes seperated by a comma.
- If the simulation is executed, the variable result gets the value 2.
- !images/runConfiguration.png!
- h2. Generating Code
- For configuring the code generation process, YAKINDU Statechart Tools uses a textual generator model called *SGen*. It can be created either by using the provided wizard *Yakindu Statechart Generator Model* or by creating a new text file with the file extension '.sgen'.
- To create a generator model with the wizard,
- # Click *File* > *New* > *Other...* > *Code Generator Model*
- # Type a name and click *Next*
- # Choose the desired generator, i.e. *YAKINDU SCT Java Code Generator*
- # Check the model(s) to generate code from and click *Finish*
- !images/genmodelwizardchooselanguage.jpg!
- The result is an .sgen file of the following format:
-
- bc(prettyprint)..
- GeneratorModel for [GeneratorId] {
- statechart [StatechartReference] {
- feature [Feature] {
- [ParameterName] = [ParameterValue]
- }
- }
- }
-
- p. The [GeneratorId] is the unique id of the Generator. Currently, the following Generators are supported out of the box:
- # yakindu::java - Generator ID for the Java Code Generator
- # yakindu::c - Generator ID for the C Code Generator
- # yakindu::xpand - Generator ID for custom Xpand based Code Generators
- # yakindu::generic - Generator ID for custom Java based Code Generators
- One GeneratorModel can contain several [StatechartReference]s. These are cross references to statechart models for which the code should be generated. For each reference, the generator process can be configured with [Feature]s. Each Feature consists of several parameters. These parameters can be configured with [ParameterName] = [ParameterValue].
-
- The Generator Model is executed by a builder. Thus, the artifacts are generated automatically if *Project* > *Build Automatically* is checked. If you want to execute your Generator Model by hand, select *Generate Statechart Artifacts* from the *Package Explorer's* context menu.
- h2. Create custom code generators
- Although Yakindu Statechart Tools is shipped with powerful code generators for C, C++ and Java out of the box it may be necessary to create a custom code generator to support different use cases. One reason for a custom code generator could be to support additional programming languages (In this case we would be happy about a contribution! :-)) or to generate code for an existing framework.
- h3. Prerequisites
- Implementing a custom code generator is not a trivial task. Before you get started, you should have a basic understanding about the "Eclipse Modeling Framework":https://www.eclipse.org/modeling/emf/ that we use to structure our data model.
- Furthermore, we highly recommend to use "Xtend":http://www.eclipse.org/xtend/ as the template language for your code generator although plain old Java is still supported. Xtend provides some great features like "Template Expressions":http://www.eclipse.org/xtend/documentation.html#templates,
- "Lambdas":http://www.eclipse.org/xtend/documentation.html#lambdas and and "Polymorphic Method Invocation":http://www.eclipse.org/xtend/documentation.html#polymorphicDispatch that boosts readability and productivity.
- h3. Creating a new code generator project
- Creating custom code generators is a first level concept in Yakindu Statechart Tools. It is not required to set up a developer workspace with the Statechart Tools source code and to start a new eclipse runtime to test your generator changes. Instead you can develop and test your custom generator at runtime! To set up a new generator project select *File* > *New* > *Other* > *Yakindu* > *Xtend2/Java Generator Project* and click next.
- !images/xtendwizard.png!
- The wizard for configuring a generator projects opens. Specify a *project name* and the name of the *generator class* like shown in the example above and check the *Use Xtend* checkbox. If you plan to export your custom generator as a single eclipse plugin to deploy it to different Yakindu Statechart Tools Installations, you should check the *configure plugin for export* checkbox. The Generator Id, Name and Description is then used to make your generator accessible after export from within a Generator Model (see chapter Generating Code). The *create feature library* checkbox allows the contribution of custom generator fragments to the generator model. This is an advanced topic and you should ignore it for now. Press finish to close the wizard.
- !images/generatornavigator.png!
- Voilà! The wizard created a new generator project with for you with the structure as shown above. The *CustomGenerator.xtend* contains a simple default code generator that simply prints the name of the statechart and all of its states to the target file.
- h3. Executing the custom code generator
- To test your custom code generator, create a new Project with a Yakindu Statechart Tools Model as described in the getting started tutorial chapter *Create a statechart model* (TODO link).
- After that, create a new generator model as described in chapter *Generating code*. As the desired generator, choose the *Custom Xtend2/Java based code generator*. As you may have noticed, the generator model for the yakindu::generic generator contains an additional feature called *Generator*. This is where you should specify the name of your custom generator project and the full qualified generator class name as shown below.
- bc(prettyprint)..
- GeneratorModel for yakindu::generic {
- statechart MyStatechart {
- feature Outlet {
- targetProject = "SCTExample"
- targetFolder = "src-gen"
- }
- feature Generator {
- generatorProject = "MyCustomGenerator"
- generatorClass = "org.yakindu.CustomGenerator"
- }
- }
- }
- p. If you right click the sgen file and select "Generate Statechart Artifacts" from the context menu
- the generator is executed and creates a new file *src-gen/MyStatechart.txt* with the following content.
- bc(prettyprint)..
- The name of the Statemachine is 'MyStatechart'
- The Statemachine has the following states:
- main_region.A
- main_region.B
- p. Congratulations, you successfully created a custom generator project! Add
- bc.
- The Statemachine contains «flow.states.size» states
- to the *CustomGenerator.xtend* and regenerate. The result in *MyStatechart.txt* is updated immediately. This is a very powerful feature of Yakindu Statechart Tools. You can develop your code generator at runtime with zero turn around time. Just hit *generate* and see the result.
- h3. Different meta models for different use cases
- *The SGraph meta model*
- The SGraph meta model defines the structural aspects of the Statechart model and is similiar to the statemachine model defined by the Unified Modeling Language (UML). A simplified version is shown in the following diagram.
- !images/sgraph_simple.png!
- A *Statechart* extends __CompositeElement__, therefore it contains 0..* __Regions__. It is the root element of the model. A *CompositeElement* is an abstract type that contains __Regions__. Known sub classes are __Statechart__ and __State__. A *Region* contains 1..* __Vertices__. A *Vertex* is a abstract type representing nodes in the SGraph tree. Vertices contain outgoing __Transitions__. A *RegularState* is an abstract type derived from __Vertex__. It has no additional features, but is the common base type for __State__ and __FinalState__. A *State* is derived from __RegularState__ and __CompositeElement__. and thus may contain __Regions__ and __Transitions__. A *FinalState*
- is derived from "RegularState". It indicated the completion of its containing __Region__. A *PseudoState* is an abstract type derived from __Vertex__. It has no additional features, but is the common base type for __Choice__, __Entry__, __Exit__ and __Synchronization__. A *Choice* is a __Pseudostate__ with the additional attribute __kind__, that determines if the element has __static__ or __dynamic__ execution semantics. An *Entry* is a __Pseudostate__ with the additional attribute "kind". A Entry may be of the kind __Initial__, __ShallowHistory__ or __DeepHistory__. An *Exit* is a __Pseudostate__. It is defined as the point where a region is left. A *Synchronization* is a __Pseudostate__. It is equivalent to a __Fork__ and a __Join__. A *Transition* is defined as a directed relationship between two vertices.
-
|