SObjectizer-5 Extra
Loading...
Searching...
No Matches
proxy.hpp
Go to the documentation of this file.
1/*!
2 * \file
3 * \brief Implementation of simple mbox proxy.
4 *
5 * \since
6 * v.1.2.0
7 */
8
9#pragma once
10
11#include <so_5_extra/error_ranges.hpp>
12
13#include <so_5/mbox.hpp>
14
15namespace so_5 {
16
17namespace extra {
18
19namespace mboxes {
20
21namespace proxy {
22
23namespace errors {
24
25/*!
26 * \brief Null pointer to underlying mbox.
27 *
28 * A proxy-mbox uses underlying mbox and delegates all actions to that mbox.
29 * Because of that underlying mbox can't be nullptr.
30 *
31 * \since
32 * v.1.2.0
33 */
36
37} /* namespace errors */
38
39//
40// simple_t
41//
42/*!
43 * \brief A simple proxy that delegates all calls to underlying actual mbox.
44 *
45 * Sometimes it is necessary to create an own mbox that does
46 * some specific task. For example, counts the number of message
47 * of some specific type. Something like:
48 * \code
49 * class my_mbox final : public so_5::abstract_message_box_t
50 * {
51 * bool is_appropriate_message_type(
52 * const std::type_index & msg_type ) const { ... }
53 *
54 * std::size_t counter_{};
55 * ...
56 * void do_deliver_message(
57 * so_5::message_delivery_mode_t delivery_mode,
58 * const std::type_index & msg_type,
59 * const so_5::message_ref_t & message,
60 * unsigned int redirection_deep ) override {
61 * if(is_appropriate_message_type(msg_type))
62 * ++counter_;
63 * ... // Actual message delivery.
64 * }
65 * };
66 * \endcode
67 * But it is hard to create a full implementation of
68 * so_5::abstract_message_box_t from the ground up. An existing mbox can be
69 * used for doing actual work:
70 * \code
71 * class my_mbox final : public so_5::abstract_message_box_t
72 * {
73 * bool is_appropriate_message_type(
74 * const std::type_index & msg_type ) const { ... }
75 *
76 * const so_5::mbox_t mbox_;
77 * std::size_t counter_{};
78 * ...
79 * public:
80 * my_mbox(so_5::mbox_t mbox) : mbox_{std::move(mbox)} {}
81 * ...
82 * void do_deliver_message(
83 * so_5::message_delivery_mode_t delivery_mode,
84 * const std::type_index & msg_type,
85 * const so_5::message_ref_t & message,
86 * unsigned int redirection_deep ) override {
87 * if(is_appropriate_message_type(msg_type))
88 * ++counter_;
89 * // Use actual mbox for message delivery.
90 * mbox_->do_deliver_message(
91 * delivery_mode, msg_type, message, redirection_deep);
92 * }
93 * };
94 * \endcode
95 * But there is a small problem with this approach: so_5::abstract_message_box_t
96 * has a rich interface with a lot of pure virtual methods. It is a boring
97 * task to reimplement all of them.
98 *
99 * In such cases simple_t can be used to reduce amount of developer's work:
100 * \code
101 * class my_mbox final : public so_5::extra::mboxes::proxy::simple_t
102 * {
103 * using base_type = so_5::extra::mboxes::proxy::simple_t;
104 *
105 * bool is_appropriate_message_type(
106 * const std::type_index & msg_type ) const { ... }
107 *
108 * std::size_t counter_{};
109 *
110 * public:
111 * my_mbox(so_5::mbox_t mbox) : base_type{std::move(mbox)} {}
112 *
113 * void do_deliver_message(
114 * so_5::message_delivery_mode_t delivery_mode,
115 * const std::type_index & msg_type,
116 * const so_5::message_ref_t & message,
117 * unsigned int redirection_deep ) override {
118 * if(is_appropriate_message_type(msg_type))
119 * ++counter_;
120 * // Use actual mbox for message delivery.
121 * base_type::do_deliver_message(
122 * delivery_mode, msg_type, message, redirection_deep);
123 * }
124 * }
125 * \endcode
126 * And that's all.
127 *
128 * \since
129 * v.5.5.23
130 */
132 {
133 //! Actual underlying mbox to be used for all calls.
134 /*!
135 * \attention Should not be nullptr.
136 */
138
139 //! Ensure that underlying mbox is not nullptr.
140 /*!
141 * \throw so_5::exception_t if \a mbox is nullptr.
142 */
143 ::so_5::mbox_t
145 ::so_5::mbox_t mbox )
146 {
147 if( !mbox )
148 SO_5_THROW_EXCEPTION(
150 "nullptr is used as underlying mbox" );
151
152 return mbox;
153 }
154
155 protected :
156 //! An accessor to actual mbox.
157 /*!
158 * This method is intended to be used in derived classes.
159 * For example:
160 * \code
161 * class my_mbox : public so_5::extra::mboxes::proxy::simple_t {
162 * public:
163 * void do_deliver_message(
164 * so_5::message_delivery_mode_t delivery_mode,
165 * const std::type_index & msg_type,
166 * const so_5::message_ref_t & message,
167 * unsigned int redirection_deep ) override {
168 * ... // Do some specific stuff.
169 * // Use actual mbox for message delivery.
170 * underlying_mbox().do_deliver_message(
171 * delivery_mode, msg_type, message, redirection_deep);
172 * }
173 * ...
174 * };
175 * \endcode
176 */
178 underlying_mbox() const noexcept
179 {
180 return *m_underlying_mbox;
181 }
182
183 public :
184 //! Initializing constructor.
186 //! Actual underlying mbox to be used for all operations.
187 //! Must not be nullptr.
188 ::so_5::mbox_t underlying_mbox )
191 {}
192
193 /*!
194 * \name Simple implementation of inherited methods.
195 * \{
196 */
198 id() const override
199 {
200 return underlying_mbox().id();
201 }
202
203 void
205 const std::type_index & msg_type,
206 ::so_5::abstract_message_sink_t & subscriber ) override
207 {
208 underlying_mbox().subscribe_event_handler( msg_type, subscriber );
209 }
210
211 void
213 const std::type_index & msg_type,
214 ::so_5::abstract_message_sink_t & subscriber ) noexcept override
215 {
216 underlying_mbox().unsubscribe_event_handler( msg_type, subscriber );
217 }
218
219 std::string
220 query_name() const override
221 {
222 return underlying_mbox().query_name();
223 }
224
226 type() const override
227 {
228 return underlying_mbox().type();
229 }
230
231 void
233 ::so_5::message_delivery_mode_t delivery_mode,
234 const std::type_index & msg_type,
235 const ::so_5::message_ref_t & message,
236 unsigned int redirection_deep ) override
237 {
238 underlying_mbox().do_deliver_message(
239 delivery_mode,
240 msg_type,
241 message,
242 redirection_deep );
243 }
244
245 void
247 const std::type_index & msg_type,
248 const ::so_5::delivery_filter_t & filter,
249 ::so_5::abstract_message_sink_t & subscriber ) override
250 {
251 underlying_mbox().set_delivery_filter(
252 msg_type,
253 filter,
254 subscriber );
255 }
256
257 void
259 const std::type_index & msg_type,
260 ::so_5::abstract_message_sink_t & subscriber ) noexcept override
261 {
262 underlying_mbox().drop_delivery_filter(
263 msg_type,
264 subscriber );
265 }
266
268 environment() const noexcept override
269 {
270 return underlying_mbox().environment();
271 }
272 /*!
273 * \}
274 */
275 };
276
277} /* namespace proxy */
278
279} /* namespace mboxes */
280
281} /* namespace extra */
282
283} /* namespace so_5 */
A simple proxy that delegates all calls to underlying actual mbox.
Definition proxy.hpp:132
::so_5::mbox_t ensure_underlying_mbox_not_null(::so_5::mbox_t mbox)
Ensure that underlying mbox is not nullptr.
Definition proxy.hpp:144
mbox_id_t id() const override
Definition proxy.hpp:198
simple_t(::so_5::mbox_t underlying_mbox)
Initializing constructor.
Definition proxy.hpp:185
const ::so_5::mbox_t m_underlying_mbox
Actual underlying mbox to be used for all calls.
Definition proxy.hpp:137
std::string query_name() const override
Definition proxy.hpp:220
so_5::environment_t & environment() const noexcept override
Definition proxy.hpp:268
void unsubscribe_event_handler(const std::type_index &msg_type, ::so_5::abstract_message_sink_t &subscriber) noexcept override
Definition proxy.hpp:212
void do_deliver_message(::so_5::message_delivery_mode_t delivery_mode, const std::type_index &msg_type, const ::so_5::message_ref_t &message, unsigned int redirection_deep) override
Definition proxy.hpp:232
::so_5::abstract_message_box_t & underlying_mbox() const noexcept
An accessor to actual mbox.
Definition proxy.hpp:178
mbox_type_t type() const override
Definition proxy.hpp:226
void drop_delivery_filter(const std::type_index &msg_type, ::so_5::abstract_message_sink_t &subscriber) noexcept override
Definition proxy.hpp:258
void subscribe_event_handler(const std::type_index &msg_type, ::so_5::abstract_message_sink_t &subscriber) override
Definition proxy.hpp:204
void set_delivery_filter(const std::type_index &msg_type, const ::so_5::delivery_filter_t &filter, ::so_5::abstract_message_sink_t &subscriber) override
Definition proxy.hpp:246
const int mboxes_proxy_errors
Starting point for errors of mboxes::proxy submodule.
const int rc_nullptr_as_underlying_mbox
Null pointer to underlying mbox.
Definition proxy.hpp:34
Ranges for error codes of each submodules.
Definition details.hpp:13