sample/dyn_reg/main.cpp
#include <iostream>
#include <ace/OS_main.h>
#include <so_4/rt/h/rt.hpp>
#include <so_4/api/h/api.hpp>
#include <so_4/timer_thread/simple/h/pub.hpp>
#include <so_4/disp/one_thread/h/pub.hpp>
const std::string child_name( "a_child" );
class a_child_t
  :   public so_4::rt::agent_t
{
  typedef so_4::rt::agent_t base_type_t;
  public :
    a_child_t();
    virtual ~a_child_t();
    virtual const char *
    so_query_type() const;
    virtual void
    so_on_subscription();
    virtual void
    so_on_deregistration();
    
    struct  msg_say_it_again {};
    void
    evt_start();
    void
    evt_say_it_again( const so_4::rt::event_data_t & data );
};
SOL4_CLASS_START( a_child_t )
  SOL4_MSG_START( msg_say_it_again, a_child_t::msg_say_it_again )
  SOL4_MSG_FINISH()
  SOL4_EVENT( evt_start )
  SOL4_EVENT( evt_say_it_again )
  SOL4_STATE_START( st_initial )
    SOL4_STATE_EVENT( evt_start )
    SOL4_STATE_EVENT( evt_say_it_again )
  SOL4_STATE_FINISH()
SOL4_CLASS_FINISH()
a_child_t::a_child_t()
:
  base_type_t( child_name )
{
  
  std::cout << so_query_name() << " created" << std::endl;
}
a_child_t::~a_child_t()
{
  
  std::cout << so_query_name() << " destroyed" << std::endl;
}
void
a_child_t::so_on_subscription()
{
  so_subscribe( "evt_start",
    so_4::rt::sobjectizer_agent_name(), "msg_start" );
  so_subscribe( "evt_say_it_again", "msg_say_it_again" );
}
void
a_child_t::so_on_deregistration()
{
  
  std::cout << so_query_name() << " deregistered" << std::endl;
}
void
a_child_t::evt_start()
{
  
  std::cout << so_query_name()
    << ": Hello, World!" << std::endl;
}
void
a_child_t::evt_say_it_again( const so_4::rt::event_data_t & data )
{
  
  std::cout << so_query_name()
    << ": and again - Hello, World!" << std::endl;
  
  
  so_4::api::send_msg( data.agent(), data.msg(), 0,
    so_query_name(), 15000 );
}
class a_parent_t
  : public so_4::rt::agent_t
{
  typedef so_4::rt::agent_t base_type_t;
  public :
    a_parent_t();
    virtual ~a_parent_t();
    virtual const char *
    so_query_type() const;
    virtual void
    so_on_subscription();
    
    struct  msg_reg_time {};
    
    
    struct  msg_dereg_time {};
    void
    evt_start();
    void
    evt_reg_time();
    void
    evt_dereg_time();
    void
    evt_coop_registered(
      const so_4::rt::msg_coop_registered & cmd );
    void
    evt_coop_deregistered(
      const so_4::rt::msg_coop_deregistered & cmd );
};
SOL4_CLASS_START( a_parent_t )
  SOL4_MSG_START( msg_reg_time, a_parent_t::msg_reg_time )
  SOL4_MSG_FINISH()
  SOL4_MSG_START( msg_dereg_time, a_parent_t::msg_dereg_time )
  SOL4_MSG_FINISH()
  SOL4_EVENT( evt_start )
  SOL4_EVENT( evt_reg_time )
  SOL4_EVENT( evt_dereg_time )
  SOL4_EVENT_STC(
    evt_coop_registered,
    so_4::rt::msg_coop_registered )
  SOL4_EVENT_STC(
    evt_coop_deregistered,
    so_4::rt::msg_coop_deregistered )
  SOL4_STATE_START( st_initial )
    SOL4_STATE_EVENT( evt_start )
    SOL4_STATE_EVENT( evt_reg_time )
    SOL4_STATE_EVENT( evt_dereg_time )
    SOL4_STATE_EVENT( evt_coop_registered )
    SOL4_STATE_EVENT( evt_coop_deregistered )
  SOL4_STATE_FINISH()
