Maki
Loading...
Searching...
No Matches
machine_conf.hpp
1//Copyright Florian Goujeon 2021 - 2026.
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_impl.hpp"
19#include "detail/type_set.hpp"
20#include "detail/type.hpp"
21#include "detail/event_action.hpp"
22#include "detail/signature_macros.hpp"
23#include "detail/friendly_impl.hpp"
24#include "detail/tuple.hpp"
25#include <type_traits>
26#include <cstdlib>
27
28namespace maki
29{
30
31#ifdef MAKI_DETAIL_DOXYGEN
32#define MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE machine_conf<IMPLEMENTATION_DETAIL>
33#else
34#define MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE auto
35#endif
36
41template<class Impl>
42class machine_conf
43{
44public:
45 using context_type = typename Impl::context_type;
46
47 constexpr machine_conf() = default;
48
49 machine_conf(const machine_conf&) = delete;
50
51 machine_conf(machine_conf&&) = delete;
52
53 ~machine_conf() = default;
54
55 machine_conf& operator=(const machine_conf&) = delete;
56
57 machine_conf& operator=(machine_conf&&) = delete;
58
59#define MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN /*NOLINT(cppcoreguidelines-macro-usage)*/ \
60 [[maybe_unused]] const auto MAKI_DETAIL_ARG_auto_start = impl_.auto_start; \
61 [[maybe_unused]] const auto MAKI_DETAIL_ARG_context_type = detail::type<typename Impl::context_type>; \
62 [[maybe_unused]] const auto MAKI_DETAIL_ARG_context_sig = impl_.context_sig; \
63 [[maybe_unused]] const auto MAKI_DETAIL_ARG_pre_processing_hooks = impl_.pre_processing_hooks; \
64 [[maybe_unused]] const auto MAKI_DETAIL_ARG_post_external_transition_hook = impl_.post_external_transition_hook; \
65 [[maybe_unused]] const auto MAKI_DETAIL_ARG_pre_external_transition_hook = impl_.pre_external_transition_hook; \
66 [[maybe_unused]] const auto MAKI_DETAIL_ARG_exception_handler = impl_.exception_handler; \
67 [[maybe_unused]] const auto MAKI_DETAIL_ARG_post_processing_hooks = impl_.post_processing_hooks; \
68 [[maybe_unused]] const auto MAKI_DETAIL_ARG_process_event_now_enabled = impl_.process_event_now_enabled; \
69 [[maybe_unused]] const auto MAKI_DETAIL_ARG_run_to_completion = impl_.run_to_completion; \
70 [[maybe_unused]] const auto MAKI_DETAIL_ARG_small_event_max_align = impl_.small_event_max_align; \
71 [[maybe_unused]] const auto MAKI_DETAIL_ARG_small_event_max_size = impl_.small_event_max_size; \
72 [[maybe_unused]] const auto MAKI_DETAIL_ARG_transition_tables = impl_.transition_tables;
73
74#define MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END /*NOLINT(cppcoreguidelines-macro-usage)*/ \
75 return machine_conf \
76 < \
77 detail::machine_conf_impl \
78 < \
79 typename std::decay_t<decltype(MAKI_DETAIL_ARG_context_type)>::type, \
80 std::decay_t<decltype(MAKI_DETAIL_ARG_pre_processing_hooks)>, \
81 std::decay_t<decltype(MAKI_DETAIL_ARG_exception_handler)>, \
82 std::decay_t<decltype(MAKI_DETAIL_ARG_pre_external_transition_hook)>, \
83 std::decay_t<decltype(MAKI_DETAIL_ARG_post_external_transition_hook)>, \
84 std::decay_t<decltype(MAKI_DETAIL_ARG_post_processing_hooks)>, \
85 std::decay_t<decltype(MAKI_DETAIL_ARG_transition_tables)> \
86 > \
87 > \
88 { \
89 MAKI_DETAIL_ARG_auto_start, \
90 MAKI_DETAIL_ARG_context_sig, \
91 MAKI_DETAIL_ARG_pre_processing_hooks, \
92 MAKI_DETAIL_ARG_post_external_transition_hook, \
93 MAKI_DETAIL_ARG_pre_external_transition_hook, \
94 MAKI_DETAIL_ARG_exception_handler, \
95 MAKI_DETAIL_ARG_post_processing_hooks, \
96 MAKI_DETAIL_ARG_process_event_now_enabled, \
97 MAKI_DETAIL_ARG_run_to_completion, \
98 MAKI_DETAIL_ARG_small_event_max_align, \
99 MAKI_DETAIL_ARG_small_event_max_size, \
100 MAKI_DETAIL_ARG_transition_tables \
101 };
102
103#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
104 \
107 template<class Context> \
108 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE context_##signature() const \
109 { \
110 return context<Context, machine_context_signature::signature>(); \
111 }
112 MAKI_DETAIL_MACHINE_CONTEXT_CONSTRUCTOR_SIGNATURES
113#undef MAKI_DETAIL_X
114
115#define MAKI_DETAIL_X(signature) /*NOLINT(cppcoreguidelines-macro-usage)*/ \
116 \
121 template<class EventSetImpl, class Action> \
122 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE pre_processing_hook_##signature(const event_set<EventSetImpl>& /*event_types*/, const Action& action) const \
123 { \
124 return pre_processing_hook<EventSetImpl, action_signature::signature>(action); \
125 } \
126 \
132 template<class Event, class Action> \
133 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE pre_processing_hook_##signature(const Action& action) const \
134 { \
135 return pre_processing_hook<detail::type_set_item<Event>, action_signature::signature>(action); \
136 }
137 MAKI_DETAIL_ACTION_SIGNATURES
138#undef MAKI_DETAIL_X
139
143 Hook must have the following form:
144
145 @snippet misc/external-transition-hook/src/main.cpp signature
146
147 This hook can be useful for logging external transitions, for example:
148
149 @snippet misc/external-transition-hook/src/main.cpp post
150 */
151 template<class Hook>
152 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE post_external_transition_hook_crste(const Hook& hook) const
153 {
154 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
155#define MAKI_DETAIL_ARG_post_external_transition_hook hook
156 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
157#undef MAKI_DETAIL_ARG_post_external_transition_hook
158 }
159
161
164 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE auto_start(const bool value) const
165 {
166 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
167#define MAKI_DETAIL_ARG_auto_start value
168 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
169#undef MAKI_DETAIL_ARG_auto_start
170 }
171
175 Hook must have the following form:
176
177 @snippet misc/external-transition-hook/src/main.cpp signature
178
179 This hook can be useful for logging external transitions, for example:
180
181 @snippet misc/external-transition-hook/src/main.cpp pre
182 */
183 template<class Hook>
184 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE pre_external_transition_hook_crste(const Hook& hook) const
185 {
186 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
187#define MAKI_DETAIL_ARG_pre_external_transition_hook hook
188 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
189#undef MAKI_DETAIL_ARG_pre_external_transition_hook
190 }
198
201 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE run_to_completion(const bool value) const
202 {
203 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
204#define MAKI_DETAIL_ARG_run_to_completion value
205 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
206#undef MAKI_DETAIL_ARG_run_to_completion
207 }
208
210
213 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE process_event_now_enabled(const bool value) const
214 {
215 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
216#define MAKI_DETAIL_ARG_process_event_now_enabled value
217 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
218#undef MAKI_DETAIL_ARG_process_event_now_enabled
219 }
220
232 @code
233 .catch_mx([](auto& mach, const std::exception_ptr& eptr)
234 {
235 //...
236 })
237 @endcode
238
239 If this action isn't set, `maki::machine` doesn't catch any exception.
240 */
241 template<class Callable>
242 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE catch_mx(const Callable& callable) const
243 {
244 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
245#define MAKI_DETAIL_ARG_exception_handler callable
246 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
247#undef MAKI_DETAIL_ARG_exception_handler
248 }
249
273 //...
274 })
275 .post_processing_hook_mep<some_other_event_type>([](auto& mach, const some_other_event_type& event, const bool processed)
276 {
277 //...
278 })
279 ;
280 @endcode
281 */
282 template<class EventSetImpl, class Action>
283 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE post_processing_hook_mep(const event_set<EventSetImpl>& /*event_types*/, const Action& action) const
284 {
285 const auto new_post_processing_hooks = append
286 (
287 impl_.post_processing_hooks,
288 detail::make_event_action<action_signature::me, EventSetImpl>(action)
289 );
290
291 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
292#define MAKI_DETAIL_ARG_post_processing_hooks new_post_processing_hooks
293 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
294#undef MAKI_DETAIL_ARG_post_processing_hooks
295 }
296
320 //...
321 })
322 .post_processing_hook_mep<some_other_event_type>([](auto& mach, const some_other_event_type& event, const bool processed)
323 {
324 //...
325 })
326 ;
327 @endcode
328 */
329 template<class Event, class Action>
330 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE post_processing_hook_mep(const Action& action) const
331 {
332 return post_processing_hook_mep(event_set{event<Event>}, action);
333 }
334
337
340 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE small_event_max_align(const std::size_t value) const
341 {
342 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
343#define MAKI_DETAIL_ARG_small_event_max_align value
344 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
345#undef MAKI_DETAIL_ARG_small_event_max_align
346 }
347
350
353 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE small_event_max_size(const std::size_t value) const
354 {
355 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
356#define MAKI_DETAIL_ARG_small_event_max_size value
357 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
358#undef MAKI_DETAIL_ARG_small_event_max_size
359 }
360
361
367 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE thread_safe(const bool /*enabled*/) const
368 {
369 return *this;
370 }
371
375
376 template<class... TransitionTables>
377 [[nodiscard]] constexpr MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE transition_tables(const TransitionTables&... tables) const
378 {
379 const auto tpl = detail::tuple<TransitionTables...>{tables...};
380 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
381#define MAKI_DETAIL_ARG_transition_tables tpl
382 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
383#undef MAKI_DETAIL_ARG_transition_tables
384 }
385
386private:
387 MAKI_DETAIL_FRIENDLY_IMPL
388
389 using impl_type = Impl;
390
391 template<class Impl2>
392 friend class machine_conf;
393
394 template<class... Args>
395 constexpr machine_conf(Args&&... args):
396 impl_{std::forward<Args>(args)...}
397 {
398 }
399
400 template<class Context2, auto ContextSig>
401 [[nodiscard]] constexpr auto context() const
402 {
403 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
404#define MAKI_DETAIL_ARG_context_type detail::type<Context2>
405#define MAKI_DETAIL_ARG_context_sig ContextSig
406 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
407#undef MAKI_DETAIL_ARG_context_type
408#undef MAKI_DETAIL_ARG_context_sig
409 }
410
411 template<class EventTypeSet, action_signature Sig, class Hook>
412 [[nodiscard]] constexpr auto pre_processing_hook(const Hook& hook) const
413 {
414 const auto new_pre_processing_hooks = append
415 (
416 impl_.pre_processing_hooks,
417 detail::make_event_action<Sig, EventTypeSet>(hook)
418 );
419
420 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
421#define MAKI_DETAIL_ARG_pre_processing_hooks new_pre_processing_hooks
422 MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
423#undef MAKI_DETAIL_ARG_pre_processing_hooks
424 }
425
426#undef MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_END
427#undef MAKI_DETAIL_MAKE_MACHINE_CONF_COPY_BEGIN
428
429 impl_type impl_;
430};
431
432#undef MAKI_DETAIL_MACHINE_CONF_RETURN_TYPE
433
434#ifdef MAKI_DETAIL_DOXYGEN
436#else
438#endif
439
440namespace detail
441{
442 template<class T>
443 struct is_machine_conf
444 {
445 static constexpr auto value = false;
446 };
447
448 template<class... Options>
449 struct is_machine_conf<machine_conf<Options...>>
450 {
451 static constexpr auto value = true;
452 };
453
454 template<class T>
455 constexpr auto is_machine_conf_v = is_machine_conf<T>::value;
456}
457
458} //namespace
459
460#endif
Represents an event type set.
Definition event_set.hpp:35
maki::machine configuration
Definition machine_conf.hpp:43
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:203
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:367
constexpr machine_conf< IMPLEMENTATION_DETAIL > post_external_transition_hook_crste(const Hook &hook) const
Specifies a hook to be called after any external transition.
Definition machine_conf.hpp:142
constexpr machine_conf< IMPLEMENTATION_DETAIL > run_to_completion(const bool value) const
Specifies whether run-to-completion is enabled.
Definition machine_conf.hpp:191
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:232
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:154
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:343
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:330
constexpr machine_conf< IMPLEMENTATION_DETAIL > post_processing_hook_mep(const event_set< EventSetImpl > &, const Action &action) const
Adds a hook to be called whenever maki::machine is done processing an event whose type is part of eve...
Definition machine_conf.hpp:273
constexpr machine_conf< IMPLEMENTATION_DETAIL > pre_external_transition_hook_crste(const Hook &hook) const
Specifies a hook to be called before any external transition.
Definition machine_conf.hpp:174
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:357
The Maki library.
Represents an action to be given to maki::transition_table.
Definition action.hpp:60