Comments (4)
I modified your example to create variables instead of temporaries, it seems to make fewer copy constructor calls. You can check here. Also, maybe you can provide a Godbolt link instead of forking the project since it's easier to try out what you're talking about.
from sml.
I just noticed a small remark in the docs, stating:
Line 57 in 5a323c5
I don't understand what is meant by injection and I couldn't find any hint to that in the docs yet.
Anyway, if states must not comprise data members, how would you implement reusable, i.e. self-contained and configurable states? Think of data
class in example/data.cpp
being reused multiple times as sub states in an enclosing higher-level state machine. Where do you store the "configuration" data of a state if not in the state itself? I could not find any example illustrating this. Any help is highly welcome.
from sml.
Ok, I learned the hard way myself:
- states
can
comprise data members, but their initialization must not happen via classical constructors, but via aggregate initialization, which doesn't allow execution of user-define code during initialization. - In order to achieve the latter as well, one must use
Context
classes, which themselves allow for custom initialization, but which are then just passed to the state via aggregate initialization. - This passing is automated by SML via template magic. This process is called dependency injection.
Here is a working minimal example:
#include <boost/sml.hpp>
#include <cstdio>
#include <queue>
#include <string>
namespace sml = boost::sml;
struct next {};
struct quit {};
const auto idle = sml::state<class idle>;
const auto s1 = sml::state<class s1>;
const auto s2 = sml::state<class s2>;
struct Context {
static int next_id;
Context() = delete;
// user-defined constructors
Context(int data, const std::string& extra) : id(++next_id), data(data), extra(extra) { printf("ctor: %d\n", id); }
Context(const Context& c) : id(++next_id), data(c.data), extra(c.extra) { printf("copy c: %d -> %d\n", c.id, id); };
Context(Context&& c) : id(++next_id), data(c.data), extra(std::move(c.extra)) { printf("move c: %d -> %d\n", c.id, id); };
Context& operator=(const Context& c) = delete;
Context& operator=(Context&& c) = delete;
int id;
int data;
std::string extra;
};
int Context::next_id = 0;
int main() {
struct sub {
// sub must not have any user-defined constructor
Context ctx; // state-local data
auto operator()() const noexcept {
using namespace sml;
// clang-format off
return make_transition_table(
* s1 + on_entry<_> / (&sub::method, process(quit{}), process(next{}))
, s2 + on_entry<_> / (process(quit{}), process(next{}))
, s1 + event<next> = s2
, s2 + event<next> = s1
);
// clang-format on
}
void method() { printf("method: %d, %s (%d)\n", ctx.data, ctx.extra.c_str(), ctx.id); }
};
struct parent {
sml::front::state_sm<sub>::type s;
auto operator()() noexcept {
using namespace sml;
// clang-format off
return make_transition_table(
* idle + event<next> = s
, s + event<quit> / [this] { printf("quitting\n"); } = X
);
// clang-format on
}
};
Context c(42, "Hello"); // initialize context with custom ctor
sub s{c}; // initialize sub-state by passing c via aggregate initialization
sml::sm<parent, sml::process_queue<std::queue>> sm(s); // inject initialized sub state into state machine
sm.process_event(next{});
sm.process_event(next{}); // + process(e2{})
}
from sml.
The Context
must be copyable (movable is not sufficient) and it is still copied a few times:
ctor: 1
copy c: 1 -> 2
copy c: 2 -> 3
copy c: 3 -> 4
copy c: 2 -> 5
method: 42, Hello (2)
quitting
from sml.
Related Issues (20)
- How to achieve shallow history behavior? HOT 1
- dependency injection through process_event() to save sm memory footprint HOT 2
- [Question] Can you know upfront if an event can be processed?
- What's the actual point of this all? HOT 9
- sm.is("state"_s) suddenly doesn't compile anymore HOT 5
- How to store a "dispatch table" in a class? HOT 1
- sml::aux::get_type_name<TAction>() not returning name of lambda function HOT 2
- Compilation error when using logger, process_queue and member function action HOT 1
- how to know weather state is a sub-state machine or a normal state HOT 1
- How to make a state transition that changes to the next state upon completion of its action?
- Question: Debugging in STM32CubeIDE
- copy of class containing transition table is made when boost::sml::sm is instantiated HOT 1
- [Documentation] Who is using it HOT 2
- can not work with CLion HOT 1
- deferred event not processed when in any orthogonal region other than first
- gcc 10.5 warning: array subscript is outside array bounds HOT 4
- SML version change caused static assert fail in state machine constructor HOT 4
- Adding boost-ext-sml to conan-center-index HOT 2
- Anonymous event HOT 1
- Hello World error HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sml.