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 */