[MSM] Is there any interest in C++14 Boost.MSM-eUML like library which compiles up to 60x quicker whilst being a slightly faster too?

Dear Boosters, I have recently released 1.0.0 version of experimental C++14 Boost.MSM-lite. Your scalable C++14 header only eUML-like meta state machine library with no dependencies, which outperform Boost.MSM - eUML in: - faster compilation times - up to 60x times faster! - smaller executable size - up to 15x smaller - slightly better performance - smaller memory usage - short error messages Check it out yourself online! http://boost-experimental.github.io/msm-lite/examples/index.html#hello-world Performance Results: http://boost-experimental.github.io/msm-lite/overview/index.html#performance Source code: https://github.com/boost-experimental/msm-lite Documentation: http://boost-experimental.github.io/msm-lite Any feedback is more than welcome! Cheers, Kris

On 28 January 2016 at 17:19, Krzysztof Jusiak <krzysztof@jusiak.net> wrote:
I would be interest just because of these 2 points. I see a lot of opportunities to use such library but most of the time I can't afford to use Boost.MSM because of the implied compile-time cost.

Thanks for your feedback and yea, Boost.MSM is great; eUML is even better, but it was written some time ago, before C++11. It still uses Boost.MPL and Boost.Fusion which are pretty slow to compile in comparison to what can be achieved nowadays. On top of that, right now we have a lambda expressions which were emulated in eUML using Boost.Phoenix. All in all, C++11/14 give as a lot of opportunities to improve the situation and Boost.MSM-lite is just a small example how much more user-friendly C++ might be as well as how much faster the code might be compiled without loosing any performance. On Thu, Jan 28, 2016 at 5:44 PM, Klaim - Joël Lamotte <mjklaim@gmail.com> wrote:

On Thursday, January 28, 2016 at 10:20:19 AM UTC-6, Krzysztof Jusiak wrote:
The library looks very nice. A couple of things: First, it's not just C++14 only as it relies on compiler intristics which just happen to work on the three major compilers you support. It would be nice if you just relied on the standard library for these things. Most likely, users are going to use the standard `type_traits` header anyway so this will cause a lot of duplication. Futhermore, the implementation of `make_index_sequence` can be much slower performance than the standard library since it doesn't take advantage of the compiler intristics that are available. Secondly, the documentation for the concepts seems confusing. In the documenatation it show the concept as this: template <class TResult, class T> concept bool callable() { return requires(T object) { { object(...) } -> TResult; } } I assume its written like this for notational purposes. However, the example shows it being used like this: auto guard = [] { return true; }; auto action = [] { }; static_assert(callable<bool, decltype(guard)>); static_assert(callable<void, decltype(action)>); Which is incorrect as in the code its an alias to an `integral_constant`, however, the `integral_constant` doesn't look like its fully implemented, so this fails as well: auto guard = [] { return true; }; auto action = [] { }; static_assert(callable<bool, decltype(guard)>()); static_assert(callable<void, decltype(action)>()); Of course, using `std::integral_constant` would make the above work. Thirdly, Boost.Hana started out in a similiar fashion, being single header and not relying on the standard library. Of course, as it grew, it needed to use multiple headers and the standard library headers as well. Finally, I like the documentation setup. I use mkdocs as well for my documenation, and I created a boost theme to try and match the boost documentation. You can see it here: https://github.com/pfultz2/boost-theme Of course, its still a WIP. I, also, like the code snippets with option to compile and run the code online in the documentation. I think I am going to try to setup something similiar for my library as well. Paul

Hi Paul, Please find my answers below.
The library looks very nice. A couple of things
Cheers
Well, the library is pure C++14, however, as you mentioned, it uses an compiler extension to create a compile time string. Having said that, it's totally optional and it doesn't have to be used at all. What I mean by that is that you can write: using namespace msm; auto state = "idle"_s; //or auto state = msm::state<class idle>{}; //or msm::state<class idle> idle; All of them will give the same result, however the first option (non-standard one) just happen to be more convenient.
It's true, however, available standard libraries are not always working the same way. Especially MSVC standard library was giving me a lot of hard times. For example. is_constructible was working differently, make_index_sequence was recursive etc. and therefore I put the implementation in the header as it was easier to maintain it. Anyway, most of the times it uses compiler support either way like __is_base_of, etc., so it's not a big deal. All in all its just 90 lines of code. I'm not saying I won't use type_traits for it, but I don't see much gain from doing it right now as I would have to put a lot of ifdefs there either way :/ Yea, I know about make_index_sequence improvements in clang/gcc, but it's still not available in the newest release of those compilers as far as I remember. I would be really happy to change the implementation into __make_index_sequence, for instance. The other point is the fact that not being depended on STL allows embedded/console games/etc. developers to use the library as they, in a lot of cases, don't have access to STL. To sum up, I agree with your points and maybe the library will use type_traits header at some point, however I don't see a lot of benefits of changing it right now.
Firstly, I'm not really using concepts-lite in the library, just a some silly emulation, so yea, its just for notation purposes. Secondly, fair point, documentation is wrong there, as above example will not compile. Thanks for pointing that out. Anyway, library is no about concepts, they are not exposed to be used outside of the library. They help getting nicer error messages and they are meant to stay this way. But I get your point and I will change the documentation.
Yea, I remeber, however this library is meant to stay 'lite'. If it comes to multiple headers. I find it very useful to have just one header in the end. I have been using this approach in my experimental boost.di library too, however, there I generate the header from all hpp files. You can check it here: https://github.com/boost-experimental/di
Cheers, and thanks for the link, looks promising. I will defo take a look. Yea, these days we can liven up documentation quite a lot with js. Feel free to use solution provided, we can also merge your boost-theme with my facilities to provide modern way of boost doc with mkdocs? Thank you very much for your feedback! Cheers, Kris -- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

Hi Kris,
I find it quite nice. The idea is very interesting. Minor nitpicks, I find weird mixing strings and <> syntax and the trick about inital states, but it's really a matter of taste. It would also be good to avoid having to declare events separately. It would be interesting to see how it fares against the eUML successor, eUML2 written using metaparse. I do plan to rewrite parts of MSM and have a second look at eUML later this year, so if you don't mind, I might use some of your ideas. I'm wondering where you want to go from there. Rewriting all of MSM is quite some work. But keeping the library lite is not really an option if you want more than a toy library because most potential users will want more features. Actually, the whole idea of dividing MSM in back and front ends was exactly to allow front-ends like yours as extensions. Would you be interested in doing this instead? If changes in back-end are necessary, why not? It has to be done anyway, as most of the library was written 7-8 years ago. It might mean that there will be a pre and post C++14 versions, but I don't think it matters. Cheers, Christophe

