Но в предшествующих v.4.2.6 версиях SObjectizer агент не мог контролировать время жизни объекта-свойства. Это приводило к тому, что в случае, когда свойство должно было существовать столько же, сколько и агент, свойство должно было быть атрибутом агента. Вот пример из использования MBAPI:
class a_receive_processor_t : public so_4::rt::agent_t { typedef so_4::rt::agent_t base_type_t; public : ... typedef mbapi_3::router::so_msg_templ_t< mbsms_1::receive_t, mbapi_3::client_dest_t, mbapi_3::server_dest_t > msg_receive; typedef mbapi_3::router::so_msg_templ_t< mbsms_1::receive_ack_t > msg_receive_ack; typedef mbapi_3::router::so_msg_templ_t< mbsms_1::receive_finish_t, mbapi_3::client_dest_t, mbapi_3::server_dest_t > msg_receive_finish; typedef mbapi_3::router::so_msg_templ_t< mbsms_1::receive_finish_ack_t > msg_receive_finish_ack; ... private : ... mbapi_3::router::so_msg_templ_postman_t< msg_receive > m_receive_postman; mbapi_3::router::so_msg_templ_postman_t< msg_receive_ack > m_receive_ack_postman; mbapi_3::router::so_msg_templ_postman_t< msg_receive_finish > m_receive_finish_postman; mbapi_3::router::so_msg_templ_postman_t< msg_receive_finish_ack > m_receive_finish_ack_postman; }; a_receive_processor_t::a_receive_processor_t( ... ) : base_type_t( self_name.c_str() ) ... , m_receive_postman( so_query_name(), "msg_receive", receive_analyzer, receive_postman_priority, mbapi_3::router::intercept_msg ) , m_receive_ack_postman( so_query_name(), "msg_receive_ack", mbapi_3::router::and_analyzer( mbapi_3::router::dest_equality_analyzer( we_as_server ), mbapi_3::router::reply_to_equality_analyzer( recipient ) ) ) , m_receive_finish_postman( so_query_name(), "msg_receive_finish", // Для сообщения receive_finish необходимо два условия: mbapi_3::router::and_analyzer( // Сообщение должно адресоваться нам и должно // придти от AGGREGATE. mbapi_3::router::and_analyzer( mbapi_3::router::dest_equality_analyzer( we_as_client ), mbapi_3::router::reply_to_equality_analyzer( aggregate_dest ) ), // Идентификатор SMS-а должен быть нам известен. new receive_finish_analyzer_t( *m_uid_map ) ), // Сообщение должно перехватываться. 1, mbapi_3::router::intercept_msg ) , m_receive_finish_ack_postman( so_query_name(), "msg_receive_finish_ack", mbapi_3::router::and_analyzer( mbapi_3::router::dest_equality_analyzer( we_as_server ), mbapi_3::router::reply_to_equality_analyzer( recipient ) ) ) { so_add_traits( m_receive_postman ); so_add_traits( m_receive_ack_postman ); so_add_traits( m_receive_finish_postman ); so_add_traits( m_receive_finish_ack_postman ); }
Подобное использование свойст агентов имеет одно неудобство -- каждое свойство почтальон должно быть описано как атрибут в описании класса. В случае же применения уничтожаемых агентом свойств данный пример можно было бы переписать, например, так:
\code class a_receive_processor_t : public so_4::rt::agent_t { typedef so_4::rt::agent_t base_type_t; public : ... typedef mbapi_3::router::so_msg_templ_t< mbsms_1::receive_t, mbapi_3::client_dest_t, mbapi_3::server_dest_t > msg_receive; typedef mbapi_3::router::so_msg_templ_t< mbsms_1::receive_ack_t > msg_receive_ack; typedef mbapi_3::router::so_msg_templ_t< mbsms_1::receive_finish_t, mbapi_3::client_dest_t, mbapi_3::server_dest_t > msg_receive_finish; typedef mbapi_3::router::so_msg_templ_t< mbsms_1::receive_finish_ack_t > msg_receive_finish_ack; ... }; a_receive_processor_t::a_receive_processor_t( ... ) : base_type_t( self_name.c_str() ) ... { so_add_destroyable_traits( new mbapi_3::router::so_msg_templ_postman_t< msg_receive >( so_query_name(), "msg_receive", receive_analyzer, receive_postman_priority, mbapi_3::router::intercept_msg ) ); so_add_destroyable_traits( new mbapi_3::router::so_msg_templ_postman_t< msg_receive_ack >( so_query_name(), "msg_receive_ack", mbapi_3::router::and_analyzer( mbapi_3::router::dest_equality_analyzer( we_as_server ), mbapi_3::router::reply_to_equality_analyzer( recipient ) ) ) ); so_add_destroyable_traits( new mbapi_3::router::so_msg_templ_postman_t< msg_receive_finish >( so_query_name(), "msg_receive_finish", // Для сообщения receive_finish необходимо два условия: mbapi_3::router::and_analyzer( // Сообщение должно адресоваться нам и должно // придти от AGGREGATE. mbapi_3::router::and_analyzer( mbapi_3::router::dest_equality_analyzer( we_as_client ), mbapi_3::router::reply_to_equality_analyzer( aggregate_dest ) ), // Идентификатор SMS-а должен быть нам известен. new receive_finish_analyzer_t( *m_uid_map ) ), // Сообщение должно перехватываться. 1, mbapi_3::router::intercept_msg ) ); so_add_destroyable_traits( new mbapi_3::router::so_msg_templ_postman_t< msg_receive_finish_ack >( so_query_name(), "msg_receive_finish_ack", mbapi_3::router::and_analyzer( mbapi_3::router::dest_equality_analyzer( we_as_server ), mbapi_3::router::reply_to_equality_analyzer( recipient ) ) ) ); }
Т.е. объем кода в теле конструктора бы не изменился, зато не нужно было бы описывать свойства как атрибуты класса a_receive_processor_t.
Уничтожаемые агентом свойства назначаются агенту посредством метода so_4::rt::agent_t::so_add_destroyable_traits(). Добавляемое таким образом свойство должно быть динамически созданным объектом, который будет уничтожен в деструкторе агента.
Метод so_4::rt::agent_t::so_add_traits() получает ссылку на объект-свойство, чье время жизни агент не контролирует.
В отношении не контролируемых свойств агента (т.е. добавляемых агенту посредством метода so_4::rt::agent_t::so_add_traits()) v.4.2.6 сохраняет полную совместимость с предыдущими версиями.
Документация по SObjectizer v.4.4 'Тебуломста'. Последние изменения: Thu Sep 18 10:26:48 2008. Создано системой 1.5.6 |