#include <iostream>
using namespace std::chrono_literals;
template< typename Completion_Handler >
{
public:
operation_performer_t(
context_t ctx,
std::chrono::milliseconds duration,
Completion_Handler && completion_handler )
:
so_5::agent_t{ std::move(ctx) }
, m_duration{ duration }
, m_completion_handler{ std::move(completion_handler) }
{}
void so_define_agent() override
{
so_subscribe_self().event( [this]( mhood_t<completed_t> ) {
m_completion_handler( m_status );
} );
}
void so_evt_start() override
{
so_5::send_delayed< completed_t >( *this, m_duration );
}
void so_evt_finish() override
{
if( status_t::inprogress == m_status )
{
std::this_thread::sleep_for( 15ms );
m_completion_handler( status_t::aborted );
}
}
private:
status_t m_status{ status_t::inprogress };
const std::chrono::milliseconds m_duration;
Completion_Handler m_completion_handler;
};
class async_operation_t final
{
public:
async_operation_t( const async_operation_t & ) = delete;
async_operation_t( async_operation_t && ) = delete;
: m_env{ env }
{}
~async_operation_t()
{
cancel();
}
template< typename Completion_Handler >
void
start(
std::chrono::milliseconds duration,
Completion_Handler && completion_handler )
{
m_performer_coop = m_env.register_agent_as_coop(
m_env.make_agent< operation_performer_t< Completion_Handler > >(
duration,
std::move(completion_handler) ) );
}
void
cancel()
{
if( m_performer_coop )
m_env.deregister_coop(
std::move(m_performer_coop),
}
private:
};
{
public:
async_operation_issuer_t(
context_t ctx,
std::string name,
std::chrono::milliseconds operation_duration,
std::chrono::milliseconds lifetime )
: agent_t{ std::move(ctx) }
, m_name{ std::move(name) }
, m_operation_duration{ operation_duration }
, m_lifetime{ lifetime }
{}
~async_operation_issuer_t() override
{
std::cout << m_name << " destroyed" << std::endl;
}
void so_define_agent() override
{
so_subscribe_self().event( [this]( mhood_t< no_more_time > ) {
so_deregister_agent_coop_normally();
} );
}
void so_evt_start() override
{
so_5::send_delayed< no_more_time >( *this, m_lifetime );
m_async_op.start( m_operation_duration,
std::cout << self->m_name << " -> "
<< (status_t::aborted ==
status ?
"aborted" :
"completed")
<< std::endl;
} );
}
void so_evt_finish() override
{
m_async_op.cancel();
}
private:
const std::string m_name;
const std::chrono::milliseconds m_operation_duration;
const std::chrono::milliseconds m_lifetime;
async_operation_t m_async_op{ so_environment() };
};
int main()
{
try
{
{
"The First Issuer (with rather long name)", 125ms, 50ms ) );
"The Second Issuer (with yet more long name)", 125ms, 100ms ) );
"The Third Issuer", 125ms, 150ms ) );
} );
}
catch( const std::exception & ex )
{
std::cerr << "Error: " << ex.what() << std::endl;
return 1;
}
return 0;
}