SObjectizer  5.1
so_sysconf_4: Meta Action

Механизм мета-действий.

Введение

Специфика so_sysconf такова, что so_ sysconf ничего не знает об особенностях тех или иных коопераций, поэтому все что он может с ними делать это регистрировать и дерегистрировать. Но все же хотелось получить какие-то механизмы управления над конкретными кооперациями. Поэтому в so_ sysconf внедрен механизм мета-действий. Когда кооперация регистрируется (через coop_ handler или coop_factory), вместе с возвращаемым значением регистратор может вернуть и набор мета-действий. Мета-действие представляет собой объект который предоставляет общее описание мета действие и может его выполнять, получая параметры в строке в виде CLS тега.

Механизм мета-действий

Для реализации механизма мета-действий Sysconf использует два класса, один из которых интерфейсный meta_action_t, а другой служит для передачи подсистеме Sysconf набора мета-действий. Для облегчения работы механизм мета-действий включает в себя генератор, который генерирует вспомогательный код, имея который достаточно задать обработчики событий агенту, для которого требуется реализовать некоторое мета-действие.

Класс meta_action_t

Класс представляет собой интерфейс, с которым работает Sysconf. Конкретная реализация генерируется автоматически, поэтому остается только включить ее в набор мета-действий вместе с возвращаемым значением.

Класс coop_registration_result_t

Класс coop_registration_result_t характеризует результат регистрации кооперации через хэндлер или фабрику коопераций. В самом простом случае он просто отвечает на вопрос: была ли кооперация зарегистрирована успешно.

Если кооперация успешно зарегистрировалась, то Sysconf проверяет, содержит ли возвращаемое значение мета-действия. Если регистрация кооперации возвращает набор мета-действий, то они закрепляются за кооперацей, и их можно использовать для инициации заданных действий.

Если кооперация не выполняет никаких мета действий, то достаточно вернуть true или false, положившись на конвертирующий конструктор, который создаст объект coop_registration_result_t, который не будет содержать никаких мета-действий. Однако лучше использовать вспомогательные функции:

Генерация вспомогательного кода

Мета-действия задумывались, как механизм отсылки сообщений какому-либо агенту. Для этого реализован генератор, который реализован на Ruby и интегрирован с Mxx_ru. Генератору необходимо передать описание сообщений в CLS формате, обработку которых планируется сделать мета-действием.

Формат описания сообщений

Формат корневого тега {sysconf_meta_actions}:

  {sysconf_meta_actions
    [{namespace <string>}]*
    [{message <string>}]*
  }

Формат тега {namespace}:

  {namespace
    [{namespace <string>}]*
    [{message <string>}]*
  }

Формат тега {message}:

  {message <string>
    {action_name <string>}
    [{comment <string>}]
    [{field_prefix <string>}]
    [{field_suffix <string>}]
    [{field <string>}]*
  }

Формат тега {field}:

  {field <string>
    {type <string>}
    [{one_of <value> <value> <value>}]
    [{min_max {min <value>} {max <value>}}]
    [{default <string>}]
  }

Пример файла с форматом сообщений

