supervisor.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // SPDX-License-Identifier: MIT
  2. // SPDX-FileCopyrightText: 2022 Ivan Baidakou
  3. #pragma once
  4. #include "actor.hpp"
  5. #include "message.hpp"
  6. #include "queue.hpp"
  7. #include <tuple>
  8. #include <type_traits>
  9. #include <utility>
  10. namespace rotor_light {
  11. struct QueueBase;
  12. struct PlannerBase;
  13. namespace details {
  14. struct ChildState {
  15. State down_state = State::off;
  16. };
  17. } // namespace details
  18. struct SupervisorBase : ActorBase {
  19. static constexpr size_t min_handlers_amount =
  20. ActorBase::min_handlers_amount + 2;
  21. friend struct ActorBase;
  22. using Parent = ActorBase;
  23. SupervisorBase(char *backends, size_t backends_count, ActorBase **actors,
  24. details::ChildState *states, size_t actors_count);
  25. inline QueueBase *get_queue() { return queue; }
  26. void initialize() override;
  27. void start(bool poll_timer = false);
  28. virtual void bind(Context &context, ActorId value = 0);
  29. uint8_t bind(ActorId initial_value, SupervisorBase *supervisor,
  30. Context &context) override;
  31. void process();
  32. void dispatch(Message &, MessageTypeId message_type_id);
  33. // handlers
  34. void advance_init() override;
  35. void advance_start() override;
  36. void advance_stop() override;
  37. inline PlannerBase *get_planner() { return planner; }
  38. protected:
  39. void on_state_change_ack(message::ChangeStateAck &);
  40. void on_child_init_failure(size_t actor_index);
  41. virtual void on_refhesh_timer(message::RefreshTime &);
  42. void on_child_down(size_t actor_index);
  43. void init_child(size_t actor_index);
  44. void start_actor(size_t actor_index);
  45. size_t process_watchdog();
  46. bool check_child_state(State subject, bool skip_self);
  47. ActorBase **actors;
  48. details::ChildState *states;
  49. size_t actors_count;
  50. QueueBase *queue;
  51. PlannerBase *planner;
  52. NowFunction now;
  53. };
  54. template <size_t HandlersCount, typename... Actors>
  55. struct Supervisor : SupervisorBase {
  56. static_assert(HandlersCount >= SupervisorBase::min_handlers_amount,
  57. "no enough handlers");
  58. Supervisor()
  59. : SupervisorBase(reinterpret_cast<char *>(&backends), HandlersCount,
  60. actors, children_states_holder, children_count + 1) {
  61. actors[0] = this;
  62. fill_actor<0>();
  63. }
  64. template <size_t ChildIndex> auto get_child() {
  65. return &std::get<ChildIndex>(children);
  66. }
  67. protected:
  68. template <size_t ChildIndex> void fill_actor() {
  69. if constexpr (ChildIndex < children_count) {
  70. actors[ChildIndex + 1] = get_child<ChildIndex>();
  71. fill_actor<ChildIndex + 1>();
  72. }
  73. }
  74. using ActorsList = std::tuple<Actors...>;
  75. static constexpr size_t children_count = std::tuple_size_v<ActorsList>;
  76. ActorsList children;
  77. ActorBase::Storage backends[HandlersCount];
  78. ActorBase *actors[children_count + 1];
  79. details::ChildState children_states_holder[children_count + 1];
  80. };
  81. template <typename MessageType, typename... Args>
  82. bool ActorBase::send(size_t queue_index, Args... args) {
  83. auto &queue = supervisor->queue;
  84. return queue->put<MessageType>(queue_index, std::forward<Args>(args)...);
  85. }
  86. } // namespace rotor_light