subscription_point.h 4.6 KB

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