
Hi,
maybe I managed to narrow it down a little.
This works for both functors and member functions:
class Queue {
...
template
G'day,
I'd like to get your opinion on a problem that puzzles me for a while. Basically, I'm trying to do sort of a delayed signals2 notification mechanism. I have a class wrapped around ASIOs io_service object that I normally use as a thread multiplexer and function storage. Now in this case I want to use it without working threads so a current thread can process whatever handlers are in it. Which works fine but now I want to connect signals to it. I have several data classes that contain signals. These are to be connected to slots, but not directly. Instead, these slots are to be wrapped in little handlers and these handlers shall be put in the io_service object. So the signal's slot should not be executed straight away but by another thread that executes everything in the io_service.
Now this strikes me as something that could be done nicely with phoenix. I want to use phoenix to create a little function that I can connect to the signal and that will do nothing more but post the handler into the io_service when the signal is triggered. I just can't figure out if that can actually work. Here's what I have so far (simplyfied). I try to illustrate on an example with a one-parameter slot.
class Queue : public boost::noncopyable {
public: template<typename Handler> void post(Handler n_handler) { m_iosrv.post(n_handler); }
std::size_t process(boost::system::error_code & n_errcode) { return m_iosrv.poll(n_errcode); };
template<typename Slot> boost::signals2::connection connect(boost::signals2::signal
&n_signal, Slot n_method) { return n_signal.connect(boost::bind(&CommandQueue::slotWrapper<Slot>, this, n_method)); }; template boost::signals2::connection connect(boost::signals2::signal & n_signal, Slot n_method) { return n_signal.connect(boost::bind(&CommandQueue::slotWrapper , this, n_method, _1)); } // ... more to come with more parameters T2, T3..... private: template<typename Slot> void slotWrapper(Slot n_method) { post(n_method); }
template
void slotWrapper(Slot n_method, T1 t1) { boost::function f(n_method); post(boost::bind(f, t1)); } // ... more to come with more parameters ... boost::asio::io_service m_iosrv; };
Now I can use this like this:
struct testslot_one { void operator()(int n_arg) const { std::cout << "testslot 1: " << n_arg << std::endl; } };
main { Queue q; boost::signals2::signal
sig1; struct testslot_one t1; q.connect(sig1, t1);
// signal not yet executed but only the handler posted sig1(42);
boost::system::error_code errc; // here we execute the accumulated signals q.process(errc); }
Now this works OK so far but I have two problems:
First of all, the standard use case will be to bind member functions and not seperate functors such as "testslot_one" in this example. Which is when the connect fails. For reasons unknown to me. But that must work. Second, I want to get rid of the "slotWrapper" functions and replace them by a phoenix expression. If that makes sense, which I'm not sure of.
Also, I am not certain about the whole thing. Can a phoenix generated function actually serve this way? Just post the handler when the signal is triggered?
Any opinions are appreciated!
Cheers, Stephan