20#pragma warning(disable : 4251)
65 static auto const constexpr has_noexcept =
66 noexcept((std::declval<A>().*std::declval<pointer_t>())(std::declval<M &>()));
67 static_assert(has_noexcept,
"message handler should have 'noexcept' specification");
73template <
typename A,
typename M>
struct handler_traits<void (A::*)(M &) noexcept> {
76 static auto const constexpr has_valid_message = std::is_base_of_v<message_base_t, M>;
79 static auto const constexpr is_actor = std::is_base_of_v<actor_base_t, A>;
82 static auto const constexpr is_plugin = std::is_base_of_v<plugin::plugin_base_t, A>;
85 static auto const constexpr is_lambda =
false;
95 static_assert(is_actor || is_plugin,
"message handler should be either actor or plugin");
101 static auto const constexpr has_valid_message = std::is_base_of_v<message_base_t, M>;
103 static_assert(has_valid_message,
"lambda does not process valid message");
106 static auto const constexpr is_actor =
false;
109 static auto const constexpr is_plugin =
false;
112 static auto const constexpr is_lambda =
true;
138 return handler_type == rhs.handler_type && actor_ptr == rhs.actor_ptr;
202template <
typename Handler>
203inline constexpr bool is_actor_handler_v =
209template <
typename Handler>
210inline constexpr bool is_plugin_handler_v =
222template <>
inline auto &plugin::plugin_base_t::access<details::to::actor>() noexcept {
return actor; }
224template <
typename Handler,
typename Enable =
void>
struct handler_t;
230template <
typename Handler>
244 if (message->type_index == final_message_t::message_type) {
245 auto final_message =
static_cast<final_message_t *
>(message.get());
246 auto &final_obj =
static_cast<backend_t &
>(*actor_ptr);
247 (final_obj.*handler)(*final_message);
252 return message->type_index == final_message_t::message_type;
256 auto final_message =
static_cast<final_message_t *
>(message.get());
257 auto &final_obj =
static_cast<backend_t &
>(*actor_ptr);
258 (final_obj.*handler)(*final_message);
261 const void *
message_type() const noexcept
override {
return final_message_t::message_type; }
265 using backend_t =
typename traits::backend_t;
266 using final_message_t =
typename traits::message_t;
269template <
typename Handler>
270const void *handler_t<Handler, std::enable_if_t<details::is_actor_handler_v<Handler>>>::handler_type =
271 static_cast<const void *
>(
typeid(Handler).name());
276template <
typename Handler>
289 :
handler_base_t{*plugin_.access<details::to::actor>(), handler_type}, plugin{plugin_}, handler{handler_} {}
292 if (message->type_index == final_message_t::message_type) {
293 auto final_message =
static_cast<final_message_t *
>(message.get());
294 auto &final_obj =
static_cast<backend_t &
>(plugin);
295 (final_obj.*handler)(*final_message);
300 return message->type_index == final_message_t::message_type;
304 auto final_message =
static_cast<final_message_t *
>(message.get());
305 auto &final_obj =
static_cast<backend_t &
>(plugin);
306 (final_obj.*handler)(*final_message);
309 const void *
message_type() const noexcept
override {
return final_message_t::message_type; }
313 using backend_t =
typename traits::backend_t;
314 using final_message_t =
typename traits::message_t;
317template <
typename Handler>
318const void *handler_t<Handler, std::enable_if_t<details::is_plugin_handler_v<Handler>>>::handler_type =
319 static_cast<const void *
>(
typeid(Handler).name());
324template <
typename Handler,
typename M>
326 std::enable_if_t<details::is_lambda_handler_v<lambda_holder_t<Handler, M>>>>
342 if (message->type_index == final_message_t::message_type) {
343 auto final_message =
static_cast<final_message_t *
>(message.get());
344 handler.
fn(*final_message);
349 return message->type_index == final_message_t::message_type;
353 auto final_message =
static_cast<final_message_t *
>(message.get());
354 handler.
fn(*final_message);
357 const void *
message_type() const noexcept
override {
return final_message_t::message_type; }
360 using final_message_t =
typename handler_backend_t::message_t;
363template <
typename Handler,
typename M>
364const void *handler_t<lambda_holder_t<Handler, M>,
365 std::enable_if_t<details::is_lambda_handler_v<lambda_holder_t<Handler, M>>>>::handler_type =
366 static_cast<const void *
>(
typeid(Handler).name());
377 size_t operator()(
const rotor::handler_ptr_t &handler)
const noexcept {
return handler->precalc_hash; }
Basic namespace for all rotor functionalities.
Definition rotor.hpp:21
intrusive_ptr_t< message_base_t > message_ptr_t
intrusive pointer for message
Definition message.h:118
constexpr lambda_holder_t< M, F > lambda(F &&fn)
helper function for lambda holder constructing
Definition handler.h:48
boost::intrusive_ref_counter< T, counter_policy_t > arc_base_t
base class to inject ref-counter with the specified policy
Definition arc.hpp:24
intrusive_ptr_t< handler_base_t > handler_ptr_t
intrusive pointer for handler
Definition forward.hpp:26
universal primitive of concurrent computation
Definition actor_base.h:47
continue handler invocation (used for intercepting)
Definition handler.h:175
virtual void operator()() const noexcept=0
continue handler invocation
Base class for rotor handler, i.e concrete message type processing point on concrete actor.
Definition handler.h:121
virtual handler_ptr_t upgrade(const void *tag) noexcept
"upgrades" handler by tagging it
size_t precalc_hash
precalculated hash for the handler
Definition handler.h:129
handler_base_t(actor_base_t &actor, const void *handler_type_) noexcept
constructs handler_base_t from raw pointer to actor, raw pointer to message type and raw pointer to h...
virtual void call_no_check(message_ptr_t &) noexcept=0
unconditionally invokes the handler for the message
virtual const void * message_type() const noexcept=0
unique per-message-type pointer used for routing
bool operator==(const handler_base_t &rhs) const noexcept
compare two handler for equality
Definition handler.h:137
actor_base_t * actor_ptr
non-null pointer to actor_base_t the actor of the handler,
Definition handler.h:126
const void * handler_type
pointer to unique handler type ( typeid(Handler).name() )
Definition handler.h:123
virtual void call(message_ptr_t &) noexcept=0
attempt to delivery message to the handler
virtual bool select(message_ptr_t &) noexcept=0
returns true if the message can be handled by the handler
proxies call to the original hanlder, applying tag-specific actions
Definition handler.h:185
void call_no_check(message_ptr_t &message) noexcept override
unconditionally invokes the handler for the message
bool select(message_ptr_t &message) noexcept override
returns true if the message can be handled by the handler
handler_intercepted_t(handler_ptr_t backend_, const void *tag_) noexcept
constructs handler_intercepted_t by proxying original hander
handler_ptr_t upgrade(const void *tag) noexcept override
"upgrades" handler by tagging it
void call(message_ptr_t &) noexcept override
attempt to delivery message to the handler
const void * message_type() const noexcept override
unique per-message-type pointer used for routing
static const void * handler_type
static pointer to unique pointer-to-member function name ( typeid(Handler).name() )
Definition handler.h:234
void call_no_check(message_ptr_t &message) noexcept override
unconditionally invokes the handler for the message
Definition handler.h:255
const void * message_type() const noexcept override
unique per-message-type pointer used for routing
Definition handler.h:261
handler_t(actor_base_t &actor, Handler &&handler_)
constructs handler from actor & pointer-to-member function
Definition handler.h:240
Handler handler
pointer-to-member function instance
Definition handler.h:237
bool select(message_ptr_t &message) noexcept override
returns true if the message can be handled by the handler
Definition handler.h:251
void call(message_ptr_t &message) noexcept override
attempt to delivery message to the handler
Definition handler.h:243
void call(message_ptr_t &message) noexcept override
attempt to delivery message to the handler
Definition handler.h:291
void call_no_check(message_ptr_t &message) noexcept override
unconditionally invokes the handler for the message
Definition handler.h:303
const void * message_type() const noexcept override
unique per-message-type pointer used for routing
Definition handler.h:309
plugin::plugin_base_t & plugin
source plugin for handler
Definition handler.h:282
bool select(message_ptr_t &message) noexcept override
returns true if the message can be handled by the handler
Definition handler.h:299
handler_t(plugin::plugin_base_t &plugin_, Handler &&handler_)
ctor form plugin and plugin handler (pointer-to-member function of the plugin)
Definition handler.h:288
Handler handler
handler itself
Definition handler.h:285
static const void * handler_type
typeid of Handler
Definition handler.h:279
static const void * handler_type
static pointer to unique pointer-to-member function name ( typeid(Handler).name() )
Definition handler.h:335
handler_backend_t handler
actually lambda function for message processing
Definition handler.h:332
bool select(message_ptr_t &message) noexcept override
returns true if the message can be handled by the handler
Definition handler.h:348
handler_t(actor_base_t &actor, handler_backend_t &&handler_)
constructs handler from actor & lambda wrapper
Definition handler.h:338
void call(message_ptr_t &message) noexcept override
attempt to delivery message to the handler
Definition handler.h:341
void call_no_check(message_ptr_t &message) noexcept override
unconditionally invokes the handler for the message
Definition handler.h:352
const void * message_type() const noexcept override
unique per-message-type pointer used for routing
Definition handler.h:357
M message_t
message type, processed by the handler
Definition handler.h:88
typename M::payload_t payload_t
alias for message type payload
Definition handler.h:91
A backend_t
alias for Actor or Plugin class
Definition handler.h:94
void(A::*)(M &) pointer_t
an alias for handler signature
Definition handler.h:62
Helper class to extract final actor class and message type from pointer-to-member function.
Definition handler.h:55
Helper struct which holds lambda function for processing particular message types.
Definition handler.h:33
typename M::payload_t payload_t
alias type for message payload
Definition handler.h:44
M message_t
alias type for message type for lambda
Definition handler.h:41
lambda_holder_t(F &&fn_)
constructs lambda by forwarding arguments
Definition handler.h:38
F fn
lambda function itself
Definition handler.h:35
base class for all actor plugins
Definition plugin_base.h:23