SObjectizer  5.7
so-5.5.9: New helper functions request_future and request_value

A synchronous interaction between agents is a very useful mechanism for some situations. But usage of long method call chaings for that interaction is sometimes complex and confusing. For example:

std::string v = converter_mbox->get_one<std::string>()
.wait_forever()
.make_sync_get<convert_int>(42);

Such long method call chains are there because there was a necessity to support of compilers without proper implementation of C++11 variadic templates. But such compilers are not supported now. It means that synchronous interactions can be simplified.

Two new helper functions have been introduced in v.5.5.9:

The usage of request_future() and request_value() can be shown in comparison with old approach:

// Old way of getting std::future<T>:
auto f1 = converter_mbox->get_one<std::string>().make_async<convert_int>(42);
// New way:
auto f2 = so_5::request_future<std::string, convert_int>(converter_mbox, 42);
// Old way of getting a value with infinite waiting:
auto v1 = converter_mbox->get_one<std::string>()
.wait_forever()
.make_sync_get<convert_int>(42);
// New way:
auto v2 = so_5::request_value<std::string, convert_int>(converter_mbox, so_5::infinite_wait, 42);
// Old way of getting a value with finite waiting time:
auto v3 = converter_mbox->get_one<std::string>()
.wait_for(std::chrono::milliseconds(150))
.make_sync_get<convert_int>(42);
// New way:
auto v4 = so_5::request_value<std::string, convert_int>(converter_mbox,
std::chrono::milliseconds(150), 42);

New functions also support signals as requests:

struct get_status : public so_5::rt::signal_t {};
...
auto f1 = so_5::request_future<std::string, get_status>(mbox);
auto v1 = so_5::request_value<std::string, get_status>(mbox, so_5::infinite_wait);

The first argument for request_future() and request_value() can be either a so_5::rt::mbox_t, a reference to so_5::rt::agent_t or a reference to ad-hoc agent proxy. For example:

env.introduce_coop( []( so_5::rt::agent_coop_t & coop ) {
auto engine = coop.make_agent_with_binder< engine_agent >(
so_5::disp::one_thread::create_private_disp()->binder(), ... );
auto indicator = coop.define_agent( so_5::disp::one_thread::create_private_disp()->binder() );
...
auto starter = coop.define_agent().on_start( [indicator, engine]{
// Synchronous signal to turn engine on.
so_5::request_value<void, turn_on>( *engine );
// Synchronous signal to show engine status.
so_5::request_value<void, engine_is_working >( indicator );
} );
} );