handler.hpp 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. // SPDX-License-Identifier: MIT
  2. // SPDX-FileCopyrightText: 2022 Ivan Baidakou
  3. #pragma once
  4. #include "message.hpp"
  5. #include <type_traits>
  6. namespace rotor_light {
  7. struct ActorBase;
  8. namespace details {
  9. template <typename T> struct handler_traits {};
  10. template <typename A, typename M> struct handler_traits<void (A::*)(M &)> {
  11. using FinalMessage = M;
  12. using Backend = A;
  13. };
  14. } // namespace details
  15. struct HandlerBase {
  16. inline HandlerBase() : message_id{0} {}
  17. inline HandlerBase(MessageTypeId message_id_) : message_id{message_id_} {}
  18. HandlerBase(HandlerBase &) = delete;
  19. HandlerBase(HandlerBase &&) = delete;
  20. virtual void call(Message &, ActorBase &actor) = 0;
  21. MessageTypeId message_id;
  22. };
  23. static_assert(std::is_trivially_destructible_v<HandlerBase>,
  24. "trivial destructor");
  25. template <typename Method> struct Handler : HandlerBase {
  26. using traits = details::handler_traits<Method>;
  27. using FinalMessage = typename traits::FinalMessage;
  28. using Backend = typename traits::Backend;
  29. static_assert(std::is_trivially_destructible_v<FinalMessage>,
  30. "message should be trivially destructible");
  31. Handler() : HandlerBase(FinalMessage::type_id), method{nullptr} {}
  32. Handler(Method &method_)
  33. : HandlerBase(FinalMessage::type_id), method{method_} {}
  34. void call(Message &message, ActorBase &actor) override {
  35. auto &final_message = static_cast<FinalMessage &>(message);
  36. auto &backend = static_cast<Backend &>(actor);
  37. (backend.*method)(final_message);
  38. };
  39. Method method;
  40. };
  41. } // namespace rotor_light