123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- // SPDX-License-Identifier: MIT
- // SPDX-FileCopyrightText: 2022 Ivan Baidakou
- #pragma once
- #include "actor.hpp"
- #include "message.hpp"
- #include "queue.hpp"
- #include <tuple>
- #include <type_traits>
- #include <utility>
- namespace rotor_light {
- struct QueueBase;
- struct PlannerBase;
- namespace details {
- struct ChildState {
- State down_state = State::off;
- };
- } // namespace details
- struct SupervisorBase : ActorBase {
- static constexpr size_t min_handlers_amount =
- ActorBase::min_handlers_amount + 2;
- friend struct ActorBase;
- using Parent = ActorBase;
- SupervisorBase(char *backends, size_t backends_count, ActorBase **actors,
- details::ChildState *states, size_t actors_count);
- inline QueueBase *get_queue() { return queue; }
- void initialize() override;
- void start(bool poll_timer = false);
- virtual void bind(Context &context, ActorId value = 0);
- uint8_t bind(ActorId initial_value, SupervisorBase *supervisor,
- Context &context) override;
- void process();
- void dispatch(Message &, MessageTypeId message_type_id);
- // handlers
- void advance_init() override;
- void advance_start() override;
- void advance_stop() override;
- inline PlannerBase *get_planner() { return planner; }
- protected:
- void on_state_change_ack(message::ChangeStateAck &);
- void on_child_init_failure(size_t actor_index);
- virtual void on_refhesh_timer(message::RefreshTime &);
- void on_child_down(size_t actor_index);
- void init_child(size_t actor_index);
- void start_actor(size_t actor_index);
- size_t process_watchdog();
- bool check_child_state(State subject, bool skip_self);
- ActorBase **actors;
- details::ChildState *states;
- size_t actors_count;
- QueueBase *queue;
- PlannerBase *planner;
- NowFunction now;
- };
- template <size_t HandlersCount, typename... Actors>
- struct Supervisor : SupervisorBase {
- static_assert(HandlersCount >= SupervisorBase::min_handlers_amount,
- "no enough handlers");
- Supervisor()
- : SupervisorBase(reinterpret_cast<char *>(&backends), HandlersCount,
- actors, children_states_holder, children_count + 1) {
- actors[0] = this;
- fill_actor<0>();
- }
- template <size_t ChildIndex> auto get_child() {
- return &std::get<ChildIndex>(children);
- }
- protected:
- template <size_t ChildIndex> void fill_actor() {
- if constexpr (ChildIndex < children_count) {
- actors[ChildIndex + 1] = get_child<ChildIndex>();
- fill_actor<ChildIndex + 1>();
- }
- }
- using ActorsList = std::tuple<Actors...>;
- static constexpr size_t children_count = std::tuple_size_v<ActorsList>;
- ActorsList children;
- ActorBase::Storage backends[HandlersCount];
- ActorBase *actors[children_count + 1];
- details::ChildState children_states_holder[children_count + 1];
- };
- template <typename MessageType, typename... Args>
- bool ActorBase::send(size_t queue_index, Args... args) {
- auto &queue = supervisor->queue;
- return queue->put<MessageType>(queue_index, std::forward<Args>(args)...);
- }
- } // namespace rotor_light
|