See also: instantiator
class reference.
Model of
Description
The instantiator class instantiates a specified type from a member variable of a specified type whenever it receives a signal. The signal is always forwarded.
Examples of applicators:
Example
The following example shows how a mutex component can be built (it is just an instantiator that instantiates a scoped_lock over a mutex whenever a signal passes).
#include <boost/dataflow/signals/component/filter.hpp> #include <boost/dataflow/signals/component/instantiator.hpp> #include <boost/dataflow/signals/component/timed_generator.hpp> #include <boost/dataflow/signals/connection.hpp> #include <boost/thread/mutex.hpp> #include <string> using namespace boost; // Ensures a component is processing only one signal at a time when using multiple threads. // To do so, we need to instantiate a scoped lock over a mutex each time we // are handling a signal. We can inherit from instantiator to accomplish this. template<typename Signature> class my_mutex : public boost::signals::instantiator< // the first parameter is the derived class my_mutex<Signature>, // the second parameter determines the type of conditional::member, // which we will be our mutex. boost::mutex, // the third parameter determines the object which will be instantiated // with the member as the constructor argument. // In our case, that is the scoped_lock. boost::mutex::scoped_lock, // the fourth parameter determines the signal Signature the component // consumes and produces. Signature> { // that's it. }; // a consumer component, to occupy some time. class printer : public boost::signals::consumer<printer> { public: void operator()(const std::string &message) { for (int j=0; j<3; j++) for (int i=0; i<10; i++) std::cout << message << i; std::cout << std::endl; } }; int main() { // timed_generators send signals in their own thread signals::timed_generator<void ()> timer1; signals::timed_generator<void ()> timer2; // other components my_mutex<void ()> lock; signals::storage<void (const std::string &)> producer("#"); printer consumer; // first, with the mutex: std::cout << "With mutex:" << std::endl; producer >>= consumer; timer1 >>= lock >>= producer.send_slot(); timer2 >>= lock; // set each timer to send a signal 5 times, in 0s intervals (i.e., instantly) timer1.enable(0.0, 5); timer2.enable(0.0, 5); // wait until they are done. timer1.wait_until_completed(); timer2.wait_until_completed(); // now, without the mutex (reconnect timer1 and timer2 directly to producer) std::cout << "Without mutex:" << std::endl; disconnect_all(timer1); disconnect_all(timer2); timer1 >>= producer.send_slot(); timer2 >>= producer.send_slot(); // set each timer to send a signal 5 times, in 0s intervals (i.e., instantly) timer1.enable(0.0, 5); timer2.enable(0.0, 5); // wait until they are done. timer1.wait_until_completed(); timer2.wait_until_completed(); timer1.join(); timer2.join(); return 0; }
A sample run of this example produces:
With mutex: #0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9 #0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9 #0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9 #0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9 #0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9 #0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9 #0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9 #0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9 #0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9 #0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9 Without mutex: #0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8##09##10##21##32##43##54##65##76##87##98##09# 1#2#3#4#5#6#7#8#9#0#1##20##31##42##53##64##75##86##97 #8##09##10##21##32##43##54##65##76##87##98##09##10##21##32##43##54##65##76##87##98##09# 1##20##31##42##53##64##75##86##97 #8##9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9 0##10#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9 #1#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9 #2#3#4#5#6#7#8##09##10##21##32##43##54##65##76##87##98##09##10##21##32##43##54##65##76##87##98##09# 1##20##31##42##53##64##75##86##97 #8#9#0#1#2#3#4#5#6#7#8#9#0#1#2#3#4#5#6#7#8#9