Hi Christophe, Thank you very much for your feedback and time. I appreciate it a lot. Yea, I like having everything visible on the transition table and therefore I put initial states as well entry/exit actions there. I know you have a different view on that, however, I find it easier to follow this way. Declare events on the fly its easy to do, however, I don't think it will bring much value as events can be accessed outside the transition table as well as they, most likely, will hold some data. Therefore, I'm not sure about it. Might be useful to have both options tho. I would love to compare MSM-lite/MSM-eUML to eUML2, however I haven't seen it yet besides some code in the emails. Can you share a link to the eUML2 version, please? I will defo add benchmarks for it. I don't see any problem with that as MSM-lite is open source. I also offer my help in designing and/or coding. Well, I would like to keep the core of the library as small as possible as in my experience a lot of users are actually not using as many features. Having said that, I have no problems adding new features via policies/extensions. Moreover, MSM-lite is already used in some of the top growing mobile games, but yea, I do agree that some users would like to see more features. Anyway, are there any specific features you are talking about which are so essential. I know that defer/history might be useful, but I don't see much more features in MSM, besides explicit/fork states? I totally admire MSM design. I really liked the separation between back and front end. I have even implemented some extensions myself: * dependency injection support (https://github.com/krzysztof-jusiak/msm) * testing support (https://github.com/krzysztof-jusiak/msm/tree/master) And I also followed this approach in MSM-lite; it's not stated explicitly but it might be found there. Although it would be interesting to incorporate with MSM I'm afraid it's not possible with the current MSM as MSM-lite has a different approach. Especially back-end is achieved in a different way which is not compatible with MSM. While MSM-lite front-end still produces transitions-like types it holds objects and relay on dependencies to be injected. All in all, MSM-lite it's quite different than the current version of MSM. It maybe would be possible with a new version of MSM, however there is no such a thing yet, is it? Thank you again for your feedback! Cheers, Kris On Sun, Jan 31, 2016 at 9:18 PM, Christophe Henry-2 [via Boost] < ml-node+s2283326n4683114h53@n4.nabble.com> wrote:
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

Le 01/02/2016 11:57, Kris a écrit : pretend to make it a sub-library of Boost.MSM. If I'm right, I suggest you to rename the namespace to msm_lite or whatever you find more appropriated. BTW, with the figures you gave I believe that there would be an interest in your library.
Well these are already quite a few features. I have not see local transitions (different from internal transitions). Please could you point me if you support choice points? While choice points are unavoidable in graphical UML, I find it not very useful while writing MSM in C++ as I prefer to do it using if or switch. However having a transition table that can have only one next-state by transition disable this possibility. I use to have a transition table with a transition that has an action_nextstate that do the action and returns the nextstate of the transition. |"s2"_s + event<e2> [ guard ] / action_nextstate This avoids the storage of local variable on the MSM data context. | Have you considered this possibility? Best, Vicente

Le 02/02/2016 19:19, Vicente J. Botet Escriba a écrit :
I see that MSM eUML defines the transitions like target == source + event [guard] / action but MSM-lite reverse the source and target src_state == dst_state + event[ guard ] / action This is confusing. Why have you chosen this syntax? Vicente

On 2 February 2016 at 19:41, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
Same question here. I misread the examples at first because the meaning is reversed. It feels unnatural that the state you are going to is part of the expression stating the conditions to get there. The MSM syntax is clearer to me at least.

On Tue, Feb 2, 2016 at 7:09 PM, Klaim - Joël Lamotte <mjklaim@gmail.com> wrote:
I see your point. It seems like I will have to change the default behaviour then as it's clearer for most devs. Guess, I'm the ackward one here. Please, check the euML emulation example -> http://boost-experimental.github.io/msm-lite/examples/index.html#euml-emulat... as DSL behaviour might be changed if it comes to states order by defining BOOST_MSM_DSL_DST_STATE_FIRST. If it comes to the transition table DSL. I was concidering a lot of options. For example MSM3(eUML2) is using src + event [guard] / action -> dst which looks great, however, having a dst state at the end is not really practical, especially after a lot of noice introduced by guard and actions (for example in place lambda expressions). Right now, I'm thinking of introducing DSL which would look like that. make_transition_table( "idle* -> state1"_t + event [ guard ] / action , "state1 -> X"_t [ guard ] / action ); Nevertheless, I'm not sure whether such approach would be seen positively because following MSM approach it should be more like that. make_transition_table( "state1 <- idle*"_t + event [ guard ] / action , "X <- state1"_t [ guard ] / action ); which looks confusing for me. Any thought on this? Thanks for your feedback, Cheers, Kris _______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Tue, Feb 2, 2016 at 9:55 PM, Klaim - Joël Lamotte [via Boost] < ml-node+s2283326n4683151h0@n4.nabble.com> wrote:
It's a compile time string parsing so there are no issues with characters here, just the design. So your suggestion would be: // *=initial "state1 <= idle*" or "idle* => state1" is that correct? '->' was chosen, simply because it might be found in the UML2 specification, but there are no limitations here. Whatever works the best. Thanks for the suggestion, Kris
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

On February 2, 2016 4:29:35 PM EST, Krzysztof Jusiak <krzysztof@jusiak.net> wrote:
Agreed
We're accustomed to seeing the target on the left of an assignment, so what about "state1 = idle*"? I get your interest in seeing the current state on the left, because the transition is from the current state to the new one. If there can be multiple transitions from one state, the only readable form puts the current state first, IMO. Using "if_" or "when" to separate the transition from the condition might help: (from -> to).when(event[guard]/condition) You could omit "when" with the parens: from -> to (event[guard]/condition) ___ Rob (Sent from my portable computation engine)

