SObjectizer 5.8
Loading...
Searching...
No Matches
so_5/ping_pong/main.cpp
#include <iostream>
#include <set>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <so_5/all.hpp>
#if defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
#endif
struct cfg_t
{
unsigned int m_request_count;
bool m_active_objects;
cfg_t()
: m_request_count( 1000 )
, m_active_objects( false )
{}
};
cfg_t try_parse_cmdline(
int argc,
char ** argv )
{
if( 1 == argc )
{
std::cout << "usage:\n"
"sample.so_5.ping_pong <options>\n"
"\noptions:\n"
"-a, --active-objects agents should be active objects\n"
"-r, --requests count of requests to send\n"
<< std::endl;
throw std::runtime_error( "No command-line errors" );
}
auto is_arg = []( const char * value,
const char * v1,
const char * v2 )
{
return 0 == std::strcmp( value, v1 ) ||
0 == std::strcmp( value, v2 );
};
cfg_t result;
char ** current = argv + 1;
char ** last = argv + argc;
while( current != last )
{
if( is_arg( *current, "-a", "--active-objects" ) )
{
result.m_active_objects = true;
}
else if( is_arg( *current, "-r", "--requests" ) )
{
++current;
if( current == last )
throw std::runtime_error( "-r requires argument" );
result.m_request_count = static_cast< unsigned int >(
std::atoi( *current ) );
}
else
{
throw std::runtime_error(
std::string( "unknown argument: " ) + *current );
}
++current;
}
return result;
}
void show_cfg(
const cfg_t & cfg )
{
std::cout << "Configuration: "
<< "active objects: " << ( cfg.m_active_objects ? "yes" : "no" )
<< ", requests: " << cfg.m_request_count
<< std::endl;
}
void run_sample(
const cfg_t & cfg )
{
// Types of signals for the agents.
struct msg_ping final : public so_5::signal_t {};
struct msg_pong final : public so_5::signal_t {};
// Type of pinger agent.
class pinger_t final : public so_5::agent_t
{
const so_5::mbox_t m_mbox;
unsigned int m_pings_left;
public :
pinger_t(
context_t ctx,
unsigned int pings_left )
: so_5::agent_t{ std::move(ctx) }
, m_mbox{ std::move(mbox) }
, m_pings_left{ pings_left }
{
so_subscribe( m_mbox ).event(
[this]( mhood_t<msg_pong> ) {
if( m_pings_left ) --m_pings_left;
if( m_pings_left )
else
} );
}
void so_evt_start() override
{
}
};
// Type of ponger agent.
class ponger_t final : public so_5::agent_t
{
public :
ponger_t( context_t ctx, const so_5::mbox_t & mbox )
: so_5::agent_t{ std::move(ctx) }
{
[mbox]( mhood_t<msg_ping> ) {
} );
}
};
[&cfg]( so_5::environment_t & env )
{
// Agents will be active or passive.
// It depends on sample arguments.
cfg.m_active_objects ?
[&]( so_5::coop_t & coop )
{
auto mbox = env.create_mbox();
// Pinger agent.
coop.make_agent< pinger_t >( mbox, cfg.m_request_count );
// Ponger agent.
coop.make_agent< ponger_t >( std::cref(mbox) );
} );
} );
}
int main( int argc, char ** argv )
{
try
{
cfg_t cfg = try_parse_cmdline( argc, argv );
show_cfg( cfg );
run_sample( cfg );
return 0;
}
catch( const std::exception & x )
{
std::cerr << "*** Exception caught: " << x.what() << std::endl;
}
return 2;
}
A helper header file for including all public SObjectizer stuff.
A base class for agents.
Definition agent.hpp:673
environment_t & so_environment() const noexcept
Access to the SObjectizer Environment which this agent is belong.
Definition agent.cpp:853
subscription_bind_t so_subscribe(const mbox_t &mbox_ref)
Initiate subscription.
Definition agent.hpp:1359
virtual void so_evt_start()
Hook on agent start inside SObjectizer.
Definition agent.cpp:701
Agent cooperation.
Definition coop.hpp:389
disp_binder_shptr_t binder() const noexcept
Get a binder for that dispatcher.
SObjectizer Environment.
void stop() noexcept
Send a shutdown signal to the Run-Time.
decltype(auto) introduce_coop(Args &&... args)
Helper method for simplification of cooperation creation and registration.
A base class for agent signals.
Definition message.hpp:275
std::enable_if< details::is_agent_method_pointer< details::method_arity::unary, Method_Pointer >::value, subscription_bind_t & >::type event(Method_Pointer pfn, thread_safety_t thread_safety=not_thread_safe)
Make subscription to the message.
Definition agent.hpp:3490
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.
Private part of message limit implementation.
Definition agent.cpp:33
void launch(Init_Routine &&init_routine)
Launch a SObjectizer Environment with default parameters.
Definition api.hpp:142
void send(Target &&to, Args &&... args)
A utility function for creating and delivering a message or a signal.
disp_binder_shptr_t make_default_disp_binder(environment_t &env)
Create an instance of the default dispatcher binder.