-

   rss_rss_hh_new

 - e-mail

 

 -

 LiveInternet.ru:
: 17.03.2011
:
:
: 51

:


, 04 2017 . 09:59 +

SObjectizer (). SObjectizer . , ... - SObjectizer machine_control. , SObjectizer-. SObjectizer- , . , .


The Engine Room - Steel Stacks, Bethlehem, PA
Photo by Mike Boening



?


, - , . , , . , . . , , . , . . , 70 . , 50 . , , 95 , , 50 .


, , . , , . machine_control .


, , , . , . - , - . , , , , .


!



, . . - , - SObjectizer-. . , ;)


?


-, . - .



- . , total_status_dashboard, - . :



statuses_analyser. , , - . , statuses_analyser . machine_controller. -.


, , . .


a_machine_t


, .. . - , - . , .


, . - . a_machine_t, :


  • , : , , ;
  • / ;
  • / .

, , , , . . , .


, a_machine_t, , a_machine_t:


//      .
enum class engine_state_t { on, off };
//      .
enum class cooler_state_t { on, off };
 
//  -     .
struct turn_engine_on : public so_5::signal_t {};
struct turn_engine_off : public so_5::signal_t {};
 
//  -     .
struct turn_cooler_on : public so_5::signal_t {};
struct turn_cooler_off : public so_5::signal_t {};
 
//    .
struct machine_status
{
	//  -  .
	//   ,      .
	const std::string m_id;
	//   .
	const engine_state_t m_engine_status;
	//   .
	const cooler_state_t m_cooler_status;
	//   .
	const float m_engine_temperature;
};

, a_machine_t - turn_engine_on/turn_engine_off turn_cooler_on/turn_cooler_off, machine_status.


a_machine_t. :


class a_machine_t : public so_5::agent_t
{
	//       
	//    .
	struct update_status : public so_5::signal_t {};
 
	// -     :
	// ,   ,
	const state_t st_engine_on{ this, "on" };
	// ,   .
	const state_t st_engine_off{ this, "off" };
 
	//  -  .
	const std::string m_id;
	//        machine_status.
	const so_5::mbox_t m_status_distrib_mbox;
 
	//    :
	//  ,
	const float m_initial_temperature;
	//       ,
	const float m_engine_heating_step;
	//       .
	const float m_cooler_impact_step;
 
	//   .
	float m_engine_temperature;
 
	//     .
	engine_state_t m_engine_status = engine_state_t::off;
	cooler_state_t m_cooler_status = cooler_state_t::off;
 
	// ID     update_status.
	//  SO-5    ID   
	//     ,   
	//   .
	so_5::timer_id_t m_update_status_timer;

a_machine_t : . -. , SObjectizer st_engine_on st_engine_off.


update_status. , , m_engine_temperature , . m_status_distrib_mbox machine_status .


- , , .


. -, so_define_agent(), , SObjectizer. a_machine_t . :


virtual void so_define_agent() override
{
	this >>= st_engine_off;
 
	st_engine_on
		.event< turn_engine_off >( &a_machine_t::evt_turn_engine_off )
		.event< turn_cooler_on >( &a_machine_t::evt_turn_cooler_on )
		.event< turn_cooler_off >( &a_machine_t::evt_turn_cooler_off )
		.event< update_status >( &a_machine_t::evt_update_status_when_engine_on );
	st_engine_off
		.event< turn_engine_on >( &a_machine_t::evt_turn_engine_on )
		.event< turn_cooler_on >( &a_machine_t::evt_turn_cooler_on )
		.event< turn_cooler_off >( &a_machine_t::evt_turn_cooler_off )
		.event< update_status >( &a_machine_t::evt_update_status_when_engine_off );
}

, update_status . , st_engine_on turn_engine_on , . turn_engine_off st_engine_off.


so_define_agent() : , . .


, . . , so_define_agent() , . (, so_define_agent() , ).


, , so_define_agent() , : , so_define_agent() . .


so_evt_start(). SObjectizer , SObjectizer-. a_machine_t so_evt_start() , update_status:


virtual void so_evt_start() override
{
	//     update_status  
	// ID ,       ,
	//   .
	m_update_status_timer = so_5::send_periodic< update_status >(
			//      .
			*this,
			//        .
			std::chrono::milliseconds(0),
			//      200ms.
			std::chrono::milliseconds(200) );
}

a_machine_t. , SObjectizer -. - . , :


st_engine_on
	.event< turn_engine_off >( &a_machine_t::evt_turn_engine_off )

SObjectizer-, turn_engine_off, evt_turn_engine_off().


a_machine_t , :


void evt_turn_engine_off()
{
	//    .
	this >>= st_engine_off;
	//   .
	m_engine_status = engine_state_t::off;
}
 
void evt_turn_engine_on()
{
	this >>= st_engine_on;
	m_engine_status = engine_state_t::on;
}
 
void evt_turn_cooler_off()
{
	//     .
	//     .
	m_cooler_status = cooler_state_t::off;
}
 
void evt_turn_cooler_on()
{
	m_cooler_status = cooler_state_t::on;
}

update_status . update_status :


void evt_update_status_when_engine_on()
{
	m_engine_temperature += m_engine_heating_step;
	if( cooler_state_t::on == m_cooler_status )
		m_engine_temperature -= m_cooler_impact_step;
 
	distribute_status();
}

, , . , , .


update_status st_engine_off, .. , , :


void evt_update_status_when_engine_off()
{
	if( cooler_state_t::on == m_cooler_status )
	{
		m_engine_temperature -= m_cooler_impact_step;
		//        
		//   .
		if( m_engine_temperature < m_initial_temperature )
			m_engine_temperature = m_initial_temperature;
	}
 
	distribute_status();
}

distribute_status() , .. machine_status :


void distribute_status()
{
	//  send-    machine_status,
	//      send.
	//         
	// m_status_distrib_mbox.
	so_5::send< machine_status >(
			//   .
			m_status_distrib_mbox,
			//      
			//   machine_status.
			m_id,
			m_engine_status,
			m_cooler_status,
			m_engine_temperature );
}

machine_status?


, - : a_machine_t / ? , , a_machine_t - ?


, :)


