#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 )
:
so_5::agent_t{ std::move(ctx) }
, m_name{ std::move(name) }
{}
{
.
event( &a_consumer_t::evt_first )
.event( &a_consumer_t::evt_second )
;
}
private:
const std::string m_name;
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 )
:
so_5::agent_t{ std::move(ctx) }
, m_dest_mbox{ consumer.so_direct_mbox() }
{}
{
}
{
so_5::send< so_5::mutable_msg<msg_first> >( m_dest_mbox, "Hello, " );
so_5::send< so_5::mutable_msg<msg_second> >( m_dest_mbox, "World!" );
so_5::send< msg_quit >( *this );
}
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 )
:
so_5::agent_t{ std::move(ctx) }
, m_name{ std::move(name) }
{}
{
.
event( &a_actual_consumer_t::evt_second )
;
}
private:
const std::string m_name;
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,
limit,
subscriber );
}
const std::type_index & msg_type,
{
if( !should_intercept( msg_type ) )
m_source->unsubscribe_event_handlers(
msg_type,
subscriber );
}
{
return m_source->query_name();
}
{
}
const std::type_index & msg_type,
unsigned int overlimit_reaction_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(
msg_type,
message,
overlimit_reaction_deep );
}
const std::type_index & msg_type,
{
if( !should_intercept( msg_type ) )
m_source->set_delivery_filter(
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;
}