SObjectizer-5 Extra
broadcast.hpp
Go to the documentation of this file.
1 /*!
2  * \file Implementation of broadcasting mbox.
3  *
4  * \since
5  * v.1.3.1
6  */
7 
8 #pragma once
9 
10 #include <so_5/mbox.hpp>
11 #include <so_5/custom_mbox.hpp>
12 #include <so_5/environment.hpp>
13 
14 #include <iterator>
15 
16 namespace so_5
17 {
18 
19 namespace extra
20 {
21 
22 namespace mboxes
23 {
24 
25 namespace broadcast
26 {
27 
28 /*!
29  * \brief A template for broadcasting mbox with fixed set of destinations.
30  *
31  * \note
32  * A set of destination is fixed at the creation time and can't be changed
33  * later. It can be not flexible enough for some senarios, but allows to
34  * avoid any additional locks during the delivery of a message.
35  *
36  * \note
37  * This type has no public constructors. To create an instance of that
38  * type public static `make` methods should be used.
39  *
40  * \attention
41  * This type of mbox prohibits the delivery of mutable messages. It is
42  * because this is MPMC mbox.
43  *
44  * \attention
45  * This type of mbox prohibits subscriptions and usage of delivery filters.
46  * An attempt to create a subscription or an attempt to set a delivery
47  * filter will lead to an exception.
48  *
49  * \tparam Container Type of a container for holding list of destination
50  * mboxes. By default it is `std::vector<mbox_t>` but a user can set
51  * any type of sequential container. For example:
52  * \code
53  * using my_broadcast_mbox = so_5::extra::mboxes::broadcast::fixed_mbox_template_t< std::array<so_5::mbox_t, 10> >;
54  * \endcode
55  *
56  * \since
57  * v.1.3.1
58  */
59 template< typename Container = std::vector<mbox_t> >
61 {
63  const mbox_id_t m_id;
64  const Container m_destinations;
65 
66 protected :
67  //! Initializing constructor.
68  /*!
69  * Intended for the case when a set of destinations should be taken
70  * from a const reference to the container of the same type.
71  */
73  //! SObjectizer Environment to work in.
74  outliving_reference_t< environment_t > env,
75  //! A unique ID of that
76  mbox_id_t id,
77  //! Source container with a set of destination mboxes.
78  const Container & destinations )
79  : m_env{ env }
80  , m_id{ id }
82  {}
83 
84  //! Initializing constructor.
85  /*!
86  * Intended for the case when a set of destinations should be borrowed
87  * (moved) from a temporary container of the same type.
88  */
90  //! SObjectizer Environment to work in.
91  outliving_reference_t< environment_t > env,
92  //! A unique ID of that
93  mbox_id_t id,
94  //! Source container with a set of destination mboxes.
95  //! The content of this container will be borrowed.
96  Container && destinations )
97  : m_env{ env }
98  , m_id{ id }
100  {}
101 
102  //! Initializing constructor.
103  /*!
104  * Intended for the case when a set of destination mboxes is specified
105  * by a pair of iterators.
106  */
107  template< typename Input_It >
109  //! SObjectizer Environment to work in.
110  outliving_reference_t< environment_t > env,
111  //! A unique ID of that
112  mbox_id_t id,
113  //! The left border of a range (inclusive).
114  Input_It first,
115  //! The right border of a range (exclusive).
116  Input_It last )
117  : m_env{ env }
118  , m_id{ id }
120  {}
121 
122 public :
123  mbox_id_t
124  id() const override { return m_id; }
125 
126  void
128  const std::type_index & /*type_index*/,
129  abstract_message_sink_t & /*subscriber*/ ) override
130  {
132  "subscribe_event_handler can't be used for broadcast mbox" );
133  }
134 
135  void
137  const std::type_index & /*type_index*/,
138  abstract_message_sink_t & /*subscriber*/ ) noexcept override
139  {
140  // Can't throw in noexcept method.
141  }
142 
143  std::string
144  query_name() const override
145  {
147  s << "<mbox:type=BROADCAST:id=" << this->m_id << ">";
148 
149  return s.str();
150  }
151 
153  type() const override
154  {
156  }
157 
158  void
160  message_delivery_mode_t delivery_mode,
161  const std::type_index & msg_type,
162  const message_ref_t & message,
163  unsigned int redirection_deep ) override
164  {
168  "a mutable message can't be sent via broadcast mbox" );
169 
170  for( auto & m : m_destinations )
172  }
173 
174  void
176  const std::type_index & /*msg_type*/,
177  const delivery_filter_t & /*filter*/,
178  abstract_message_sink_t & /*subscriber*/ ) override
179  {
181  "set_delivery_filter can't be used for broadcast mbox" );
182  }
183 
184  void
186  const std::type_index & /*msg_type*/,
187  abstract_message_sink_t & /*subscriber*/ ) noexcept override
188  {}
189 
190  environment_t &
191  environment() const noexcept override
192  {
193  return m_env.get();
194  }
195 
196  /*!
197  * \brief Factory method for the creation of new instance of a mbox.
198  *
199  * Copies the whole content from \a destinations container.
200  *
201  * Usage example:
202  * \code
203  * using broadcasting_mbox = so_5::extra::mboxes::broadcast::fixed_mbox_template_t<>;
204  *
205  * std::vector< so_5::mbox_t > destinations;
206  * destinations.push_back( some_agent->so_direct_mbox() );
207  * destinations.push_back( another_agent->so_direct_mbox() );
208  * ...
209  * auto first_broadcaster = broadcasting_mbox::make( env, destinations );
210  * auto second_broadcaster = broadcasting_mbox::make( env, destinations );
211  * ...
212  * \endcode
213  */
214  static mbox_t
216  //! SObjectizer Environment to work in.
217  environment_t & env,
218  //! A set of destinations for a new mbox.
219  const Container & destinations )
220  {
221  return env.make_custom_mbox(
222  [&destinations]( const mbox_creation_data_t & data ) {
225  data.m_env,
226  data.m_id,
227  destinations )
228  };
229  } );
230  }
231 
232  /*!
233  * \brief Factory method for the creation of new instance of a mbox.
234  *
235  * Borrows (moves from) the whole content from \a destinations container.
236  *
237  * Usage example:
238  * \code
239  * using broadcasting_mbox = so_5::extra::mboxes::broadcast::fixed_mbox_template_t<>;
240  *
241  * std::vector< so_5::mbox_t > make_destinations() {
242  * std::vector< so_5::mbox_t > result;
243  * result.push_back( some_agent->so_direct_mbox() );
244  * result.push_back( another_agent->so_direct_mbox() );
245  * ...
246  * return result;
247  * }
248  *
249  * auto broadcaster = broadcasting_mbox::make( env, make_destinations() );
250  * ...
251  * \endcode
252  */
253  static mbox_t
255  //! SObjectizer Environment to work in.
256  environment_t & env,
257  //! A temporary container with a set of destination mboxes.
258  //! The content of that container will be moved into a new mbox.
260  {
261  return env.make_custom_mbox(
262  [&destinations]( const mbox_creation_data_t & data ) {
265  data.m_env,
266  data.m_id,
267  std::move(destinations) )
268  };
269  } );
270  }
271 
272  /*!
273  * \brief Factory method for the creation of new instance of a mbox.
274  *
275  * Uses values from a range [\a first, \a last) for initialization of
276  * destinations container.
277  *
278  * Usage example:
279  * \code
280  * using broadcasting_mbox = so_5::extra::mboxes::broadcast::fixed_mbox_template_t<>;
281  *
282  * so_5::mbox_t destinations[] = {
283  * some_agent->so_direct_mbox(),
284  * another_agent->so_direct_mbox(),
285  * ...
286  * };
287  *
288  * auto broadcaster = broadcasting_mbox::make( env,
289  * std::begin(destinations), std::end(destinations) );
290  * ...
291  * \endcode
292  */
293  template< typename Input_It >
294  static mbox_t
296  //! SObjectizer Environment to work in.
297  environment_t & env,
298  //! The left border of a range (inclusive).
299  Input_It first,
300  //! The right border of a range (exclusive).
301  Input_It last )
302  {
303  return env.make_custom_mbox(
304  [&first, &last]( const mbox_creation_data_t & data ) {
307  data.m_env,
308  data.m_id,
309  first, last )
310  };
311  } );
312  }
313 
314  /*!
315  * \brief Factory method for the creation of new instance of a mbox.
316  *
317  * Uses the whole content of a container of other type.
318  *
319  * Usage example:
320  * \code
321  * using broadcasting_mbox = so_5::extra::mboxes::broadcast::fixed_mbox_template_t<>;
322  *
323  * std::array<so_5::mbox_t, 5> destinations{
324  * some_agent->so_direct_mbox(),
325  * another_agent->so_direct_mbox(),
326  * ...
327  * };
328  *
329  * auto broadcaster = broadcasting_mbox::make( env, destinations );
330  * ...
331  * \endcode
332  */
333  template< typename Another_Container >
334  static mbox_t
336  //! SObjectizer Environment to work in.
337  environment_t & env,
338  //! The container (or range object) with a set of destinations to a new mbox.
340  {
341  using std::begin;
342  using std::end;
343 
344  // Ensure that destinations if a container or range-like object
345  // with mbox_t inside.
346  static_assert(
348  decltype(
349  ++std::declval<
351  decltype(begin(std::declval<const Another_Container &>()))>
352  >()
353  == end(std::declval<const Another_Container &>()) ),
354  bool>,
355  "destinations should be a container or range-like object" );
356 
357  static_assert(
358  std::is_same_v<
359  std::decay_t<
360  decltype(*begin(std::declval<const Another_Container &>())) >,
361  mbox_t >,
362  "mbox_t should be accessible via iterator for destinations container (or "
363  "range-like object" );
364 
365  return make( env, begin(destinations), end(destinations) );
366  }
367 
368 };
369 
370 } /* namespace broadcast */
371 
372 } /* namespace mboxes */
373 
374 } /* namespace extra */
375 
376 } /* namespace so_5 */
void unsubscribe_event_handler(const std::type_index &, abstract_message_sink_t &) noexcept override
Definition: broadcast.hpp:136
outliving_reference_t< environment_t > m_env
Definition: broadcast.hpp:62
void set_delivery_filter(const std::type_index &, const delivery_filter_t &, abstract_message_sink_t &) override
Definition: broadcast.hpp:175
Ranges for error codes of each submodules.
Definition: details.hpp:13
void subscribe_event_handler(const std::type_index &, abstract_message_sink_t &) override
Definition: broadcast.hpp:127
fixed_mbox_template_t(outliving_reference_t< environment_t > env, mbox_id_t id, Container &&destinations)
Initializing constructor.
Definition: broadcast.hpp:89
void do_deliver_message(message_delivery_mode_t delivery_mode, const std::type_index &msg_type, const message_ref_t &message, unsigned int redirection_deep) override
Definition: broadcast.hpp:159
static mbox_t make(environment_t &env, const Another_Container &destinations)
Factory method for the creation of new instance of a mbox.
Definition: broadcast.hpp:335
A template for broadcasting mbox with fixed set of destinations.
Definition: broadcast.hpp:60
environment_t & environment() const noexcept override
Definition: broadcast.hpp:191
static mbox_t make(environment_t &env, const Container &destinations)
Factory method for the creation of new instance of a mbox.
Definition: broadcast.hpp:215
fixed_mbox_template_t(outliving_reference_t< environment_t > env, mbox_id_t id, Input_It first, Input_It last)
Initializing constructor.
Definition: broadcast.hpp:108
fixed_mbox_template_t(outliving_reference_t< environment_t > env, mbox_id_t id, const Container &destinations)
Initializing constructor.
Definition: broadcast.hpp:72
static mbox_t make(environment_t &env, Container &&destinations)
Factory method for the creation of new instance of a mbox.
Definition: broadcast.hpp:254
void drop_delivery_filter(const std::type_index &, abstract_message_sink_t &) noexcept override
Definition: broadcast.hpp:185
static mbox_t make(environment_t &env, Input_It first, Input_It last)
Factory method for the creation of new instance of a mbox.
Definition: broadcast.hpp:295