{sysconf_meta_actions
	|| пространство имен с которым будет идти
	|| реализация классов meta-инфой о сообщении.
	{namespace "meta_action_sample"
	{namespace "messages"

		{message "sample_msg_1"
			{action_name "Test action #1"}
			{comment "Sample message #1"}
			{field_prefix "m_"}
			{field_suffix ""}
			{field "name"
				{type "std::string"}

				|| необязательно
				{default "Vova"}
				{one_of "Vova" "Masha" "Dasha"}
			}

			{field "age"
				{type "int"}
				|| необязательно
				{default "10"}
				{min_max
					{min 5}
					{max 50}
				}
			}
		}

	} || {namespace "messages"
	} || {namespace "meta_action_sample"
}

В результате генерируется 4 файлов, из которых явно использовать необходимо только 2. Предположим что имя файла с описанием формата сообщений – 'sample_messages'. Тогда сгенерируются следующие файлы:

Агент, который использует данные мета-действия может выглядеть следующим образом:

Заголовочный файл

/*
Модуль для демонстрации работы coop_handler.
Агент с мета-действиями.
*/
#if !defined( _SAMPLE__SO_SYSCONF_4__WITH_META_ACTION__A_META_ACTION_RECEIVER_HPP_ )
#define _SAMPLE__SO_SYSCONF_4__WITH_META_ACTION__A_META_ACTION_RECEIVER_HPP_
#include <string>
// Загружаем необходимые описания из SObjectizer.
#include <so_5/rt/h/rt.hpp>
// Сгенерированные файлы
#include "../fmt_dir/sample_messages.hpp"
namespace meta_action_sample
{
class a_meta_action_receiver_t
:
{
typedef so_5::rt::agent_t base_type_t;
public:
explicit a_meta_action_receiver_t(
virtual ~a_meta_action_receiver_t();
virtual void
so_define_agent();
virtual void
so_evt_start();
void
evt_on_meta_action_structure(
void
evt_meta_action_1(
private:
so_5::rt::mbox_ref_t m_sysconf_mbox;
};
} /* namespace meta_action_sample */
#endif

Файл реализации

/*
Модуль для демонстрации работы coop_handler.
Агент с мета-действаиями.
*/
#include <iostream>
#include <sample/so_sysconf_4/dll/with_meta_action/h/a_meta_action_receiver.hpp>
namespace meta_action_sample
{
a_meta_action_receiver_t::a_meta_action_receiver_t(
base_type_t( env ),
m_sysconf_mbox(
so_environment().query_layer< so_sysconf_4::so_sysconf_layer_t >()->
query_mbox() )
{}
a_meta_action_receiver_t::~a_meta_action_receiver_t()
{
}
void
a_meta_action_receiver_t::so_define_agent()
{
so_subscribe( m_sysconf_mbox )
.event( &a_meta_action_receiver_t::evt_on_meta_action_structure );
so_subscribe( m_sysconf_mbox )
.event( &a_meta_action_receiver_t::evt_meta_action_1 );
}
void
a_meta_action_receiver_t::evt_on_meta_action_structure(
{
// Будем печатать информацию котрая касается
// непосредственно нашего агента.
if( evt_data->m_coop_name == so_coop_name() )
{
// Получено описание структуры мета-действия.
std::cout << "\n\n" << so_coop_name()
<< "::evt_on_meta_action_structure:\n"
"\tcoop_name = " << evt_data->m_coop_name << "\n"
"\taction_name = " << evt_data->m_action_name << "\n"
"\tmeta_action_structure = "
<< evt_data->m_meta_action_structure << "\n\n";
}
}
void
a_meta_action_receiver_t::so_evt_start()
{
// В самом начале своей работы отправим запросы на получение
// информации о своих-же мета-действиях.
std::cout << "\n\n" << so_coop_name()
<< "::evt_start()\n";
so_environment().query_layer< so_sysconf_4::so_sysconf_layer_t >()->
query_meta_action_structure( so_coop_name() , "Test action #1" );
// Вручную составляем параметр мета-действие и отправляем его.
std::string msg_content =
"{sample_msg_1 {name \"Vova\"} {age 12} }";
so_environment().query_layer< so_sysconf_4::so_sysconf_layer_t >()->
query_meta_action_execution(
so_coop_name() , "Test action #1" , msg_content );
}
void
a_meta_action_receiver_t::evt_meta_action_1(
{
std::cout << "\n\n" << so_coop_name()
<< "::evt_meta_action_1():\n"
"name = " << evt_data->m_name << "\n"
"age = " << evt_data->m_age << "\n";
}
} /* namespace meta_action_sample */

Документация по SObjectizer v.5.1 'Джимара'. Последние изменения: Ср 15 Май 2013 12:56:21. Создано системой  doxygen1.8.3.1 Intervale SourceForge.net Logo