How to bind member and non-member functions to act as event handlers.
Imagine you have a DDispatcher, and are trying to respond to received messages. DDispatcher has a function called addHandler that looks like this:
void addHandler(boost::function<void (DBuffer&)> handler);
addHandler wants us to supply a method without a return type, and that takes a DBuffer& as a parameter. We can provide a reference to any static function as follows:
void aHandler(DBuffer &theMessage) { } myDispatcher.addHandler(&aHandler);
Now, aHandler will be called whenever a new message is received from the DDispatcher. This method will also work for static member functions.
If we want to respond to events inside of a class, we can register a non-static member function as an event handler with boost::bind.
class MessageClient { public: void aHandler(DBuffer &theMessage) { } }; MessageClient msgClient; myDispatcher.addHandler(boost::bind(&MessageClient::aHandler, &msgClient, _1));
Be sure to delete or disconnect the event generator before deleting the event receiver!
The first parameter in boost::bind is the function to call. The second parameter is a pointer to the object to call the function on. The last parameter is a placeholder - it will be set to a specific value whenever an event is generated. In this case it will be a DBuffer&, which will contain the received data. The placeholders should be arranged in increasing order, one for each parameter we expect to receive. For example:
void DClient::setSendHandler(boost::function<void (void)> sendHandler);
class MessageClient { public: void sendHandler(void) { } }; MessageClient msgClient; myDClient.addHandler(boost::bind(&MessageClient::sendHandler, &msgClient));
void DClient::startConnect(const string &hostName, uint16_t portNumber, boost::function<void (string, libdasyne::NetworkCode)> connectHandler)
class MessageClient { public: void connectHandler(string message, NetworkCode connectStatus) { } }; MessageClient msgClient; myDClient.startConnect("127.0.0.1", 5002, boost::bind(&MessageClient::connectHandler, &msgClient, _1, _2));