- - , , . (): , .


a_machine_t : ( ). a_machine_t / , - - -, , - . .


a_machine_t , , - , , . a_machine_t .


a_total_status_dashboard_t


a_total_status_dashboard_t machine_status, .


a_total_status_dashboard_t :


virtual void so_define_agent() override
{
	so_subscribe( m_status_distrib_mbox )
		.event( &a_total_status_dashboard_t::evt_machine_status );
 
	so_subscribe_self().event< show_dashboard >(
			&a_total_status_dashboard_t::evt_show_dashboard );
}

, machine_status, , a_machine_t machine_status-. , show_dashboard, a_total_status_dashboard_t :


virtual void so_evt_start() override
{
	//     
	//    .
	const auto period = std::chrono::milliseconds( 1500 );
	m_show_timer = so_5::send_periodic< show_dashboard >( *this,
			period, period );
}

a_total_status_dashboard_t , a_machine_t so_evt_start(), SObjectizer a_total_status_dashboard_t.


machine_status : :


void evt_machine_status( const machine_status & status )
{
	m_machine_statuses[ status.m_id ] = one_machine_status_t{
			status.m_engine_status, status.m_cooler_status,
			status.m_engine_temperature
		};
}

show_dashboard : :


void evt_show_dashboard()
{
	auto old_precision = std::cout.precision( 5 );
	std::cout << "=== The current status ===" << std::endl;
 
	for( const auto & m : m_machine_statuses )
	{
		show_one_status( m );
	}
 
	std::cout << "==========================" << std::endl;
	std::cout.precision( old_precision );
}

a_total_status_dashboard_t , . , a_total_status_dashboard_t .


a_statuses_analyser_t a_machine_controller_t


machine_control a_machine_t - .


-, a_statuses_analyser_t, machine_status, , a_machine_t - .


-, - a_machine_controller_t, a_statuses_analyser_t . , a_machine_controlle_t , turn_cooler_on a_machine_t. a_machine_controller_t , turn_engine_off. ..


, a_statuses_analyser_t a_machine_controller_t . a_statuses_analyser_t, , . , , a_statuses_analyser_t .


machaine_control SObjectizer-, , - , a_statuses_analyser_t a_machine_controller_t.


, a_machine_t, a_statuses_analyser_t a_machine_controller_t :


  • a_machine_t machine_status;
  • a_statuses_analyser_t machine_status , - a_machine_t. , a_status_analyser_t machine_needs_attention , ;
  • a_machine_controller_t machine_needs_attention turn_engine_on/turn_engine_off / turn_cooler_on/turn_cooler_off a_machine_t.


machine_needs_attention :


// ,      .
enum class attention_t 
{
	none,
	engine_cooling_done,
	engine_cooling_needed,
	engine_overheat_detected
};
 
