#include <iostream>
#include <ace/OS_main.h>
#include <cpp_util_2/h/defs.hpp>
#include <cpp_util_2/h/lexcast.hpp>
#include <so_4/rt/h/rt.hpp>
#include <so_4/transport_layer/socket/h/pub.hpp>
#include <so_4/rt/comm/h/a_sop_incoming_channel_processor.hpp>
#include <so_4/api/h/api.hpp>
#include <so_4/timer_thread/simple/h/pub.hpp>
#include <so_4/disp/active_obj/h/pub.hpp>
#include <so_sysconf_2/h/pub.hpp>
#include <so_sysconf_2/h/breakflag.hpp>
#include <gemont_1/h/pub.hpp>
#include <gemont_1/h/temporary_sources.hpp>
#include <gemont_1/h/value_holder.hpp>
class a_data_source_t :
public virtual so_4::rt::agent_t
{
typedef so_4::rt::agent_t agent_type_t;
public :
a_data_source_t();
virtual ~a_data_source_t();
virtual const char *
so_query_type() const;
virtual void
so_on_subscription();
struct msg_tick {};
void
evt_start();
void
evt_tick();
private :
unsigned int m_ticker;
gemont_1::value_holder_t< unsigned int > m_ticker_2;
gemont_1::value_holder_t< std::string > m_appender;
std::auto_ptr<
gemont_1::value_holder_t< std::string > > m_dynamic_appender;
gemont_1::value_holder_as_trait_t< unsigned int > m_cycles;
gemont_1::str_data_source_t m_parity;
gemont_1::uint_data_source_t m_ticker_monitor;
gemont_1::uint_data_source_t m_2x_ticker_monitor;
gemont_1::uint_data_source_t m_3x_ticker_monitor;
gemont_1::temporary_sources_t<
gemont_1::uint_data_source_t,
unsigned int >
m_3x_tens;
gemont_1::scalar_data_source_t< unsigned int > m_2plus_ticker;
std::auto_ptr<
gemont_1::scalar_data_source_t< std::string > > m_3plus_ticker;
gemont_1::uint_data_source_t m_frequently_changed;
};
SOL4_CLASS_START( a_data_source_t )
SOL4_MSG_START( msg_tick, a_data_source_t::msg_tick )
SOL4_MSG_FINISH()
SOL4_EVENT( evt_start )
SOL4_EVENT( evt_tick )
SOL4_STATE_START( st_normal )
SOL4_STATE_EVENT( evt_start )
SOL4_STATE_EVENT( evt_tick )
SOL4_STATE_FINISH()
SOL4_CLASS_FINISH()
a_data_source_t::a_data_source_t()
:
agent_type_t( "a_data_source" )
, m_ticker( 0 )
, m_ticker_2( "Тикер N2", "ticker", 0 )
, m_appender( "Appender", "appender", "a" )
, m_cycles( "Циклы", "cycles", 0 )
, m_parity( "Четность", "parity", "НЕ ИЗВЕСТНО" )
, m_ticker_monitor( "Тикер", "ticker", m_ticker )
, m_2x_ticker_monitor( "Тикер * 2", "2x_ticker", 2 * m_ticker )
, m_3x_ticker_monitor( "Тикер * 3", "3x_ticker", 3 * m_ticker )
, m_2plus_ticker( "Тикер + 2", "2plus_ticker", 2 + m_ticker )
, m_frequently_changed( "Frequently changed", "frequently_changed", 0 )
{
so_add_traits( m_cycles );
so_add_traits( m_parity );
so_add_traits( m_ticker_monitor );
so_add_traits( m_2x_ticker_monitor );
so_add_traits( m_3x_ticker_monitor );
so_add_traits( m_3x_tens );
so_add_traits( m_frequently_changed );
}
a_data_source_t::~a_data_source_t()
{
}
void
a_data_source_t::so_on_subscription()
{
so_subscribe( "evt_start",
so_4::rt::sobjectizer_agent_name(), "msg_start" );
so_subscribe( "evt_tick", "msg_tick" );
}
void
a_data_source_t::evt_start()
{
so_4::api::send_msg( so_query_name(), "msg_tick", 0,
so_query_name(), 1500, 1500 );
m_2plus_ticker.start();
m_3plus_ticker.reset(
new gemont_1::scalar_data_source_t< std::string >(
"Тикер + 3", "3plus_ticker",
cpp_util_2::slexcast( m_ticker ) + " + 3",
&gemont_1::auto_start ) );
m_ticker_2.start();
m_appender.start();
m_dynamic_appender.reset(
new gemont_1::value_holder_t< std::string >(
"Динамический appender", "appender", "d",
&gemont_1::auto_start ) );
}
void
a_data_source_t::evt_tick()
{
std::cout << "m_ticker: " << m_ticker << std::endl;
m_parity.set( ( m_ticker & 1 ? "Не четное" : "Четное" ) );
m_ticker_monitor.set( m_ticker );
m_2x_ticker_monitor.set( 2 * m_ticker );
unsigned int ticker_3x = 3 * m_ticker;
m_3x_ticker_monitor.set( ticker_3x );
unsigned int t = ticker_3x / 10;
gemont_1::uint_data_source_t * tens = m_3x_tens.find( t );
if( tens )
tens->set( tens->current() + 1 );
else
{
m_3x_tens.insert( t,
new gemont_1::uint_data_source_t(
std::string( "tens " ) + cpp_util_2::slexcast( t ),
"3x_ticker_tens", 1 ) );
}
m_2plus_ticker.set( 2 + m_ticker );
m_3plus_ticker->set( cpp_util_2::slexcast( m_ticker ) + " + 3" );
for( unsigned int i = 0, i_max = m_3x_ticker_monitor.current();
i <= i_max; ++i )
{
m_frequently_changed.set( i );
}
++m_ticker;
++(**m_ticker_2);
if( m_ticker > 45 )
{
m_ticker = 0;
m_3x_tens.clear();
(**m_ticker_2) = 0;
++(**m_cycles);
}
(***m_dynamic_appender).append( "d" );
(**m_appender).append( "a" );
if( 20 < (**m_appender).length() )
{
(**m_appender) = "a";
(***m_dynamic_appender) = "d";
}
}
const std::string comm_channel_agent( "a_srv_channel" );
class a_main_t
: public so_4::rt::agent_t
{
public :
a_main_t(
const std::string & cfg_file_name );
virtual ~a_main_t();
virtual const char *
so_query_type() const;
virtual void
so_on_subscription();
struct msg_make_data_source {};
void
evt_comm_socket_creation_ok();
void
evt_comm_socket_creation_fail(
const so_4::rt::comm::msg_fail & cmd );
void
evt_make_data_source();
private :
typedef so_4::rt::agent_t base_type_t;
std::string m_cfg_file_name;
};
SOL4_CLASS_START( a_main_t )
SOL4_MSG_START( msg_make_data_source,
a_main_t::msg_make_data_source )
SOL4_MSG_FINISH()
SOL4_EVENT(
evt_comm_socket_creation_ok )
SOL4_EVENT_STC(
evt_comm_socket_creation_fail,
so_4::rt::comm::msg_fail )
SOL4_EVENT( evt_make_data_source )
SOL4_STATE_START( st_initial )
SOL4_STATE_EVENT( evt_comm_socket_creation_ok )
SOL4_STATE_EVENT( evt_comm_socket_creation_fail )
SOL4_STATE_EVENT( evt_make_data_source )
SOL4_STATE_FINISH()
SOL4_CLASS_FINISH()
a_main_t::a_main_t( const std::string & cfg_file_name )
: base_type_t( "a_main" )
, m_cfg_file_name( cfg_file_name )
{
}
a_main_t::~a_main_t()
{
}
void
a_main_t::so_on_subscription()
{
so_subscribe( "evt_comm_socket_creation_ok",
comm_channel_agent, "msg_success" );
so_subscribe( "evt_comm_socket_creation_fail",
comm_channel_agent, "msg_fail" );
so_subscribe( "evt_make_data_source", "msg_make_data_source" );
}
void
a_main_t::evt_comm_socket_creation_ok()
{
so_sysconf_2::register_coop();
if( !so_sysconf_2::run_script( m_cfg_file_name ) )
{
so_4::api::send_msg(
so_4::rt::sobjectizer_agent_name(),
"msg_normal_shutdown" );
}
so_4::api::send_msg( so_query_name(), "msg_make_data_source", 0,
so_query_name(), 250 );
}
void
a_main_t::evt_comm_socket_creation_fail(
const so_4::rt::comm::msg_fail & cmd )
{
std::cerr << "Creation of communication socket failed: "
<< cmd.m_reason << std::endl;
so_4::api::send_msg(
so_4::rt::sobjectizer_agent_name(),
"msg_alarm_shutdown" );
}
void
a_main_t::evt_make_data_source()
{
so_4::rt::dyn_agent_coop_helper_t helper(
new so_4::rt::dyn_agent_coop_t(
new a_data_source_t() ) );
}
so_4::rt::agent_coop_t *
create_main_coop(
const std::string & ip_address,
const std::string & cfg_file_name)
{
a_main_t * a_main = new a_main_t( cfg_file_name );
using namespace so_4::rt::comm;
using namespace so_4::transport_layer;
using namespace so_4::transport_layer::socket;
std::auto_ptr< a_sop_incoming_channel_processor_t > a_socksrv(
new a_sop_incoming_channel_processor_t(
comm_channel_agent,
create_acceptor_controller(
acceptor_params( ip_address ) ) )
);
so_4::disp::active_obj::make_active( *a_socksrv );
so_4::rt::agent_t * main_coop_agents[] =
{
a_main, a_socksrv.release()
};
so_4::rt::dyn_agent_coop_t * main_coop =
new so_4::rt::dyn_agent_coop_t(
"a_main", main_coop_agents,
CPP_UTIL_2_ASIZE( main_coop_agents ) );
return main_coop;
}
int
main( int argc, char ** argv )
{
if( 2 == argc )
{
so_sysconf_2::setup_signal_handlers();
so_4::ret_code_t rc = so_4::api::start(
so_4::disp::active_obj::create_disp(
so_4::timer_thread::simple::create_timer_thread(),
so_4::auto_destroy_timer ),
so_4::auto_destroy_disp,
create_main_coop( argv[ 1 ], "etc/sysconf.cfg" ) );
if( rc )
std::cerr << rc << std::endl;
return rc.m_code;
}
else {
std::cerr << "sample_sysconf <ip_address>\n\n"
"Configuration file sysconf.cfg must exist in "
"directory ./etc" << std::endl;
return 1;
}
}