1 /*
2 * A simple test for so_has_subscription method.
3 */
4
5 #include <iostream>
6 #include <map>
7 #include <exception>
8 #include <stdexcept>
9 #include <cstdlib>
10 #include <thread>
11 #include <chrono>
12
13 #include <so_5/all.hpp>
14
15 #include <test/3rd_party/various_helpers/time_limited_execution.hpp>
16 #include <test/3rd_party/various_helpers/ensure.hpp>
17
18 class a_test_t : public so_5::agent_t
19 {
20 struct finish : public so_5::signal_t {};
21
22 struct sig_1 : public so_5::signal_t {};
23 struct sig_2 : public so_5::signal_t {};
24
25 struct msg_1 : public so_5::message_t {};
26 struct msg_2 : public so_5::message_t {};
27 struct msg_3 : public so_5::message_t {};
28 struct msg_4 : public so_5::message_t {};
29 struct msg_5 : public so_5::message_t {};
30
31 struct umsg_1 {};
32 struct umsg_2 {};
33 struct umsg_3 {};
34 struct umsg_4 {};
35 struct umsg_5 {};
36 struct umsg_6 {};
37
38 struct ret_msg_1 : public so_5::message_t {};
39 struct ret_msg_2 : public so_5::message_t {};
40 struct ret_msg_3 : public so_5::message_t {};
41 struct ret_msg_4 : public so_5::message_t {};
42 struct ret_msg_5 : public so_5::message_t {};
43
44 struct ret_umsg_1 {};
45 struct ret_umsg_2 {};
46 struct ret_umsg_3 {};
47 struct ret_umsg_4 {};
48 struct ret_umsg_5 {};
49 struct ret_umsg_6 {};
50
51 public :
a_test_t(context_t ctx)52 a_test_t( context_t ctx )
53 : so_5::agent_t( ctx )
54 {}
55
56 virtual void
so_define_agent()57 so_define_agent() override
58 {
59 so_subscribe_self()
60 .event( &a_test_t::on_finish )
61 .event( &a_test_t::on_sig_1 )
62 .event( &a_test_t::on_sig_2 )
63 .event( &a_test_t::on_msg_1 )
64 .event( &a_test_t::on_msg_2 )
65 .event( &a_test_t::on_msg_3 )
66 .event( &a_test_t::on_msg_4 )
67 .event( &a_test_t::on_msg_5 )
68 .event( &a_test_t::on_umsg_1 )
69 .event( &a_test_t::on_umsg_2 )
70 .event( &a_test_t::on_umsg_3 )
71 .event( &a_test_t::on_umsg_4 )
72 .event( &a_test_t::on_umsg_5 )
73 .event( &a_test_t::on_umsg_6 )
74 .event( &a_test_t::on_ret_msg_1 )
75 .event( &a_test_t::on_ret_msg_2 )
76 .event( &a_test_t::on_ret_msg_3 )
77 .event( &a_test_t::on_ret_msg_4 )
78 .event( &a_test_t::on_ret_msg_5 )
79 .event( &a_test_t::on_ret_umsg_1 )
80 .event( &a_test_t::on_ret_umsg_2 )
81 .event( &a_test_t::on_ret_umsg_3 )
82 .event( &a_test_t::on_ret_umsg_4 )
83 .event( &a_test_t::on_ret_umsg_5 )
84 .event( &a_test_t::on_ret_umsg_6 )
85 ;
86
87 #define ENSURE_SUBSCRIBED(handler) \
88 ensure( so_has_subscription(so_direct_mbox(), \
89 so_default_state(), \
90 &a_test_t:: handler), \
91 #handler " must be subscribed" )
92
93 ENSURE_SUBSCRIBED(on_sig_1);
94 ENSURE_SUBSCRIBED(on_sig_2);
95 ENSURE_SUBSCRIBED(on_msg_1);
96 ENSURE_SUBSCRIBED(on_msg_2);
97 ENSURE_SUBSCRIBED(on_msg_3);
98 ENSURE_SUBSCRIBED(on_msg_4);
99 ENSURE_SUBSCRIBED(on_msg_5);
100
101 ENSURE_SUBSCRIBED(on_umsg_1);
102 ENSURE_SUBSCRIBED(on_umsg_2);
103 ENSURE_SUBSCRIBED(on_umsg_3);
104 ENSURE_SUBSCRIBED(on_umsg_4);
105 ENSURE_SUBSCRIBED(on_umsg_5);
106 ENSURE_SUBSCRIBED(on_umsg_6);
107
108 ENSURE_SUBSCRIBED(on_ret_msg_1);
109 ENSURE_SUBSCRIBED(on_ret_msg_2);
110 ENSURE_SUBSCRIBED(on_ret_msg_3);
111 ENSURE_SUBSCRIBED(on_ret_msg_4);
112 ENSURE_SUBSCRIBED(on_ret_msg_5);
113
114 ENSURE_SUBSCRIBED(on_ret_umsg_1);
115 ENSURE_SUBSCRIBED(on_ret_umsg_2);
116 ENSURE_SUBSCRIBED(on_ret_umsg_3);
117 ENSURE_SUBSCRIBED(on_ret_umsg_4);
118 ENSURE_SUBSCRIBED(on_ret_umsg_5);
119 ENSURE_SUBSCRIBED(on_ret_umsg_6);
120
121 #undef ENSURE_SUBSCRIBED
122 }
123
124 virtual void
so_evt_start()125 so_evt_start() override
126 {
127 so_5::send<sig_1>( *this );
128 so_5::send<sig_2>( *this );
129
130 so_5::send<msg_1>( *this );
131 so_5::send<msg_2>( *this );
132 so_5::send<msg_3>( *this );
133 so_5::send<so_5::mutable_msg<msg_4>>( *this );
134 so_5::send<so_5::mutable_msg<msg_5>>( *this );
135
136 so_5::send<umsg_1>( *this );
137 so_5::send<umsg_2>( *this );
138 so_5::send<umsg_3>( *this );
139 so_5::send<so_5::mutable_msg<umsg_4>>( *this );
140 so_5::send<so_5::mutable_msg<umsg_5>>( *this );
141 so_5::send<umsg_6>( *this );
142
143 so_5::send<ret_msg_1>( *this );
144 so_5::send<ret_msg_2>( *this );
145 so_5::send<ret_msg_3>( *this );
146 so_5::send<so_5::mutable_msg<ret_msg_4>>( *this );
147 so_5::send<so_5::mutable_msg<ret_msg_5>>( *this );
148
149 so_5::send<ret_umsg_1>( *this );
150 so_5::send<ret_umsg_2>( *this );
151 so_5::send<ret_umsg_3>( *this );
152 so_5::send<so_5::mutable_msg<ret_umsg_4>>( *this );
153 so_5::send<so_5::mutable_msg<ret_umsg_5>>( *this );
154 so_5::send<ret_umsg_6>( *this );
155
156 so_5::send<finish>( *this );
157 }
158
159 private:
160 void
on_sig_1(const mhood_t<sig_1> &)161 on_sig_1(const mhood_t<sig_1> &)
162 {
163 so_drop_subscription(
164 so_direct_mbox(), so_default_state(), &a_test_t::on_sig_1 );
165 }
166
167 void
on_sig_2(mhood_t<sig_2>)168 on_sig_2(mhood_t<sig_2>)
169 {
170 so_drop_subscription(
171 so_direct_mbox(), so_default_state(), &a_test_t::on_sig_2 );
172 }
173
174 void
on_msg_1(const msg_1 &)175 on_msg_1(const msg_1 &)
176 {
177 so_drop_subscription(
178 so_direct_mbox(), so_default_state(), &a_test_t::on_msg_1 );
179 }
180 void
on_msg_2(const mhood_t<msg_2> &)181 on_msg_2(const mhood_t<msg_2> &)
182 {
183 so_drop_subscription(
184 so_direct_mbox(), so_default_state(), &a_test_t::on_msg_2 );
185 }
186 void
on_msg_3(mhood_t<msg_3>)187 on_msg_3(mhood_t<msg_3>)
188 {
189 so_drop_subscription(
190 so_direct_mbox(), so_default_state(), &a_test_t::on_msg_3 );
191 }
192 void
on_msg_4(mutable_mhood_t<msg_4>)193 on_msg_4(mutable_mhood_t<msg_4>)
194 {
195 so_drop_subscription(
196 so_direct_mbox(), so_default_state(), &a_test_t::on_msg_4 );
197 }
198 void
on_msg_5(const mutable_mhood_t<msg_5> &)199 on_msg_5(const mutable_mhood_t<msg_5> &)
200 {
201 so_drop_subscription(
202 so_direct_mbox(), so_default_state(), &a_test_t::on_msg_5 );
203 }
204
205 void
on_umsg_1(const umsg_1 &)206 on_umsg_1(const umsg_1 &)
207 {
208 so_drop_subscription(
209 so_direct_mbox(), so_default_state(), &a_test_t::on_umsg_1 );
210 }
211 void
on_umsg_2(const mhood_t<umsg_2> &)212 on_umsg_2(const mhood_t<umsg_2> &)
213 {
214 so_drop_subscription(
215 so_direct_mbox(), so_default_state(), &a_test_t::on_umsg_2 );
216 }
217 void
on_umsg_3(mhood_t<umsg_3>)218 on_umsg_3(mhood_t<umsg_3>)
219 {
220 so_drop_subscription(
221 so_direct_mbox(), so_default_state(), &a_test_t::on_umsg_3 );
222 }
223 void
on_umsg_4(mutable_mhood_t<umsg_4>)224 on_umsg_4(mutable_mhood_t<umsg_4>)
225 {
226 so_drop_subscription(
227 so_direct_mbox(), so_default_state(), &a_test_t::on_umsg_4 );
228 }
229 void
on_umsg_5(const mutable_mhood_t<umsg_5> &)230 on_umsg_5(const mutable_mhood_t<umsg_5> &)
231 {
232 so_drop_subscription(
233 so_direct_mbox(), so_default_state(), &a_test_t::on_umsg_5 );
234 }
235 void
on_umsg_6(umsg_6)236 on_umsg_6(umsg_6)
237 {
238 so_drop_subscription(
239 so_direct_mbox(), so_default_state(), &a_test_t::on_umsg_6 );
240 }
241
242 int
on_ret_msg_1(const ret_msg_1 &)243 on_ret_msg_1(const ret_msg_1 &)
244 {
245 so_drop_subscription(
246 so_direct_mbox(), so_default_state(), &a_test_t::on_ret_msg_1 );
247 return 0;
248 }
249 int
on_ret_msg_2(const mhood_t<ret_msg_2> &)250 on_ret_msg_2(const mhood_t<ret_msg_2> &)
251 {
252 so_drop_subscription(
253 so_direct_mbox(), so_default_state(), &a_test_t::on_ret_msg_2 );
254 return 0;
255 }
256 int
on_ret_msg_3(mhood_t<ret_msg_3>)257 on_ret_msg_3(mhood_t<ret_msg_3>)
258 {
259 so_drop_subscription(
260 so_direct_mbox(), so_default_state(), &a_test_t::on_ret_msg_3 );
261 return 0;
262 }
263 int
on_ret_msg_4(mutable_mhood_t<ret_msg_4>)264 on_ret_msg_4(mutable_mhood_t<ret_msg_4>)
265 {
266 so_drop_subscription(
267 so_direct_mbox(), so_default_state(), &a_test_t::on_ret_msg_4 );
268 return 0;
269 }
270 int
on_ret_msg_5(const mutable_mhood_t<ret_msg_5> &)271 on_ret_msg_5(const mutable_mhood_t<ret_msg_5> &)
272 {
273 so_drop_subscription(
274 so_direct_mbox(), so_default_state(), &a_test_t::on_ret_msg_5 );
275 return 0;
276 }
277
278 int
on_ret_umsg_1(const ret_umsg_1 &)279 on_ret_umsg_1(const ret_umsg_1 &)
280 {
281 so_drop_subscription(
282 so_direct_mbox(), so_default_state(), &a_test_t::on_ret_umsg_1 );
283 return 0;
284 }
285 int
on_ret_umsg_2(const mhood_t<ret_umsg_2> &)286 on_ret_umsg_2(const mhood_t<ret_umsg_2> &)
287 {
288 so_drop_subscription(
289 so_direct_mbox(), so_default_state(), &a_test_t::on_ret_umsg_2 );
290 return 0;
291 }
292 int
on_ret_umsg_3(mhood_t<ret_umsg_3>)293 on_ret_umsg_3(mhood_t<ret_umsg_3>)
294 {
295 so_drop_subscription(
296 so_direct_mbox(), so_default_state(), &a_test_t::on_ret_umsg_3 );
297 return 0;
298 }
299 int
on_ret_umsg_4(mutable_mhood_t<ret_umsg_4>)300 on_ret_umsg_4(mutable_mhood_t<ret_umsg_4>)
301 {
302 so_drop_subscription(
303 so_direct_mbox(), so_default_state(), &a_test_t::on_ret_umsg_4 );
304 return 0;
305 }
306 int
on_ret_umsg_5(const mutable_mhood_t<ret_umsg_5> &)307 on_ret_umsg_5(const mutable_mhood_t<ret_umsg_5> &)
308 {
309 so_drop_subscription(
310 so_direct_mbox(), so_default_state(), &a_test_t::on_ret_umsg_5 );
311 return 0;
312 }
313 int
on_ret_umsg_6(ret_umsg_6)314 on_ret_umsg_6(ret_umsg_6)
315 {
316 so_drop_subscription(
317 so_direct_mbox(), so_default_state(), &a_test_t::on_ret_umsg_6 );
318 return 0;
319 }
320
321 void
on_finish(mhood_t<finish>)322 on_finish(mhood_t<finish>)
323 {
324 #define ENSURE_UNSUBSCRIBED(handler) \
325 ensure( !so_has_subscription(so_direct_mbox(), \
326 so_default_state(), \
327 &a_test_t:: handler), \
328 #handler " must not be subscribed" )
329
330 ENSURE_UNSUBSCRIBED(on_sig_1);
331 ENSURE_UNSUBSCRIBED(on_sig_2);
332 ENSURE_UNSUBSCRIBED(on_msg_1);
333 ENSURE_UNSUBSCRIBED(on_msg_2);
334 ENSURE_UNSUBSCRIBED(on_msg_3);
335 ENSURE_UNSUBSCRIBED(on_msg_4);
336 ENSURE_UNSUBSCRIBED(on_msg_5);
337
338 ENSURE_UNSUBSCRIBED(on_umsg_1);
339 ENSURE_UNSUBSCRIBED(on_umsg_2);
340 ENSURE_UNSUBSCRIBED(on_umsg_3);
341 ENSURE_UNSUBSCRIBED(on_umsg_4);
342 ENSURE_UNSUBSCRIBED(on_umsg_5);
343 ENSURE_UNSUBSCRIBED(on_umsg_6);
344
345 ENSURE_UNSUBSCRIBED(on_ret_msg_1);
346 ENSURE_UNSUBSCRIBED(on_ret_msg_2);
347 ENSURE_UNSUBSCRIBED(on_ret_msg_3);
348 ENSURE_UNSUBSCRIBED(on_ret_msg_4);
349 ENSURE_UNSUBSCRIBED(on_ret_msg_5);
350
351 ENSURE_UNSUBSCRIBED(on_ret_umsg_1);
352 ENSURE_UNSUBSCRIBED(on_ret_umsg_2);
353 ENSURE_UNSUBSCRIBED(on_ret_umsg_3);
354 ENSURE_UNSUBSCRIBED(on_ret_umsg_4);
355 ENSURE_UNSUBSCRIBED(on_ret_umsg_5);
356 ENSURE_UNSUBSCRIBED(on_ret_umsg_6);
357
358 #undef ENSURE_UNSUBSCRIBED
359
360 so_deregister_agent_coop_normally();
361 }
362 };
363
364 int
main()365 main()
366 {
367 try
368 {
369 run_with_time_limit(
370 []()
371 {
372 so_5::launch( []( so_5::environment_t & env ) {
373 env.introduce_coop( []( so_5::coop_t & coop ) {
374 coop.make_agent< a_test_t >();
375 } );
376 } );
377 },
378 20,
379 "so_has_subscription test" );
380 }
381 catch( const std::exception & ex )
382 {
383 std::cerr << "Error: " << ex.what() << std::endl;
384 return 1;
385 }
386
387 return 0;
388 }
389
390