]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/include/listener.hh
Merge branch 'issue4032'
[lilypond.git] / lily / include / listener.hh
index 5b290f4f20e15878bcc219bc643747f5104788a0..51ad5db821d30885303cb72e9ef787b12720efb9 100644 (file)
@@ -1,9 +1,20 @@
 /*
-  listener.hh -- declare Listener
+  This file is part of LilyPond, the GNU music typesetter.
 
-  source file of the GNU LilyPond music typesetter
+  Copyright (C) 2005 Erik Sandberg <mandolaerik@gmail.com>
 
-  (c) 2005 Erik Sandberg <mandolaerik@gmail.com>
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #ifndef LISTENER_HH
@@ -16,7 +27,7 @@
   register a method as an event handler in a dispatcher, then you
   must:
 
-  - declare the method using the DECLARE_LISTENER macro. 
+  - declare the method using the DECLARE_LISTENER macro.
   class Foo
   {
     DECLARE_LISTENER (method);
@@ -42,7 +53,7 @@
   Stream_distributor *d = (...);
   Listener l = GET_LISTENER (foo->method);
   d->register_listener (l, "EventClass");
-  
+
   Whenever d hears a stream-event ev of class "EventClass",
   the implemented procedure is called.
 
 
 #include "smobs.hh"
 
-typedef struct {
+typedef struct
+{
   void (*listen_callback) (void *, SCM);
   void (*mark_callback) (void *);
+  bool (*equal_callback) (void *, void *);
 } Listener_function_table;
 
-class Listener {
+class Listener
+{
   void *target_;
   Listener_function_table *type_;
 public:
@@ -68,40 +82,49 @@ public:
   void listen (SCM ev) const;
 
   bool operator == (Listener const &other) const
-  { return target_ == other.target_ && type_ == other.type_; }
+  {
+    return type_ == other.type_
+           && (*type_->equal_callback) ((void *) target_, (void *) other.target_);
+  }
 
   DECLARE_SIMPLE_SMOBS (Listener);
 };
-DECLARE_UNSMOB (Listener, listener);
-
-#define IMPLEMENT_LISTENER(cl, method)                 \
-void                                                   \
-cl :: method ## _callback (void *self, SCM ev)         \
-{                                                      \
-  cl *s = (cl *)self;                                  \
-  s->method (ev);                                      \
-}                                                      \
-void                                                   \
-cl :: method ## _mark (void *self)                     \
-{                                                      \
-  cl *s = (cl *)self;                                  \
-  scm_gc_mark (s->self_scm ());                                \
-}                                                      \
-Listener                                               \
-cl :: method ## _listener () const                     \
-{                                                      \
-  static Listener_function_table callbacks;            \
-  callbacks.listen_callback = &cl::method ## _callback;        \
-  callbacks.mark_callback = &cl::method ## _mark;      \
-  return Listener (this, &callbacks);                  \
+
+#define IMPLEMENT_LISTENER(cl, method)                  \
+void                                                    \
+cl :: method ## _callback (void *self, SCM ev)          \
+{                                                       \
+  cl *s = (cl *)self;                                   \
+  s->method (ev);                                       \
+}                                                       \
+void                                                    \
+cl :: method ## _mark (void *self)                      \
+{                                                       \
+  cl *s = (cl *)self;                                   \
+  scm_gc_mark (s->self_scm ());                         \
+}                                                       \
+bool                                                    \
+cl :: method ## _is_equal (void *a, void *b)            \
+{                                                       \
+  return a == b;                                        \
+}                                                       \
+Listener                                                \
+cl :: method ## _listener () const                      \
+{                                                       \
+  static Listener_function_table callbacks;             \
+  callbacks.listen_callback = &cl::method ## _callback; \
+  callbacks.mark_callback = &cl::method ## _mark;       \
+  callbacks.equal_callback = &cl::method ## _is_equal;  \
+  return Listener (this, &callbacks);                   \
 }
 
 #define GET_LISTENER(proc) proc ## _listener ()
 
-#define DECLARE_LISTENER(name)                         \
-  inline void name (SCM);                              \
-  static void name ## _callback (void *self, SCM ev);  \
-  static void name ## _mark (void *self);              \
+#define DECLARE_LISTENER(name)                          \
+  inline void name (SCM);                               \
+  static void name ## _callback (void *self, SCM ev);   \
+  static void name ## _mark (void *self);               \
+  static bool name ## _is_equal (void *a, void *b);     \
   Listener name ## _listener () const
 
 #endif /* LISTENER_HH */