On Wed, Feb 3, 2016 at 9:12 AM, Rob Stewart [via Boost] < ml-node+s2283326n4683164h3@n4.nabble.com> wrote:
Thanks for your valuable input. Yea, it's all about the parens in the end. Right now I do understand that my assumptions were wrong as I was putting the parens (in my mind) the following way. (s1 == s2) + event [ guard ] / action (although they weren't really there). Anyway, thanks to the input provided I realized it wasn't the best idea and therefore I have changed the DSL to. // Prefix Notation "state"_s <= *"idle"_s + event [ guard ] / action // Postfix Notation *"idle"_s + event [ guard ] / action = "state"_s // '=>' would be better, however C++ only allows for '>=' which is not ideal here Moreover, I have added a few UML-like notations. For initial state(*), terminate state(X), history state(H). X <= "idle"_s(H) + event [ guard ] / action or "idle"_s(H) + event [ guard ] / action = X Please take a look at the new versions of examples: http://boost-experimental.github.io/msm-lite/examples/index.html#hello-world http://boost-experimental.github.io/msm-lite/examples/index.html#euml-emulat... http://boost-experimental.github.io/msm-lite/examples/index.html#sdl2-integr... and please let me know what do you think. Cheers, Kris
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

On Tue, Feb 2, 2016 at 6:41 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
Well, I read it from left to right and therefore I found it more natural for me to do it this way. However, msm-lite supports both syntaxes. You change it to dst_state == src_state by setting up BOOST_MSM_DSL_DST_STATE_FIRST. Currently the default is src == dst but it might be changed to the, less confusing, one if that what devs are more comfortable with. You can find an example here -> http://boost-experimental.github.io/msm-lite/examples/index.html#euml-emulat... Cheers for the question, Kris

On Tue, Feb 2, 2016 at 6:19 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
Fair point, thanks for pointing it out. It's a valid concern. I have nothing against changing the namespace/name as 'msm-lite' is just a working title either way. Not sure what the best name should be tho?
Yea interna(local) transitions are supported. Example here -> http://boost-experimental.github.io/msm-lite/examples/index.html#transitions
Please could you point me if you support choice points? While choice points are unavoidable in graphical UML, I find it not very
Interesting idea, can you elaborate please as I'm not sure whether I follow the idea with the action_nextstate? If it comes to the choice points, I guess the easier way is just to have multiple transitions from the same state? make_transition_table( s1 -> s2 + e2 [some_guard1 && some_guard2] / action1 , s1 -> s3 + e2 [other_guard] / action2 , s1 + e2 / action3 ); would be the same as if (e2) { if (some_guard1 && some_guard2) { action1; change_state_to(s2); } else if(other_guard) { action2; change_state_to(s3); } else { action3; } }
Best, Vicente
Thank you for you feedback. Cheers, Kris

