This example demonstrates the usage of event buffers and their impact on the event processing of a state machine. For more details, please also refer to our documentation.
Event buffering can be enabled or disabled with the
@EventBuffering(inEvents, localEvents) annotation. Event buffering can be enabled/disabled separately for incoming and local (internal) events. Event buffering is enabled per default for incoming and local events.
The kind of buffers are different for event-driven and cycle-based state machines. An event-driven state machine will use a queue for buffering events, while a cycle-based state machine will use an event vector. Queued events are processed one by one, each starting a new run-to-completion (RTC) step, until the queue is empty. Events buffered in a vector are all activated at once and consumed in the same RTC step.
Let's consider the example as shown above. It demonstrates event buffering on the example of local events in a cycle-based statechart. The two orthogonal regions amplify the difference between downstream and upstream visibility as both regions are processed in a determined order (first
When event buffers are enabled (or nothing different is declared), events that are raised in one run-to-completion step will be stored and processed in the next step. In contrast to that, with disabled event buffering, events that are raised are only visible in the same RTC step which can lead to counter intuitive behavior.
When incoming event
e is raised, state
A raises local event
l1. This event is stored in a buffer for the next RTC step. However, as in the same RTC step, region
r2 is processed next, the event
l1 will be directly consumed, leading to a state switch from
D. This state switch is also performed with disabled event buffering.
When incoming event
f is raised, the transition from
C raises local event
l2. This event is stored in a buffer and not processed as this RTC step is finished. In the next RTC step, the buffered event is activated, leading to a state switch from
B. This state switch would not happen if event buffers were disabled.
When event buffering is disabled, events that are raised are only visible downstream within the same RTC step. Transitions that were already evaluated earlier in the same RTC step will not fire, even if they declare this event as a trigger.
In most cases it is best to enable event buffering. Hence, it is already enabled per default. The downside is a higher memory consumption of the generated state machine code. In environments with restricted memory capacity it can be useful to disable event buffering. For more information, please refer to our documentation.