Introduction
This is an easy to use set of classes that allows dispatching of every kind of data to objects which may be unknown to the sender. The code needs RTTI and the STL and depends on templates. If you pass pointers, you must ensure that no receiver tries to delete the pointer because there may be more than one receiver. If it's possible, you should only pass objects which are copy-able (e.g. an autoptr for a refcounted object). It also supports dispatching to a different thread if a threadbridge is used (see What about threads for more info about threads).
Here is a simple demo using MFC:
class CMyView : public CView
{
protected:
CMyView();
DECLARE_DYNCREATE(CMyView)
public:
void HandleNewData(char* data);
protected:
receiver<CMyView, char*> m_MyReceiver;
};
extern channel MyChannel;
CMyView::CMyView()
{
m_MyReceiver.init(this, HandleNewData);
m_MyReceiver.link(&MyChannel);
}
void CMyView::HandleNewData(char* data)
{
MessageBox(data);
}
channel MyChannel;
void generate_data()
{
MyChannel << "Hallo Welt";
}
It's also possible to link a channel to another channel. The threadbridge is derived from channel so it can be used where a channel could be used. Note that the threadbridge only works if the threads that have created it has a message pump. threadbridge::message_pump() is a very simple message pump that can be used.
Note that data that is sent through a threadbridge must stay valid. The data may be passed to more than one receiver so you don't know when the data is no longer needed. This may cause a problem if you want to pass data via pointers. You should make your data reference counted and pass it via a simple class like this:
template<class T>
class refptr
{
public:
refptr(const T* v) : _V(v) {if(_V)_V->addref();}
refptr(const refptr<T> &s) : _V(s._V) {if(_V)_V->addref();}
~refptr() {if(_V)_V->release();}
operator T* () {return _V;}
refptr<T>& operator = (const T* v) {
if(_V)_V->release();
_V = v;
if(_V)_V->addref();
return *this;
}
protected:
T* _V;
};
Have fun ...