Le 02/02/2016 22:12, Krzysztof Jusiak a écrit :
Internal and local transitions are not the same. How do you make syntactically the difference. I've not see and reference to local transitions.
This is almost the idea. But the use case is the followings, sorry I will use the src + evt / act = dst notation make_transition_table( s0 + e / action0 -> cp cp [some_guard1] / action1 -> s1 cp [else] / action2 -> s2 ); With action-next-state transition could be s0 + e / action_nextstate where action_nextstate is auto action_nextstate = [](auto const& evt) { action0; if (some_guard1) { action1; next_state(s1); // You could also return a state if there is a type that can store any state of the state machine. } else { action2; next_state(s2); } } Note that these action-nextstate could define some local variables in action0 that can be used in some_guard1 and in action1 and action2 . The uml transition schema forces to store these local variable on the state machine context (or a state context if supported), which is less than optimal. This is needed because there is no way to share variables between the action0, some_guard1 and in action1 and action2. In addition action1 and action2 have no access to the event e, as only the action0 has it as parameter. Do you think that this kind of transitions goes against the UML semantics? Best, Vicente

On Wed, Feb 3, 2016 at 6:48 PM, Vicente Botet [via Boost] < ml-node+s2283326n4683171h20@n4.nabble.com> wrote: preferable?
Actually msm-lite, since today, supports almost this syntax. There are pre/post fix notations available. src_state + event [guard] / action = dst_state or dst_state <= src_state + event [guard] / action
Hmm, interesting idea. However, it seems to be against the transition table concept a bit as guards are hidden in the actions instead. I do understand the concept tho, it's more like custom_reaction in the Boost.Statechart. I would still model it using transition table because it makes it more visible/clear to understand what is going on. With action_nexstate approach you have to check all actions to verify whether they are not changing the state which might be tricky to do. Unless, you have a solution for that? BTW. msm-lite has a bit different approach than MSM to share the data because guards/actions may share data as objects are injected into them when they are required. For example, auto action = [] {}; // action, not data, no event auto action_with_some_data = [] (int i, data& d) {} auto action_with_some_data_and_event = [] (int i, const auto & event, data& d) {} // order doesn't matter auto guard_with_data = [] (data& d, const auto& event) { return true; } make_transition_table( *s1 + e1 [ guard_with_data ] / action = s2 , s2 + e2 / (action_with_some_data, action_with_some_data_and_event) ); data d; sm fsm{d, 42}; // order doesn't matter, this data will be injected into guards/actions It's a bit tedious to pass all required objects into state machine constructor and therefore depenendy injection framework may become handy here, for example experimental boost.di -> https://github.com/boost-experimental/di More examples: http://boost-experimental.github.io/msm-lite/examples/index.html#actions-gua... http://boost-experimental.github.io/msm-lite/examples/index.html#dependency-... Thanks for your feedback, Kris
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

Le 03/02/2016 21:48, Kris a écrit :
A local transition (https://en.wikipedia.org/wiki/UML_state_machine#Local_versus_external_transi...) form an outer state to itself exists from the most inner state but don't exit from the outer state. If in addition the local transition goes to a history state the inner state in re-entered. An internal transition don't exits at all. I have no preference for the notation, but why not replace the + sign with a ^ src ^ event [guard] / action = src src ^ event [guard] / action = src(H)
You could also restrict the possible next states in the table. s0 + e / action_nextstate(s1, s2)
Hmm, this will not reduce the size of the shared data. What I want is to be able to use local data shared between transition segments. This local could be encoded in the transition table, but I'm not sure it is worth the effort.
I don't understand how this helps in this context. Vicente

On Wed, Feb 3, 2016 at 9:59 PM, Vicente Botet [via Boost] < ml-node+s2283326n4683180h99@n4.nabble.com> wrote:
I have seen it, thanks. Yea, local transitions are not supported currently by msm-lite. Are they supported by MSM? I haven't seen support for it there too. Anyway, they are not hard to implement. Do you have any important use case for them?
Well, I have just followed MSM approach and '+' was used there and I was fine with it. Is there any reason why '+' is wrong and it should be replaced with '^' instead?
I implemented action_nextstate, so please take a look. It might be checked online HERE -> http://melpon.org/wandbox/permlink/IMZUWJpiHDP62WEO It's really easy to implement it, the basic idea below. auto action_nextstate = [](auto... s) { std::tuple<decltype(s)...> states{s...}; return [=](msm::sm<auto>& sm, auto const& evt, bool external_value) { action0(); if (some_guard1(external_value)) { action1(); sm.change_state(std::get<0>(states)); } else { action2(evt); sm.change_state(std::get<1>(states)); } }; }; I had to add `change_state` to the msm-lite as it doesn't support changing states unless in testing mode. template <class... TStates> void change_state(const detail::state<TStates> &...) noexcept { decltype(current_state_) new_states = {aux::get_id<states_ids_t, 0, TStates>()...}; *current_state_ = *new_states; } I hope that helps.I do understand your concept, however I'm not sure whether such approach is the best, but, at least, it's easy to implement. I guess if you can prove that this is a common case and that performance might be gained using it then it's worth to consider such practice in general.
Me neither, so again, please take a look into the example and experiment with it (http://melpon.org/wandbox/permlink/IMZUWJpiHDP62WEO). It's defo worth trying it out.
Probably is not as your idea is based on local and not external data. I misunderstood your concept at first.
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

Le 04/02/2016 11:45, Kris a écrit :
std::get<0>(states) doesn't scale. Passing all the states each time to the action_nextstate will not be the more efficient way. The states tuple are part of the lambda so the SM will store the tuple of states once for each transition. Even if this is not instantiated for each instance of the SM, this seems unnecessary. I would suggest to have a single SM context that stores anything needed and let each transition have access to it.
For performances, there is already the space performances, there is no need to store local variable on the state machine context, and this can grow quickly. For runtime, you avoid calling to process event on each transition segment, the code of a transition been in a single function the compiler can inline, optimize, ... Note that I'm not saying that MSM-lite should not support eUML2 transitions. Vicente

On Fri, Feb 5, 2016 at 6:36 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
Yea, I do get it know. Thanks for explanations.
Fair do's, it ain't perfect. However, it doesn't have to be done this way. I mean, states don't even have to be passed into action_nextState at all, which makes the implemention clener and easier to follow. So, the new version would look like that. auto action_nextstate = [](msm::sm<auto>& sm, auto const& evt, bool external_value) { action0(); if (some_guard1(external_value)) { action1(); fsm(sm).set_current_states("s1"_s); } else { action2(evt); fsm(sm).set_current_states("s2"_s); } }; and transition table return make_transition_table( *"idle"_s + "event"_t / action_nextstate , "s1"_s + "event"_t / [] { std::cout << "in s1" << std::endl; } , "s2"_s + "event"_t / [] { std::cout << "in s2" << std::endl; } ); BTW. This version is achieved without any changes to the current version of msm-lite because setting states is done via testing extension. Working example here -> http://melpon.org/wandbox/permlink/2SJCL6WAK0n9q7bs
I would suggest to have a single SM context that stores anything needed and let each transition have access to it.
I don't like 'God objects'. IMHO, it's way better to inject whatever is required by guards/actions. It's easier to test and maintain it this way and there is no need for a SM context in the action_nextState example.
Okay, I see your points. I guess usage of action_nextState might be justified and might be easily implemented in msm-lite too.

On February 3, 2016 3:48:14 PM EST, Kris <krzysztof@jusiak.net> wrote: [snip]
Why = for the one and <= for the other? Can't you use = for both? [snip discussion of action-nextstate] [snip quoting of irrelevant content] ___ Rob (Sent from my portable computation engine)

On Thu, Feb 4, 2016 at 10:41 AM, Rob Stewart [via Boost] < ml-node+s2283326n4683202h81@n4.nabble.com> wrote:
Fair point, its not really consistent, is it? The initial idea was to have <= in the prefix notation and => in the postfix one. However the latter had to become >= which was quite awkward. I guess it can be changed into. dst = src + event [guard] / action and src + event[guard] / action = dst I'm just not sure whether this approach is not confusing as we have the same syntax for both notations, but sometimes src and sometimes dst is used on the left side? Do you think, if it possible, it would be better to use = for both notations?
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

On February 4, 2016 5:56:29 AM EST, Kris <krzysztof@jusiak.net> wrote:
It is rather odd to see so much on the left side of the assignment. We're accustomed to the shift operators being used directionally by IOStreams, so what about the following? dst << src + event [guard] / action src + event[guard] / action >> dst [snip quoted snips, signature block, and more] Please don't quote irrelevant content on this list. ___ Rob (Sent from my portable computation engine)

On Fri, Feb 5, 2016 at 10:15 PM, Rob Stewart [via Boost] < ml-node+s2283326n4683264h3@n4.nabble.com> wrote:
Yea, shift operators are symmetrical, which is awesome. I don't find them odd and I have even tried them at some point in the past. However, I have encountered one ackward thing with the usage of them with data events. src + event<some_event_data> >> dst // '> >>' is quite unfortunate combination here All in all, I'm not sure which syntax would be the best in the end. On the one hand, '<-' and '->' would be perfect, but can't be done with operators. On the other hand, '=', '=' is short and sweat, but might be a bit confusing. Finally, '<<', '>>' is symetric, but sometimes a bit ackward. Any suggestions, which one would be the best? Right now, I'm thinking '=' is the best choice, but maybe it would be best to give user a final decision? Not sure.
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

On February 6, 2016 3:59:30 PM EST, Kris <krzysztof@jusiak.net> wrote:
How ironic. We got a new rule in the language to allow for multiple >'s to be considered template argument list delimiters, but it won't help here. Such are the problems of EDSLs. So far, we have these options: 1) d = s + e[g]/a s + e[g]/a = d 2) d << s + e[g]/a s + e[g]/a >> d The choices are limited. Another pair that comes to mind is <= and ->. 3) d <= s + e[g]/a s + e[g]/a -> d Those are directional and the = vs. - asymmetry might be a good thing. The last pair I can suggest is the following: 4) d = s + e[g]/a s + e[g]/a -> d 1) is strange given that we expect assignment to be to the expression on the LHS. 2) has the template argument list and shift operator parsing issue. I always put a space on either side of binary operators, so that wouldn't actually affect me. 3) is only troubling due to the asymmetry in the number of lines between = and -. 4) involves normal assignment semantics in the one case and evokes the new return type function syntax in the other. The imbalance between the syntaxes for 3) and 4) may not be a big deal since users will adopt one or the other. An issue arises when reading our maintaining the code of someone using the opposite syntax, of course. My favorite of these is 2). ___ Rob (Sent from my portable computation engine)

