SObjectizer-5 Extra
Loading...
Searching...
No Matches
so_5_extra
mboxes
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
> >
60
class
fixed_mbox_template_t
final :
public
abstract_message_box_t
61
{
62
outliving_reference_t
<
environment_t
>
m_env
;
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
*/
72
fixed_mbox_template_t
(
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
}
81
,
m_destinations
{
destinations
}
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
*/
89
fixed_mbox_template_t
(
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
}
99
,
m_destinations
{
std
::
move
(
destinations
) }
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
>
108
fixed_mbox_template_t
(
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
}
119
,
m_destinations
{
first
,
last
}
120
{}
121
122
public
:
123
mbox_id_t
124
id
()
const
override
{
return
m_id
; }
125
126
void
127
subscribe_event_handler
(
128
const
std
::
type_index
&
/*type_index*/
,
129
abstract_message_sink_t
&
/*subscriber*/
)
override
130
{
131
SO_5_THROW_EXCEPTION
(
rc_not_implemented
,
132
"subscribe_event_handler can't be used for broadcast mbox"
);
133
}
134
135
void
136
unsubscribe_event_handler
(
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
{
146
std
::
ostringstream
s
;
147
s
<<
"<mbox:type=BROADCAST:id="
<<
this
->
m_id
<<
">"
;
148
149
return
s
.
str
();
150
}
151
152
mbox_type_t
153
type
()
const
override
154
{
155
return
mbox_type_t
::
multi_producer_multi_consumer
;
156
}
157
158
void
159
do_deliver_message
(
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
{
165
if
(
message_mutability_t
::
mutable_message
==
message_mutability
(
message
) )
166
SO_5_THROW_EXCEPTION
(
167
rc_mutable_msg_cannot_be_delivered_via_mpmc_mbox
,
168
"a mutable message can't be sent via broadcast mbox"
);
169
170
for
(
auto
&
m
:
m_destinations
)
171
m
->
do_deliver_message
(
delivery_mode
,
msg_type
,
message
,
redirection_deep
);
172
}
173
174
void
175
set_delivery_filter
(
176
const
std
::
type_index
&
/*msg_type*/
,
177
const
delivery_filter_t
&
/*filter*/
,
178
abstract_message_sink_t
&
/*subscriber*/
)
override
179
{
180
SO_5_THROW_EXCEPTION
(
rc_not_implemented
,
181
"set_delivery_filter can't be used for broadcast mbox"
);
182
}
183
184
void
185
drop_delivery_filter
(
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
215
make
(
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
) {
223
return
std
::
unique_ptr
<
fixed_mbox_template_t
>{
224
new
fixed_mbox_template_t
(
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
254
make
(
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.
259
Container
&&
destinations
)
260
{
261
return
env
.
make_custom_mbox
(
262
[&
destinations
](
const
mbox_creation_data_t
&
data
) {
263
return
std
::
unique_ptr
<
fixed_mbox_template_t
>{
264
new
fixed_mbox_template_t
(
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
295
make
(
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
) {
305
return
std
::
unique_ptr
<
fixed_mbox_template_t
>{
306
new
fixed_mbox_template_t
(
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
335
make
(
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.
339
const
Another_Container
&
destinations
)
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
(
347
std
::
is_convertible_v
<
348
decltype
(
349
++
std
::
declval
<
350
std
::
add_lvalue_reference_t
<
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 */
so_5::extra::mboxes::broadcast::fixed_mbox_template_t::m_id
const mbox_id_t m_id
Definition
broadcast.hpp:63
so_5::extra::mboxes::broadcast::fixed_mbox_template_t::fixed_mbox_template_t
fixed_mbox_template_t(outliving_reference_t< environment_t > env, mbox_id_t id, const Container &destinations)
Initializing constructor.
Definition
broadcast.hpp:72
so_5::extra::mboxes::broadcast::fixed_mbox_template_t::m_env
outliving_reference_t< environment_t > m_env
Definition
broadcast.hpp:62
so_5::extra::mboxes::broadcast::fixed_mbox_template_t::m_destinations
const Container m_destinations
Definition
broadcast.hpp:64
so_5::extra::mboxes::broadcast
Definition
broadcast.hpp:26
so_5::extra::mboxes
Definition
broadcast.hpp:23
so_5::extra
Definition
details.hpp:15
so_5
Ranges for error codes of each submodules.
Definition
details.hpp:13
Generated by
1.12.0