sample/dyn_reg/main.cpp

00001 /*
00002   Пример использования:
00003   - динамической кооперации;
00004   - обработки сообщений SObjectizer-а о регистрации и
00005   дерегистрации коопераций;
00006   - переопределения метода so_4::rt::agent_t::so_on_deregistration().
00007 */
00008 
00009 #include <iostream>
00010 
00011 // Загружаем основные заголовочные файлы SObjectizer.
00012 #include <so_4/rt/h/rt.hpp>
00013 #include <so_4/api/h/api.hpp>
00014 
00015 // Загружаем описание нити таймера и диспетчера.
00016 #include <so_4/timer_thread/simple/h/pub.hpp>
00017 #include <so_4/disp/one_thread/h/pub.hpp>
00018 
00019 // Имя дочернего агента и динамической кооперации.
00020 const std::string child_name( "a_child" );
00021 
00022 // Класс агента, который будет входить в динамическую кооперацию.
00023 class a_child_t
00024   :   public so_4::rt::agent_t
00025 {
00026   typedef so_4::rt::agent_t base_type_t;
00027 
00028   public :
00029     a_child_t();
00030     virtual ~a_child_t();
00031 
00032     virtual const char *
00033     so_query_type() const;
00034 
00035     virtual void
00036     so_on_subscription();
00037 
00038     virtual void
00039     so_on_deregistration();
00040 
00041     // Сообщение, которым обладает данный агент.
00042     struct  msg_say_it_again {};
00043 
00044     void
00045     evt_start();
00046 
00047     void
00048     evt_say_it_again( const so_4::rt::event_data_t & data );
00049 };
00050 
00051 SOL4_CLASS_START( a_child_t )
00052 
00053   SOL4_MSG_START( msg_say_it_again, a_child_t::msg_say_it_again )
00054   SOL4_MSG_FINISH()
00055 
00056   SOL4_EVENT( evt_start )
00057 
00058   SOL4_EVENT( evt_say_it_again )
00059 
00060   SOL4_STATE_START( st_initial )
00061     SOL4_STATE_EVENT( evt_start )
00062     SOL4_STATE_EVENT( evt_say_it_again )
00063   SOL4_STATE_FINISH()
00064 
00065 SOL4_CLASS_FINISH()
00066 
00067 a_child_t::a_child_t()
00068 :
00069   base_type_t( child_name )
00070 {
00071   // Информируем о том, что мы созданы.
00072   std::cout << so_query_name() << " created" << std::endl;
00073 }
00074 
00075 a_child_t::~a_child_t()
00076 {
00077   // Информируем о том, что мы уничтожены.
00078   std::cout << so_query_name() << " destroyed" << std::endl;
00079 }
00080 
00081 void
00082 a_child_t::so_on_subscription()
00083 {
00084   so_subscribe( "evt_start",
00085     so_4::rt::sobjectizer_agent_name(), "msg_start" );
00086 
00087   so_subscribe( "evt_say_it_again", "msg_say_it_again" );
00088 }
00089 
00090 void
00091 a_child_t::so_on_deregistration()
00092 {
00093   // Сообщаем о том, что нас дерегистрируют.
00094   std::cout << so_query_name() << " deregistered" << std::endl;
00095 }
00096 
00097 void
00098 a_child_t::evt_start()
00099 {
00100   // Сообщаем о том, что мы стартовали.
00101   std::cout << so_query_name()
00102     << ": Hello, World!" << std::endl;
00103 }
00104 
00105 void
00106 a_child_t::evt_say_it_again( const so_4::rt::event_data_t & data )
00107 {
00108   // Сообщаем, что мы получили сообщение.
00109   std::cout << so_query_name()
00110     << ": and again - Hello, World!" << std::endl;
00111 
00112   // Отошлем его самим себе с задержкой. Если нас за это
00113   // время дерегистрируют, то мы его не получим.
00114   so_4::api::send_msg( data.agent(), data.msg(), 0,
00115     so_query_name(), 15000 );
00116 }
00117 
00118 //
00119 // Класс агента, который создает и уничтожает динамическую кооперацию.
00120 //
00121 class a_parent_t
00122   : public so_4::rt::agent_t
00123 {
00124   typedef so_4::rt::agent_t base_type_t;
00125   public :
00126     a_parent_t();
00127     virtual ~a_parent_t();
00128 
00129     virtual const char *
00130     so_query_type() const;
00131 
00132     virtual void
00133     so_on_subscription();
00134 
00135     // При поступлении этого сообщения кооперация будет создана.
00136     struct  msg_reg_time {};
00137 
00138     // При поступлении этого сообщения кооперация
00139     // будет дерегистрирована.
00140     struct  msg_dereg_time {};
00141 
00142     void
00143     evt_start();
00144 
00145     void
00146     evt_reg_time();
00147 
00148     void
00149     evt_dereg_time();
00150 
00151     void
00152     evt_coop_registered(
00153       const so_4::rt::msg_coop_registered & cmd );
00154 
00155     void
00156     evt_coop_deregistered(
00157       const so_4::rt::msg_coop_deregistered & cmd );
00158 };
00159 
00160 SOL4_CLASS_START( a_parent_t )
00161 
00162   SOL4_MSG_START( msg_reg_time, a_parent_t::msg_reg_time )
00163   SOL4_MSG_FINISH()
00164 
00165   SOL4_MSG_START( msg_dereg_time, a_parent_t::msg_dereg_time )
00166   SOL4_MSG_FINISH()
00167 
00168   SOL4_EVENT( evt_start )
00169 
00170   SOL4_EVENT( evt_reg_time )
00171 
00172   SOL4_EVENT( evt_dereg_time )
00173 
00174   SOL4_EVENT_STC(
00175     evt_coop_registered,
00176     so_4::rt::msg_coop_registered )
00177 
00178   SOL4_EVENT_STC(
00179     evt_coop_deregistered,
00180     so_4::rt::msg_coop_deregistered )
00181 
00182   SOL4_STATE_START( st_initial )
00183     SOL4_STATE_EVENT( evt_start )
00184     SOL4_STATE_EVENT( evt_reg_time )
00185     SOL4_STATE_EVENT( evt_dereg_time )
00186     SOL4_STATE_EVENT( evt_coop_registered )
00187     SOL4_STATE_EVENT( evt_coop_deregistered )
00188   SOL4_STATE_FINISH()
00189 
00190 SOL4_CLASS_FINISH()
00191 
00192 a_parent_t::a_parent_t()
00193 :
00194   base_type_t( "a_parent" )
00195 {}
00196 
00197 a_parent_t::~a_parent_t()
00198 {}
00199 
00200 void
00201 a_parent_t::so_on_subscription()
00202 {
00203   so_subscribe( "evt_start",
00204     so_4::rt::sobjectizer_agent_name(), "msg_start" );
00205 
00206   so_subscribe( "evt_reg_time", "msg_reg_time" );
00207 
00208   so_subscribe( "evt_dereg_time", "msg_dereg_time" );
00209 
00210   // Если приоритит у этого события больше, чем приоритет
00211   // evt_start у дочернего агента, то мы должны отработать
00212   // быстрее, чем дочерний агент (для приоритеных диспетчеров).
00213   so_subscribe( "evt_coop_registered",
00214     so_4::rt::sobjectizer_agent_name(), "msg_coop_registered", 1 );
00215 
00216   so_subscribe( "evt_coop_deregistered",
00217     so_4::rt::sobjectizer_agent_name(), "msg_coop_deregistered" );
00218 }
00219 
00220 void
00221 a_parent_t::evt_start()
00222 {
00223   // Указываем, когда дочерняя кооперация будет зарегистрирована.
00224   unsigned int sec = 1;
00225   std::cout << so_query_name()
00226     << ": child coop will be registered after "
00227     << sec << " sec" << std::endl;
00228 
00229   so_4::api::send_msg( so_query_name(), "msg_reg_time", 0,
00230     so_query_name(), sec * 1000 );
00231 }
00232 
00233 void
00234 a_parent_t::evt_reg_time()
00235 {
00236   std::cout << so_query_name()
00237     << ": It's time to register child coop"
00238     << std::endl;
00239 
00240   // Регистрируем дочернюю кооперацию.
00241   so_4::rt::dyn_agent_coop_helper_t helper(
00242     new so_4::rt::dyn_agent_coop_t( new a_child_t() ) );
00243   if( helper.result() )
00244   {
00245     // Ошибка регистрации!
00246     std::cerr << "register_coop: " << helper.result() << std::endl;
00247     so_4::api::send_msg( so_4::rt::sobjectizer_agent_name(),
00248       "msg_alarm_shutdown", 0 );
00249   }
00250 }
00251 
00252 void
00253 a_parent_t::evt_dereg_time()
00254 {
00255   std::cout << so_query_name()
00256     << ": It's time to deregister child coop" << std::endl;
00257 
00258   so_4::ret_code_t rc = so_4::api::deregister_coop( child_name );
00259   if( rc )
00260   {
00261     std::cerr << "deregister_coop: " << rc << std::endl;
00262     so_4::api::send_msg( so_4::rt::sobjectizer_agent_name(),
00263       "msg_alarm_shutdown", 0 );
00264   }
00265 }
00266 
00267 void
00268 a_parent_t::evt_coop_registered(
00269   const so_4::rt::msg_coop_registered & cmd )
00270 {
00271   std::cout << so_query_name()
00272     << ": Cooperation registered: "
00273     << cmd.m_coop_name << std::endl;
00274 
00275   if( child_name == cmd.m_coop_name )
00276   {
00277     // Это наша дочерняя кооперация, которую нужно
00278     // дерегистрировать.
00279 
00280     unsigned int sec = 2;
00281     std::cout << so_query_name()
00282       << ": child coop will be deregistered after "
00283       << sec << " sec" << std::endl;
00284 
00285     so_4::api::send_msg(
00286       so_query_name(), "msg_dereg_time", 0,
00287       so_query_name(), sec * 1000 );
00288 
00289     // Заставляем дочернего агента еще раз сказать Hello...
00290     so_4::api::send_msg( child_name, "msg_say_it_again" );
00291   }
00292 }
00293 
00294 void
00295 a_parent_t::evt_coop_deregistered(
00296   const so_4::rt::msg_coop_deregistered & cmd )
00297 {
00298   std::cout << so_query_name()
00299     << ": Cooperation deregistered: "
00300     << cmd.m_coop_name << std::endl;
00301 
00302   if( child_name == cmd.m_coop_name )
00303   {
00304     // Дочерняя кооперация дерегистрирована. Можно завершать работу.
00305     std::cout << so_query_name()
00306       << ": Work finished" << std::endl;
00307 
00308     so_4::api::send_msg(
00309       so_4::rt::sobjectizer_agent_name(),
00310       "msg_normal_shutdown", 0 );
00311   }
00312 }
00313 
00314 int
00315 main()
00316 {
00317   // Родительский агент.
00318   a_parent_t a_parent;
00319   // И кооперация для него.
00320   so_4::rt::agent_coop_t  a_parent_coop( a_parent );
00321 
00322   // Запускаем SObjectizer Run-Time.
00323   so_4::ret_code_t rc = so_4::api::start(
00324     so_4::disp::one_thread::create_disp(
00325       so_4::timer_thread::simple::create_timer_thread(),
00326       so_4::auto_destroy_timer ),
00327     so_4::auto_destroy_disp,
00328     &a_parent_coop );
00329   if( rc ) {
00330     // Запустить SObjectizer Run-Time не удалось.
00331     std::cerr << "start: " << rc << std::endl;
00332   }
00333 
00334   return int( rc );
00335 }

Документация по SObjectizer. Последние изменения: Thu Jan 12 10:52:49 2006. Создано системой  doxygen 1.4.6-NO
Hosted by uCoz