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 ...