The generated state machine code implements one of two execution schemes:
You can select the execution scheme via the
@EventDriven annotations. Write the appropriate annotation to the top of your statechart’s definition section, see sections
In the cycle-based execution scheme, each run cycle consists of two different phases:
This approach allows for explicitly processing several events at the same time as well as for checking combinations of events, e.g., a guard condition like
[eventA && eventB]. This is very useful for systems that are close to hardware and input signals. Basically it is the
input-process-output (IPO) model.
Example: The sample client code below first raises events eventA and eventB in the state machine. These events are lingering in the state machine until the client code calls runCycle() to actually process the events.
sc_raiseEventA(handle); sc_raiseEventB(handle); … sc_runCycle(handle);
Please note: In the cycle-based execution scheme, an event that has been raised internally using the raise statement is visible in the run cycle “downstream” only, i.e., in such regions and the states therein that have not yet been processed in the current run cycle. Everything that is “upstream” in the run cycle cannot “see” this event. This is semantically different from the event-driven execution scheme. Read more on this topic in section "Raising and processing an event".
event-driven execution scheme, each incoming event or time event immediately triggers the execution of a run-to-completion step. As a consequence, the state machine will never process two events simultaneously, and a guard condition like
[eventA && eventB] will never become true.
Example: The sample client code below raises the events eventA and eventB. The state machine processes each event immediately as it arrives, triggered by the respective raise…() method. Thus the client code does not need to call runCycle().
Please note: In the event-driven execution scheme, an event that is raised internally in a run-to-completion step using the raise statement will not be acted upon by any active state “downstream” in the event cycle. The reason is that only a single event can be processed at a time, and this is the event that caused the current run cycle to execute in the first place. The internally-raised event will trigger its own run-to-completion step subsequently. Thus it will be visible to all active states in that RTC. This is semantically different from the cycle-based execution scheme. Read more on this topic in section "Raising and processing an event".
The generated source code supports a basic statechart execution model that can be used to implement different variants. It is important to understand the responsibilities of the generated code, i.e., what it cares about and what it doesn’t. The remaining issues are out of scope and must be dealt with in the client code the developer has to provide.
The generated code basically takes care about the following:
There are some predefined constraints:
Out of scope are:
All these things are out of the generated code’s scope, since the code generators coming with YAKINDU Statechart Tools cannot provide tailored solutions without knowing any details about a respective specific environment, like runtime system, libraries, etc.
In order to have a better code generator support for specific usage patterns, you would have to implement corresponding code generator extensions.
In order to circumvent the missing thread-safety of the runCycle() method, the Java code generator has an option for generating a so-called runnable wrapper, providing event queueing and multi-threading support. For details, see section "GeneralFeatures". It is easy to implement this as a general solution for Java, since the programming language provides corresponding standard features that by definition are available everywhere and can simply be used.
The C programming language, however, does not have any standardized threading features. Therefore a general solution cannot be given. Specific solutions for specific threading libraries would require the implementation of a suitable code generator extension.