X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;ds=sidebyside;f=lily%2Finclude%2Flistener.hh;h=e0827f8786dc372ceaee9256f159e7d1dbe0c7d5;hb=04ce84386dc022316c347ee0c5049c852eea3421;hp=fd7a7e2adfa3db21399a025581248ffc1fd74d9a;hpb=9f3572d98bb948c9689cd1f75401a029451fa001;p=lilypond.git diff --git a/lily/include/listener.hh b/lily/include/listener.hh index fd7a7e2adf..e0827f8786 100644 --- a/lily/include/listener.hh +++ b/lily/include/listener.hh @@ -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 - (c) 2005 Erik Sandberg + 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 . */ #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. @@ -52,54 +63,69 @@ #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: Listener (const void *target, Listener_function_table *type); Listener (Listener const &other); + Listener (); + 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_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 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 */