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  const message_limit::control_block_t * /*limit*/,
130  agent_t & /*subscriber*/ ) override
131  {
133  "subscribe_event_handler can't be used for broadcast mbox" );
134  }
135 
136  void
138  const std::type_index & /*type_index*/,
139  agent_t & /*subscriber*/ ) override
140  {
142  "unsubscribe_event_handler can't be used for broadcast mbox" );
143  }
144 
145  std::string
146  query_name() const override
147  {
149  s << "<mbox:type=BROADCAST:id=" << this->m_id << ">";
150 
151  return s.str();
152  }
153 
155  type() const override
156  {
158  }
159 
160  void
162  const std::type_index & msg_type,
163  const message_ref_t & message,
164  unsigned int overlimit_reaction_deep ) override
165  {
169  "a mutable message can't be sent via broadcast mbox" );
170 
171  for( auto & m : m_destinations )
173  }
174 
175  void
177  const std::type_index & /*msg_type*/,
178  const delivery_filter_t & /*filter*/,
179  agent_t & /*subscriber*/ ) override
180  {
182  "set_delivery_filter can't be used for broadcast mbox" );
183  }
184 
185  void
187  const std::type_index & /*msg_type*/,
188  agent_t & /*subscriber*/ ) noexcept override
189  {}
190 
191  environment_t &
192  environment() const noexcept override
193  {
194  return m_env.get();
195  }
196 
197  /*!
198  * \brief Factory method for the creation of new instance of a mbox.
199  *
200  * Copies the whole content from \a destinations container.
201  *
202  * Usage example:
203  * \code
204  * using broadcasting_mbox = so_5::extra::mboxes::broadcast::fixed_mbox_template_t<>;
205  *
206  * std::vector< so_5::mbox_t > destinations;
207  * destinations.push_back( some_agent->so_direct_mbox() );
208  * destinations.push_back( another_agent->so_direct_mbox() );
209  * ...
210  * auto first_broadcaster = broadcasting_mbox::make( env, destinations );
211  * auto second_broadcaster = broadcasting_mbox::make( env, destinations );
212  * ...
213  * \endcode
214  */
215  static mbox_t
217  //! SObjectizer Environment to work in.
218  environment_t & env,
219  //! A set of destinations for a new mbox.
220  const Container & destinations )
221  {
222  return env.make_custom_mbox(
223  [&destinations]( const mbox_creation_data_t & data ) {
226  data.m_env,
227  data.m_id,
228  destinations )
229  };
230  } );
231  }
232 
233  /*!
234  * \brief Factory method for the creation of new instance of a mbox.
235  *
236  * Borrows (moves from) the whole content from \a destinations container.
237  *
238  * Usage example:
239  * \code
240  * using broadcasting_mbox = so_5::extra::mboxes::broadcast::fixed_mbox_template_t<>;
241  *
242  * std::vector< so_5::mbox_t > make_destinations() {
243  * std::vector< so_5::mbox_t > result;
244  * result.push_back( some_agent->so_direct_mbox() );
245  * result.push_back( another_agent->so_direct_mbox() );
246  * ...
247  * return result;
248  * }
249  *
250  * auto broadcaster = broadcasting_mbox::make( env, make_destinations() );
251  * ...
252  * \endcode
253  */
254  static mbox_t
256  //! SObjectizer Environment to work in.
257  environment_t & env,
258  //! A temporary container with a set of destination mboxes.
259  //! The content of that container will be moved into a new mbox.
261  {
262  return env.make_custom_mbox(
263  [&destinations]( const mbox_creation_data_t & data ) {
266  data.m_env,
267  data.m_id,
268  std::move(destinations) )
269  };
270  } );
271  }
272 
273  /*!
274  * \brief Factory method for the creation of new instance of a mbox.
275  *
276  * Uses values from a range [\a first, \a last) for initialization of
277  * destinations container.
278  *
279  * Usage example:
280  * \code
281  * using broadcasting_mbox = so_5::extra::mboxes::broadcast::fixed_mbox_template_t<>;
282  *
283  * so_5::mbox_t destinations[] = {
284  * some_agent->so_direct_mbox(),
285  * another_agent->so_direct_mbox(),
286  * ...
287  * };
288  *
289  * auto broadcaster = broadcasting_mbox::make( env,
290  * std::begin(destinations), std::end(destinations) );
291  * ...
292  * \endcode
293  */
294  template< typename Input_It >
295  static mbox_t
297  //! SObjectizer Environment to work in.
298  environment_t & env,
299  //! The left border of a range (inclusive).
300  Input_It first,
301  //! The right border of a range (exclusive).
302  Input_It last )
303  {
304  return env.make_custom_mbox(
305  [&first, &last]( const mbox_creation_data_t & data ) {
308  data.m_env,
309  data.m_id,
310  first, last )
311  };
312  } );
313  }
314 
315  /*!
316  * \brief Factory method for the creation of new instance of a mbox.
317  *
318  * Uses the whole content of a container of other type.
319  *
320  * Usage example:
321  * \code
322  * using broadcasting_mbox = so_5::extra::mboxes::broadcast::fixed_mbox_template_t<>;
323  *
324  * std::array<so_5::mbox_t, 5> destinations{
325  * some_agent->so_direct_mbox(),
326  * another_agent->so_direct_mbox(),
327  * ...
328  * };
329  *
330  * auto broadcaster = broadcasting_mbox::make( env, destinations );
331  * ...
332  * \endcode
333  */
334  template< typename Another_Container >
335  static mbox_t
337  //! SObjectizer Environment to work in.
338  environment_t & env,
339  //! The container (or range object) with a set of destinations to a new mbox.
341  {
342  using std::begin;
343  using std::end;
344 
345  // Ensure that destinations if a container or range-like object
346  // with mbox_t inside.
347  static_assert(
349  decltype(
350  ++std::declval<
352  decltype(begin(std::declval<const Another_Container &>()))>
353  >()
354  == end(std::declval<const Another_Container &>()) ),
355  bool>,
356  "destinations should be a container or range-like object" );
357 
358  static_assert(
359  std::is_same_v<
360  std::decay_t<
361  decltype(*begin(std::declval<const Another_Container &>())) >,
362  mbox_t >,
363  "mbox_t should be accessible via iterator for destinations container (or "
364  "range-like object" );
365 
366  return make( env, begin(destinations), end(destinations) );
367  }
368 
369 };
370 
371 } /* namespace broadcast */
372 
373 } /* namespace mboxes */
374 
375 } /* namespace extra */
376 
377 } /* namespace so_5 */
void set_delivery_filter(const std::type_index &, const delivery_filter_t &, agent_t &) override
Definition: broadcast.hpp:176
outliving_reference_t< environment_t > m_env
Definition: broadcast.hpp:62
Ranges for error codes of each submodules.
Definition: details.hpp:13
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(const std::type_index &msg_type, const message_ref_t &message, unsigned int overlimit_reaction_deep) override
Definition: broadcast.hpp:161
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:336
A template for broadcasting mbox with fixed set of destinations.
Definition: broadcast.hpp:60
void subscribe_event_handler(const std::type_index &, const message_limit::control_block_t *, agent_t &) override
Definition: broadcast.hpp:127
environment_t & environment() const noexcept override
Definition: broadcast.hpp:192
static mbox_t make(environment_t &env, const Container &destinations)
Factory method for the creation of new instance of a mbox.
Definition: broadcast.hpp:216
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:255
void drop_delivery_filter(const std::type_index &, agent_t &) noexcept override
Definition: broadcast.hpp:186
void unsubscribe_event_handlers(const std::type_index &, agent_t &) override
Definition: broadcast.hpp:137
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:296