SObjectizer  5.5
so_5/stop_guard/main.cpp
/*
* A sample of using stop_guard.
*/
#include <iostream>
// Main SObjectizer header files.
#include <so_5/all.hpp>
// Definition of stop_guard for the example.
// This guard sends a shutdown_started signal to the specified mbox.
class example_guard final
, public std::enable_shared_from_this< example_guard >
{
public :
// A signal to be sent when shutdown is started.
struct shutdown_started final : public so_5::signal_t {};
example_guard(
// Mbox to which shutdown_started must be sent.
so_5::mbox_t dest ) : m_dest( std::move(dest) )
{}
void stop() noexcept override
{
so_5::send< shutdown_started >( m_dest );
}
private :
const so_5::mbox_t m_dest;
};
// Definition of an agent for SObjectizer.
class worker final : public so_5::agent_t
{
// Worker will have two states:
state_t st_normal{ this }, st_shutdown{ this };
// These signals will be used by worker.
struct timer final : public so_5::signal_t {};
struct terminate_work final : public so_5::signal_t {};
public:
worker( context_t ctx ) : so_5::agent_t( std::move(ctx) )
{
this >>= st_normal;
st_normal
.event( &worker::on_timer_normal )
.event( &worker::on_shutdown_started );
st_shutdown
.event( &worker::on_timer_shutdown )
.event( &worker::on_terminate );
}
// A reaction to start of work in SObjectizer.
void so_evt_start() override
{
// Stop_guard must be created and installed.
m_guard = std::make_shared< example_guard >( so_direct_mbox() );
// Periodic timer message must be sent.
m_timer = so_5::send_periodic< timer >( *this,
std::chrono::milliseconds(125),
std::chrono::milliseconds(125) );
}
private :
// Stop_guard to be used by this agent.
// Timer ID for periodic message.
void on_timer_normal( mhood_t<timer> )
{
std::cout << "working in normal mode..." << std::endl;
}
void on_timer_shutdown( mhood_t<timer> )
{
std::cout << "working in shutdown mode..." << std::endl;
}
void on_shutdown_started( mhood_t<example_guard::shutdown_started> )
{
std::cout << "shutdown is in progress!" << std::endl;
this >>= st_shutdown;
so_5::send_delayed< terminate_work >( *this,
std::chrono::milliseconds(300) );
}
void on_terminate( mhood_t<terminate_work> )
{
std::cout << "terminate work." << std::endl;
}
};
// This agent will initiate the stop operation.
class work_stopper final : public so_5::agent_t
{
struct stop_work final : public so_5::signal_t {};
public :
work_stopper( context_t ctx ) : so_5::agent_t( std::move(ctx) )
{
so_subscribe_self().event( [this]( mhood_t<stop_work> ) {
// Initiate shutdown of SObjectizer Environment.
} );
}
void so_evt_start() override
{
so_5::send_delayed< stop_work >( *this,
std::chrono::milliseconds(400) );
}
};
int main()
{
try
{
// Starting SObjectizer.
// A function for SO Environment initialization.
[]( so_5::environment_t & env )
{
// Create coop with example's agents.
env.introduce_coop( []( so_5::coop_t & coop ) {
coop.make_agent< worker >();
coop.make_agent< work_stopper >();
} );
} );
}
catch( const std::exception & ex )
{
std::cerr << "Error: " << ex.what() << std::endl;
return 1;
}
return 0;
}