SObjectizer 5.8
Loading...
Searching...
No Matches
so-5.5.14: mhood_t and event handler formats

An event handler for agent can be specified as ordinary method:

class my_agent : public so_5::agent_t {
public :
virtual void so_define_agent() override {
so_subscribe_self().event( &my_agent::some_handler );
...
}
...
void some_handler( const some_message & msg ) {...}
};
A base class for agents.
Definition agent.hpp:673
virtual void so_define_agent()
Hook on define agent for SObjectizer.
Definition agent.cpp:841
subscription_bind_t so_subscribe_self()
Initiate subscription to agent's direct mbox.
Definition agent.hpp:1416
std::enable_if< details::is_agent_method_pointer< details::method_arity::unary, Method_Pointer >::value, subscription_bind_t & >::type event(Method_Pointer pfn, thread_safety_t thread_safety=not_thread_safe)
Make subscription to the message.
Definition agent.hpp:3490

Also an event handler for agent can be specified as lambda-function:

class my_agent : public so_5::agent_t {
public :
virtual void so_define_agent() override {
[&]( const some_message & msg ) {...} );
...
}
};

Please note that event handlers for ad-hoc agents can be specified only as lambda-functions.

But in versions prior to v.5.5.14 there was some discrimination for lambda-like event handlers: it was impossible to pass an so_5::event_data_t<M> as argument for lambda-function. This flaw in event handlers design had two major negative consequences.

There was no possibitity to resend the same message object or to store it for the future use. Event handler in the form of agent's method can receive message as so_5::event_data_t<M> and call make_reference() method. But lambda-style event handler couldn't do that.

There was some difficulty in writing template code. For example it was not a simple task to write something like this:

template< typename M >
void define_reaction_for( so_5::agent_t & receiver )
{
receiver.so_subscribe_self().event( []( const M & ) {...) );
}

It is because if M is a signal then event handler must have different format.

Since v.5.5.14 lambda-style event handlers can have the same format as method-style event handler.

In v.5.5.14 any event handler (as lambda-style as well as method-style) can have one of the following formats:

// Applicable for messages and signals.
return_type handler( so_5::mhood_t< message_type > msg );
return_type handler( const so_5::mhood_t< message_type > & msg );
// Applicable for messages only.
return_type handler( const message_type & msg );
return_type handler( message_type msg );
// Applicable for signals only.
return_type handler();
A message wrapped to be used as type of argument for event handlers.
Definition mhood.hpp:570

Old name so_5::event_data_t is now just an alias for so_5::mhood_t. Name event_data_t is deprecated and will be removed in v.5.6.0. Name mhood_t must be used instead.

Method mhood_t::make_reference allows to receive smart pointer to message object even if message type is not derived from so_5::message_t. It makes possible to write something like this:

so_subscribe_self().event( [&]( mhood_t< std::string > msg ) {
// Redirecting message to different mbox.
m_next_target->deliver_message( msg.make_reference() );
} );

If M is not derived from so_5::message_t then mhood_t<M>::make_reference returns so_5::intrusive_ptr_t<so_5::user_type_message_t<M>>.

NOTE! In previous versions it was possible to write:

void some_handler( const so_5::event_data_t< so_5::user_type_message_t< M > > & msg ) {
...
}
Template class for representing object of user type as a message.
Definition message.hpp:315

Now it is prohibited. Such code must be rewritten as:

void some_handler( mhood_t< M > msg ) {
...
}
// Or:
void some_handler( const mhood_t< M > & msg ) {
...
}

NOTE! There is an alias so_5::agent_t::mhood_t. It allows to use short name mhood_t<M> instead of so_5::mhood_t<M> in the scope of a class which is derived from so_5::agent_t. For example:

class my_agent : public so_5::agent_t {
...
private:
void some_handler( mhood_t< some_message > msg ) {...}
void another_handler( mhood_t< another_message > msg ) {...}
...
};