|
/*
(c) Sergey Ryazanov (http://home.onego.ru/~ryazanov)
Fast delegate compatible with C++ Standard.
*/
#ifndef SRUTIL_EVENT_INCLUDED
#define SRUTIL_EVENT_INCLUDED
namespace srutil
{
template <typename TSink> class event_source;
template <typename TSink> class event_binder;
template <typename TSink> class event_binder
{
public:
typedef TSink sink_type;
typedef event_source<sink_type> event_source_type;
event_binder() : sink(sink_type()) {next = prev = this;}
~event_binder() {unbind();}
void bind(const event_source<sink_type>& source, sink_type sink);
void unbind()
{
prev->next = next;
next->prev = prev;
next = prev = this;
}
private:
event_binder* prev;
event_binder* next;
sink_type sink;
friend class event_source<sink_type>;
void attach_after(event_binder* that)
{
next = that->next;
next->prev = this;
that->next = this;
prev = that;
}
event_binder(event_binder const&);
event_binder const& operator=(event_binder const&);
};
template <typename TSink> class event_source
{
public:
typedef TSink sink_type;
typedef event_binder<sink_type> binder_type;
void bind(binder_type& bndr, sink_type sink)
{
bndr.attach_after(&list_head);
bndr.sink = sink;
}
template <class TInvoker>
void emit(TInvoker const& invoker)
{
binder_type* current = list_head.next;
while (current != &list_head)
{
if (current->sink)
{
event_binder<sink_type> bookmark;
bookmark.attach_after(current);
invoker(current->sink); // *current may be excluded from list, but mookmark will always keep valid
current = bookmark.next;
}
else
current = current->next;
}
}
private:
mutable binder_type list_head;
friend class event_binder<sink_type>;
};
template <typename TSink>
void event_binder<TSink>::bind(const event_source<sink_type>& source, sink_type sink)
{
unbind();
attach_after(&source.list_head);
this->sink = sink;
}
}
#endif// SRUTIL_EVENT_INCLUDED
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I'm MS in Math (with honor). I've been working as a software engineer in the Vessel Traffic System department since the year 2002.
I like the C++, riddle solving, travelling and sports. My daughter was born when I was participating in a rock climbing competition (4 Jul 2004). Also I took up kayaking and skydiving, but unfortunately now I have no time for it.
I have about 4 years experience in ACM ICPC (ICP contests). The best achievement is 18-th place in World Finals (2002).