Maki
Loading...
Searching...
No Matches
machine_conf.hpp
1//Copyright Florian Goujeon 2021 - 2025.
2//Distributed under the Boost Software License, Version 1.0.
3//(See accompanying file LICENSE or copy at
4//https://www.boost.org/LICENSE_1_0.txt)
5//Official repository: https://github.com/fgoujeon/maki
6
11
12#ifndef MAKI_MACHINE_CONF_HPP
13#define MAKI_MACHINE_CONF_HPP
14
15#include "event_set.hpp"
16#include "context.hpp"
17#include "action.hpp"
18#include "detail/machine_conf_fwd.hpp"
19#include "detail/type.hpp"
20#include "detail/event_action.hpp"
21#include "detail/signature_macros.hpp"
22#include "detail/impl.hpp"
23#include "detail/tuple.hpp"
24#include <type_traits>
25#include <cstdlib>
26
27namespace maki
28{
29
30#ifdef MAKI_DETAIL_DOXYGEN
31#define MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE machine_conf<IMPLEMENTATION_DETAIL>
32#else
33#define MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE auto
34#endif
35
40template<class Impl>
41class machine_conf
42{
43public:
44 using context_type = typename Impl::context_type;
45
46 constexpr machine_conf() = default;
47
48 machine_conf(const machine_conf&) = delete;
49
50 machine_conf(machine_conf&&) = delete;
51
52 ~machine_conf() = default;
53
54 machine_conf& operator=(const machine_conf&) = delete;
55
56 machine_conf& operator=(machine_conf&&) = delete;
57
58#define MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN /*NOLINT(cppcoreguidelines-macro-usage)*/ \
59 [[maybe_unused]] const auto MAKI_DETAIL_ARG_auto_start = impl_.auto_start; \
60 [[maybe_unused]] const auto MAKI_DETAIL_ARG_context_type = detail::type<typename Impl::context_type>; \
61 [[maybe_unused]] const auto MAKI_DETAIL_ARG_context_sig = impl_.context_sig; \
62 [[maybe_unused]] const auto MAKI_DETAIL_ARG_pre_processing_hooks = impl_.pre_processing_hooks; \
63 [[maybe_unused]] const auto MAKI_DETAIL_ARG_post_external_transition_hook = impl_.post_external_transition_hook; \
64 [[maybe_unused]] const auto MAKI_DETAIL_ARG_pre_external_transition_hook = impl_.pre_external_transition_hook; \
65 [[maybe_unused]] const auto MAKI_DETAIL_ARG_exception_handler = impl_.exception_handler; \
66 [[maybe_unused]] const auto MAKI_DETAIL_ARG_post_processing_hooks = impl_.post_processing_hooks; \
67 [[maybe_unused]] const auto MAKI_DETAIL_ARG_process_event_now_enabled = impl_.process_event_now_enabled; \
68 [[maybe_unused]] const auto MAKI_DETAIL_ARG_run_to_completion = impl_.run_to_completion; \
69 [[maybe_unused]] const auto MAKI_DETAIL_ARG_small_event_max_align = impl_.small_event_max_align; \
70 [[maybe_unused]] const auto MAKI_DETAIL_ARG_small_event_max_size = impl_.small_event_max_size; \
71 [[maybe_unused]] const auto MAKI_DETAIL_ARG_transition_tables = impl_.transition_tables;
72
73#define MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END /*NOLINT(cppcoreguidelines-macro-usage)*/ \
74 return machine_conf \
75 < \
76 detail::machine_conf_option_set \
77 < \
78 typename std::decay_t<decltype(MAKI_DETAIL_ARG_context_type)>::type, \
79 std::decay_t<decltype(MAKI_DETAIL_ARG_pre_processing_hooks)>, \
80 std::decay_t<decltype(MAKI_DETAIL_ARG_exception_handler)>, \
81 std::decay_t<decltype(MAKI_DETAIL_ARG_pre_external_transition_hook)>, \
82 std::decay_t<decltype(MAKI_DETAIL_ARG_post_external_transition_hook)>, \
83 std::decay_t<decltype(MAKI_DETAIL_ARG_post_processing_hooks)>, \
84 std::decay_t<decltype(MAKI_DETAIL_ARG_transition_tables)> \
85 > \
86 > \
87 { \
88 MAKI_DETAIL_ARG_auto_start, \
89 MAKI_DETAIL_ARG_context_sig, \
90 MAKI_DETAIL_ARG_pre_processing_hooks, \
91 MAKI_DETAIL_ARG_post_external_transition_hook, \
92 MAKI_DETAIL_ARG_pre_external_transition_hook, \
93 MAKI_DETAIL_ARG_exception_handler, \
94 MAKI_DETAIL_ARG_post_processing_hooks, \
95 MAKI_DETAIL_ARG_process_event_now_enabled, \
96 MAKI_DETAIL_ARG_run_to_completion, \
97 MAKI_DETAIL_ARG_small_event_max_align, \
98 MAKI_DETAIL_ARG_small_event_max_size, \
99 MAKI_DETAIL_ARG_transition_tables \
100 };
101
102#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
103 \
106 template<class Context> \
107 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE context_##signature() const \
108 { \
109 return context<Context, machine_context_signature::signature>(); \
110 }
111 MAKI_DETAIL_MACHINE_CONTEXT_CONSTRUCTOR_SIGNATURES
112#undef MAKI_DETAIL_X
113
114#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
115 \
120 template<class EventSetPredicate, class Action> \
121 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE pre_processing_hook_##signature(const event_set<EventSetPredicate>& evt_set, const Action& action) const \
122 { \
123 return pre_processing_hook<action_signature::signature>(evt_set, action); \
124 } \
125 \
131 template<class Event, class Action> \
132 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE pre_processing_hook_##signature(const Action& action) const \
133 { \
134 return pre_processing_hook_##signature(event_set{event<Event>}, action); \
135 }
136 MAKI_DETAIL_ACTION_SIGNATURES
137#undef MAKI_DETAIL_X
138
142 Hook must have the following form:
143
144 @snippet misc/external-transition-hook/src/main.cpp signature
145
146 This hook can be useful for logging external transitions, for example:
147
148 @snippet misc/external-transition-hook/src/main.cpp post
149 */
150 template<class Hook>
151 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE post_external_transition_hook_crset(const Hook& hook) const
152 {
153 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
154#define MAKI_DETAIL_ARG_post_external_transition_hook hook
155 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
156#undef MAKI_DETAIL_ARG_post_external_transition_hook
157 }
158
160
163 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE auto_start(const bool value) const
164 {
165 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
166#define MAKI_DETAIL_ARG_auto_start value
167 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
168#undef MAKI_DETAIL_ARG_auto_start
169 }
170
174 Hook must have the following form:
175
176 @snippet misc/external-transition-hook/src/main.cpp signature
177
178 This hook can be useful for logging external transitions, for example:
179
180 @snippet misc/external-transition-hook/src/main.cpp pre
181 */
182 template<class Hook>
183 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE pre_external_transition_hook_crset(const Hook& hook) const
184 {
185 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
186#define MAKI_DETAIL_ARG_pre_external_transition_hook hook
187 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
188#undef MAKI_DETAIL_ARG_pre_external_transition_hook
189 }
197
200 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE run_to_completion(const bool value) const
201 {
202 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
203#define MAKI_DETAIL_ARG_run_to_completion value
204 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
205#undef MAKI_DETAIL_ARG_run_to_completion
206 }
207
209
212 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE process_event_now_enabled(const bool value) const
213 {
214 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
215#define MAKI_DETAIL_ARG_process_event_now_enabled value
216 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
217#undef MAKI_DETAIL_ARG_process_event_now_enabled
218 }
219
231 @code
232 .catch_mx([](auto& mach, const std::exception_ptr& eptr)
233 {
234 //...
235 })
236 @endcode
237
238 If this action isn't set, `maki::machine` doesn't catch any exception.
239 */
240 template<class Callable>
241 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE catch_mx(const Callable& callable) const
242 {
243 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
244#define MAKI_DETAIL_ARG_exception_handler callable
245 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
246#undef MAKI_DETAIL_ARG_exception_handler
247 }
248
272 //...
273 })
274 .post_processing_hook_mep<some_other_event_type>([](auto& mach, const some_other_event_type& event, const bool processed)
275 {
276 //...
277 })
278 ;
279 @endcode
280 */
281 template<class EventSetPredicate, class Action>
282 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE post_processing_hook_mep(const event_set<EventSetPredicate>& evt_set, const Action& action) const
283 {
284 const auto new_post_processing_hooks = tuple_append
285 (
286 impl_.post_processing_hooks,
287 detail::make_event_action<action_signature::me>(evt_set, action)
288 );
289
290 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
291#define MAKI_DETAIL_ARG_post_processing_hooks new_post_processing_hooks
292 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
293#undef MAKI_DETAIL_ARG_post_processing_hooks
294 }
295
319 //...
320 })
321 .post_processing_hook_mep<some_other_event_type>([](auto& mach, const some_other_event_type& event, const bool processed)
322 {
323 //...
324 })
325 ;
326 @endcode
327 */
328 template<class Event, class Action>
329 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE post_processing_hook_mep(const Action& action) const
330 {
331 return post_processing_hook_mep(event_set{event<Event>}, action);
332 }
333
336
339 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE small_event_max_align(const std::size_t value) const
340 {
341 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
342#define MAKI_DETAIL_ARG_small_event_max_align value
343 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
344#undef MAKI_DETAIL_ARG_small_event_max_align
345 }
346
349
352 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE small_event_max_size(const std::size_t value) const
353 {
354 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
355#define MAKI_DETAIL_ARG_small_event_max_size value
356 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
357#undef MAKI_DETAIL_ARG_small_event_max_size
358 }
359
360
366 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE thread_safe(const bool /*enabled*/) const
367 {
368 return *this;
369 }
370
374
375 template<class... TransitionTables>
376 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE transition_tables(const TransitionTables&... tables) const
377 {
378 const auto tpl = detail::tuple<TransitionTables...>{detail::distributed_construct, tables...};
379 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
380#define MAKI_DETAIL_ARG_transition_tables tpl
381 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
382#undef MAKI_DETAIL_ARG_transition_tables
383 }
384
385private:
386 using impl_type = Impl;
387
388 template<class Impl2>
389 friend class machine_conf;
390
391 template<class... Args>
392 constexpr machine_conf(Args&&... args):
393 impl_{std::forward<Args>(args)...}
394 {
395 }
396
397 template<class Context2, auto ContextSig>
398 [[nodiscard]] constexpr auto context() const
399 {
400 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
401#define MAKI_DETAIL_ARG_context_type detail::type<Context2>
402#define MAKI_DETAIL_ARG_context_sig ContextSig
403 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
404#undef MAKI_DETAIL_ARG_context_type
405#undef MAKI_DETAIL_ARG_context_sig
406 }
407
408 template<action_signature Sig, class EventSetPredicate, class Hook>
409 [[nodiscard]] constexpr auto pre_processing_hook(const event_set<EventSetPredicate>& evt_set, const Hook& hook) const
410 {
411 const auto new_pre_processing_hooks = tuple_append
412 (
413 impl_.pre_processing_hooks,
414 detail::make_event_action<Sig>(evt_set, hook)
415 );
416
417 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
418#define MAKI_DETAIL_ARG_pre_processing_hooks new_pre_processing_hooks
419 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
420#undef MAKI_DETAIL_ARG_pre_processing_hooks
421 }
422
423#undef MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
424#undef MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
425
426 MAKI_DETAIL_FRIENDLY_IMPL
427};
428
429#undef MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE
430
431namespace detail
432{
433 template<class T>
434 struct is_machine_conf
435 {
436 static constexpr auto value = false;
437 };
438
439 template<class... Options>
440 struct is_machine_conf<machine_conf<Options...>>
441 {
442 static constexpr auto value = true;
443 };
444
445 template<class T>
446 constexpr auto is_machine_conf_v = is_machine_conf<T>::value;
447}
448
449} //namespace
450
451#endif
Represents an event type set.
Definition event_set.hpp:37
event_set(event_t< Event >) -> event_set< IMPLEMENTATION_DETAIL >
Class template argument deduction guide for maki::event_set.
constexpr machine_conf< IMPLEMENTATION_DETAIL > process_event_now_enabled(const bool value) const
Specifies whether the unsafe function maki::machine::process_event_now() can be called.
Definition machine_conf.hpp:202
constexpr machine_conf< IMPLEMENTATION_DETAIL > transition_tables(const TransitionTables &... tables) const
Specifies the list of transition tables. One region per transition table is created.
Definition machine_conf.hpp:366
constexpr machine_conf< IMPLEMENTATION_DETAIL > run_to_completion(const bool value) const
Specifies whether run-to-completion is enabled.
Definition machine_conf.hpp:190
constexpr machine_conf< IMPLEMENTATION_DETAIL > catch_mx(const Callable &callable) const
Sets up a try/catch(...) block at the top-level of every non-const member function of maki::machine a...
Definition machine_conf.hpp:231
constexpr machine_conf< IMPLEMENTATION_DETAIL > auto_start(const bool value) const
Specifies whether the constructor of maki::machine must call maki::machine::start().
Definition machine_conf.hpp:153
constexpr machine_conf< IMPLEMENTATION_DETAIL > post_external_transition_hook_crset(const Hook &hook) const
Specifies a hook to be called after any external transition.
Definition machine_conf.hpp:141
constexpr machine_conf< IMPLEMENTATION_DETAIL > small_event_max_size(const std::size_t value) const
Specifies the maximum object size for the run-to-completion event queue to enable small object optimi...
Definition machine_conf.hpp:342
constexpr machine_conf< IMPLEMENTATION_DETAIL > small_event_max_align(const std::size_t value) const
Specifies the maximum object alignment requirement for the run-to-completion event queue to enable sm...
Definition machine_conf.hpp:329
constexpr machine_conf< IMPLEMENTATION_DETAIL > post_processing_hook_mep(const event_set< EventSetPredicate > &evt_set, const Action &action) const
Adds a hook to be called whenever maki::machine is done processing an event whose type is part of evt...
Definition machine_conf.hpp:272
constexpr machine_conf< IMPLEMENTATION_DETAIL > pre_external_transition_hook_crset(const Hook &hook) const
Specifies a hook to be called before any external transition.
Definition machine_conf.hpp:173
constexpr machine_conf< IMPLEMENTATION_DETAIL > thread_safe(const bool) const
Currently doesn't do anything. Once thread safety is implemented, will specify whether thread safety ...
Definition machine_conf.hpp:356
The Maki library.
Represents an action to be given to maki::transition_table.
Definition action.hpp:60