Purpose
A traditional way of starting SO Environment is to use so_5::launch free function:
...
} );
void launch(Init_Routine &&init_routine)
Launch a SObjectizer Environment with default parameters.
This way is useful if all application logic is implemented by SObjectizer’s agents and there is only one SO Environment in the application. But sometimes it is not the case. For example if an application has to have GUI-event handling loop. In that case application’s main() function could look like:
int main()
{
...
...
while(!GetMessage(...))
ProcessMessage(...);
...
...
}
Usage of so_5::launch() in such cases is not as straightforward as intended to be. It could look like:
int main()
{
so_5::rt::environment_t * env_ptr = nullptr;
env_ptr = &env;
...
} );
...
while(!GetMessage(...))
ProcessMessage(...);
env_ptr->stop();
...
}
It is not a simple approach and it could lead to mistakes.
To simplify a development of applications with some GUI-event loops a new class has been added in v.5.5.9: so_5::wrapped_env_t. With that class the example above can be rewritten that way:
int main()
{
...
} );
...
while(!GetMessage(...))
ProcessMessage(...);
...
}
decltype(auto) introduce_coop(Args &&... args)
Helper method for simplification of cooperation creation and registration.
void stop_then_join()
Send stop signal and wait for complete finish of environment's work.
environment_t & environment() const
Access to wrapped environment.
Working Principle
Working principle of so_5::wrapped_env_t is very simple:
- a thread is created inside a constructor of wrapped_env_t;
- an analog of so_5::launch is called on the context of that thread;
- pointer to actual so_5::rt::environment_t instance is stored inside wrapped_env_t;
- this thread is stopped and joined automatically in the destructor of so_5::wrapped_env_t.
This way of working guarantees that a reference to actual so_5::rt::environment_t instance will be valid for the whole lifetime of wrapped_env_t object.
- Note
- If wrapped_env_t::join() or wrapped_env_t::stop_then_join() is called explicitely then the helper thread will be finished before exit from join()/stop_then_join() methods. A reference to so_5::rt::environment_t instance still will be valid, but this SO Environment will be stopped and cannot be used later.
-
There is no way to restart SO Environment controlled by wrapped_env_t object after call to stop() or stop_then_join() methods. If such logic is necessary then consider destroyment and recreation of the whole wrapped_env_t object:
while( some_condition )
{
...
...
}
Usage Examples
There are several constructors for so_5::wrapped_env_t. The simplest one is the default constructor:
New coops could be added later via traditional approaches:
...
auto coop = env.
environment().create_coop( so_5::autoname );
...
env.environment().register_coop( std::move(coop) );
std::unique_ptr< Agent > make_agent(Args &&... args)
Helper method for simplification of agents creation.
There is also a constructor which receives a lambda-function or a functional object for doing initial actions right after start of SO Environment (just like in the case of so_5::launch):
[]( so_5::rt::environment_t & env ) {
...
env.introduce_coop(...);
} };
There are also two constructors which allows to tune SO Environment parameters. One of them receives a rvalue reference to so_5::rt::environment_params_t object:
so_5::rt::environment_params_t prepare_params()
{
so_5::rt::environment_params_t params;
params.exception_reaction( so_5::rt::shutdown_sobjectizer_on_exception );
...
return params;
}
...
so_5::wrapped_env_t env{
[]( so_5::rt::environment_t & ) {},
prepare_params() };
timer_thread_factory_t timer_list_factory()
Factory for timer_list thread with default parameters.
The second receives parameters' tuner lambda or functional object:
so_5::rt::environment_params_t prepare_params()
{
so_5::rt::environment_params_t params;
params.exception_reaction( so_5::rt::shutdown_sobjectizer_on_exception );
...
return params;
}
...
so_5::wrapped_env_t env{
[]( so_5::rt::environment_t & ) {},
[]( so_5::rt::environment_params_t & params ) {
params.exception_reaction( so_5::rt::shutdown_sobjectizer_on_exception );
} };
Wrapped_env and Autoshutdown Option
Class wrapped_env_t always adds disable_autoshutdown option to SO Environment parameters. It means that SO Environment will not be stopped after deregistration of the last coop. Only explicit call to wrapped_env_t::stop() or wrapped_ent_t::stop_then_join() stops SO Environment. SO Environment also automatically stopped in the wrapped_env’s destructor.