#include <iostream>
#include <string>
using namespace std;
using namespace std::chrono;
{
const state_t st_idle{ this };
const state_t st_started{ this };
const state_t st_finished{ this };
using clock = steady_clock;
public :
struct ask_status {};
struct status_idle {};
struct status_in_progress {};
struct status_finished { unsigned long long m_ms; };
struct start_ping_pong { unsigned int m_pings; };
struct ping_pong_stopped {};
a_supervisor(
context_t ctx,
, m_req_mbox{ std::move(req_mbox) }
, m_chain{ std::move(chain) }
{}
{
this >>= st_idle;
st_idle
.event( m_req_mbox, [this]( ask_status ) {
} )
.event( m_req_mbox, &a_supervisor::evt_start_ping_pong );
st_started
.event( m_req_mbox, [this]( ask_status ) {
} )
.event( [this]( ping_pong_stopped ) {
m_last_duration_ms = static_cast< unsigned long long >(
duration_cast< milliseconds >(
clock::now() - m_started_at ).count() );
st_finished.activate();
} );
st_finished
.event( m_req_mbox, [this]( ask_status ) {
} )
.event( m_req_mbox, &a_supervisor::evt_start_ping_pong );
}
private :
clock::time_point m_started_at;
unsigned long long m_last_duration_ms;
struct ping{ unsigned int m_v; };
struct pong{ unsigned int m_v; };
{
unsigned int m_pings;
public :
a_pinger(
context_t ctx,
unsigned int pings )
, m_parent_mbox{ std::move(parent_mbox) }
, m_pings( pings )
{
so_subscribe_self().event(
[this]( mhood_t<pong> reply ) {
if( reply->m_v )
else
{
so_deregister_agent_coop_normally();
}
} );
}
void set_ponger(
const so_5::mbox_t & mbox ) { m_ponger = mbox; }
void so_evt_start() override
{
}
};
{
public :
{
so_subscribe_self().event(
[this]( mhood_t<ping> req ) {
} );
}
void set_pinger(
const so_5::mbox_t & mbox ) { m_pinger = mbox; }
};
void evt_start_ping_pong( start_ping_pong evt )
{
this >>= st_started;
m_started_at = clock::now();
{
evt.m_pings );
pinger->set_ponger( ponger->so_direct_mbox() );
ponger->set_pinger( pinger->so_direct_mbox() );
} );
}
};
void demo()
{
auto chain = create_mchain( sobj );
coop.
make_agent< a_supervisor >( req_mbox, chain );
} );
while( true )
{
cout << "Enter command (status,start,exit): " << flush;
string choice;
cin >> choice;
if( "status" == choice )
{
from( chain ).handle_all().empty_timeout( milliseconds(200) ),
[]( a_supervisor::status_idle ) {
cout << "status: IDLE" << endl;
},
[]( a_supervisor::status_in_progress ) {
cout << "status: IN PROGRESS" << endl;
},
[]( a_supervisor::status_finished v ) {
cout << "status: finished in " << v.m_ms << "ms" << endl;
} );
if( !r.handled() )
cout << "--- no response from supervisor ---" << endl;
}
else if( "start" == choice )
{
cout << "Enter pings count: " << flush;
unsigned int pings = 0;
cin >> pings;
}
else if( "exit" == choice || "quit" == choice )
break;
}
}
int main()
{
try
{
demo();
}
catch( const exception & x )
{
cerr << "Exception: " << x.what() << endl;
return 2;
}
return 0;
}
A helper header file for including all public SObjectizer stuff.
virtual void so_define_agent()
Hook on define agent for SObjectizer.
const mbox_t & so_direct_mbox() const
Get the agent's direct mbox.
environment_t & so_environment() const noexcept
Access to the SObjectizer Environment which this agent is belong.
Agent * make_agent(Args &&... args)
Helper method for simplification of agents creation.
mbox_t create_mbox()
Create an anonymous MPMC mbox.
decltype(auto) introduce_coop(Args &&... args)
Helper method for simplification of cooperation creation and registration.
environment_t & environment() const
Access to wrapped environment.
SO_5_FUNC dispatcher_handle_t make_dispatcher(environment_t &env, const std::string_view data_sources_name_base, disp_params_t params)
Create an instance of active_obj dispatcher.
mchain_receive_params_t< mchain_props::msg_count_status_t::undefined > from(mchain_t chain)
A helper function for simplification of creation of mchain_receive_params instance.
decltype(auto) introduce_child_coop(agent_t &owner, Args &&... args)
A simple way for creating and registering child cooperation.
void send(Target &&to, Args &&... args)
A utility function for creating and delivering a message or a signal.
mchain_receive_result_t receive(const mchain_receive_params_t< Msg_Count_Status > ¶ms, Handlers &&... handlers)
Advanced version of receive from mchain.