sample/hello_all/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>

//
// a_msg_owner_t
//

// Класс агента, единственной задачей которого является
// владение сообщениями.
class a_msg_owner_t :
  public so_4::rt::agent_t
{
  typedef so_4::rt::agent_t base_type_t;

  public :
    a_msg_owner_t()
    : base_type_t( agent_name() )
    {}

    virtual ~a_msg_owner_t()
    {}

    virtual const char *
    so_query_type() const;

    virtual void
    so_on_subscription()
    {}

    static std::string
    agent_name()
    {
      return "a_msg_owner";
    }

    // Сообщение, которым будут пользоваться агенты примера.
    struct  msg_hello
    {
      std::string m_sender;

      msg_hello() {}
      msg_hello(
        const std::string & sender )
      : m_sender( sender )
      {}

      static bool
      check( const msg_hello * msg )
      {
        return ( 0 != msg &&
          msg->m_sender.length() );
      }
    };
};

SOL4_CLASS_START( a_msg_owner_t )

  SOL4_MSG_START( msg_hello_to_all, a_msg_owner_t::msg_hello )
    SOL4_MSG_FIELD( m_sender )

    SOL4_MSG_CHECKER( a_msg_owner_t::msg_hello::check )
  SOL4_MSG_FINISH()

  SOL4_MSG_START( msg_hello_to_you, a_msg_owner_t::msg_hello )
    SOL4_MSG_FIELD( m_sender )

    SOL4_MSG_CHECKER( a_msg_owner_t::msg_hello::check )
  SOL4_MSG_FINISH()

SOL4_CLASS_FINISH()

//
// a_msg_receiver_t
//

// Класс агента, который получает сообщения.
class a_msg_receiver_t :
  public so_4::rt::agent_t
{
  typedef so_4::rt::agent_t base_type_t;

  public :
    a_msg_receiver_t(
      const std::string & agent_name );
    virtual ~a_msg_receiver_t();

    virtual const char *
    so_query_type() const;

    virtual void
    so_on_subscription();

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

    void
    evt_hello_to_all(
      const a_msg_owner_t::msg_hello & cmd );

    void
    evt_hello_to_you(
      const a_msg_owner_t::msg_hello & cmd );
};

SOL4_CLASS_START( a_msg_receiver_t )

  SOL4_EVENT( evt_start )
  SOL4_EVENT_STC(
    evt_hello_to_all,
    a_msg_owner_t::msg_hello )
  SOL4_EVENT_STC(
    evt_hello_to_you,
    a_msg_owner_t::msg_hello )

  SOL4_STATE_START( st_initial )
    SOL4_STATE_EVENT( evt_start )
    SOL4_STATE_EVENT( evt_hello_to_all )
    SOL4_STATE_EVENT( evt_hello_to_you )
  SOL4_STATE_FINISH()

SOL4_CLASS_FINISH()

//
// a_msg_receiver_t
//
a_msg_receiver_t::a_msg_receiver_t(
  const std::string & agent_name )
:
  base_type_t( agent_name )
{}

a_msg_receiver_t::~a_msg_receiver_t()
{}

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

  so_subscribe( "evt_hello_to_all",
    a_msg_owner_t::agent_name(),
    "msg_hello_to_all", 1 );

  so_subscribe( "evt_hello_to_you",
    a_msg_owner_t::agent_name(),
    "msg_hello_to_you", 1 );
}

void
a_msg_receiver_t::evt_start()
{
  std::cout << so_query_name() << ".evt_start" << std::endl;

  so_4::api::send_msg_safely(
    a_msg_owner_t::agent_name(), "msg_hello_to_all",
    new a_msg_owner_t::msg_hello( so_query_name() ) );
}

void
a_msg_receiver_t::evt_hello_to_all(
  const a_msg_owner_t::msg_hello & cmd )
{
  std::cout << so_query_name() << ".evt_hello_to_all: "
    << cmd.m_sender << std::endl;
  // Если привествие слали не мы, то отошлем ответ.
  if( so_query_name() != cmd.m_sender )
  {
    so_4::api::send_msg_safely(
      a_msg_owner_t::agent_name(),
      "msg_hello_to_you",
      new a_msg_owner_t::msg_hello( so_query_name() ),
      cmd.m_sender );
  }
}

void
a_msg_receiver_t::evt_hello_to_you(
  const a_msg_owner_t::msg_hello & cmd )
{
  std::cout << so_query_name() << ".evt_hello_to_you: "
    << cmd.m_sender << std::endl;
}

//
// a_shutdowner_t
//

// Агент для завершения работы примера.
class a_shutdowner_t :
  public so_4::rt::agent_t
{
  typedef so_4::rt::agent_t base_type_t;

  public :
    a_shutdowner_t();
    virtual ~a_shutdowner_t();

    virtual const char *
    so_query_type() const;

    virtual void
    so_on_subscription();

    static std::string
    agent_name();

    void
    evt_shutdown();
};

SOL4_CLASS_START( a_shutdowner_t )

  SOL4_EVENT( evt_shutdown )

  SOL4_STATE_START( st_initial )
    SOL4_STATE_EVENT( evt_shutdown )
  SOL4_STATE_FINISH()

SOL4_CLASS_FINISH()

//
// a_shutdowner_t
//
a_shutdowner_t::a_shutdowner_t() :
  base_type_t( agent_name().c_str() )
{
}

a_shutdowner_t::~a_shutdowner_t() {
}

void
a_shutdowner_t::so_on_subscription()
{
  so_subscribe( "evt_shutdown",
    so_4::rt::sobjectizer_agent_name(),
    "msg_start" );
}

std::string
a_shutdowner_t::agent_name()
{
  return "a_shutdowner";
}

void
a_shutdowner_t::evt_shutdown()
{
  so_4::api::send_msg( so_4::rt::sobjectizer_agent_name(),
    "msg_normal_shutdown" );
}


int
main( int, char ** )
{
  // Агенты примера.
  a_msg_owner_t a_msg_owner;
  a_shutdowner_t  a_shutdowner;

  a_msg_receiver_t  a_receiver_one( "a_receiver_one" );
  a_msg_receiver_t  a_receiver_two( "a_receiver_two" );
  a_msg_receiver_t  a_receiver_three( "a_receiver_three" );

  // Кооперация примера.
  so_4::rt::agent_t * g_coop_agents[] = {
    &a_msg_owner,
    &a_shutdowner,
    &a_receiver_one,
    &a_receiver_two,
    &a_receiver_three
  };

  so_4::rt::agent_coop_t  a_coop( "a_coop", g_coop_agents,
    sizeof( g_coop_agents ) / sizeof( g_coop_agents[ 0 ] ) );

  so_4::ret_code_t rc = so_4::api::start(
    // Диспетчер будет уничтожен при выходе из 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_coop );
  if( rc )
  {
    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