1 /*
2  * A test for redirection of mutable messages.
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 #include <test/3rd_party/utest_helper/helper.hpp>
11 
12 using namespace std;
13 
14 class sobj_message_tester final : public so_5::agent_t
15 {
16 	struct hello final : public so_5::message_t
17 	{
18 		std::string m_content;
hellosobj_message_tester::hello19 		hello( std::string content ) : m_content( std::move(content) ) {}
20 	};
21 
22 public :
sobj_message_tester(context_t ctx)23 	sobj_message_tester(context_t ctx)
24 		:	so_5::agent_t(std::move(ctx))
25 	{
26 		so_subscribe_self().event( &sobj_message_tester::on_hello );
27 	}
28 
29 	virtual void
so_evt_start()30 	so_evt_start() override
31 	{
32 		so_5::send< so_5::mutable_msg< hello > >( *this, "hello" );
33 	}
34 
35 private :
36 	const hello * m_received_ptr{ nullptr };
37 
on_hello(mhood_t<so_5::mutable_msg<hello>> cmd)38 	void on_hello( mhood_t< so_5::mutable_msg< hello > > cmd )
39 	{
40 		std::cout << "sobj: " << cmd->m_content << std::endl;
41 		if( !m_received_ptr )
42 		{
43 			m_received_ptr = cmd.get();
44 
45 			cmd->m_content = "bye";
46 			send( *this, std::move(cmd) );
47 		}
48 		else
49 		{
50 			ensure( m_received_ptr == cmd.get(), "expect the same message" );
51 			ensure( "bye" == cmd->m_content, "expect 'bye' message" );
52 
53 			so_deregister_agent_coop_normally();
54 		}
55 	}
56 };
57 
58 class user_message_tester final : public so_5::agent_t
59 {
60 	struct hello final
61 	{
62 		std::string m_content;
hellouser_message_tester::hello63 		hello( std::string content ) : m_content( std::move(content) ) {}
64 	};
65 
66 public :
user_message_tester(context_t ctx)67 	user_message_tester(context_t ctx)
68 		:	so_5::agent_t(std::move(ctx))
69 	{
70 		so_subscribe_self().event( &user_message_tester::on_hello );
71 	}
72 
73 	virtual void
so_evt_start()74 	so_evt_start() override
75 	{
76 		so_5::send< so_5::mutable_msg< hello > >( *this, "hello" );
77 	}
78 
79 private :
80 	const hello * m_received_ptr{ nullptr };
81 
on_hello(mhood_t<so_5::mutable_msg<hello>> cmd)82 	void on_hello( mhood_t< so_5::mutable_msg< hello > > cmd )
83 	{
84 		std::cout << "user: " << cmd->m_content << std::endl;
85 		if( !m_received_ptr )
86 		{
87 			m_received_ptr = cmd.get();
88 
89 			cmd->m_content = "bye";
90 			send( *this, std::move(cmd) );
91 		}
92 		else
93 		{
94 			ensure( m_received_ptr == cmd.get(), "expect the same message" );
95 			ensure( "bye" == cmd->m_content, "expect 'bye' message" );
96 
97 			so_deregister_agent_coop_normally();
98 		}
99 	}
100 };
101 
102 int
main()103 main()
104 {
105 	try
106 	{
107 		run_with_time_limit(
108 			[]() {
109 				so_5::launch(
110 					[&](so_5::environment_t & env) {
111 						env.register_agent_as_coop(
112 								env.make_agent<sobj_message_tester>());
113 
114 						env.register_agent_as_coop(
115 								env.make_agent<user_message_tester>());
116 					},
117 					[](so_5::environment_params_t & params) {
118 						(void)params;
119 #if 0
120 						params.message_delivery_tracer( so_5::msg_tracing::std_cout_tracer() );
121 #endif
122 					} );
123 			},
124 			5,
125 			"simple agent");
126 	}
127 	catch(const exception & ex)
128 	{
129 		cerr << "Error: " << ex.what() << endl;
130 		return 1;
131 	}
132 
133 	return 0;
134 }
135 
136