//   ,     - .
struct machine_needs_attention
{
	//  - .
	const std::string m_id;
	//   .
	const attention_t m_attention;
	//      (/).
	const engine_state_t m_engine_status;
	//     (/).
	const cooler_state_t m_cooler_status;
};

a_statuses_analyser_t , machine_status. , , , a_statuses_analyser_t machine_needs_attention. a_machine_controller_t a_machine_t .


a_statuses_analyser_t


a_statuses_analyser_t . , -. ( - , ), :


  • a_statuses_analyser_t -. - ;
  • machine_status , . , -, machine_needs_attention;
  • a_statuses_analyser_t .

, .


a_statuses_analyser_t, SObjectizer-, : - so_define_agent() - :


virtual void so_define_agent() override
{
	so_subscribe( m_status_distrib_mbox ).event(
			&a_statuses_analyzer_t::evt_machine_status );
}
void evt_machine_status( const machine_status & status )
{
	auto it = m_last_infos.find( status.m_id );
	if( it == m_last_infos.end() )
		//        .
		//     .
		it = m_last_infos.insert( last_info_map_t::value_type {
				status.m_id,
				last_machine_info_t {
					attention_t::none,
					status.m_engine_temperature
				} } ).first;
 
	handle_new_status( status, it->second );
}

handle_new_status(), evt_machine_status(), -, .


a_machine_controller_t


a_machine_controller_t?


a_machine_controller_t : a_statuses_analyser_t , , , . -, . -, , .


a_statuses_analyser_t, . a_statuses_analyser_t -. a_machine_controller_t. a_machine_controller_t , . , a_machine_contoller_t machine_needs_attention -. , a_machine_controller_t machine_needs_attention .


a_machine_controller_t


- a_machine_controller_t , :


template< class LOGIC >
class a_machine_controller_t : public so_5::agent_t
{
public :
	a_machine_controller_t(
		context_t ctx,
		so_5::priority_t priority,
		so_5::mbox_t status_distrib_mbox,
		const machine_dictionary_t & machines )
		:	so_5::agent_t( ctx + priority )
		,	m_status_distrib_mbox( std::move( status_distrib_mbox ) )
		,	m_machines( machines )
		,	m_logic()
	{}
 
	virtual void so_define_agent() override
	{
		so_set_delivery_filter( m_status_distrib_mbox,
			[this]( const machine_needs_attention & msg ) {
				return m_logic.filter( msg );
			} );
 
		so_subscribe( m_status_distrib_mbox )
			.event( [this]( const machine_needs_attention & evt ) {
					m_logic.action( m_machines, evt );
				} );
	}
 
private :
	const so_5::mbox_t m_status_distrib_mbox;
 
	const machine_dictionary_t & m_machines;
 
	const LOGIC m_logic;
};

, , : , a_machine_controller_t. LOGIC :


struct LOGIC
{
	bool filter( const machine_needs_attention & msg ) const;
 
	void action(
		const machine_dictionary_t & machines,
		const machine_needs_attention & evt ) const;
};

C++11 , , , a_machine_controller_t, . , .. C++11 , .


a_machine_controller_t LOGIC . , , -.


:


-, , . a_machine_controller_t :


so_set_delivery_filter( m_status_distrib_mbox,
	[this]( const machine_needs_attention & msg ) {
		return m_logic.filter( msg );
	} );

SObjectizer-. , T M, T, , .


so_set_delivery_filter() , -, M , T. true, . false, , , .



. Subscriber-1 mbox-. Subscriber-2 , .


LOGIC::filter() , machine_needs_attention, .


-, - machine_needs_attention, , .


LOGIC::action(). a_machine_controller_t machine_needs_attention:


so_subscribe( m_status_distrib_mbox )
	.event( [this]( const machine_needs_attention & evt ) {
		m_logic.action( m_machines, evt );
	} );

controller-


, , a_machine_controller_t, . , turn_engine_off, :


struct engine_stopper_t
{
	bool filter( const machine_needs_attention & msg ) const
	{
		return msg.m_attention == attention_t::engine_overheat_detected;
	}
 
	void action(
		const machine_dictionary_t & machines,
		const machine_needs_attention & evt ) const
	{
		so_5::send< turn_engine_off >( machines.find_mbox( evt.m_id ) );
	}
};

.. machine_needs_attention, . , - turn_engine_off.


:


struct cooler_starter_t
{
	bool filter( const machine_needs_attention & msg ) const
	{
		return (msg.m_attention == attention_t::engine_overheat_detected ||
				msg.m_attention == attention_t::engine_cooling_needed) &&
				msg.m_cooler_status == cooler_state_t::off;
	}
 
	void action(
		const machine_dictionary_t & machines,
		const machine_needs_attention & evt ) const
	{
		so_5::send< turn_cooler_on >( machines.find_mbox( evt.m_id ) );
	}
};

. , , .


:


  • engine_stopper_t ;
  • engine_starter_t ;
  • cooler_starter_t ;
  • cooler_stopper_t .

, a_machine_controller_t .


a_machine_controller_t


machine_control , machine_needs_attention . , machine_needs_attention attention_t::engine_overheat_detected cooler_status_t::off, : engine_stopper_t, cooler_starter_t.


, . , engine_overheat_detected turn_engine_off, turn_cooler_on. - , . , . , .


SObjectizer- ?


. , . , . . , , .


SObjectizer : , . so_5::disp::prio_one_thread::strictly_ordered. a_machine_controller_t .


- :


  • engine_stopper_t, .. ;
  • cooler_starter_t, ;
  • engine_starter_t;
  • cooler_stopper_t.

, a_machine_controller_t :


a_machine_controller_t(
	...,
	so_5::priority_t priority,
	... )
	:	so_5::agent_t( ctx + priority )
	,	...
{}

:


coop.make_agent_with_binder< a_machine_controller_t< engine_stopper_t > >(
		disp->binder(),
		so_5::prio::p4,
		status_distrib_mbox,
		machines );
 
coop.make_agent_with_binder< a_machine_controller_t< cooler_starter_t > >(
		disp->binder(),
		so_5::prio::p3,
		status_distrib_mbox,
		machines );

so_5::prio::p4 so_5::prio::p3 .


-


, a_machine_t st_engine_off, .. . , . , a_machine_t, a_machine_controller_t ?


, - -, turn_engine_on -.


, C++ , a_machine_t, a_total_status_dashboard_t, a_statuses_analyser_t a_machine_controller_t. , ad-hoc . .. , -. machine_control :


coop.define_agent().on_start( [&dict] {
		dict.for_each(
			[]( const std::string &, const so_5::mbox_t & mbox ) {
				so_5::send< turn_engine_on >( mbox );
			} );
	} );

define_agent() ad-hoc , . ad-hoc SObjectizer-: turn_engine_on.



SObjectizer-, , .


. - . SObjectizer . , .


machine_control , :


  • - , one_thread;
  • a_total_status_dashboard_t ( one_thread);
  • a_statuses_analyser_t ( one_thread);
  • a_machine_controller_t prio_one_thread::strictly_ordered, ;
  • - .


?


, , , : machine_dictionary. , - - .


, - ( machine_status machine_needs_attention) . SObjectizer , , , turn_engine_on, . machine_dictionary.


?


, , , .


, , , , a_machine_t a_machine_controller_t, .


SObjectizer-, ad-hoc . , , - SObjectizer, , , , . -, , ping-pong, , . , SObjectizer.


, , . , , Actor Model Publish/Subscribe .



machine_control , (.. ) .


, a_machine_t machine_status , , . a_machine_t ( ) . , .


a_machine_t ( turn_engine_on), , . a_machine_t , . , a_machine_t .


, - turn_engine_on a_machine_t, Actor Model, 1:1.


machine_status machine_needs_attention Actor Model, .. 1:N. Publish/Subscribe. , machine_status machine_needs_attention, . - Publish. Subscribe, , , a_total_status_dashboard_t, a_statuses_analyser_t a_machine_controller_t so_define_agent().


, SObjectizer: . , SObjectizer multi-producer/multi-consumer , 1:N.


, machine_status, , , . a_total_status_dashboard_t machine_status . a_statuses_analyser_t machine_status a_machine_t.


. , . a_total_status_dashboard_t a_statuses_analyser_t. a_total_status_dashboard_t - a_gui_status_dashboard_t, std::cout, . , , , machine_status.


SObjectizer , , . SObjectizer , ( CSP- ).


SObjectizer , , . (.. ), .


, . . , . -, - , so_5::signal_t, . , - , - . , , - - .



, , .


, SObjectizer- so_5_extra, SObjectizer. , SObjectizer , , . so_5_extra , . - SObjectizer, . SObjectizer, so_5_extra.

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/332166/

:  

: [1] []
 

:
: 

: ( )

:

  URL