1 /*
2 * Test of resending the same message as a mutable.
3 */
4
5 #include <so_5/all.hpp>
6
7 #include <test/3rd_party/various_helpers/time_limited_execution.hpp>
8 #include <test/3rd_party/various_helpers/ensure.hpp>
9
10 struct message final : public so_5::message_t
11 {
12 std::string m_value;
13
messagemessage14 message( std::string value ) : m_value{ std::move(value) } {}
15 };
16
17 class first_sender_t final : public so_5::agent_t
18 {
19 public :
first_sender_t(context_t ctx,so_5::mbox_t second)20 first_sender_t( context_t ctx, so_5::mbox_t second )
21 : so_5::agent_t{ std::move(ctx) }
22 , m_second{ std::move(second) }
23 , m_message{ std::piecewise_construct, "hello!" }
24 {}
25
26 void
so_evt_start()27 so_evt_start() override
28 {
29 so_5::send( m_second, std::move(m_message) );
30 }
31
32 private :
33 const so_5::mbox_t m_second;
34 so_5::message_holder_t< so_5::mutable_msg< message > > m_message;
35 };
36
37 class second_sender_t final : public so_5::agent_t
38 {
39 public :
second_sender_t(context_t ctx,so_5::mbox_t third)40 second_sender_t( context_t ctx, so_5::mbox_t third )
41 : so_5::agent_t{ std::move(ctx) }
42 , m_third{ std::move(third) }
43 {
44 so_subscribe_self().event( &second_sender_t::on_message );
45 }
46
47 private :
48 const so_5::mbox_t m_third;
49
50 void
on_message(so_5::mutable_mhood_t<message> cmd)51 on_message( so_5::mutable_mhood_t<message> cmd )
52 {
53 cmd->m_value += "!";
54 so_5::send( m_third, std::move(cmd) );
55 }
56 };
57
58 class third_sender_t final : public so_5::agent_t
59 {
60 struct resend final : public so_5::signal_t {};
61
62 public :
third_sender_t(context_t ctx,so_5::mbox_t fourth)63 third_sender_t( context_t ctx, so_5::mbox_t fourth )
64 : so_5::agent_t{ std::move(ctx) }
65 , m_fourth{ std::move(fourth) }
66 {
67 so_subscribe_self()
68 .event( &third_sender_t::on_message )
69 .event( &third_sender_t::on_resend );
70 }
71
72 private :
73 const so_5::mbox_t m_fourth;
74 so_5::message_holder_t< so_5::mutable_msg<message> > m_message;
75
76 void
on_message(so_5::mutable_mhood_t<message> cmd)77 on_message( so_5::mutable_mhood_t<message> cmd )
78 {
79 cmd->m_value += "!";
80 m_message = cmd.make_holder();
81
82 so_5::send<resend>( *this );
83 }
84
85 void
on_resend(so_5::mhood_t<resend>)86 on_resend( so_5::mhood_t<resend> )
87 {
88 so_5::send( m_fourth, std::move(m_message) );
89 }
90 };
91
92 class last_t final : public so_5::agent_t
93 {
94 public :
last_t(context_t ctx)95 last_t( context_t ctx ) : so_5::agent_t{ std::move(ctx) }
96 {
97 so_subscribe_self().event( &last_t::on_message );
98 }
99
100 private :
101 void
on_message(so_5::mutable_mhood_t<message> cmd)102 on_message( so_5::mutable_mhood_t<message> cmd )
103 {
104 ensure_or_die( cmd->m_value == "hello!!!",
105 "unexpected value: " + cmd->m_value );
106
107 so_deregister_agent_coop_normally();
108 }
109 };
110
111 int
main()112 main()
113 {
114 run_with_time_limit( [] {
115 so_5::launch(
116 []( so_5::environment_t & env )
117 {
118 env.introduce_coop( []( so_5::coop_t & coop ) {
119 auto last = coop.make_agent< last_t >();
120 auto third = coop.make_agent< third_sender_t >(
121 last->so_direct_mbox() );
122 auto second = coop.make_agent< second_sender_t >(
123 third->so_direct_mbox() );
124 coop.make_agent< first_sender_t >(
125 second->so_direct_mbox() );
126 } );
127 } );
128 },
129 10 );
130
131 return 0;
132 }
133
134