-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Snapshot for the 1.0.4 release with updated docs and fixed param for …
…the onEnteredState
- Loading branch information
1 parent
dd853d7
commit 5a78ee2
Showing
9 changed files
with
544 additions
and
308 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# C++ State Machine code generator for Xstate Tutorial | ||
[Back to README page](README.md) for introduction. | ||
|
||
This tutorial is based on the model [engineer.ts](demo-project/engineer.ts) and the demo project [engineer_demo.cpp](demo-project/engineer_demo.cpp). | ||
|
||
## Install the package and generate the code | ||
|
||
Please follow the [Quick Start guide](README.md#install-and-quick-start-tutorial) to generate the code from `engineer.ts` model. | ||
|
||
## The generated header walkthrough | ||
|
||
### What happens when an Event is posted | ||
|
||
The State Machine header generated by the demo model is [engineer_sm.h](demo-project/engineer_sm.h). Let's follow a fragment [engineer.ts](demo-project/engineer.ts) to find how it maps to the generated C++ code. In the model we have one of the state transitions declared as: | ||
|
||
```TypeScript | ||
sleeping: { | ||
entry: 'startWakeupTimer', | ||
exit: 'morningRoutine', | ||
on: { | ||
'TIMER': { target: 'working', actions: ['startHungryTimer', 'startTiredTimer'] }, | ||
} | ||
}, | ||
``` | ||
it means that if the Engineer SM is in state `sleeping`, it will transition to the `working` state when the `TIMER` event is posted. | ||
|
||
The State Machine is declared as: | ||
```C++ | ||
template <typename SMSpec = DefaultEngineerSMSpec<std::nullptr_t>> | ||
class EngineerSM { | ||
... | ||
} | ||
``` | ||
The template argument `SMSpec` has a convenient default already generated, but it can be replaced with another template struct to do the full customization of the State Machine at compile time. | ||
To post the `TIMER` event call this method: | ||
```C++ | ||
void postEventTimer(std::shared_ptr<TimerPayload> payload); | ||
``` | ||
Here the `TimerPayload` is declared in the `SMSpec` and by declaring this struct you can use an arbitrary class as `TimerPayload`. | ||
|
||
When `TIMER` is posted, and the machine is in `sleeping` state, the generated State Machine engine will do the following steps: | ||
|
||
* Call the method `morningRoutine(EngineerSM<DefaultEngineerSMSpec>* sm)`, which is an exit action from the `sleeping` state | ||
* Call the virtual method `onLeavingSleepingState(State nextState)`. Such exit methods are generated for every state | ||
* Call method `startHungryTimer(EngineerSM<DefaultEngineerSMSpec>* sm, std::shared_ptr<EventTimerPayload>)` for the transition action. Here the `std::shared_ptr<EventTimerPayload>)` is the same event payload that was sent with the `postEventTimer()` call | ||
* Call method `startTiredTimer(EngineerSM<DefaultEngineerSMSpec>* sm, std::shared_ptr<EventTimerPayload>)`, which is another modeled transition action | ||
* Call method `void onEnteringStateWorkingOnTIMER(State nextState, std::shared_ptr<TimerPayload> payload)`. Again, the `payload` is probagated to this callback as well. | ||
* As `working` state was declared with the following entry events: | ||
```TypeScript | ||
working: { | ||
entry: ['checkEmail', 'startHungryTimer', 'checkIfItsWeekend' ], | ||
``` | ||
the action callbacks `checkEmail(EngineerSM<DefaultEngineerSMSpec>* sm)`, `startHungryTimer(EngineerSM<DefaultEngineerSMSpec>* sm)` and `checkIfItsWeekend(EngineerSM<DefaultEngineerSMSpec>* sm)` will be invoked as well | ||
* Note: all those actions above were invoked while the SM state is still `sleepng` | ||
* Transition to the new state `working`. This involves changing the internal data structures protected under `std::mutex` lock. Thus the SM is transitioned to the next state atomically | ||
* Invoke the callback `onEnteredStateWorkingOnTIMER(std::shared_ptr<TimerPayload> payload)` | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.