Closed kris-jusiak closed 8 years ago
Thanks @redboltz
By default, defer, most likely, will be using a simple circular array (therefore BOOST_MSM_LITE_DEFER_LIMIT_SIZE
).
Nevertheless, there will be an option to change it to use std::deque
or any other container and use it with a variable length too (via policies).
@krzysztof-jusiak thank you for the response.
By default, defer, most likely, will be using a simple circular array (therefore BOOST_MSM_LITE_DEFER_LIMIT_SIZE).
I understand.
Nevertheless, there will be an option to change it to use std::deque or any other container and use it with a variable length too (via policies).
Sounds good. I'm looking forward to using the functionality :)
implemented in the newest master. Tests are -> here https://github.com/boost-experimental/msm-lite/blob/master/test/ft/ft_defer.cpp.
Closing it for now as I'm trying to clean up issues a bit. Please, reopen if it's not working as expected. Thanks!
BTW. test cases from http://redboltz.wikidot.com/deferred-events seem to work, but defo there are some cases which aren't covered properly.
Thank you for implementing defer functionality!
I've double checked using my example http://redboltz.wikidot.com/deferred-events
I implemented the first state machine diagram as follows:
#include <cassert>
#include <queue>
#include "boost/sml.hpp"
namespace sml = boost::sml;
struct e1 {};
struct e2 {};
struct defer_test {
auto operator()() const noexcept {
using namespace sml;
// clang-format off
return make_transition_table(
*"s1"_s + event<e1> / defer
, "s1"_s + event<e2> = "s2"_s
, "s2"_s + event<e1> / defer
, "s2"_s + event<e2> = "s3"_s
, "s3"_s + event<e1> = "s4"_s
, "s4"_s + event<e1> = "s5"_s
, "s5"_s + event<e1> = "s6"_s
);
// clang-format on
}
};
int main() {
using namespace sml;
sm<defer_test, sml::defer_queue<std::queue>> sm;
assert(sm.is("s1"_s));
sm.process_event(e1{}); // defer
assert(sm.is("s1"_s));
sm.process_event(e1{}); // defer again
assert(sm.is("s1"_s));
sm.process_event(e2{}); // transition to s2 by e2, and then deferred e1s should still be deferred.
assert(sm.is("s2"_s));
sm.process_event(e2{}); // transition to s3 by e2, and then transition to s4, s5 by deferred e1s
assert(sm.is("s5"_s));
}
The code corresponding to the second state machine diagram is follows:
#include <cassert>
#include <queue>
#include "boost/sml.hpp"
namespace sml = boost::sml;
struct e1 {};
struct e2 {};
struct defer_test {
auto operator()() const noexcept {
using namespace sml;
// clang-format off
return make_transition_table(
*"s1"_s + event<e1> / defer
, "s1"_s + event<e2> = "s2"_s
, "s2"_s + event<e1> = "s5"_s
, "s2"_s = "s3"_s
, "s3"_s + event<e1> = "s4"_s
);
// clang-format on
}
};
int main() {
using namespace sml;
sm<defer_test, sml::defer_queue<std::queue>> sm;
assert(sm.is("s1"_s));
sm.process_event(e1{}); // defer
assert(sm.is("s1"_s));
sm.process_event(e2{});
assert(sm.is("s4"_s));
}
Both work as I expected.
Awesome! thanks for checking @redboltz. Sorry for taking so long, though.
Hi, thank you for writing a great library. I'm using Boost.MSM now and suffering from a long compile time. I watched C++Now 2016 Video and slides. I am deeply impressed at a great compile-time, performance of msm-lite.
If defer is supported, I can migrate some of my project from Boost.MSM to msm-lite. I really want to defer functionality.
I found
#if defined(BOOST_MSM_LITE_DEFER_LIMIT_SIZE)
in the code. I'm not sure but it implies the length of deferred queue is fixed size. Is that right? If you provide a variable length version, for example usingstd::deque
, it is matched to my use case.My use case is a kind of networking server. The server has a state machine. In some transitional state, received events should be deferred. And the number of events is difficult to predict. After leaving the transitional state, then deferred event are processed. That is why I need a variable length version.
Do you have any plan to support that?