Mercurial > ~dholland > hg > ag > index.cgi
diff anagram/vaclgui/dispatch.hpp @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/anagram/vaclgui/dispatch.hpp Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,97 @@ +/* + * AnaGram, A System for Syntax Directed Programming + * Copyright 1997-2002 Parsifal Software. All Rights Reserved. + * See the file COPYING for license and usage terms. + * + * dispatch.hpp + */ + +#ifndef DISPATCH_HPP +#define DISPATCH_HPP + +#include <ievent.hpp> + + +class AgDispatcher { +public: + class Kernel { + private: + int useCount; + public: + virtual ~Kernel() {} + virtual void dispatch(IEvent &) const = 0; + + Kernel() : useCount(0) {} + void lock() { useCount++; } + int unlock() { return --useCount <= 0; } + }; + +protected: + Kernel *kernel; + + AgDispatcher(AgDispatcher::Kernel *kernel_) : + kernel(kernel_) + { + if (kernel) { + kernel->lock(); + } + } + +public: + AgDispatcher() : + kernel(0) + {} + AgDispatcher(const AgDispatcher &a) : + kernel(a.kernel) + { + if (kernel) { + kernel->lock(); + } + } + AgDispatcher &operator = (const AgDispatcher &a) { + if (kernel && kernel->unlock()) { + delete kernel; + } + kernel = a.kernel; + if (kernel) { + kernel->lock(); + } + return *this; + } + ~AgDispatcher() { + if (kernel && kernel->unlock()) { + delete kernel; + } + } + void dispatch(IEvent &e) const { + if (kernel) { + kernel->dispatch(e); + } + } +}; + + +template<class T> +class AgObjectDispatcher : public AgDispatcher { + class Kernel : public AgDispatcher::Kernel { + T &object; + void (T:: * memberFunction)(IEvent &); + public: + Kernel(T &object_, void (T:: * memberFunction_)(IEvent &)) : + object(object_) , + memberFunction(memberFunction_) + {} + void dispatch(IEvent &e) const { (object.*memberFunction)(e); } + }; + +public: + AgObjectDispatcher(T &object_, void (T:: * memberFunction_)(IEvent &)) : + AgDispatcher(new AgObjectDispatcher<T>::Kernel(object_,memberFunction_)) + {} + AgObjectDispatcher(const AgObjectDispatcher<T> &a) : + AgDispatcher(a) + {} +}; + + +#endif /* DISPATCH_HPP */