On Sun, Feb 7, 2016 at 5:01 PM, Rob Stewart [via Boost] < ml-node+s2283326n4683304h43@n4.nabble.com> wrote:
Heheh, true that.
That's is a winner for me! However, I don't think it is possible to implement, is it? `->` is not really user friendly for writing DSLs. Or maybe, like that, but that is even harder to achieve. d <- s + e[g]/a s + e[g]/a -> d
1) is strange given that we expect assignment to be to the expression on the LHS.
Yea, its a fair point. '<<', '<-' seems to be better for the dst - src option.
I like this option, but I find it extremly ackward to have following notation - src + exception<std::runtime_error> >> dst
3) is only troubling due to the asymmetry in the number of lines between = and -.
Yea, it's defo a decent option. I would gladly choose this option, but I don't think '->' is easy to achieve.
Thank you for the analysis. It's extremely useful. IMHO s + e[g]/a ->d is the winner for the postfix notation as it follows UML notation and has a direction. However, I don't think is achievable. Well, at least I don't have any idea how to do it :( If it comes to the prefix notation, I guess, '<=', "<<" are the options to choose from. I will try to work on '->', maybe it's possible, it is C++ in the end.
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

On Mon, Feb 1, 2016 at 11:21 AM, Krzysztof Jusiak <krzysztof@jusiak.net> wrote:
I added a simple benchmark using Boost.MSM3-eUML2 to the performance tests. Results can be found here -> http://boost-experimental.github.io/msm-lite/overview/index.html#performance It seems that Boost.MSM3-eUML2 (not sure what is the proper name?) compiles 2.5 times slower than the eUML, but maybe there are some flags/options to speed it up? Moreover, I'm not sure how to disable the slowing down options such as deffered events etc.? I would assume it should be as fast as eUML as it using the same back-end? I have also noticed that the parser is not really strict as you can write not valid code which will compiles. For example. EUML2_ROW("Stopped + stop / stopped_again - Stopped"); // - instead of ->
I don't see any problem with that as MSM-lite is open source. I also offer
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

Compile-time is proportional to string length, reducing it would help. So would reducing BOOST_MPL_LIMIT_STRING_SIZE. As they are empty, you can also remove you action definitions.

On Wed, Feb 3, 2016 at 8:51 PM, Christophe Henry-2 [via Boost] < ml-node+s2283326n4683176h75@n4.nabble.com> wrote:
Cheers, I have been experimenting with BOOST_MPL_LIMIT_STRING_SIZE already. However, it would be a bit bias to remove actions/guards in order to speed it up as it would not reflect the real life example. I know they are not doing much in the example, but they still have to be called or removed by the compiler depending on the approach. For example msm-lite is affected by empty guards/actions if it comes to memory size as it stores them in order to call lambda expressions.
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

On Wed, Feb 3, 2016 at 9:51 PM, Krzysztof Jusiak <krzysztof@jusiak.net> wrote:
I added composite and complex tests using eUML2 front end -> http://boost-experimental.github.io/msm-lite/overview/index.html#performance Actually, I haven't noticed a huge trade-offs whilst limiting BOOST_MPL_LIMIT_STRING_SIZE length - max around 20%. Anyway, interesting finding is the fact that eUML2, although compiling around 2.5x time slower than eUML, compiles faster on the complex test using Clang! On GCC is still 2x slower then eUML but Clang has done some amazing job here. Ah, I have also figured out why eUML2 was slower than eUML in my previous tests. I had to disable exceptions, message queue add add empty no_transition handler. Hope you find the results interesting too.
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

Moreover, I'm not sure how to disable the slowing down options such as deffered events etc.?
I would be surprised if deferred events costed much compile time.

On Wed, Feb 3, 2016 at 8:54 PM, Christophe Henry-2 [via Boost] < ml-node+s2283326n4683177h6@n4.nabble.com> wrote: than eUML (17ms vs 100ms) and therefore I assumed that not the same back-end is used, in a sens, that is less optimized, because it has some features enabled by default. _______________________________________________
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

On Wed, Feb 3, 2016 at 10:17 PM, Vicente Botet [via Boost] < ml-node+s2283326n4683181h30@n4.nabble.com> wrote:
Totally agree and this approach is taken by msm-lite as well as MSM. However, you can see that eUML2 (successor of eUML) is slower than eUML in the sample test and therefore my confusion if it didn't have those features turned on by default as the same back-end is used for both. http://boost-experimental.github.io/msm-lite/overview/index.html#performance MSM requires to turn defferal events/queue etc. by adding a typedef to the state machine. All in all, it is just an assumption as I don't know the implementation details of eUML2, maybe it's just slower?
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

Le 28/01/2016 17:19, Krzysztof Jusiak a écrit :
Hi, I have not found anything about how exceptions are managed nor about inheritance of state machines. Is there something related to these two subjects on your library? Best, Vicente P.S. Sorry, I don't know how MSM or statecharts covers these subjects.

On Fri, Feb 5, 2016 at 5:55 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
It's a valid point. Documentation was lacking much info about exceptions safety. I've just added it here -> http://boost-experimental.github.io/msm-lite/overview/index.html#exception-s... Currently, there is no much policy about exception handling though. However, if guard/action throws state machine will be in a defined state. Any problems you have encountered with the exceptions? Suggestions are more than welcome as I'm not sure what would be the best solution here. Can you elaborate what you mean by `inheritance of state machines`, please? Is the question related to composite/sub state machines or just whether a state machine might be inherited? Best,
Vicente
P.S. Sorry, I don't know how MSM or statecharts covers these subjects.
MSM has a policy called `no_exception` which basically disable catching exceptions. Otherwise they are caught within the process_event. Don't know how statechart is handling it.

