2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 2005 Erik Sandberg <mandolaerik@gmail.com>
6 LilyPond is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 LilyPond is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
26 Listeners are used for stream event dispatching. If you want to
27 register a method as an event handler in a dispatcher, then you
30 - declare the method using the DECLARE_LISTENER macro.
33 DECLARE_LISTENER (method);
36 This macro declares the method to take a SCM as parameter, and to
37 return void. It also declares some other stuff that shouldn't be
40 - implement the method using IMPLEMENT_LISTENER:
41 IMPLEMENT_LISTENER (Foo, method)
44 write ("Foo hears an event!");
47 - Extract a listener using GET_LISTENER (Foo->method)
48 - Register the method to the dispatcher using Dispatcher::register
53 Stream_distributor *d = (...);
54 Listener l = GET_LISTENER (foo->method);
55 d->register_listener (l, "EventClass");
57 Whenever d hears a stream-event ev of class "EventClass",
58 the implemented procedure is called.
61 - DECLARE_LISTENER currently only works inside smob classes.
68 void (*listen_callback) (void *, SCM);
69 void (*mark_callback) (void *);
70 bool (*equal_callback) (void *, void *);
71 } Listener_function_table;
73 class Listener : public Simple_smob<Listener>
76 static SCM equal_p (SCM, SCM);
78 static const char type_p_name_[];
81 Listener_function_table *type_;
83 Listener (const void *target, Listener_function_table *type);
84 Listener (Listener const &other);
87 void listen (SCM ev) const;
89 bool operator == (Listener const &other) const
91 return type_ == other.type_
92 && (*type_->equal_callback) ((void *) target_, (void *) other.target_);
97 #define IMPLEMENT_LISTENER(cl, method) \
99 cl :: method ## _callback (void *self, SCM ev) \
101 cl *s = (cl *)self; \
105 cl :: method ## _mark (void *self) \
107 cl *s = (cl *)self; \
108 scm_gc_mark (s->self_scm ()); \
111 cl :: method ## _is_equal (void *a, void *b) \
116 cl :: method ## _listener () const \
118 static Listener_function_table callbacks; \
119 callbacks.listen_callback = &cl::method ## _callback; \
120 callbacks.mark_callback = &cl::method ## _mark; \
121 callbacks.equal_callback = &cl::method ## _is_equal; \
122 return Listener (this, &callbacks); \
125 #define GET_LISTENER(proc) proc ## _listener ()
127 #define DECLARE_LISTENER(name) \
128 inline void name (SCM); \
129 static void name ## _callback (void *self, SCM ev); \
130 static void name ## _mark (void *self); \
131 static bool name ## _is_equal (void *a, void *b); \
132 Listener name ## _listener () const
134 #endif /* LISTENER_HH */