actor.hpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // SPDX-License-Identifier: MIT
  2. // SPDX-FileCopyrightText: 2022 Ivan Baidakou
  3. #pragma once
  4. #include "context.hpp"
  5. #include "definitions.hpp"
  6. #include "handler.hpp"
  7. #include "messages.hpp"
  8. #include <cassert>
  9. namespace rotor_light {
  10. struct SupervisorBase;
  11. struct QueueBase;
  12. struct ActorBase {
  13. using Backend = Handler<void (ActorBase::*)(Message &)>;
  14. using Storage = std::aligned_storage_t<sizeof(ActorBase::Backend),
  15. alignof(ActorBase::Backend)>;
  16. static constexpr auto backend_size = sizeof(Backend);
  17. static constexpr size_t min_handlers_amount = 1;
  18. ActorBase(char *backends, size_t backends_count);
  19. ActorBase(const ActorBase &) = delete;
  20. ActorBase(ActorBase &&) = delete;
  21. virtual void initialize();
  22. virtual uint8_t bind(ActorId initial_value, SupervisorBase *supervisor,
  23. Context &context);
  24. inline ActorId get_id() const { return id; }
  25. inline State get_state() const { return state; }
  26. inline FailPolicy get_fail_policy() const { return fail_policy; }
  27. inline void set_fail_policy(FailPolicy value) { fail_policy = value; }
  28. void stop();
  29. bool add_event(Duration delta, Callback callback, void *data);
  30. template <typename MessageType, typename... Args>
  31. bool send(size_t queue_index, Args... args);
  32. template <typename Method> void subscribe(Method method) {
  33. using MethodHandler = Handler<Method>;
  34. static_assert(std::is_trivially_destructible_v<MethodHandler>,
  35. "trivial destructor");
  36. assert(state == State::off);
  37. assert(backend_idx < (int)backends_count);
  38. auto ptr = backends_ptr + ++backend_idx * sizeof(Backend);
  39. new (ptr) MethodHandler(method);
  40. }
  41. protected:
  42. friend struct SupervisorBase;
  43. void on_state_change(message::ChangeState &);
  44. virtual void advance_init();
  45. virtual void advance_start();
  46. virtual void advance_stop();
  47. ActorId id;
  48. ActorId mask;
  49. State state = State::off;
  50. SupervisorBase *supervisor;
  51. char *backends_ptr;
  52. size_t backends_count;
  53. int backend_idx;
  54. FailPolicy fail_policy;
  55. };
  56. template <size_t HandlersCount> struct Actor : ActorBase {
  57. static_assert(HandlersCount >= Actor::min_handlers_amount,
  58. "no enough handlers");
  59. Actor() : ActorBase(reinterpret_cast<char *>(&backends), HandlersCount) {}
  60. ActorBase::Storage backends[HandlersCount];
  61. };
  62. } // namespace rotor_light