Le 05/02/2016 22:30, Krzysztof Jusiak a écrit :
Thanks for the pointer. With the UML2 transition model is harder to manage with exceptions, as the next state is on the transition table and the the engine must be concerned. I don't understand clearly the different behavior when exceptions escapes a guard or an action. Changing to the next state could call to the entry of the state. In any case what you proposes don't allow to handle the exception at a higher level. My preference is to go to an associated catch exception 'pseudo state' and request the process of an associated exception event. I believe that we could add an associated catch pseudo-state src_st + event [guard] / action = dst_st|catch_st When there is an exception on this transition the catch_st is entered and an exception event is handled. catch pseudo states can also be associated to an state so that it acts as the default catch state for all the transitions from this state. We can see also an upper state as a exception-catcher. src_st + event [guard] / action = dst_st If an exception is throw on guard or action, the exception event is handled on the nesting state of src_st. The interest of having local transition segments is that the exit of the current state is not called until there is an external transition segment. src_st ^ event [guard] / action = dst_st If an exception is throw on guard or action, the exception event is handled on src_st. An exception throw on the dst_st entry should be handled by its nesting state. Associating a single TOP level state to a SM allows to associate a catch state to the SM. Of course transitions that throw from the catch state associated to the top level should be transported to the caller or the sender (depending on whether the mechanism is synchronous or asynchronous). You can find some descriptions of UML and exception handling e.g. at [1] for activities or [2]. Look for UML exception handling on your preferred search engine. Note that when we use the action_nextstate model, the action_next can catch the exception and do whatever is needed and possible go to a specific state after handling the error. I don't know if all this is compatible with UML2 model, I believe UML2 doesn't model exceptions (C++ exceptions) on guards/actions. There is the concept of an exception signal, but I'm not sure this respond to what I'm asking for.
1* adding new transitions 2* refining a state by adding sub-states and transitions 3* refining the next state of a transition with a sub-state of the derived next state (or an entry point, but I believe that MSM-lite has no entry/exit points associated to an state, isn't it?) 4* refining the guard of a transition 5* refining the action of a transition I'm for at least the 3 first extension mechanisms. The last two can be emulated with virtual functions. Point 3* could be not needed if the base class transitions make use of entry points. [3] presents an OOHSM with abstract states.
Do you know what MSM does with the caught exception?
Don't know how statechart is handling it.
Vicente [1] http://edn.embarcadero.com/article/30169 [2] https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&cad=rja&uact=8&ved=0ahUKEwipzI_H2OHKAhWG2hoKHRHZCuwQFgg3MAI&url=http%3A%2F%2Fwww.mit.bme.hu%2F~pinter%2Fpublications-files%2Fpinter-majzik-2004-fidji-modeling-and-analysis-of-exception-handling-techniques-by-using-uml-statecharts.pdf&usg=AFQjCNEkHdkPZJT2Cn7A8qAyHXJ4W5zcrw&sig2=q5oZ9NfLd7GXnWkFdprb7Q [3] https://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=7&cad=rja&uact=8&ved=0ahUKEwjxp8qm3-HKAhWGWhQKHdnRA60QFghRMAY&url=http%3A%2F%2Fwww2.ic.uff.br%2F~esteban%2Ffiles%2Fcadabra.pdf&usg=AFQjCNE5KJWQr4m0RB87cgrnKFLDKjBj1A&sig2=uC0-Zikp3OoZVNjzXMUTJw

On Sat, Feb 6, 2016 at 12:03 AM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
Thanks for materials and ideas. It's a really intresesting idea with the pseudo states. I'm not sure if it is not to complex for msm-lite, but I will defo take a look. Your approach also gave me and idea to add exception handling into the transition table the way events are handled too. Not sure about such approach, but I guess, it's worth to consider too. src + event [guard]/action = dst // guard throws runtime_error src + exception<runtime_error> = X // handle exception Anyway, I have created a ticket for it here -> http://boost-experimental.github.io/msm-lite/TODO/index.html
Not yet, explicit entry/exit points are not supported yet.
Okay, well, msm-lite doesn't support that as a feature. However, you can achieve more or less all of mentioned things just by using C++. For example, you can extend transiton table of a state machine by joining it with another one. auto table1 = make_transition_table(transitions...); auto table2 = make_transition_table(table1, other_transitions...);
By default assert will be called, but you can override the default behaviour by adding your custom handler to the state machine. template <class FSM,class Event> void exception_caught (Event const&,FSM&,std::exception& ) { ... // handle exception here }

Le 06/02/2016 22:07, Krzysztof Jusiak a écrit :
This should respond to point 1*. 2* should need to replace the refined state in table1. Point 3 would covered if the make_transition_table function overrides the redefined transitions. It would be great if you show how the user can address these points with your library using some run-able concrete examples. Vicente

On Sat, Feb 6, 2016 at 10:34 PM, Vicente Botet [via Boost] < ml-node+s2283326n4683294h33@n4.nabble.com> wrote:
Great. I have improved error handling if it comes to exceptions. Right now, if you do NOT compile with `-fno-exceptions` and do not specify configure noexcept then you can handle any exceptions thrown on the transition table. make_transition_table( *"idle"_s + "event1"_t / [] { throw std::runtime_error{"error"}; } , "idle"_s + "event2"_t / [] { throw 0; } , *"error_handling"_s + exception<std::runtime_error> / [] { std::cout << "exception caught" << std::endl; } , "error_handling"_s + exception<> / [] { std::cout << "generic exception caught, terminate..." << std::endl; } = X ); You can handle specific type of the exception(exception<type>) or just any(exception<>). Improved documentation and examples here: * http://boost-experimental.github.io/msm-lite/overview/index.html#exception-s... * http://boost-experimental.github.io/msm-lite/tutorial/index.html#8-error-han... * http://boost-experimental.github.io/msm-lite/examples/index.html#error-handl...
I was wondering whether your point with extending transitions can't be achieved using sub machines instead ? For example. struct example { auto configure() const noexcept { using namespace msm; return make_transition_table( *"idle"_s + event<e1> / [] { std::cout << "in sub sm" << std::endl; } = "s1"_s , "s1"_s + event<e2> / [] { std::cout << "finish sub sm" << std::endl; } = X ); } }; struct extend_example auto configure() const noexcept { using namespace msm; state<sm<example>> composite; return make_transition_table( *composite = composite // composite region //-----------------------------------// // add new transitions for error handling , *"error_handling"_s + unexpected_event<> / [] { std::cout << "unexpected event, terminate..." << std::endl; } = X , "error_handling"_s + exception<std::runtime_error> / [] { std::cout << "exception caught" << std::endl; } , "error_handling"_s + exception<> / [] { std::cout << "generic exception caught, terminate..." << std::endl; } = X ); } }; Right now, sm<example> sm; sm.process_event(e1{}); // handled by example sm.process_event(e2{}); // handled by example sm.process_event(e3{}); // handled by extended_example error handling
It would be great if you show how the user can address these points with your library using some run-able concrete examples.
Yea, I will work on that. Cheers for the pointers.
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

Le 08/02/2016 20:32, Kris a écrit :
I don't think you should correlate whether MSM manage exceptions and whether the configure function is noexcept. When you say " When guard/action throws an exception State Machine <http://boost-experimental.github.io/msm-lite/user_guide/index.html##sm-state-machine> will stay in a current state.", do you mean that if there is an exception in the action part, the state will be the nesting state of the transition, as the exit of the source state will already be executed? If yes, this is not a leaf state, this is why I added a pseudo-state, to ensure a leaf state.
Thanks for working on this. Vicente

On Tue, Feb 9, 2016 at 5:13 PM, Vicente Botet [via Boost] < ml-node+s2283326n4683364h3@n4.nabble.com> wrote:
Well, you can make it more explicit if you wish by changing the syntax a bit (*"idle"_s) + "event1"_t / [] { throw std::runtime_error{"error"}; } , "idle"_s + "event2"_t / [] { throw 0; } //---------------------------------------------------------------------------------------------------------/ , (*"error_handling"_s) + exception<std::runtime_error> / [] { }
The idea to have an orthogonal section that does the error handling is good, but how would you do error recovery?
Well, it depends whether you have to or not recover out of it. If you don't, another orthogonal region which will do the cleanup is good enough. However, if you do have to recover I would use another state for it, as you suggested. make_transition_table( (*"idle"_s) + "event1"_t / [] { throw std::runtime_error{"error"}; } , "idle"_s + "event2"_t / [] { throw 0; } , "idle"_s + exception<std::runtime_error> / [] { ... } = "recover"_s , "recover"_s + "okay"_t = "idle"_s // fine now );
I don't think you should correlate whether MSM manage exceptions and whether the configure function is noexcept.
Why not? I find it better then being forced to setup some dummy type in the state machine to enable exception handling. Please notice that exceptions handling is enabled by default (unless you compile with -fno-exceptions). The only reason why noexcept with configure when you create a transition table counts its because it will give you more performance.
It means that if exception won't be handled and that source state will remains the current state. Exit of the source state won't happen in such case too. Change the state happens after guards/actions were executed properly, otherwise source state is still a current state. src_state + event [ guard ] / action = dst_state ^ | 1. src_state + on_exit 2. dst_state + on_entry
Simply, none. It won't compile when you try to add action/guard with the event for this transition. In case of exception<>: auto guard = [] (auto event) {} // won't compile auto guard = [] () {} // okay However, you can get some info about the exception using std::current_exception auto action = [] () { auto exptr = std::current_exception(); ... }
Np
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

On Tue, Feb 9, 2016 at 11:00 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote: that transition table can throw otherwise?. For example, noexcept(false) seems a bit silly to use. We don't have 'except' and therefore default behavior supports exceptions unless you disable them via compiler flag.
I think UML doesn't specify the order when any of these should happen. At least I'm not aware of it, but I might be wrong? Anyway, defining it the following way 1 guard 2 action 3 src_state exit 4 change state 5 dst_state entry may things much easier to handle from programming perspective. One doesn't have to deal with undefined states . Just for the record, Boost.MSM has a policy to set when change state should happen.

Le 10/02/2016 11:51, Krzysztof Jusiak a écrit :
I understand that the try-catch would take time, and must be configurable. However I don't think that the noexcept qualification in the configure function is correct, as the configure function will throw or not independently on whether you have this try-catch, as it is related to the transition firing, not the transition table construction.
I don't have a link to the UML recommendation, but the wiki agrees with my order. https://en.wikipedia.org/wiki/UML_state_machine#Transition_execution_sequenc...
Best, Vicente

On Wed, Feb 10, 2016 at 5:11 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
Yea, I do get your point but IMHO when you look at transition table (make_transion_table) and you see that configure function is noexcept it's quite easy to get what is going on, but again, it's just my opinion. I tried different approach before, when I was checking all guards/actions whether they are noexcept or not. The problem with this solution was that lambdas expression are usually written without the noexcept and, since the state machine was behaving the same, it was hard to notice that performance went done. All in all, I just like the idea of using facilities provided by the standard here. I know it's not exactly what one may expect as configure will never throw or be/should called by the user.
Yea, it seems like. It's easier to handle exceptions this way, however, being compliant with the UML is important. I may change the order then as it will save me time in the future explaining why it was done the other way ;) Thanks for pointing that out.
No idea what Statechart does. MSM rationale is here -> http://www.boost.org/doc/libs/1_57_0/libs/msm/doc/HTML/ch03s05.html#d0e2714 BTW. I have a question related to local transitions. Concept seems to be nice but I don't undesrtand why exit/entry is NOT triggered only 'if the main target state is a substate of the main source'. Why this concept can't be more general? Wouldn't that be nice? s1 + e1 = s2 // exit from s1 / entry to s2 s1 ^ e1 = s2 // no exit from s1 / no entry to s2

Le 10/02/2016 22:07, Krzysztof Jusiak a écrit :
A local transition will ensure that there is no exit on s1, but there should be an entry in s2 if s2 is not s1. You will need to have a nested examples to see the difference between an external and a local transition. Vicente

On Thu, Feb 11, 2016 at 12:28 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
I checked UML2.5 specification and I have found "Transition execution sequence" (14.2.3.9.6 / page 316). However, there is no much info about the sequence there. It's mostly about that exit of the main state has to happen before entry to the target state. I can't find anything about when guard/action should happen in the sequence :/ buy it's a long document so maybe it might be found somewhere?
Yea, I do get it. Cheers. Do have any example when local transitions are useful? I see some usage for them but I struggle really to find a really good use case for them.

Le 12/02/2016 12:20, Krzysztof Jusiak a écrit :
On page 377 I see an example where the order is clear xS11; t1; xS1; t2; eT1; eT11; t3; eT111 Where xAAA means exit action on state AAA and eAAA entry on state AAA. ti are actions on the segmented transitions. Just before this example you can find *"Transition execution sequence ** *Every Transition, except for internal and local Transitions, causes exiting of a source State, and entering of the target State. These two States, which may be composite, are designated as the main source and the main target of a Transition respectively. The main source is a direct substate of the Region that contains the source States, and the main target is the substate of the Region that contains the target States. NOTE. A Transition from one Region to another in the same immediate enclosing composite State is not allowed. Once a Transition is enabled and is selected to fire, the following steps are carried out in order: 1. Starting with the main source State, the States that contain the main source State are exited according to the rules of State exit (or, composite State exit if the main source State is nested) as described earlier. 2. The series of State exits continues until the first Region that contains, directly or indirectly, both the main source and main target states is reached. The Region that contains both the main source and main target states is called their least common ancestor. At that point, the effect Behavior of the Transition that connects the sub-configuration of source States to the sub-configuration of target States is executed. (A “sub-configuration” here refers to that subset of a full state configuration contained within the least common ancestor Region.) 3. The configuration of States containing the main target State is entered, starting with the outermost State in the least common ancestor Region that contains the main target State. The execution of Behaviors follows the rules of State entry (or composite State entry) described earlier. " I believe this is clear enough. 1 exits 2 action 3 entries
Let say that you have a state S with two sub-states S1 and S2. While in state S, if you receive the event E1 you want to go to S1, but don't want to execute the exit of state S. However you want to execute the exit of S1 or S2. S ^ E1 = S1; Think of E1 as an event that interrupts whatever you were doing on S1 or S2. Vicente

On Fri, Feb 12, 2016 at 6:44 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
For me it is semi clear, but I do agree with your conclusion though. However, there is no info about guards being executed before src state exit. It might be implied by the statement that transition has to be enabled, but I'm not sure about it.
Yea, yea I do get that. I was asking more about real life example. I mean, what use case would require such behavior, because I can't think of any, but I know there are some. I'm asking because I don't have any experience with local transition and it is hard to justify adding a new feature without a meaningful rationale. Thank you for you feedback, it is very useful.

Le 15/02/2016 11:08, Krzysztof Jusiak a écrit :
Yes, I believe that event reception and the guard evaluation are the enablers of the transition.
Let say that we are on a disabled state. In this state you have sub-states representing the path to go to another enabled state (e.g. requesting a password, ...) . If you receive a reset event this would disable any trial to go to the enabled state. From the disabled state you could have a local transition when receiving this reset event and go to the sub-state disabled/idle. What is important is that you are always in the disabled state, so the disabled exit has not been executed. Vicente

On Mon, Feb 15, 2016 at 12:17 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
Yea, but that would mean that guard has to be evaluated before exit of the state or any action, so the order would be. 1. guard [to enable transition] 2. exit src state 3. actions... 4. entry dst state When the actual state change should happen in above sequence it's not stated in the document as well. I would assume following order according to the spec + a bit of rationality? 1. guard [to enable transition] 2. exit src state 3. actions... 4. CHANGE THE STATE TO DST HERE? 5. entry dst state
Cheers, it helps a lot.

On Tue, Feb 16, 2016 at 9:50 PM, Vicente Botet [via Boost] < ml-node+s2283326n4683550h69@n4.nabble.com> wrote:
Great to hear that. However, above sequence makes exception handling a bit harder as with guards we haven't left the src state but with actions we started the exit already. 1. When exception happens in a guard * src state is unchanged 2. When exception happens in an action * src state is exited Moreover, following below sequence 3. actions... 4. CHANGE THE STATE TO DST HERE? makes it harder to process internal events "src"_s + event / process_event(other_event) = "dst"_s , "src"_s + other_event = X // most likely, should be this one as we haven't changed the state yet? , "dst"_s + other_event = X and, therefore, maybe it's better to have it the other way around? 3. CHANGE THE STATE TO DST HERE? 4. actions... Vicente
-- View this message in context: http://boost.2283326.n4.nabble.com/MSM-Is-there-any-interest-in-C-14-Boost-M... Sent from the Boost - Dev mailing list archive at Nabble.com.

Le 17/02/2016 16:20, Kris a écrit :
I have never used process_event in an action on the same state machine (You are re-entering the state machine :( ). The single think you can do is to post it (push in a queue) or call process_event in another state machine. However you must ensure the there are no cycles. The asynchronous way avoids always the possible cycles. In some projects I have defined a hierarchy of state machines and the upper layer state machines use synchronous communication to communicate to lower state machines and the reverse, lower layer use always asynchronous communication with upper layer state machines (half sync/half async). There are 3 features that I'm missing in UML state machines that I found in SDL [1]. Maybe these features have no sense with synchronous state machines. * Procedures that can contain states. The difference with nested states is that procedures are stack based and return to the point of call when the procedure terminates. You can reuse a procedure inside a state machine several times of course. * Synchronous Remote Procedures that allows to do a call/replay at once. This avoids the use of wait states on which the every other event tan the replay is deferred. * Synchronous Remote Variables that allows to read a remote variable.The same here; but just to query for the value of a remote variable. Vicente [1] https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=5&cad=rja&uact=8&ved=0ahUKEwi1vqWwqP_KAhUGWhoKHa-DB3oQFghEMAQ&url=http%3A%2F%2Fwww.itu.int%2FITU-T%2Fstudygroups%2Fcom10%2Flanguages%2FZ.100_1199.pdf&usg=AFQjCNFwOMg8j5RuW77nxtjPuj3c8eq2mQ&sig2=svSxdC5kgb1EBGDbnchYwg [2] https://fr.wikipedia.org/wiki/Specification_and_Description_Language

On Wed, Feb 17, 2016 at 5:46 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
It's a great point! To be honest with you, I have never liked process_event on the transition table, however, I blindly followed MSM approach (fsm is always passed to guards/actions in MSM, so you can do whatever) but it's a bit dangerous here, as you mentioned. I'm going to change that to support only defer or queue events on the transition table. Thanks for your input on that, makes complete sense.
participants (7)
-
christophe.j.henry@gmail.com
-
Klaim - Joël Lamotte
-
Kris
-
Krzysztof Jusiak
-
Paul Fultz II
-
Rob Stewart
-
Vicente J. Botet Escriba