#include <iostream>
#include <iterator>
#include <numeric>
#include <cstdlib>
enum color_t
{
BLUE = 0,
RED = 1,
YELLOW = 2,
FADED = 3
};
{
color_t m_color;
msg_meeting_result( color_t color )
: m_color( color )
{}
};
using meeting_result_msg_holder_t =
{
color_t m_color;
meeting_result_msg_holder_t m_result_message;
msg_meeting_request(
color_t color,
meeting_result_msg_holder_t result_message )
: m_who( who )
, m_color( color )
, m_result_message( std::move(result_message) )
{}
};
using meeting_request_msg_holder_t =
{
int m_creatures_met;
msg_shutdown_ack( int creatures_met )
: m_creatures_met( creatures_met )
{}
};
{
public :
a_meeting_place_t(
context_t ctx,
int creatures,
int meetings )
, m_creatures_alive( creatures )
, m_remaining_meetings( meetings )
, m_total_meetings( 0 )
{}
{
this >>= st_empty;
st_empty
.event( &a_meeting_place_t::evt_first_creature )
.event( &a_meeting_place_t::evt_shutdown_ack );
st_one_creature_inside
.event( &a_meeting_place_t::evt_second_creature );
}
private :
void evt_first_creature( mutable_mhood_t< msg_meeting_request > evt )
{
if( m_remaining_meetings )
{
this >>= st_one_creature_inside;
m_first_creature_info =
}
else
so_5::send< msg_shutdown_request >( evt->m_who );
}
void evt_second_creature(
mutable_mhood_t< msg_meeting_request > evt )
{
evt->m_result_message->m_color =
m_first_creature_info->m_color;
m_first_creature_info->m_result_message->m_color = evt->m_color;
m_first_creature_info->m_result_message );
m_first_creature_info.reset();
--m_remaining_meetings;
this >>= st_empty;
}
void evt_shutdown_ack(
const msg_shutdown_ack & evt )
{
m_total_meetings += evt.m_creatures_met;
if( 0 >= --m_creatures_alive )
{
std::cout << "Total: " << m_total_meetings << std::endl;
}
}
const state_t st_empty{ this, "empty" };
const state_t st_one_creature_inside{ this, "one_creature_inside" };
int m_creatures_alive;
int m_remaining_meetings;
int m_total_meetings;
meeting_request_msg_holder_t m_first_creature_info;
};
{
public :
a_creature_t(
context_t ctx,
color_t color )
, m_meeting_place_mbox( std::move(meeting_place_mbox) )
, m_meeting_counter( 0 )
, m_response_message( new msg_meeting_result( color ) )
, m_request_message( new msg_meeting_request(
so_direct_mbox(),
color,
m_response_message ) )
{}
{
.
event( &a_creature_t::evt_meeting_result )
.
event( &a_creature_t::evt_shutdown_request );
}
{
m_meeting_place_mbox,
m_request_message );
}
private :
void evt_meeting_result(
mutable_mhood_t< msg_meeting_result > evt )
{
m_request_message->m_color = complement( evt->m_color );
m_meeting_counter++;
so_5::send( m_meeting_place_mbox, m_request_message );
}
void evt_shutdown_request( mhood_t< msg_shutdown_request > )
{
m_request_message->m_color = FADED;
std::cout << "Creatures met: " << m_meeting_counter << std::endl;
so_5::send< msg_shutdown_ack >(
m_meeting_place_mbox, m_meeting_counter );
}
int m_meeting_counter;
meeting_result_msg_holder_t m_response_message;
meeting_request_msg_holder_t m_request_message;
color_t complement( color_t other ) const noexcept
{
switch( m_request_message->m_color )
{
case BLUE:
return other == RED ? YELLOW : RED;
case RED:
return other == BLUE ? YELLOW : BLUE;
case YELLOW:
return other == BLUE ? RED : BLUE;
case FADED:
break;
}
return m_request_message->m_color;
}
};
const int creature_count = 4;
{
{
color_t creature_colors[ creature_count ] =
{ BLUE, RED, YELLOW, BLUE };
auto a_meeting_place = coop.
make_agent< a_meeting_place_t >(
creature_count,
meetings );
for( int i = 0; i != creature_count; ++i )
{
a_meeting_place->so_direct_mbox(),
creature_colors[ i ] );
}
} );
}
int main( int argc, char ** argv )
{
try
{
const int meetings = 2 == argc ? std::atoi( argv[1] ) : 10;
init( env, meetings );
} );
}
catch( const std::exception & ex )
{
std::cerr << "Error: " << ex.what() << std::endl;
return 1;
}
return 0;
}