Event Handling



How to bind member and non-member functions to act as event handlers.


Static Functions

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.


Non-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:


No Parameters

void DClient::setSendHandler(boost::function<void (void)> sendHandler);

class MessageClient
{
    public:
        void sendHandler(void)
        {
        }
};

MessageClient msgClient;
myDClient.addHandler(boost::bind(&MessageClient::sendHandler, &msgClient));


Two Parameters

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));











Back to contents