From e391e47d29945653870cde23b91f487c0106a67d Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Thu, 30 Apr 2015 17:47:29 +0200 Subject: [PATCH] Issue 4357/7: Replace translator_listener_record mess with Scheme --- lily/include/scheme-engraver.hh | 8 ++--- lily/include/translator.hh | 42 ++++++++----------------- lily/include/translator.icc | 22 +++++--------- lily/scheme-engraver.cc | 36 +++------------------- lily/translator.cc | 54 ++++++++++++++------------------- 5 files changed, 50 insertions(+), 112 deletions(-) diff --git a/lily/include/scheme-engraver.hh b/lily/include/scheme-engraver.hh index 9b9db00317..c7d16d76e9 100644 --- a/lily/include/scheme-engraver.hh +++ b/lily/include/scheme-engraver.hh @@ -30,8 +30,6 @@ public: void init_from_scheme (SCM definition); TRANSLATOR_DECLARATIONS_NO_LISTENER (Scheme_engraver); - static Listener tlr_get_listener (void *generic_arg, SCM event); - protected: ~Scheme_engraver (); @@ -43,7 +41,7 @@ protected: virtual void initialize (); virtual void finalize (); virtual void derived_mark () const; - virtual translator_listener_record *get_listener_list () const; + virtual SCM get_listener_list () const; virtual bool must_be_last () const; private: @@ -71,8 +69,8 @@ private: SCM listeners_alist_; // We dont use this, but need it for the documentation boilerplate. - static translator_listener_record *listener_list_; - translator_listener_record *per_instance_listeners_; + static Protected_scm listener_list_; + SCM per_instance_listeners_; }; #endif /* SCHEME_ENGRAVER_HH */ diff --git a/lily/include/translator.hh b/lily/include/translator.hh index 9abea3b64c..22e656ceb8 100644 --- a/lily/include/translator.hh +++ b/lily/include/translator.hh @@ -28,26 +28,6 @@ #include "std-vector.hh" #include "protected-scm.hh" -/* - Each translator class has a static list of listener records. Each - record makes one explains how to register one of the class's stream event - listeners to a context. -*/ -typedef struct translator_listener_record -{ - Listener (*get_listener_) (void *, SCM event_class); - SCM event_class_; - struct translator_listener_record *next_; - - translator_listener_record () - { - next_ = 0; - event_class_ = SCM_EOL; - get_listener_ = 0; - } - -} translator_listener_record; - #define TRANSLATOR_DECLARATIONS_NO_LISTENER(NAME) \ public: \ NAME (); \ @@ -69,12 +49,19 @@ typedef struct translator_listener_record } \ /* end #define */ +/* + Each translator class has a static alist of event class symbols + mapping to callbacks that are called with a translator instance and + a stream event when an event of the appropriate event class is + announced in a context. +*/ + #define TRANSLATOR_DECLARATIONS(NAME) \ TRANSLATOR_DECLARATIONS_NO_LISTENER(NAME) \ private: \ - static translator_listener_record *listener_list_; \ + static Protected_scm listener_list_; \ public: \ - virtual translator_listener_record *get_listener_list () const \ + virtual SCM get_listener_list () const \ { \ return listener_list_; \ } \ @@ -84,9 +71,7 @@ public: \ public: \ inline void listen_ ## m (Stream_event *); \ /* Should be private */ \ -static void _internal_declare_ ## m (); \ -private: \ - static Listener _get_ ## m ## _listener (void *, SCM); +static void _internal_declare_ ## m (); #define DECLARE_ACKNOWLEDGER(x) public : void acknowledge_ ## x (Grob_info); protected: #define DECLARE_END_ACKNOWLEDGER(x) public : void acknowledge_end_ ## x (Grob_info); protected: @@ -151,13 +136,10 @@ protected: // should be private. void protect_event (SCM ev); friend class Callback_wrapper; virtual void derived_mark () const; - static void add_translator_listener (translator_listener_record **listener_list, - translator_listener_record *r, - Listener (*get_listener) (void *, SCM), - const char *ev_class); + static SCM event_class_symbol (const char *ev_class); SCM static_translator_description (const char *grobs, const char *desc, - translator_listener_record *listener_list, + SCM listener_list, const char *read, const char *write) const; diff --git a/lily/include/translator.icc b/lily/include/translator.icc index f583d32aad..7fc128fe72 100644 --- a/lily/include/translator.icc +++ b/lily/include/translator.icc @@ -48,7 +48,7 @@ /* end define */ #define DEFINE_TRANSLATOR_LISTENER_LIST(T) \ - translator_listener_record *T::listener_list_; \ + Protected_scm T::listener_list_ (SCM_EOL); \ /* end define */ #define DEFINE_ACKNOWLEDGERS(classname) \ @@ -135,18 +135,12 @@ generic_get_acknowledger (SCM sym, void \ cl :: _internal_declare_ ## m () \ { \ - static translator_listener_record r; \ - add_translator_listener (&listener_list_, &r, _get_ ## m ## _listener, #m); \ -} \ - \ -ADD_SCM_INIT_FUNC (cl ## _declare_event_ ## m, cl::_internal_declare_ ## m); \ - \ - Listener \ - cl :: _get_ ## m ## _listener (void *me, SCM) \ - { \ - cl *obj = (cl *) me; \ - return obj->get_listener \ - (Callback_wrapper::make_smob ()); \ - } + listener_list_ = scm_acons \ + (event_class_symbol (#m), \ + Callback_wrapper::make_smob (), \ + listener_list_); \ +} \ + \ +ADD_SCM_INIT_FUNC (cl ## _declare_event_ ## m, cl::_internal_declare_ ## m); #endif /* TRANSLATOR_ICC */ diff --git a/lily/scheme-engraver.cc b/lily/scheme-engraver.cc index 6762c753c9..7e601f8db7 100644 --- a/lily/scheme-engraver.cc +++ b/lily/scheme-engraver.cc @@ -33,24 +33,16 @@ Scheme_engraver::Scheme_engraver () process_acknowledged_function_ = SCM_EOL; initialize_function_ = SCM_EOL; finalize_function_ = SCM_EOL; - listeners_alist_ = SCM_EOL; interface_acknowledger_hash_ = SCM_EOL; interface_end_acknowledger_hash_ = SCM_EOL; must_be_last_ = false; - per_instance_listeners_ = 0; + per_instance_listeners_ = SCM_EOL; } Scheme_engraver::~Scheme_engraver () { - translator_listener_record *next = 0; - for (translator_listener_record *r = per_instance_listeners_; - r; r = next) - { - next = r->next_; - delete r; - } } // Extracts the value if callable, if not return #f. @@ -82,13 +74,12 @@ Scheme_engraver::init_from_scheme (SCM definition) SCM listeners = ly_assoc_get (ly_symbol2scm ("listeners"), definition, SCM_EOL); - listeners_alist_ = SCM_EOL; + per_instance_listeners_ = SCM_EOL; must_be_last_ = to_boolean (ly_assoc_get (ly_symbol2scm ("must-be-last"), definition, SCM_BOOL_F)); - translator_listener_record **tail = &per_instance_listeners_; for (SCM p = listeners; scm_is_pair (p); p = scm_cdr (p)) { SCM event_class = scm_caar (p); @@ -100,13 +91,7 @@ Scheme_engraver::init_from_scheme (SCM definition) // We should check the arity of the function? // Record for later lookup. - listeners_alist_ = scm_acons (event_class, proc, listeners_alist_); - - translator_listener_record *rec = new translator_listener_record; - *tail = rec; - rec->event_class_ = event_class; - rec->get_listener_ = &Scheme_engraver::tlr_get_listener; - tail = &rec->next_; + per_instance_listeners_ = scm_acons (event_class, proc, per_instance_listeners_); } init_acknowledgers (ly_assoc_get (ly_symbol2scm ("acknowledgers"), @@ -171,18 +156,7 @@ Scheme_engraver::acknowledge_grob_by_hash (Grob_info info, } } -/* static */ -Listener -Scheme_engraver::tlr_get_listener (void *arg, SCM name) -{ - Scheme_engraver *me = (Scheme_engraver *) arg; - SCM func = ly_assoc_get (name, me->listeners_alist_, SCM_BOOL_F); - assert (ly_is_procedure (func)); - - return me->get_listener (func); -} - -translator_listener_record * +SCM Scheme_engraver::get_listener_list () const { return per_instance_listeners_; @@ -212,7 +186,7 @@ Scheme_engraver::derived_mark () const scm_gc_mark (finalize_function_); scm_gc_mark (process_music_function_); scm_gc_mark (process_acknowledged_function_); - scm_gc_mark (listeners_alist_); + scm_gc_mark (per_instance_listeners_); scm_gc_mark (interface_acknowledger_hash_); scm_gc_mark (interface_end_acknowledger_hash_); } diff --git a/lily/translator.cc b/lily/translator.cc index d6874ef78c..87fc0a15a4 100644 --- a/lily/translator.cc +++ b/lily/translator.cc @@ -118,48 +118,38 @@ Translator::finalize () void Translator::connect_to_context (Context *c) { - for (translator_listener_record *r = get_listener_list (); r; r = r->next_) - c->events_below ()->add_listener (r->get_listener_ (this, r->event_class_), - r->event_class_); + for (SCM r = get_listener_list (); scm_is_pair (r); r = scm_cdr (r)) + { + SCM event_class = scm_caar (r); + SCM callback = scm_cdar (r); + + c->events_below ()->add_listener (get_listener (callback), + event_class); + } } void Translator::disconnect_from_context (Context *c) { - for (translator_listener_record *r = get_listener_list (); r; r = r->next_) - c->events_below ()->remove_listener (r->get_listener_ (this, r->event_class_), - r->event_class_); -} + for (SCM r = get_listener_list (); scm_is_pair (r); r = scm_cdr (r)) + { + SCM event_class = scm_caar (r); + SCM callback = scm_cdar (r); -/* - internally called once, statically, for each translator - listener. Connects the name of an event class with a procedure that - fetches the corresponding listener. + c->events_below ()->remove_listener (get_listener (callback), + event_class); + } +} - The method should only be called from the macro - IMPLEMENT_TRANSLATOR_LISTENER. - */ -void -Translator::add_translator_listener (translator_listener_record **listener_list, - translator_listener_record *r, - Listener (*get_listener) (void *, SCM), - const char *ev_class) +SCM +Translator::event_class_symbol (const char *ev_class) { /* ev_class is the C++ identifier name. Convert to scm symbol */ string name = string (ev_class); name = replace_all (&name, '_', '-'); name += "-event"; - // we make the symbol permanent in order not to have to bother about - // the static translator_listener_record chains while garbage - // collecting. - - SCM class_sym = scm_permanent_object (scm_from_ascii_symbol (name.c_str ())); - - r->event_class_ = class_sym; - r->get_listener_ = get_listener; - r->next_ = *listener_list; - *listener_list = r; + return scm_from_ascii_symbol (name.c_str ()); } /* @@ -168,7 +158,7 @@ Translator::add_translator_listener (translator_listener_record **listener_list, SCM Translator::static_translator_description (const char *grobs, const char *desc, - translator_listener_record *listener_list, + SCM listener_list, const char *read, const char *write) const { @@ -181,8 +171,8 @@ Translator::static_translator_description (const char *grobs, scm_from_utf8_string (desc), static_properties); SCM list = SCM_EOL; - for (; listener_list; listener_list = listener_list->next_) - list = scm_cons (listener_list->event_class_, list); + for (; scm_is_pair (listener_list); listener_list = scm_cdr (listener_list)) + list = scm_cons (scm_caar (listener_list), list); static_properties = scm_acons (ly_symbol2scm ("events-accepted"), list, static_properties); -- 2.39.2