Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Easy to use data dispatcher

0.00/5 (No votes)
14 Jul 2001 1  
An easy to use set of classes to dispatch any kind of data.

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:

// define your class (MFC or what ever you want)

class CMyView : public CView
{
protected: // Nur aus Serialisierung erzeugen

    CMyView();
    DECLARE_DYNCREATE(CMyView)

public:
    //

    // any function you need

    //


    // and now your data handle (for simple string)

    void HandleNewData(char* data);

protected:
    // and now the receiver

    receiver<CMyView, char*> m_MyReceiver;
};

// a channel object (my come from everywhere)

extern channel MyChannel;

// now the implementation

CMyView::CMyView()
{
    // initialize the receiver to work with your class (and function)

    m_MyReceiver.init(this, HandleNewData);

    // now link the receiver to a channel

    // object (let it be global for this example)

    // you may also place the pointer as the third parameter in init

    // you can link a receiver to any number of channels

    // you can destroy the channel or the receiver

    // at anytime (in any order!)

    m_MyReceiver.link(&MyChannel);
}

void CMyView::HandleNewData(char* data)
{
    // do what ever you want

    MessageBox(data);
}

// some where else in your application

// delcare the channel object

channel MyChannel;

// and send some data

void generate_data()
{
    // send what every you want

    // every compatible receiver that's linked

    // (directly or indirectly) to this channel is called

    // NOTE: string like this are NOT const and will only work

    // with <..., char*> receivers !

    MyChannel << "Hallo Welt";
}

What about threads

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

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here