subscription_point.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #pragma once
  2. //
  3. // Copyright (c) 2019-2025 Ivan Baidakou (basiliscos) (the dot dmol at gmail dot com)
  4. //
  5. // Distributed under the MIT Software License
  6. //
  7. #include "rotor/forward.hpp"
  8. #include "rotor/address.hpp"
  9. #include <list>
  10. #if defined(_MSC_VER)
  11. #pragma warning(push)
  12. #pragma warning(disable : 4251)
  13. #endif
  14. namespace rotor {
  15. struct actor_base_t;
  16. namespace tags {
  17. ROTOR_API extern const void *io;
  18. }
  19. /** \brief who owns the subscription point
  20. *
  21. * - plugin (i.e. subscription was invoked from plugin)
  22. *
  23. * - supervisor (temporally instantiated subscription for request/response handling)
  24. *
  25. * - foreign (when it is subscribed for foreign address)
  26. *
  27. * - anonymous (subscription point was created from actor)
  28. *
  29. */
  30. enum class owner_tag_t {
  31. ANONYMOUS,
  32. PLUGIN,
  33. SUPERVISOR,
  34. FOREIGN,
  35. };
  36. /** \struct subscription_point_t
  37. * \brief pair of {@link handler_base_t} linked to particular {@link address_t}
  38. */
  39. struct ROTOR_API subscription_point_t {
  40. /** \brief intrusive pointer to messages' handler */
  41. handler_ptr_t handler;
  42. /** \brief intrusive pointer to address */
  43. address_ptr_t address;
  44. /** \brief non-owning pointer to an actor, which performs subscription */
  45. const actor_base_t *owner_ptr;
  46. /** \brief kind of ownership of the subscription point */
  47. owner_tag_t owner_tag;
  48. /** \brief ctor from handler and related address (used for comparison) */
  49. subscription_point_t(const handler_ptr_t &handler_, const address_ptr_t &address_) noexcept
  50. : handler{handler_}, address{address_}, owner_ptr{nullptr}, owner_tag{owner_tag_t::ANONYMOUS} {}
  51. /** \brief full ctor (handler, address, actor, and owner tag) */
  52. subscription_point_t(const handler_ptr_t &handler_, const address_ptr_t &address_, const actor_base_t *owner_ptr_,
  53. owner_tag_t owner_tag_) noexcept
  54. : handler{handler_}, address{address_}, owner_ptr{owner_ptr_}, owner_tag{owner_tag_} {}
  55. /** \brief copy-ctor */
  56. subscription_point_t(const subscription_point_t &) = default;
  57. /** \brief move-ctor */
  58. subscription_point_t(subscription_point_t &&) = default;
  59. /** \brief partial comparison by handler and address */
  60. bool operator==(const subscription_point_t &other) const;
  61. };
  62. /** \struct subscription_info_t
  63. * \brief {@link subscription_point_t} with extended information (e.g. state)
  64. */
  65. struct ROTOR_API subscription_info_t : public arc_base_t<subscription_info_t>, subscription_point_t {
  66. /** \brief subscription info state (subscribing, established, unsubscribing */
  67. enum state_t { SUBSCRIBING, ESTABLISHED, UNSUBSCRIBING };
  68. /** \brief ctor from subscription point, internal address and internal handler and state */
  69. subscription_info_t(const subscription_point_t &point, bool internal_address_, bool internal_handler_,
  70. state_t state_) noexcept
  71. : subscription_point_t{point}, internal_address{internal_address_}, internal_handler{internal_handler_},
  72. state{state_} {}
  73. /** \brief marks handler for blocking operations
  74. *
  75. * It is suitable for thread backend.
  76. *
  77. */
  78. inline void tag_io() noexcept { tag(tags::io); }
  79. /** \brief generic non-public fields accessor */
  80. template <typename T> auto &access() noexcept;
  81. /** \brief generic non-public methods accessor */
  82. template <typename T, typename... Args> auto access(Args... args) noexcept;
  83. private:
  84. void tag(const void *t) noexcept;
  85. /** \brief whether the subscription point (info) belongs to internal address, i.e. to the "my" supervisor */
  86. bool internal_address;
  87. /** \brief whether the subscription point (info) has internal handler, i.e. will be processed by "my" supervisor */
  88. bool internal_handler;
  89. /** \brief subscription state */
  90. state_t state;
  91. };
  92. /** \brief intrusive pointer for {@link subscription_info_t} */
  93. using subscription_info_ptr_t = intrusive_ptr_t<subscription_info_t>;
  94. /** \struct subscription_container_t
  95. * \brief list of {@link subscription_info_ptr_t} with possibility to find via {@link subscription_point_t}
  96. */
  97. struct ROTOR_API subscription_container_t : public std::list<subscription_info_ptr_t> {
  98. /** \brief looks up for the subscription info pointer (returned as iterator) via the subscription point */
  99. iterator find(const subscription_point_t &point) noexcept;
  100. };
  101. } // namespace rotor
  102. #if defined(_MSC_VER)
  103. #pragma warning(pop)
  104. #endif