diff --git a/README.md b/README.md index 19f9ae4..d60643c 100644 --- a/README.md +++ b/README.md @@ -3,29 +3,34 @@ This package allows to convert TypeScript language State Machine developed using [Xstate](https://github.com/davidkpiano/xstate) into C++ generated SM, no coding required. -Project location: https://github.com/shuvalov-mdb/xstate-cpp-generator -Copyright Andrew Shuvalov, MIT [License](https://github.com/shuvalov-mdb/xstate-cpp-generator/blob/master/LICENSE) +* Project location: https://github.com/shuvalov-mdb/xstate-cpp-generator +* NPM TypeScript package location: https://www.npmjs.com/package/xstate-cpp-generator +* Copyright Andrew Shuvalov, MIT [License](https://github.com/shuvalov-mdb/xstate-cpp-generator/blob/master/LICENSE) ## Features * Design and test the State Machine in [Xstate](https://github.com/davidkpiano/xstate) and then convert to C++ without any changes * Use the [online vizualizer](https://xstate.js.org/viz/) to debug the State Machine -* SM basics: [States](https://xstate.js.org/docs/guides/states.html), [Events](https://xstate.js.org/docs/guides/events.html), [Transitions](https://xstate.js.org/docs/guides/transitions.html) +* SM basic features supported: [States](https://xstate.js.org/docs/guides/states.html), [Events](https://xstate.js.org/docs/guides/events.html), [Transitions](https://xstate.js.org/docs/guides/transitions.html) + * SM extra features supported: [Actions](https://xstate.js.org/docs/guides/actions.html#declarative-actions) * Generated C++ is fully synchronized, safe to use in multi-threaded environemnt without any changes -* No exteral dependencies except STL. No boost dependency. -* Callback model based on subclassing and virtual methods - * Callbacks are invoked when: leaving a state, entering a state, after entering a state +* No external dependencies except STL. No boost dependency. +* Callback model: + * Entry, Exit and Trasition [Actions](https://xstate.js.org/docs/guides/actions.html#declarative-actions) are code + generated as static methods in the template object used to declare the State Machine and can be implemented by the user + * Every state and transtion callbacks are generated as virtual methods that can be overloaded by subclassing * Arbitrary user-defined data structure (called Context) can be stored in the SM * Any event can have an arbitrary user-defined payload attached. The event payload is propagated to related callbacks ## Install and Quick Start Tutorial -Install the xstate-cpp-generator TypeScript package, locally (or globally with `-g` option): +### 1. Install the xstate-cpp-generator TypeScript package, locally (or globally with `-g` option): ```bash npm install xstate-cpp-generator ``` -Create a simple Xstate model file `ping.ts` with few lines to trigger C++ generation at the end: +### 2. Create a simple Xstate model file `engineer.ts` with few lines to trigger C++ generation at the end: +(this example is located at https://github.com/shuvalov-mdb/xstate-cpp-generator/tree/master/demo-project) ```TypeScript const CppGen = require('xstate-cpp-generator'); @@ -42,43 +47,78 @@ const engineerMachine = Machine({ exit: 'morningRoutine', on: { 'TIMER': { target: 'working', actions: ['startHungryTimer', 'startTiredTimer'] }, - 'TIRED': { target: 'sleeping' } } }, working: { - entry: ['checkEmail', 'startHungryTimer' ], + entry: ['checkEmail', 'startHungryTimer', 'checkIfItsWeekend' ], on: { 'HUNGRY': { target: 'eating', actions: ['checkEmail']}, - 'TIRED': { target: 'sleeping' } + 'TIRED': { target: 'sleeping' }, + 'ENOUGH': { target: 'weekend' } }, }, eating: { entry: 'startShortTimer', - exit: [ 'checkEmail', 'startHungryTimer', 'startTiredTimer' ], + exit: [ 'checkEmail', 'startHungryTimer' ], on: { 'TIMER': { target: 'working', actions: ['startHungryTimer'] }, 'TIRED': { target: 'sleeping' } } + }, + weekend: { + type: 'final', } } }); - CppGen.generateCpp({ xstateMachine: engineerMachine, destinationPath: "", - namespace: "mongo", + namespace: "engineer_demo", pathForIncludes: "", tsScriptName: path.basename(__filename) }); + ``` +To visualize this State Machine copy-paste the 'Machine' method call to the [online vizualizer](https://xstate.js.org/viz/). -And generate C++ with: +### 3. And generate C++ with ```bash - ts-node ping.ts + ts-node engineer.ts ``` You should see new generated files: ``` -ping_sm.cpp ping_sm.h ping_test.cpp +engineer_sm.h engineer_sm.cpp engineer_test.cpp ``` + +The `engineer_test.cpp` is an automatically generated Unit Test for the model. Create a simple `SConscript` file to compile it: + +``` +env = Environment() + +LIBS ='' + +common_libs = ['gtest_main', 'gtest', 'pthread'] +env.Append( LIBS = common_libs ) + +env.Append(CCFLAGS=['-fsanitize=address,undefined', + '-fno-omit-frame-pointer'], + LINKFLAGS='-fsanitize=address,undefined') + +env.Program('engineer_test', ['engineer_sm.cpp', 'engineer_test.cpp'], + LIBS, LIBPATH='/opt/gtest/lib:/usr/local/lib', CXXFLAGS="-std=c++17") + +``` +and run it with: +``` + scons + ./engineer_test +``` + + +## Release Notes + +### V 1.0.3 +* Full support of entry, exit and transition Actions +* Multi-threading bugfixes diff --git a/package.json b/package.json index 97811de..0ecf53e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xstate-cpp-generator", - "version": "1.0.2", + "version": "1.0.3", "description": "C++ code generator for Xstate State Machine", "main": "dist/index.js", "types": "dist/index.d.ts",