Home | Libraries | People | FAQ | More |
The 'aspects' concept allow user to customize, and extend library functionality in easy way. The diagram below shows the way to extend or create new aspect.
The 'A' shows the more complex aspects, that needs to meet a well defined interface, which is used internally by the application mode.
On 'B' we have simplest aspect that can be any C++ class.
Thus, the user can customize the default behavior of any handler. To do this, the user needs inheriting of contract handler class (abstract) that he wants to modify the behavior.
For sample: The default behavior of wait_for_termination_request is unblock and exit of application. To change this behavior user can do as follows:
class myapp { public: myapp(application::context& context) : context_(context) { } // param int operator()() { std::cout << "Test" << std::endl; context_.find<application::wait_for_termination_request>()->wait(); return 0; } private: application::context& context_; }; // my made by hand behaviour class wait_for_termination_request_my_behaviour : public application::wait_for_termination_request { public: void wait(){ char type; do { std::cout << "Exit? [y/n]" << std::endl; std::cin >> type; } while( !std::cin.fail() && type!='y' ); } void proceed(){ // do nothing } }; // main int main(int argc, char *argv[]) { application::context app_context; myapp app(app_context); app_context.insert<application::args>( boost::make_shared<application::args>(argc, argv)); // if user do this, the default behavoiur will be ignored, // and the user behaviour will be executed by application::server app_context.insert< application::wait_for_termination_request>( shared_ptr<application::wait_for_termination_request>( new wait_for_termination_request_my_behaviour)); return application::launch<application::common>(app, app_context); }
Like a handler, the user is free to customize the SIGNALS of application.
Note | |
---|---|
The SIGNALS can not be customized when Windows Service (server application mode on windows) is used. Windows Service uses a completely different set of signals called 'events', so in this case you should customize 'pause', 'resume' and 'stop' handlers |
This feature allows user configure/add handlers for others SIGNALS.
In this sample we will create a handler to SIGUSR2 POSIX signal. Note that this signal is not available on Windows.
To do this user need inheriting of signal_manager class and add new signal bind, like:
class myapp { public: myapp(context& context) : context_(context) { } ~myapp() { std::cout << "~myapp()" << std::endl; } void work_thread() { while(1) { boost::this_thread::sleep(boost::posix_time::seconds(2)); std::cout << "running" << std::endl; } } // param int operator()() { std::cout << "operator()" << std::endl; // launch a work thread boost::thread thread(boost::bind(&myapp::work_thread, this)); context_.find<wait_for_termination_request>()->wait(); return 0; } private: context& context_; }; class my_signal_manager : public signal_manager { public: my_signal_manager(context &context) : signal_manager(context) { handler<>::callback cb = boost::bind<bool>(&my_signal_manager::stop, this); // define my own signal / handler #if defined( BOOST_WINDOWS_API ) bind(SIGINT, cb); // CTRL-C (2) #elif defined( BOOST_POSIX_API ) bind(SIGUSR2, cb); #endif } bool stop() { BOOST_APPLICATION_FEATURE_SELECT #if defined( BOOST_WINDOWS_API ) std::cout << "exiting..." << std::endl; #elif defined( BOOST_POSIX_API ) std::ofstream my_log_file; my_log_file.open((context_.find< path>()->executable_path().string() + "/log_stop.txt").c_str()); my_log_file << ":0)-" << std::endl; my_log_file.close(); #endif shared_ptr<wait_for_termination_request> th = context_.find<wait_for_termination_request>(); th->proceed(); return false; } }; // main int main(int argc, char *argv[]) { context app_context; myapp app(app_context); app_context.insert<path>( boost::make_shared<path_default_behaviour>(argc, argv)); // we will customize our signals behaviour my_signal_manager sm(app_context); #if defined( BOOST_WINDOWS_API ) return launch<common>(app, sm, app_context); #elif defined( BOOST_POSIX_API ) return launch<server>(app, sm, app_context); #endif }