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.
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:
43 write ("Foo hears an event!");
46 - Extract a listener using GET_LISTENER (Foo->method)
47 - Register the method to the dispatcher using Dispatcher::register
52 Stream_distributor *d = (...);
53 Listener l = foo->GET_LISTENER (Foo, method);
54 d->register_listener (l, "EventClass");
56 Whenever d hears a stream-event ev of class "EventClass",
57 the implemented procedure is called.
60 - DECLARE_LISTENER currently only works inside smob classes.
67 void (*listen_callback) (void *, SCM);
68 void (*mark_callback) (void *);
69 bool (*equal_callback) (void *, void *);
70 } Listener_function_table;
72 class Listener : public Simple_smob<Listener>
75 static SCM equal_p (SCM, SCM);
77 static const char type_p_name_[];
80 Listener_function_table *type_;
82 Listener (const void *target, Listener_function_table *type);
83 Listener (Listener const &other);
86 void listen (SCM ev) const;
88 LY_DECLARE_SMOB_PROC (1, 0, 0, (SCM self, SCM ev))
90 Listener::unsmob (self)->listen (ev);
91 return SCM_UNSPECIFIED;
94 bool operator == (Listener const &other) const
96 return type_ == other.type_
97 && (*type_->equal_callback) ((void *) target_, (void *) other.target_);
102 #define IMPLEMENT_LISTENER(cl, method) \
104 cl :: method ## _callback (void *self, SCM ev) \
106 cl *s = (cl *)self; \
110 cl :: method ## _mark (void *self) \
112 cl *s = (cl *)self; \
113 scm_gc_mark (s->self_scm ()); \
116 cl :: method ## _is_equal (void *a, void *b) \
121 cl :: method ## _listener () const \
123 static Listener_function_table callbacks; \
124 callbacks.listen_callback = &cl::method ## _callback; \
125 callbacks.mark_callback = &cl::method ## _mark; \
126 callbacks.equal_callback = &cl::method ## _is_equal; \
127 return Listener (this, &callbacks); \
130 #define GET_LISTENER(proc) proc ## _listener ()
132 #define DECLARE_LISTENER(name) \
133 inline void name (SCM); \
134 static void name ## _callback (void *self, SCM ev); \
135 static void name ## _mark (void *self); \
136 static bool name ## _is_equal (void *a, void *b); \
137 Listener name ## _listener () const
139 #endif /* LISTENER_HH */