Git Product home page Git Product logo

fsmlite's People

Contributors

tkem avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fsmlite's Issues

Request: Support for multiple guards

I have a use case where I often need to validate transitions using multiple guards. For now, this requires an extra member function that wraps other boolean checks such that a single bool output is provided to the fsm API. It would be awesome to reduce some of the boilerplate by supporting the ability to provide a list of guards that need to all be AND'd together to validate the transition. Then on the handle_event, here, you'd just check for each of the provided guards before proceeding. This pattern is similar to the API provided by the python transitions lib.

Why change to .h

fsmlite is definitely a C++ lib. Why use the .h extension, indicating that it will be a c-lib? The common way is to either have no extension (as per STL), or to have .hpp (as per Boost), take your pick, but not .h.

Additionally use _MSVC_LANG for determining the C++ language version

MSVC requires /Zc:__cplusplus to correctly set __cplusplus:
https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
However, there is also _MSVC_LANG:

_MSVC_LANG Defined as an integer literal that specifies the C++ language standard targeted by the compiler. It's set only in code compiled as C++. The macro is the integer literal value 201402L by default, or when the /std:c++14 compiler option is specified. The macro is set to 201703L if the /std:c++17 compiler option is specified. It's set to a higher, unspecified value when the /std:c++latest option is specified. Otherwise, the macro is undefined. The _MSVC_LANG macro and /std (Specify Language Standard Version) compiler options are available beginning in Visual Studio 2015 Update 3.
https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-160

Consider checking for specific C++ versions/features using both __cplusplus and _MSVC_LANG, so users do not have to remember turning on /Zc:__cplusplus.

Support for CMake

Hi, thanks for all the work on this project!

I'm building and using fsmlite via CMake. This way I am able to find, link and test fsmlite on multiple platforms. I was wondering if a PR for support of CMake would be considered? Perhaps even replacing Make.

That way you could easily build and test using MSVC, GCC, Clang or any other compiler. To be able to build the tests with MSVC >=19.14, a change was required for successful compilation, basically:

-    friend class fsm;  // base class needs access to transition_table
+    friend class fsmlite::fsm<state_machine>;  // base class needs access to transition_table

After that, testing is easy as ctest -C Debug

Test project C:/dev/third_party/fsmlite/build
    Start 1: fsmlite_tests_test_basic_row
1/9 Test #1: fsmlite_tests_test_basic_row .....   Passed    1.43 sec
    Start 2: fsmlite_tests_test_mem_fn_row
2/9 Test #2: fsmlite_tests_test_mem_fn_row ....   Passed    1.44 sec
    Start 3: fsmlite_tests_test_notrans
3/9 Test #3: fsmlite_tests_test_notrans .......   Passed    1.63 sec
    Start 4: fsmlite_tests_test_player
4/9 Test #4: fsmlite_tests_test_player ........   Passed    1.63 sec
    Start 5: fsmlite_tests_test_recursive
5/9 Test #5: fsmlite_tests_test_recursive .....   Passed    2.60 sec
    Start 6: fsmlite_tests_test_row
6/9 Test #6: fsmlite_tests_test_row ...........   Passed    0.07 sec
    Start 7: fsmlite_tests_test_scoped
7/9 Test #7: fsmlite_tests_test_scoped ........   Passed    0.05 sec
    Start 8: fsmlite_tests_test_shared
8/9 Test #8: fsmlite_tests_test_shared ........   Passed    1.45 sec
    Start 9: fsmlite_tests_test_traits
9/9 Test #9: fsmlite_tests_test_traits ........   Passed    0.07 sec

100% tests passed, 0 tests failed out of 9

Total Test time (real) =  10.46 sec

Drop basic_row

It's kind of awkward to use, and with C++17 serves no real purpose any more.
Also think about renaming mem_fn_row to simply row on C++11, should be reasonably forward-compatible with the C++17 implementation (except for overloaded member functions).

Documentation build improvements

[ ] Sphinx version information should be extracted from configure.ac.
[ ] Presence of doxygen and sphinx-build should be checked in autoconf.

time complxity of this fsm

I aprreciate the code you shared. But it seems that every time this fsm handles an event, it needs to search the transition table. So the time complexity for each call of process_event is O(N) (N is the count of rows) , not O(1), which makes this fsm unpractical .

Add "queuing" FSM

As stated in #5, process_event() must not be called recursively. Since this is a common pattern, especially with multiple FSMs passing events to each other, a "queuing" FSM type should be added.

Warning/Error when compiling with -Wextra (fix included)

Hi,

Great lib, works out of the box. Almost.
Test program with #include "fsm.h"

