SObjectizer 5.8
Loading...
Searching...
No Matches
so_5/agent_name/main.cpp
/*
* A sample of usage of agent name.
*/
#include <so_5/all.hpp>
#include <iostream>
#include <set>
// Name of mbox for sending information to agents registry.
const std::string registry_mbox_name{ "agents_registry" };
// Agent that plays role of agents registry.
class agents_registry final : public so_5::agent_t
{
public:
// Message for informing about start of an agent.
struct agent_started final : public so_5::message_t
{
const std::string m_name;
agent_started( std::string name ) : m_name{ std::move(name) }
{}
};
// Message for informing that agent finished its work.
struct agent_finished final : public so_5::message_t
{
const std::string m_name;
agent_finished( std::string name ) : m_name{ std::move(name) }
{}
};
agents_registry( context_t ctx )
: so_5::agent_t{ std::move(ctx) }
{}
void so_define_agent() override
{
so_subscribe( so_environment().create_mbox( registry_mbox_name ) )
.event( &agents_registry::evt_agent_started )
.event( &agents_registry::evt_agent_finished )
;
.event( &agents_registry::evt_show_registry )
;
}
void so_evt_start() override
{
// Initiate periodic message for showing the content of the registry.
m_show_timer = so_5::send_periodic< show_registry >( *this,
std::chrono::milliseconds{ 20 },
std::chrono::milliseconds{ 20 } );
}
private:
// Periodic signal for showing the current content of the registry.
struct show_registry final : public so_5::signal_t {};
// A list of currently working agents.
std::set< std::string > m_registry;
// Timer for showing the current content of the registry.
so_5::timer_id_t m_show_timer;
void evt_agent_started( mhood_t<agent_started> cmd )
{
m_registry.insert( cmd->m_name );
std::cout << " started: " << cmd->m_name << std::endl;
}
void evt_agent_finished( mhood_t<agent_finished> cmd )
{
m_registry.erase( cmd->m_name );
std::cout << "finished: " << cmd->m_name << std::endl;
if( m_registry.empty() )
// It's time to complete.
}
void evt_show_registry( mhood_t<show_registry> )
{
std::cout << "--- registry begin ---" << std::endl;
for( const auto & name : m_registry )
std::cout << " " << name << std::endl;
std::cout << "--- registry end ---" << std::endl;
}
};
// Base class for worker. Agents of this type have no names.
class simple_worker : public so_5::agent_t
{
public:
simple_worker( context_t ctx, std::chrono::milliseconds work_time )
: so_5::agent_t{ std::move(ctx) }
, m_work_time{ work_time }
{}
void so_define_agent() override
{
so_subscribe_self().event( &simple_worker::evt_done );
}
void so_evt_start() override
{
// Should inform about the start.
so_environment().create_mbox( registry_mbox_name ),
so_agent_name().to_string() );
// Limit the work time.
so_5::send_delayed< done >( *this, m_work_time );
}
void so_evt_finish() override
{
// Should inform about the finish.
so_environment().create_mbox( registry_mbox_name ),
so_agent_name().to_string() );
}
private:
// Signal for limiting work time of the agent.
struct done final : public so_5::signal_t {};
// How long the agent should work.
const std::chrono::milliseconds m_work_time;
void evt_done( mhood_t<done> )
{
}
};
// Type of worker with name.
//
// It's derived from simple_worker just to make example code shorter.
class named_worker : public simple_worker
{
public:
named_worker( context_t ctx, std::string_view name, std::chrono::milliseconds work_time )
: simple_worker{ ctx + name_for_agent(name), work_time }
{}
// There is no need to define something else.
};
int main()
{
try
{
// Starting SObjectizer.
// A function for SO Environment initialization.
[]( so_5::environment_t & env )
{
// Starting the registry.
env.make_agent< agents_registry >() );
// Starting workers.
using namespace std::chrono_literals;
env.make_agent< simple_worker >( 30ms ) );
env.make_agent< simple_worker >( 50ms ) );
env.make_agent< named_worker >( "Alice", 50ms ) );
env.make_agent< simple_worker >( 70ms ) );
env.make_agent< named_worker >( "Bob", 90ms ) );
} );
}
catch( const std::exception & ex )
{
std::cerr << "Error: " << ex.what() << std::endl;
return 1;
}
return 0;
}
A helper header file for including all public SObjectizer stuff.
A base class for agents.
Definition agent.hpp:673
virtual void so_define_agent()
Hook on define agent for SObjectizer.
Definition agent.cpp:841
subscription_bind_t so_subscribe_self()
Initiate subscription to agent's direct mbox.
Definition agent.hpp:1416
void so_deregister_agent_coop_normally()
A helper method for deregistering agent's coop in case of normal deregistration.
Definition agent.cpp:982
virtual void so_evt_finish()
Hook of agent finish in SObjectizer.
Definition agent.cpp:707
agent_identity_t so_agent_name() const noexcept
Get an optional name of the agent.
Definition agent.cpp:1000
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
SObjectizer Environment.
coop_handle_t register_agent_as_coop(std::unique_ptr< A > agent)
Register single agent as a cooperation.
std::unique_ptr< Agent > make_agent(Args &&... args)
Helper method for simplification of agents creation.
A base class for agent messages.
Definition message.hpp:47
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
An indentificator for the timer.
Definition timers.hpp:73
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
timer_id_t send_periodic(Target &&target, std::chrono::steady_clock::duration pause, std::chrono::steady_clock::duration period, Args &&... args)
A utility function for creating and delivering a periodic message to the specified destination.
void send(Target &&to, Args &&... args)
A utility function for creating and delivering a message or a signal.
void send_delayed(Target &&target, std::chrono::steady_clock::duration pause, Args &&... args)
A utility function for creating and delivering a delayed message to the specified destination.