123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- #pragma once
- #include "context.hpp"
- #include "definitions.hpp"
- #include "messages.hpp"
- #include <cassert>
- namespace rotor_light {
- struct SupervisorBase;
- struct QueueBase;
- struct ActorBase {
-
- using GenericMethod = void (ActorBase::*)(Message &);
-
- template <typename T> struct handler_traits {};
- template <typename A, typename M> struct handler_traits<void (A::*)(M &)> {
-
- using FinalMessage = M;
-
- using Backend = A;
- };
- struct Handler;
-
- using MethodEntry = void (*)(Message &, ActorBase &, Handler &);
-
- struct Handler {
-
- GenericMethod method;
-
- MethodEntry entry;
-
- MessageTypeId message_id;
- };
-
- static constexpr size_t min_handlers_amount = 1;
- ActorBase(const ActorBase &) = delete;
- ActorBase(ActorBase &&) = delete;
-
- virtual void initialize();
-
- virtual uint8_t bind(ActorId initial_value, SupervisorBase *supervisor,
- Context &context);
-
- inline ActorId get_id() const { return id; }
-
- inline State get_state() const { return state; }
-
- inline FailPolicy get_fail_policy() const { return fail_policy; }
-
- inline void set_fail_policy(FailPolicy value) { fail_policy = value; }
-
- void stop();
-
- template <typename Ctx>
- EventId add_event(Duration delta, Callback callback, void *data);
-
- void cancel_event(EventId event_id);
-
- template <typename Ctx, typename MessageType, typename... Args>
- bool send(size_t queue_index, Args &&...args) {
- return send_impl<Ctx, MessageType, false>(queue_index,
- std::forward<Args>(args)...);
- }
-
- template <typename Ctx, typename MessageType, typename... Args>
- bool transmit(size_t queue_index, Args &&...args) {
- return send_impl<Ctx, MessageType, true>(queue_index,
- std::forward<Args>(args)...);
- }
-
- template <typename Method> void subscribe(Method method) {
- assert(state == State::off);
- assert(backend_idx < (int)backends_count);
- auto ptr = backends_ptr + ++backend_idx * sizeof(Handler);
- make_handler(method, *reinterpret_cast<Handler *>(ptr));
- }
- protected:
-
- ActorBase(char *backends, size_t backends_count);
-
- virtual void advance_init();
-
- virtual void advance_start();
-
- virtual void advance_stop();
-
- ActorId id;
-
- ActorId mask;
-
- State state = State::off;
-
- SupervisorBase *supervisor;
-
- FailPolicy fail_policy;
- private:
- template <typename Ctx, typename MessageType, bool force, typename... Args>
- bool send_impl(size_t queue_index, Args &&...args);
- void on_state_change(message::ChangeState &);
- template <typename Method>
- void make_handler(Method &method, Handler &handler) {
- using traits = handler_traits<Method>;
- using FinalMessage = typename traits::FinalMessage;
- using Backend = typename traits::Backend;
- handler.message_id = FinalMessage::type_id;
- handler.entry = [](Message &message, ActorBase &actor, Handler &handler) {
- auto &final_message = static_cast<FinalMessage &>(message);
- auto &backend = static_cast<Backend &>(actor);
- auto method = handler.method;
- (backend.*reinterpret_cast<Method &>(method))(final_message);
- };
- handler.method = reinterpret_cast<GenericMethod &>(method);
- }
- char *backends_ptr;
- size_t backends_count;
- int backend_idx;
- friend struct SupervisorBase;
- };
- template <size_t HandlersCount> struct Actor : ActorBase {
- static_assert(HandlersCount >= Actor::min_handlers_amount,
- "no enough handlers");
- Actor() : ActorBase(reinterpret_cast<char *>(&backends), HandlersCount) {}
-
- ActorBase::Handler backends[HandlersCount];
- };
- }
|