SOL4_CLASS_FINISH()
a_parent_t::a_parent_t()
:
  base_type_t( "a_parent" )
{}
a_parent_t::~a_parent_t()
{}
void
a_parent_t::so_on_subscription()
{
  so_subscribe( "evt_start",
    so_4::rt::sobjectizer_agent_name(), "msg_start" );
  so_subscribe( "evt_reg_time", "msg_reg_time" );
  so_subscribe( "evt_dereg_time", "msg_dereg_time" );
  
  
  
  so_subscribe( "evt_coop_registered",
    so_4::rt::sobjectizer_agent_name(), "msg_coop_registered", 1 );
  so_subscribe( "evt_coop_deregistered",
    so_4::rt::sobjectizer_agent_name(), "msg_coop_deregistered" );
}
void
a_parent_t::evt_start()
{
  
  unsigned int sec = 1;
  std::cout << so_query_name()
    << ": child coop will be registered after "
    << sec << " sec" << std::endl;
  so_4::api::send_msg( so_query_name(), "msg_reg_time", 0,
    so_query_name(), sec * 1000 );
}
void
a_parent_t::evt_reg_time()
{
  std::cout << so_query_name()
    << ": It's time to register child coop"
    << std::endl;
  
  so_4::rt::dyn_agent_coop_helper_t helper(
    new so_4::rt::dyn_agent_coop_t( new a_child_t() ) );
  if( helper.result() )
  {
    
    std::cerr << "register_coop: " << helper.result() << std::endl;
    so_4::api::send_msg( so_4::rt::sobjectizer_agent_name(),
      "msg_alarm_shutdown", 0 );
  }
}
void
a_parent_t::evt_dereg_time()
{
  std::cout << so_query_name()
    << ": It's time to deregister child coop" << std::endl;
  so_4::ret_code_t rc = so_4::api::deregister_coop( child_name );
  if( rc )
  {
    std::cerr << "deregister_coop: " << rc << std::endl;
    so_4::api::send_msg( so_4::rt::sobjectizer_agent_name(),
      "msg_alarm_shutdown", 0 );
  }
}
void
a_parent_t::evt_coop_registered(
  const so_4::rt::msg_coop_registered & cmd )
{
  std::cout << so_query_name()
    << ": Cooperation registered: "
    << cmd.m_coop_name << std::endl;
  if( child_name == cmd.m_coop_name )
  {
    
    
    unsigned int sec = 2;
    std::cout << so_query_name()
      << ": child coop will be deregistered after "
      << sec << " sec" << std::endl;
    so_4::api::send_msg(
      so_query_name(), "msg_dereg_time", 0,
      so_query_name(), sec * 1000 );
    
    so_4::api::send_msg( child_name, "msg_say_it_again" );
  }
}
void
a_parent_t::evt_coop_deregistered(
  const so_4::rt::msg_coop_deregistered & cmd )
{
  std::cout << so_query_name()
    << ": Cooperation deregistered: "
    << cmd.m_coop_name << std::endl;
  if( child_name == cmd.m_coop_name )
  {
    
    std::cout << so_query_name()
      << ": Work finished" << std::endl;
    so_4::api::send_msg(
      so_4::rt::sobjectizer_agent_name(),
      "msg_normal_shutdown", 0 );
  }
}
int
main( int, char ** )
{
  
  a_parent_t a_parent;
  
  so_4::rt::agent_coop_t  a_parent_coop( a_parent );
  
  so_4::ret_code_t rc = so_4::api::start(
    so_4::disp::one_thread::create_disp(
      so_4::timer_thread::simple::create_timer_thread(),
      so_4::auto_destroy_timer ),
    so_4::auto_destroy_disp,
    &a_parent_coop );
  if( rc ) {
    
    std::cerr << "start: " << rc << std::endl;
  }
  return int( rc );
}