sample/hello_periodic/main.cpp

/*
  Пример простейшего агента, который использует собственные
  переодические сообщения.
*/

#include <iostream>

#include <time.h>

#include <ace/OS_main.h>

// Загружаем основные заголовочные файлы SObjectizer.
#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>

// C++ описание класса агента.
class a_hello_t
  : public so_4::rt::agent_t
{
  // Псевдоним для базового типа.
  typedef so_4::rt::agent_t base_type_t;
  public :
    a_hello_t();
    virtual ~a_hello_t();

    virtual const char *
    so_query_type() const;

    virtual void
    so_on_subscription();

    // Переодичесткое сообщение без данных.
    struct  msg_hello_no_data {};

    // Переодическое сообщение, которое содержит данные.
    struct  msg_hello_with_data
    {
      std::string m_msg;

      msg_hello_with_data() {}
      msg_hello_with_data(
        const std::string & msg )
      : m_msg( msg )
      {}

      // Не разрешает ходения сообщения без данных.
      static bool
      check( const msg_hello_with_data * msg )
      {
        return ( 0 != msg );
      }
    };

    // Начало работы агента в системе.
    void
    evt_start();

    // Реакция на сообщение без данных.
    void
    evt_hello_no_data();

    // Реакция на сообщение с данными.
    void
    evt_hello_with_data(
      const msg_hello_with_data & cmd );

  private :
    // Оставшеся количество циклов до завершения работы.
    unsigned int  m_remaining;
};

// Описание класса агента для SObjectizer-а.
SOL4_CLASS_START( a_hello_t )

  // Описание сообщений.
  SOL4_MSG_START( msg_hello_no_data, a_hello_t::msg_hello_no_data )
  SOL4_MSG_FINISH()

  SOL4_MSG_START( msg_hello_with_data, a_hello_t::msg_hello_with_data )
    SOL4_MSG_CHECKER( a_hello_t::msg_hello_with_data::check )
  SOL4_MSG_FINISH()

  // Описание событий.
  SOL4_EVENT( evt_start )
  SOL4_EVENT( evt_hello_no_data )
  SOL4_EVENT_STC(
    evt_hello_with_data,
    a_hello_t::msg_hello_with_data )

  // Описание единственного состояния.
  SOL4_STATE_START( st_initial )
    SOL4_STATE_EVENT( evt_start )
    SOL4_STATE_EVENT( evt_hello_no_data )
    SOL4_STATE_EVENT( evt_hello_with_data )
  SOL4_STATE_FINISH()

SOL4_CLASS_FINISH()

a_hello_t::a_hello_t()
:
  base_type_t( "a_hello" )
, m_remaining( 5 )
{}

a_hello_t::~a_hello_t()
{}

void
a_hello_t::so_on_subscription()
{
  so_subscribe( "evt_start",
    so_4::rt::sobjectizer_agent_name(), "msg_start" );

  so_subscribe( "evt_hello_no_data", "msg_hello_no_data" );
  so_subscribe( "evt_hello_with_data", "msg_hello_with_data" );
}

void
a_hello_t::evt_start()
{
  unsigned int no_data_delay = 2;
  unsigned int no_data_period = 1;
  unsigned int with_data_delay = 0;
  unsigned int with_data_period = 2;

  time_t t = time( 0 );

  // Сообщаем, что и когда будет происходить.
  std::cout << so_query_name() << ".evt_start: "
    << asctime( localtime( &t ) )
    << "\thello_no_data delay: " << no_data_delay
    << "\n\thello_no_data period: " << no_data_period
    << "\n\thello_with_data delay: " << with_data_delay
    << "\n\thello_with_data period: " << with_data_period
    << std::endl;

  // Запускаем переодические сообщения.
  so_4::api::send_msg_safely(
    so_query_name(),
    "msg_hello_with_data",
    new msg_hello_with_data(
      std::string( "Sample started at " ) +
      asctime( localtime( &t ) ) ),
    so_4::api::receiver_unknown(),
    with_data_delay * 1000,
    with_data_period * 1000 );

  so_4::api::send_msg(
    so_query_name(), "msg_hello_no_data", 0,
    so_4::api::receiver_unknown(),
    no_data_delay * 1000, no_data_period * 1000 );
}

void
a_hello_t::evt_hello_no_data()
{
  --m_remaining;

  time_t t = time( 0 );
  std::cout << so_query_name() << ".evt_hello_no_data: "
    << asctime( localtime( &t ) )
    << "\tremaining: " << m_remaining << std::endl;

  if( !m_remaining )
    // Отсылаем сообщение для завершения работы.
    so_4::api::send_msg(
      so_4::rt::sobjectizer_agent_name(),
      "msg_normal_shutdown", 0 );
}

void
a_hello_t::evt_hello_with_data(
  const msg_hello_with_data & cmd )
{
  time_t t = time( 0 );
  std::cout << so_query_name() << ".evt_hello_with_data: "
    << asctime( localtime( &t ) )
    << "\t" << cmd.m_msg << std::endl;
}

int
main( int, char ** )
{
  // Наш агент.
  a_hello_t a_hello;
  // И кооперация для него.
  so_4::rt::agent_coop_t  a_hello_coop( a_hello );

  // Запускаем SObjectizer Run-Time.
  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_hello_coop );
  if( rc )
  {
    // Запустить SObjectizer Run-Time не удалось.
    std::cerr << "start: " << rc << std::endl;
  }

  return int( rc );
}

Документация по SObjectizer v.4.4 'Тебуломста'. Последние изменения: Thu Sep 18 10:26:45 2008. Создано системой  doxygen1.5.6 Intervale SourceForge.net Logo