#include <iostream>
{
std::string m_payload;
msg_first( std::string payload ) : m_payload{ std::move(payload) }
{}
};
{
std::string m_payload;
msg_second( std::string payload ) : m_payload{
std::move(payload) }
{}
};
{
public:
a_consumer_t( context_t ctx, std::string name )
, m_name{
std::move(name) }
{}
{
.
event( &a_consumer_t::evt_first )
.event( &a_consumer_t::evt_second )
;
}
private:
void evt_first( mutable_mhood_t<msg_first> cmd )
{
std::cout << m_name << " => msg_first arrived: "
<< cmd->m_payload << std::endl;
}
void evt_second( mutable_mhood_t<msg_second> cmd )
{
std::cout << m_name << " => msg_second arrived: "
<< cmd->m_payload << std::endl;
}
};
{
public:
a_producer_t(
context_t ctx,
const a_consumer_t & consumer )
, m_dest_mbox{ consumer.so_direct_mbox() }
{}
{
}
{
}
private:
void evt_quit( mhood_t<msg_quit> )
{
std::cout << "--- Work completed ---" << std::endl;
}
};
void run_normal_scenario()
{
std::cout << "*** Start of normal scenario ***" << std::endl;
auto * consumer = coop.
make_agent< a_consumer_t >(
"normal" );
} );
} );
}
{
public:
a_actual_consumer_t( context_t ctx, std::string name )
, m_name{
std::move(name) }
{}
{
.
event( &a_actual_consumer_t::evt_second )
;
}
private:
void evt_second( mutable_mhood_t<msg_second> cmd )
{
std::cout << m_name << " => msg_second arrived: "
<< cmd->m_payload << std::endl;
}
};
{
[[nodiscard]]
static bool should_intercept( const std::type_index & msg_type )
{
}
public:
intercepting_mbox_t(
: m_source{
std::move(source) }
, m_target{
std::move(target) }
{}
{
return m_source->id();
}
const std::type_index & msg_type,
{
if( !should_intercept( msg_type ) )
m_source->subscribe_event_handler(
msg_type,
subscriber );
}
const std::type_index & msg_type,
{
if( !should_intercept( msg_type ) )
m_source->unsubscribe_event_handler(
msg_type,
subscriber );
}
{
return m_source->query_name();
}
{
}
const std::type_index & msg_type,
unsigned int redirection_deep ) override
{
auto & dest = should_intercept( msg_type ) ? *m_target : *m_source;
std::cout << "do_deliver_message for '" << msg_type.name()
<< "', should_intercept: " << should_intercept( msg_type )
<< ", dest_id: " << dest.id() << std::endl;
dest.do_deliver_message(
delivery_mode,
msg_type,
message,
redirection_deep );
}
const std::type_index & msg_type,
{
if( !should_intercept( msg_type ) )
msg_type,
filter,
subscriber );
}
const std::type_index & msg_type,
{
if( !should_intercept( msg_type ) )
m_source->drop_delivery_filter(
msg_type,
subscriber );
}
{
return m_source->environment();
}
};
void run_intercepting_scenario()
{
std::cout << "*** Start of interception scenario ***" << std::endl;
auto * actual_consumer = coop.
make_agent< a_actual_consumer_t >(
"actual" );
auto mbox_factory =
[target_mbox = actual_consumer->so_direct_mbox()]
{
return { std::make_unique< intercepting_mbox_t >( source_mbox, target_mbox ) };
};
std::make_unique< a_consumer_t >(
"original" ) );
coop.
make_agent< a_producer_t >( *original_consumer );
} );
} );
}
int main()
{
try
{
run_normal_scenario();
run_intercepting_scenario();
}
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.
virtual void unsubscribe_event_handler(const std::type_index &type_index, abstract_message_sink_t &subscriber) noexcept=0
Remove all message handlers.
virtual void subscribe_event_handler(const std::type_index &type_index, abstract_message_sink_t &subscriber)=0
Add the message handler.
virtual so_5::environment_t & environment() const noexcept=0
SObjectizer Environment for which the mbox is created.
virtual void drop_delivery_filter(const std::type_index &msg_type, abstract_message_sink_t &subscriber) noexcept=0
Removes delivery filter for message type and subscriber.
virtual void set_delivery_filter(const std::type_index &msg_type, const delivery_filter_t &filter, abstract_message_sink_t &subscriber)=0
Set a delivery filter for message type and subscriber.
virtual mbox_id_t id() const =0
Unique ID of this mbox.
virtual std::string query_name() const =0
Get the mbox name.
virtual void do_deliver_message(message_delivery_mode_t delivery_mode, const std::type_index &msg_type, const message_ref_t &message, unsigned int redirection_deep)=0
Deliver message for all subscribers with respect to message limits.
virtual mbox_type_t type() const =0
Get the type of message box.
Interface for message sink.
A context for agent construction and tuning.
const name_for_agent_t m_name
Optional name for the agent.
virtual void so_define_agent()
Hook on define agent for SObjectizer.
subscription_bind_t so_subscribe_self()
Initiate subscription to agent's direct mbox.
static custom_direct_mbox_factory_t custom_direct_mbox_factory(Lambda &&lambda)
Helper for creation a custom direct mbox factory.
void so_deregister_agent_coop_normally()
A helper method for deregistering agent's coop in case of normal deregistration.
virtual void so_evt_start()
Hook on agent start inside SObjectizer.
environment_t & environment() const noexcept
Access to SO Environment for which cooperation is bound.
Agent * make_agent(Args &&... args)
Helper method for simplification of agents creation.
Agent * add_agent(std::unique_ptr< Agent > agent)
Add agent to cooperation.
An interface of delivery filter object.
decltype(auto) introduce_coop(Args &&... args)
Helper method for simplification of cooperation creation and registration.
A base class for agent messages.
Wrapper around a pointer to partially constructed agent.
A base class for agent signals.
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.
Private part of message limit implementation.
message_delivery_mode_t
Possible modes of message/signal delivery.
void launch(Init_Routine &&init_routine)
Launch a SObjectizer Environment with default parameters.
mbox_type_t
Type of the message box.
void send(Target &&to, Args &&... args)
A utility function for creating and delivering a message or a signal.
unsigned long long mbox_id_t
A type for mbox indentifier.
A special marker for mutable message.