g++ -g -Wall -Wextra -Werror -std=c++17 prog.cc -o prog

fsm.h:242:47: error: unused parameter ‘event’ [-Werror=unused-parameter]

Fix to silent compiler warning:

--- fsm.h	2020-06-05 11:15:19.387923805 +0200
+++ fsm-patched.h	2020-06-05 11:30:52.649638975 +0200
@@ -240,7 +240,7 @@
          */
         template<class Event>
         state_type no_transition(const Event& event) {
-            return m_state;
+            (void)event; return m_state;
         }

Best Regards,
Johan

Link errors with clang/LLVM (windows/VS2015) in player example.

Compilation without errors, the following link errors arise:

1>------ Rebuild All started: Project: test, Configuration: Release x64 ------
1>test_player_main.obj : error LNK2019: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::open_drawer(struct player::open_close const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::open_drawer(struct player::open_close const &)>::value" (?value@?$mem_fn_action@Uopen_close@player@@$1?open_drawer@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A) referenced in function "public: static void __cdecl fsmlite::fsm<class player,int>::basic_row<0,struct player::open_close,1,struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::open_drawer(struct player::open_close const &)>::type,&public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::open_drawer(struct player::open_close const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::open_drawer(struct player::open_close const &)>::value,struct fsmlite::fsm<class player,int>::no_guard::type,&public: static struct fsmlite::fsm<class player,int>::no_guard::type fsmlite::fsm<class player,int>::no_guard::value>::process_event(class player &,struct player::open_close const &)" (?process_event@?$basic_row@$0A@Uopen_close@player@@$00Utype@?$mem_fn_action@Uopen_close@player@@$1?open_drawer@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@$1?value@456@2U3456@AU3?$no_guard@Uopen_close@player@@@56@$1?7856@2U3856@A@?$fsm@Vplayer@@h@fsmlite@@SAXAEAVplayer@@AEBUopen_close@4@@z)
1>test_player_main.obj : error LNK2019: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::close_drawer(struct player::open_close const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::close_drawer(struct player::open_close const &)>::value" (?value@?$mem_fn_action@Uopen_close@player@@$1?close_drawer@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A) referenced in function "public: static void __cdecl fsmlite::fsm<class player,int>::basic_row<1,struct player::open_close,2,struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::close_drawer(struct player::open_close const &)>::type,&public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::close_drawer(struct player::open_close const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::close_drawer(struct player::open_close const &)>::value,struct fsmlite::fsm<class player,int>::no_guard::type,&public: static struct fsmlite::fsm<class player,int>::no_guard::type fsmlite::fsm<class player,int>::no_guard::value>::process_event(class player &,struct player::open_close const &)" (?process_event@?$basic_row@$00Uopen_close@player@@$01Utype@?$mem_fn_action@Uopen_close@player@@$1?close_drawer@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@$1?value@456@2U3456@AU3?$no_guard@Uopen_close@player@@@56@$1?7856@2U3856@A@?$fsm@Vplayer@@h@fsmlite@@SAXAEAVplayer@@AEBUopen_close@4@@z)
1>test_player_main.obj : error LNK2019: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::stop_and_open(struct player::open_close const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::stop_and_open(struct player::open_close const &)>::value" (?value@?$mem_fn_action@Uopen_close@player@@$1?stop_and_open@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A) referenced in function "public: static void __cdecl fsmlite::fsm<class player,int>::basic_row<3,struct player::open_close,1,struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::stop_and_open(struct player::open_close const &)>::type,&public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::stop_and_open(struct player::open_close const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::stop_and_open(struct player::open_close const &)>::value,struct fsmlite::fsm<class player,int>::no_guard::type,&public: static struct fsmlite::fsm<class player,int>::no_guard::type fsmlite::fsm<class player,int>::no_guard::value>::process_event(class player &,struct player::open_close const &)" (?process_event@?$basic_row@$02Uopen_close@player@@$00Utype@?$mem_fn_action@Uopen_close@player@@$1?stop_and_open@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@$1?value@456@2U3456@AU3?$no_guard@Uopen_close@player@@@56@$1?7856@2U3856@A@?$fsm@Vplayer@@h@fsmlite@@SAXAEAVplayer@@AEBUopen_close@4@@z)
1>test_player_main.obj : error LNK2019: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::cd_detected,&private: void __cdecl player::store_cd_info(struct player::cd_detected const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::cd_detected,&private: void __cdecl player::store_cd_info(struct player::cd_detected const &)>::value" (?value@?$mem_fn_action@Ucd_detected@player@@$1?store_cd_info@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A) referenced in function "public: static void __cdecl fsmlite::fsm<class player,int>::basic_row<2,struct player::cd_detected,0,struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::cd_detected,&private: void __cdecl player::store_cd_info(struct player::cd_detected const &)>::type,&public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::cd_detected,&private: void __cdecl player::store_cd_info(struct player::cd_detected const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::cd_detected,&private: void __cdecl player::store_cd_info(struct player::cd_detected const &)>::value,struct fsmlite::fsm<class player,int>::no_guard::type,&public: static struct fsmlite::fsm<class player,int>::no_guard::type fsmlite::fsm<class player,int>::no_guard::value>::process_event(class player &,struct player::cd_detected const &)" (?process_event@?$basic_row@$01Ucd_detected@player@@$0A@Utype@?$mem_fn_action@Ucd_detected@player@@$1?store_cd_info@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@$1?value@456@2U3456@AU3?$no_guard@Ucd_detected@player@@@56@$1?7856@2U3856@A@?$fsm@Vplayer@@h@fsmlite@@SAXAEAVplayer@@AEBUcd_detected@4@@z)
1>test_player_main.obj : error LNK2019: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::start_playback(struct player::play const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::start_playback(struct player::play const &)>::value" (?value@?$mem_fn_action@Uplay@player@@$1?start_playback@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A) referenced in function "public: static void __cdecl fsmlite::fsm<class player,int>::basic_row<0,struct player::play,3,struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::start_playback(struct player::play const &)>::type,&public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::start_playback(struct player::play const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::start_playback(struct player::play const &)>::value,struct fsmlite::fsm<class player,int>::no_guard::type,&public: static struct fsmlite::fsm<class player,int>::no_guard::type fsmlite::fsm<class player,int>::no_guard::value>::process_event(class player &,struct player::play const &)" (?process_event@?$basic_row@$0A@Uplay@player@@$02Utype@?$mem_fn_action@Uplay@player@@$1?start_playback@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@$1?value@456@2U3456@AU3?$no_guard@Uplay@player@@@56@$1?7856@2U3856@A@?$fsm@Vplayer@@h@fsmlite@@SAXAEAVplayer@@AEBUplay@4@@z)
1>test_player_main.obj : error LNK2019: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::resume_playback(struct player::play const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::resume_playback(struct player::play const &)>::value" (?value@?$mem_fn_action@Uplay@player@@$1?resume_playback@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A) referenced in function "public: static void __cdecl fsmlite::fsm<class player,int>::basic_row<4,struct player::play,3,struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::resume_playback(struct player::play const &)>::type,&public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::resume_playback(struct player::play const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::resume_playback(struct player::play const &)>::value,struct fsmlite::fsm<class player,int>::no_guard::type,&public: static struct fsmlite::fsm<class player,int>::no_guard::type fsmlite::fsm<class player,int>::no_guard::value>::process_event(class player &,struct player::play const &)" (?process_event@?$basic_row@$03Uplay@player@@$02Utype@?$mem_fn_action@Uplay@player@@$1?resume_playback@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@$1?value@456@2U3456@AU3?$no_guard@Uplay@player@@@56@$1?7856@2U3856@A@?$fsm@Vplayer@@h@fsmlite@@SAXAEAVplayer@@AEBUplay@4@@z)
1>test_player_main.obj : error LNK2019: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::pause,&private: void __cdecl player::pause_playback(struct player::pause const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::pause,&private: void __cdecl player::pause_playback(struct player::pause const &)>::value" (?value@?$mem_fn_action@Upause@player@@$1?pause_playback@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A) referenced in function "public: static void __cdecl fsmlite::fsm<class player,int>::basic_row<3,struct player::pause,4,struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::pause,&private: void __cdecl player::pause_playback(struct player::pause const &)>::type,&public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::pause,&private: void __cdecl player::pause_playback(struct player::pause const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::pause,&private: void __cdecl player::pause_playback(struct player::pause const &)>::value,struct fsmlite::fsm<class player,int>::no_guard::type,&public: static struct fsmlite::fsm<class player,int>::no_guard::type fsmlite::fsm<class player,int>::no_guard::value>::process_event(class player &,struct player::pause const &)" (?process_event@?$basic_row@$02Upause@player@@$03Utype@?$mem_fn_action@Upause@player@@$1?pause_playback@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@$1?value@456@2U3456@AU3?$no_guard@Upause@player@@@56@$1?7856@2U3856@A@?$fsm@Vplayer@@h@fsmlite@@SAXAEAVplayer@@AEBUpause@4@@z)
1> LINK : MSIL .netmodule or module compiled with /GL found; restarting link with /LTCG; add /LTCG to the link command line to improve linker performance
1>test_player_main.obj : error LNK2001: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::open_drawer(struct player::open_close const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::open_drawer(struct player::open_close const &)>::value" (?value@?$mem_fn_action@Uopen_close@player@@$1?open_drawer@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A)
1>test_player_main.obj : error LNK2001: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::close_drawer(struct player::open_close const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::close_drawer(struct player::open_close const &)>::value" (?value@?$mem_fn_action@Uopen_close@player@@$1?close_drawer@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A)
1>test_player_main.obj : error LNK2001: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::stop_and_open(struct player::open_close const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::open_close,&private: void __cdecl player::stop_and_open(struct player::open_close const &)>::value" (?value@?$mem_fn_action@Uopen_close@player@@$1?stop_and_open@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A)
1>test_player_main.obj : error LNK2001: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::cd_detected,&private: void __cdecl player::store_cd_info(struct player::cd_detected const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::cd_detected,&private: void __cdecl player::store_cd_info(struct player::cd_detected const &)>::value" (?value@?$mem_fn_action@Ucd_detected@player@@$1?store_cd_info@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A)
1>test_player_main.obj : error LNK2001: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::start_playback(struct player::play const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::start_playback(struct player::play const &)>::value" (?value@?$mem_fn_action@Uplay@player@@$1?start_playback@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A)
1>test_player_main.obj : error LNK2001: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::resume_playback(struct player::play const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::play,&private: void __cdecl player::resume_playback(struct player::play const &)>::value" (?value@?$mem_fn_action@Uplay@player@@$1?resume_playback@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A)
1>test_player_main.obj : error LNK2001: unresolved external symbol "public: static struct fsmlite::fsm<class player,int>::mem_fn_action<struct player::pause,&private: void __cdecl player::pause_playback(struct player::pause const &)>::type fsmlite::fsm<class player,int>::mem_fn_action<struct player::pause,&private: void __cdecl player::pause_playback(struct player::pause const &)>::value" (?value@?$mem_fn_action@Upause@player@@$1?pause_playback@2@AEAAXAEBU12@@z@?$fsm@Vplayer@@h@fsmlite@@2Utype@123@A)
1>x64\Release\test.exe : fatal error LNK1120: 7 unresolved externals
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

Require C++17

There are basically two separate interfaces for specifying transitions, row which works for C++17 only, and mem_fn_row which works since C++11. With C++17 support widely available now (except maybe for embedded), it's maybe time to drop mem_fn_row and C++11 support altogether.

See also #21 about dropping basic_row along the way.

Explicitly specify locking strategy for fsm

A third template parameter should be added to class fsm, which specifies a BasicLockable.
This would be locked at the start of process_event(), so recursive invocations can be detected.
The default class should throw a logic_error in this case, except if exceptions are disabled.

Suggestion: target_state()

Hi,

Maybe I am missing something fundamental here.
Besides current_state(), wouldn't it be useful to have target_state()?

An example:
I am creating a SIP packet analyzer. At the moment I just want to save the timestamp of the incoming packet. See the transition_table below.
As seen in the table, the same Action, SaveTimestamp(), could be used for all packets if target_state() could be accessed from within SaveTimestamp().

Best Regards,
Johan

using transition_table = table<
//       Start         Event           Target          Action                  Guard (optional)
//  ----+-------------+---------------+---------------+-----------------------+-----------------+-
    row< BEGIN,        EvInvite,       INVITE,         &m::SaveTimestamp                         >, // Save INVITE ts

    row< INVITE,       EvInvite,       INVITE,         &m::SaveTimestamp                         >, // Save INVITE ts
    row< INVITE,       EvAuth407,      INVITE,         &m::SaveTimestamp                         >, // Save INVITE ts
    row< INVITE,       EvTrying100,    TRYING,         &m::SaveTimestamp                         >, // Save TRYING ts
    row< INVITE,       EvRinging180,   RINGING,        &m::SaveTimestamp                         >, // Save RINGING ts
    row< INVITE,       EvOk200,        INVITE_OK,      &m::SaveTimestamp                         >, // Save INVITE_OK ts
    row< INVITE,       EvFailureXXX,   INVITE_FAILURE, &m::SaveTimestamp                         >, // Save INVITE_FAILURE ts

    row< TRYING,       EvOk200,        INVITE_OK,      &m::SaveTimestamp                         >, // Save INVITE_OK ts
    row< TRYING,       EvRinging180,   RINGING,        &m::SaveTimestamp                         >, // Save RINGING ts
    row< TRYING,       EvCancel,       CANCEL,         &m::SaveTimestamp                         >, // Save CANCEL ts
    row< TRYING,       EvUnsuccessful, UNSUCCESSFUL,   &m::SaveTimestamp                         >, // Save INVITE_FAILURE ts

    row< RINGING,      EvOk200,        INVITE_OK,      &m::SaveTimestamp                         >, // Save INVITE_OK ts
    row< RINGING,      EvCancel,       CANCEL,         &m::SaveTimestamp                         >, // Save CANCEL ts
    row< RINGING,      EvUnsuccessful, UNSUCCESSFUL,   &m::DoNothing                             >,

    row< INVITE_OK,    EvBye,          BYE,            &m::SaveTimestamp                         >, // Save BYE ts

    row< BYE,          EvOk200,        BYE_OK,         &m::SaveTimestamp                         >, // Save BYE_OK ts

    row< CANCEL,       EvOk200,        CANCEL_OK,      &m::SaveTimestamp                         >, // Save CANCEL_OK ts

    row< BYE_OK,       EvAny,          END,            &m::DoNothing                             >,
    row< CANCEL_OK,    EvAny,          END,            &m::DoNothing                             >,
    row< UNSUCCESSFUL, EvAny,          END,            &m::DoNothing                             >
//  ----+-------------+---------------+---------------+-----------------------+-----------------+-
    >;

Add docs to dist

After unpacking the distribution archives, the docs directory only contains the Makefiles.

Improve documentation

  • Add motivational section to README
  • Add design guidelines (self-contained, performance, embedded use)
  • Add supported/tested compilers and versions
  • Add build/installation instructions (copy fsm.hpp, link to latest dist, configure, make)
  • Add guards examples (player with autoplay/autoeject)
  • Add typed_row examples (plain functions, lambdas, std::function, static members...)
  • Add links/badges to Travis and coveralls.io

How to use std::shared_ptr as a trigger event in the state transition table

In the examples given in fsmlite/tests/, replacing the event data type with an event-type std::shared_ptr gives the following error

fsm.h:140:106: error: call of overloaded ‘forward<const std::shared_ptr<event>&>(const std::shared_ptr<event>&)’ is ambiguous return binary_fn_helper<F, Arg1, Arg2>::invoke(forward<F>(f), forward<Arg1>(a), forward<Arg2>(b));

Doc or example of mapping a simple type to event type

Hi,

Is there a way to "map" an event defined as an empty struct to a simple type such as int?
I cannot find any example or anything in the docs which describes what I want to achieve, so I explain with a couple of examples:

Using a switch works, but makes the code redundant, as any added event to the player class (declaration and transition_table antry) would also require an switch state:

enum event_index {OPEN_CLOSE, CD_DETECTED, PLAY, PAUSE, STOP};

// Straight-forward, but a bit "clumsy"
void test_player_switch(enum event_index e)
{
  player p;
  switch (e)
  {
  case OPEN_CLOSE:
    p.process_event(player::open_close());
    break;
  case CD_DETECTED:
    p.process_event(player::open_close());
    break;
  case PLAY:
    p.process_event(player::cd_detected{"louie, louie"});
    break;
  case PAUSE:
    p.process_event(player::play());
    break;
  case STOP:
    p.process_event(player::pause());
    break;
  default:
    break
  }
}

Instead of using a switch, I would like "map" an integer to en event, like this:
(note this is pseudo-code, and I am not sure it is even possible to do it that way):

// Map Event Index to their corresponding Event
const std::unordered_map<enum event_index, ??? EventType<T> ???> EventMap = {
  {OPEN_CLOSE  , player::open_close()},
  {CD_DETECTED , player::cd_detected()},
  {PLAY        , player::play()},
  {PAUSE       , player::pause()},
  {STOP        , player::stop()},
};

void test_player_map(enum event_index e)
{
  player p;
  auto ??? event ??? = EventMap.find(e);
  p.process_event(event); // How to get type-of-event ???
}

Or, if there is an undocumented way of doing this in another way, I would appreciate knowing about that.

BR,
Johan

Exit action

Hello,

Is there a way to detect that a state is exited?

Thanks

Require C++11 support

All supported/tested compilers should now correctly set __cplusplus to 201103L or higher. fsm.h should #error out otherwise.

Add -DNDEBUG and -fno-exceptions Travis builds

Looks like passing CXXFLAGS=-fno-exceptions breaks configure's check for C++11 support (and rightly so).
Since reverting to <cassert> is not an option on freestanding implementations, this wll have to be checked manually.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.