/*
- 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
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);
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:
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 */