1 /*
2 * SObjectizer-5
3 */
4
5 /*!
6 * \since
7 * v.5.5.3
8 *
9 * \file
10 * \brief An interface of subscription storage.
11 */
12
13 #pragma once
14
15 #include <ostream>
16 #include <sstream>
17 #include <vector>
18
19 #include <so_5/types.hpp>
20
21 #include <so_5/mbox.hpp>
22 #include <so_5/state.hpp>
23 #include <so_5/execution_demand.hpp>
24 #include <so_5/subscription_storage_fwd.hpp>
25
26 namespace so_5
27 {
28
29 namespace impl
30 {
31
32 //
33 // event_handler_data_t
34 //
35 /*!
36 * \since
37 * v.5.4.0
38 *
39 * \brief Information about event_handler and its properties.
40 */
41 struct event_handler_data_t
42 {
43 //! Method for handling event.
44 event_handler_method_t m_method;
45 //! Is event handler thread safe or not.
46 thread_safety_t m_thread_safety;
47 //! Kind of this event handler.
48 /*!
49 * \since
50 * v.5.7.0
51 */
52 event_handler_kind_t m_kind;
53
event_handler_data_tso_5::impl::event_handler_data_t54 event_handler_data_t(
55 event_handler_method_t method,
56 thread_safety_t thread_safety,
57 event_handler_kind_t kind )
58 : m_method( std::move( method ) )
59 , m_thread_safety( thread_safety )
60 , m_kind( kind )
61 {}
62 };
63
64 /*!
65 * \since
66 * v.5.5.3
67 *
68 * \brief Common stuff for various subscription storage implementations.
69 */
70 namespace subscription_storage_common
71 {
72
73 /*!
74 * \since
75 * v.5.5.3
76 *
77 * \brief An information about one subscription.
78 */
79 struct subscr_info_t
80 {
81 //! Reference to mbox.
82 /*!
83 * Reference must be stored because we must have
84 * access to mbox during destroyment of all
85 * subscriptions in destructor.
86 */
87 mbox_t m_mbox;
88 std::type_index m_msg_type;
89 const state_t * m_state;
90 event_handler_data_t m_handler;
91
subscr_info_tso_5::impl::subscription_storage_common::subscr_info_t92 subscr_info_t(
93 mbox_t mbox,
94 std::type_index msg_type,
95 const state_t & state,
96 const event_handler_method_t & method,
97 thread_safety_t thread_safety,
98 event_handler_kind_t handler_kind )
99 : m_mbox( std::move( mbox ) )
100 , m_msg_type( std::move( msg_type ) )
101 , m_state( &state )
102 , m_handler( method, thread_safety, handler_kind )
103 {}
104 };
105
106 /*!
107 * \since
108 * v.5.5.3
109 *
110 * \brief Type of vector with subscription information.
111 */
112 using subscr_info_vector_t = std::vector< subscr_info_t >;
113
114 /*!
115 * \since
116 * v.5.5.3
117 *
118 * \brief A helper function for creating subscription description.
119 */
120 inline std::string
make_subscription_description(const mbox_t & mbox_ref,std::type_index msg_type,const state_t & state)121 make_subscription_description(
122 const mbox_t & mbox_ref,
123 std::type_index msg_type,
124 const state_t & state )
125 {
126 std::ostringstream s;
127 s << "(mbox:'" << mbox_ref->query_name()
128 << "', msg_type:'" << msg_type.name() << "', state:'"
129 << state.query_name() << "')";
130
131 return s.str();
132 }
133
134 } /* namespace subscription_storage_common */
135
136 /*!
137 * \since
138 * v.5.5.3
139 *
140 * \brief An interface of subscription storage
141 *
142 * Prior to v.5.5.3 there where only one subscription_storage implementation.
143 * But this implementation was not efficient for all cases.
144 *
145 * Sometimes an agent has very few subscriptions and efficient
146 * implementation for that case can be based on std::vector.
147 * Sometimes an agent has very many subscriptions and efficient
148 * implementation can require std::map or std::unordered_map.
149 *
150 * The purpose of this interface is hiding details of concrete
151 * subscription_storage implementation.
152 */
153 class subscription_storage_t
154 {
155 public :
156 subscription_storage_t( agent_t * owner );
157 virtual ~subscription_storage_t() noexcept = default;
158
159 virtual void
160 create_event_subscription(
161 const mbox_t & mbox,
162 const std::type_index & msg_type,
163 const message_limit::control_block_t * limit,
164 const state_t & target_state,
165 const event_handler_method_t & method,
166 thread_safety_t thread_safety,
167 event_handler_kind_t handler_kind ) = 0;
168
169 virtual void
170 drop_subscription(
171 const mbox_t & mbox,
172 const std::type_index & msg_type,
173 const state_t & target_state ) = 0;
174
175 virtual void
176 drop_subscription_for_all_states(
177 const mbox_t & mbox,
178 const std::type_index & msg_type ) = 0;
179
180 virtual const event_handler_data_t *
181 find_handler(
182 mbox_id_t mbox_id,
183 const std::type_index & msg_type,
184 const state_t & current_state ) const noexcept = 0;
185
186 virtual void
187 debug_dump( std::ostream & to ) const = 0;
188
189 //! Drop all content.
190 /*!
191 * All information about subscription must be erased,
192 * but without real unsubscription.
193 *
194 * This method will be called after successful copy of
195 * subscription information to another storage.
196 */
197 virtual void
198 drop_content() = 0;
199
200 //! Get content for copying subscription information
201 //! to another storage object.
202 virtual subscription_storage_common::subscr_info_vector_t
203 query_content() const = 0;
204
205 //! Setup content from information from another storage object.
206 virtual void
207 setup_content(
208 subscription_storage_common::subscr_info_vector_t && info ) = 0;
209
210 //! Count of subscriptions in the storage.
211 virtual std::size_t
212 query_subscriptions_count() const = 0;
213
214 protected :
215 agent_t *
216 owner() const;
217
218 private :
219 agent_t * m_owner;
220 };
221
222 } /* namespace impl */
223
224 } /* namespace so_5 */
225
226