[[sm-triggers]]
== Triggering Transitions

Driving a state machine is done by using transitions, which are triggered
by triggers. The currently supported triggers are `EventTrigger` and
`TimerTrigger`.

=== Using `EventTrigger`

`EventTrigger` is the most useful trigger, because it lets you
directly interact with a state machine by sending events to it. These
events are also called signals. You can add a trigger to a transition
by associating a state with it during configuration.
The following example shows how to do so:

====
[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetO]
----
====

Whether you send one event or multiple events, result is always a sequence
of results. This is so because in a presence multiple reqions, results will
come back from multiple machines in those regions. This is shown
with method `sendEventCollect` which gives a list of results. Method
itself is a just a syntactic sugar collecting `Flux` as list. If there is
just one region, this list contains one result.

====
[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetO3]
----
====

IMPORTANT: Nothing happens until returned flux is subscribed. See more about it from
<<sm-triggers-statemachineeventresult>>.

The preceding example sends an events by constructing a `Mono` wrapping
a `Message` and subscribing into returned `Flux` of results. `Message` lets
us add arbitrary extra information to an event, which is then visible
to `StateContext` when (for example) you implement actions.

NOTE: Message headers are generally passed on until machine runs to
completion for a specific event. For example if an event is causing
transition into a state `A` which have an anonymous transition into a
state `B`, original event is available for actions or guards in state
`B`.

It is also possible to send a `Flux` of messages instead of sending just
one with a `Mono`.

====
[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests.java[tags=snippetO2]
----
====

[[sm-triggers-statemachineeventresult]]
==== StateMachineEventResult

`StateMachineEventResult` contains more detailed information about a result
of a event sending. From this you can get a `Region` which handled an event,
`Message` itself and what was an actual `ResultType`. From `ResultType` you
can see if message was accepted, denied or deferred. Generally speaking when
subscribtion completes, events are passed into a machine.

=== Using `TimerTrigger`

`TimerTrigger` is useful when something needs to be triggered
automatically without any user interaction. `Trigger` is added to a
transition by associating a timer with it during a configuration.

Currently, there are two types of supported timers, one that fires
continuously and one that fires once a source state is entered.
The following example shows how to use the triggers:

====
[source,java,indent=0]
----
include::samples/DocsConfigurationSampleTests2.java[tags=snippetA]
----
====

The preceding example has three states: `S1`, `S2`, and `S3`. We have a normal
external transition from `S1` to `S2` and from `S1` to `S3` with
events `E1` and `E2`, respectively. The interesting parts
for working with `TimerTrigger` are when we define
internal transitions for source states `S2` and `S3`.

For both transitions, we invoke the `Action` bean (`timerAction`), where
source state `S2` uses `timer` and `S3` uses `timerOnce`.
Values given are in milliseconds (`1000` milliseconds, or one second, in both cases).

Once a state machine receives event `E1`, it does a transition
from `S1` to `S2` and the timer kicks in. When the state is `S2`,
`TimerTrigger` runs and causes a transition associated with that
state -- in this case, the internal transition that has the
`timerAction` defined.

Once a state machine receives the `E2`, event it does a transition
from `S1` to `S3` and the timer kicks in. This timer is executed only once
after the state is entered (after a delay defined in a timer).

NOTE: Behind the scenes, timers are simple triggers that may cause a
transition to happen. Defining a transition with a `timer()` keeps
firing triggers and causes transition only if the source state is active.
Transition with `timerOnce()` is a little different, as it
triggers only after a delay when a source state is actually entered.

TIP: Use `timerOnce()` if you want something to happen after a delay
exactly once when state is entered.
