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);
77 static int print_smob (SCM, SCM, scm_print_state *);
78 static SCM mark_smob (SCM);
79 static const char type_p_name_[];
82 Listener_function_table *type_;
84 Listener (const void *target, Listener_function_table *type);
85 Listener (Listener const &other);
88 void listen (SCM ev) const;
90 bool operator == (Listener const &other) const
92 return type_ == other.type_
93 && (*type_->equal_callback) ((void *) target_, (void *) other.target_);
98 #define IMPLEMENT_LISTENER(cl, method) \
100 cl :: method ## _callback (void *self, SCM ev) \
102 cl *s = (cl *)self; \
106 cl :: method ## _mark (void *self) \
108 cl *s = (cl *)self; \
109 scm_gc_mark (s->self_scm ()); \
112 cl :: method ## _is_equal (void *a, void *b) \
117 cl :: method ## _listener () const \
119 static Listener_function_table callbacks; \
120 callbacks.listen_callback = &cl::method ## _callback; \
121 callbacks.mark_callback = &cl::method ## _mark; \
122 callbacks.equal_callback = &cl::method ## _is_equal; \
123 return Listener (this, &callbacks); \
126 #define GET_LISTENER(proc) proc ## _listener ()
128 #define DECLARE_LISTENER(name) \
129 inline void name (SCM); \
130 static void name ## _callback (void *self, SCM ev); \
131 static void name ## _mark (void *self); \
132 static bool name ## _is_equal (void *a, void *b); \
133 Listener name ## _listener () const
135 #endif /* LISTENER_HH */