From 8deff48226b1f608d7949c6198f0965222b6cb8d Mon Sep 17 00:00:00 2001 From: David Kastrup Date: Thu, 28 Apr 2016 10:08:43 +0200 Subject: [PATCH] Issue 4842/3: Replace Engraver_dispatch_entry with Method_instance This also replaces a lot of C++-centric callback machinery (like the Grob_info_callback type) with SCM-based code. --- lily/auto-beam-engraver.cc | 1 + lily/beam-engraver.cc | 2 +- lily/include/coherent-ligature-engraver.hh | 2 + lily/include/engraver.hh | 17 ++++++++ lily/include/gregorian-ligature-engraver.hh | 2 + lily/include/ligature-engraver.hh | 1 + lily/include/scheme-engraver.hh | 1 - lily/include/slur-proto-engraver.hh | 1 + lily/include/translator-dispatch-list.hh | 9 +---- lily/include/translator.hh | 43 ++++++++++++++------- lily/include/translator.icc | 20 +++++----- lily/kievan-ligature-engraver.cc | 1 + lily/mensural-ligature-engraver.cc | 1 + lily/phrasing-slur-engraver.cc | 1 + lily/slur-engraver.cc | 1 + lily/translator-dispatch-list.cc | 31 ++++++--------- lily/translator.cc | 6 +-- lily/vaticana-ligature-engraver.cc | 2 +- 18 files changed, 88 insertions(+), 54 deletions(-) diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index 3787257738..68c61d97a8 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -574,6 +574,7 @@ ADD_TRANSLATOR (Auto_beam_engraver, class Grace_auto_beam_engraver : public Auto_beam_engraver { TRANSLATOR_DECLARATIONS (Grace_auto_beam_engraver); + TRANSLATOR_INHERIT (Auto_beam_engraver) DECLARE_TRANSLATOR_LISTENER (beam_forbid); private: diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index e6ca4caf16..554aeda7a1 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -337,7 +337,7 @@ class Grace_beam_engraver : public Beam_engraver { public: TRANSLATOR_DECLARATIONS (Grace_beam_engraver); - + TRANSLATOR_INHERIT (Beam_engraver); DECLARE_TRANSLATOR_LISTENER (beam); protected: diff --git a/lily/include/coherent-ligature-engraver.hh b/lily/include/coherent-ligature-engraver.hh index 19e731815a..b7f77f8402 100644 --- a/lily/include/coherent-ligature-engraver.hh +++ b/lily/include/coherent-ligature-engraver.hh @@ -26,6 +26,8 @@ class Coherent_ligature_engraver : public Ligature_engraver public: // no TRANSLATOR_DECLARATIONS (Coherent_ligature_engraver) needed // since this class is abstract + TRANSLATOR_INHERIT (Ligature_engraver) + DECLARE_TRANSLATOR_CALLBACKS (Coherent_ligature_engraver); protected: virtual void build_ligature (Spanner *ligature, diff --git a/lily/include/engraver.hh b/lily/include/engraver.hh index 1f7e31ce40..d0f6e8979c 100644 --- a/lily/include/engraver.hh +++ b/lily/include/engraver.hh @@ -20,6 +20,8 @@ #ifndef ENGRAVER_HH #define ENGRAVER_HH +#include "callback.hh" +#include "grob.hh" #include "grob-info.hh" #include "translator.hh" @@ -46,6 +48,20 @@ protected: Engraver_group *get_daddy_engraver () const; public: + template + static SCM ack_trampoline (SCM target, SCM grob, SCM source_engraver) + { + T *t = LY_ASSERT_SMOB (T, target, 1); + Grob *g = LY_ASSERT_SMOB (Grob, grob, 2); + Engraver *e = LY_ASSERT_SMOB (Engraver, source_engraver, 3); + + (t->*callback) (Grob_info (e, g)); + return SCM_UNSPECIFIED; + } + template + static SCM ack_find_base () + { return Callback2_wrapper::make_smob > (); } + /** Announce element. Default: pass on to daddy. Utility */ @@ -65,6 +81,7 @@ public: override other ctor */ DECLARE_CLASSNAME (Engraver); + DECLARE_TRANSLATOR_CALLBACKS (Engraver); Engraver (); }; diff --git a/lily/include/gregorian-ligature-engraver.hh b/lily/include/gregorian-ligature-engraver.hh index 5aea42662b..a29b9d64e8 100644 --- a/lily/include/gregorian-ligature-engraver.hh +++ b/lily/include/gregorian-ligature-engraver.hh @@ -29,6 +29,8 @@ public: // no TRANSLATOR_DECLARATIONS (Gregorian_ligature_engraver) needed // since this class is abstract + TRANSLATOR_INHERIT(Coherent_ligature_engraver) + DECLARE_TRANSLATOR_CALLBACKS (Gregorian_ligature_engraver); protected: Gregorian_ligature_engraver (); diff --git a/lily/include/ligature-engraver.hh b/lily/include/ligature-engraver.hh index 6f53331a4e..0c45f8c225 100644 --- a/lily/include/ligature-engraver.hh +++ b/lily/include/ligature-engraver.hh @@ -43,6 +43,7 @@ protected: public: // no TRANSLATOR_DECLARATIONS (Ligature_engraver) needed since this // class is abstract + DECLARE_TRANSLATOR_CALLBACKS (Ligature_engraver); private: Drul_array events_drul_; diff --git a/lily/include/scheme-engraver.hh b/lily/include/scheme-engraver.hh index 286bcdd995..103176fc37 100644 --- a/lily/include/scheme-engraver.hh +++ b/lily/include/scheme-engraver.hh @@ -74,4 +74,3 @@ private: }; #endif /* SCHEME_ENGRAVER_HH */ - diff --git a/lily/include/slur-proto-engraver.hh b/lily/include/slur-proto-engraver.hh index c11926b21a..4ffeb6007f 100644 --- a/lily/include/slur-proto-engraver.hh +++ b/lily/include/slur-proto-engraver.hh @@ -80,6 +80,7 @@ protected: public: // no TRANSLATOR_DECLARATIONS (Slur_proto_engraver) needed since this // class is abstract + DECLARE_TRANSLATOR_CALLBACKS (Slur_proto_engraver); }; #endif // SLUR_PROTO_ENGRAVER_HH diff --git a/lily/include/translator-dispatch-list.hh b/lily/include/translator-dispatch-list.hh index 6fd03beecf..eb74e74cd6 100644 --- a/lily/include/translator-dispatch-list.hh +++ b/lily/include/translator-dispatch-list.hh @@ -21,19 +21,14 @@ #define TRANSLATOR_DISPATCH_LIST_HH #include "lily-proto.hh" +#include "callback.hh" #include "std-vector.hh" #include "smobs.hh" #include "translator.hh" -struct Engraver_dispatch_entry -{ - Engraver *engraver_; - Translator::Grob_info_callback function_; -}; - class Engraver_dispatch_list : public Simple_smob { - vector dispatch_entries_; + vector dispatch_entries_; public: static const char * const type_p_name_; // = 0 void apply (Grob_info); diff --git a/lily/include/translator.hh b/lily/include/translator.hh index 5a93564d9a..ea8b9782ae 100644 --- a/lily/include/translator.hh +++ b/lily/include/translator.hh @@ -23,6 +23,7 @@ #include "global-ctor.hh" #include "lily-proto.hh" #include "virtual-methods.hh" +#include "callback.hh" #include "input.hh" // for error reporting #include "smobs.hh" #include "std-vector.hh" @@ -33,18 +34,28 @@ VIRTUAL_COPY_CONSTRUCTOR (Translator, NAME); \ static Drul_array > acknowledge_static_array_drul_; \ virtual void fetch_precomputable_methods (Callback methods[]); \ - static Grob_info_callback static_get_acknowledger (SCM sym); \ - static Grob_info_callback static_get_end_acknowledger(SCM); \ - virtual Grob_info_callback get_acknowledger (SCM sym) \ + DECLARE_TRANSLATOR_CALLBACKS (NAME); \ + TRANSLATOR_INHERIT (Translator) \ + static SCM static_get_acknowledger (SCM sym); \ + static SCM static_get_end_acknowledger(SCM); \ + virtual SCM get_acknowledger (SCM sym) \ { \ return static_get_acknowledger (sym); \ } \ - virtual Grob_info_callback get_end_acknowledger (SCM sym) \ + virtual SCM get_end_acknowledger (SCM sym) \ { \ return static_get_end_acknowledger (sym); \ } \ /* end #define */ +#define TRANSLATOR_INHERIT(BASE) \ + using BASE::ack_finder; + +#define DECLARE_TRANSLATOR_CALLBACKS(NAME) \ + template \ + static SCM ack_finder () { return ack_find_base (); } \ + /* end #define */ + /* Each translator class has a static alist of event class symbols mapping to callbacks that are called with a translator instance and @@ -53,7 +64,8 @@ */ #define TRANSLATOR_DECLARATIONS(NAME) \ - TRANSLATOR_FAMILY_DECLARATIONS(NAME) \ + public: \ + TRANSLATOR_FAMILY_DECLARATIONS (NAME); \ static SCM static_description_; \ static Protected_scm listener_list_; \ public: \ @@ -90,10 +102,6 @@ enum Translator_precompute_index class Translator : public Smob { public: - // We don't make Grob_info_callback specific to Engraver since we - // otherwise get into a circular mess with regard to the definitions - // as the timing of Engraver is exercised from within Translator - typedef void (Translator::*Grob_info_callback) (Grob_info); typedef void (Translator::*Callback) (void); int print_smob (SCM, scm_print_state *) const; SCM mark_smob () const; @@ -134,8 +142,8 @@ public: virtual void fetch_precomputable_methods (Callback methods[]) = 0; virtual SCM get_listener_list () const = 0; virtual SCM translator_description () const = 0; - virtual Grob_info_callback get_acknowledger (SCM sym) = 0; - virtual Grob_info_callback get_end_acknowledger (SCM sym) = 0; + virtual SCM get_acknowledger (SCM sym) = 0; + virtual SCM get_end_acknowledger (SCM sym) = 0; protected: // should be private. Context *daddy_context_; @@ -153,6 +161,15 @@ protected: // should be private. return SCM_UNSPECIFIED; } + // Overriden in Engraver. + template + static SCM + ack_find_base () { return SCM_UNDEFINED; } + + template + static SCM + ack_finder () { return SCM_UNDEFINED; } + virtual void derived_mark () const; static SCM event_class_symbol (const char *ev_class); SCM static_translator_description (const char *grobs, @@ -167,12 +184,12 @@ protected: // should be private. struct Acknowledge_information { SCM symbol_; - Translator::Grob_info_callback function_; + SCM function_; Acknowledge_information () { symbol_ = SCM_EOL; - function_ = 0; + function_ = SCM_UNDEFINED; } }; diff --git a/lily/include/translator.icc b/lily/include/translator.icc index 3b700d815c..cebfba52e9 100644 --- a/lily/include/translator.icc +++ b/lily/include/translator.icc @@ -22,7 +22,7 @@ #include "callback.hh" #include "std-vector.hh" -#include "translator.hh" +#include "engraver.hh" /* TODO: derive "foo-bar-interface" from Foo_bar classname. @@ -53,12 +53,12 @@ #define DEFINE_ACKNOWLEDGERS(classname) \ Drul_array< vector > classname::acknowledge_static_array_drul_; \ - Translator::Grob_info_callback \ + SCM \ classname::static_get_acknowledger (SCM sym) \ { \ return generic_get_acknowledger (sym, &acknowledge_static_array_drul_[START]); \ } \ - Translator::Grob_info_callback \ + SCM \ classname::static_get_end_acknowledger (SCM sym) \ { \ return generic_get_acknowledger (sym, &acknowledge_static_array_drul_[STOP]); \ @@ -108,25 +108,27 @@ : static_cast (&T::process_acknowledged); \ } -void add_acknowledger (Translator::Grob_info_callback ptr, +void add_acknowledger (SCM ptr, char const *func_name, vector *ack_array); -Translator::Grob_info_callback +SCM generic_get_acknowledger (SCM sym, vector const *ack_array); #define ADD_ACKNOWLEDGER(CLASS, NAME) \ void CLASS ## NAME ## _ack_adder () \ { \ - add_acknowledger (static_cast (&CLASS::acknowledge_ ## NAME), #NAME, &CLASS::acknowledge_static_array_drul_[START]); \ + add_acknowledger (CLASS::ack_finder<&CLASS::acknowledge_ ## NAME> (), \ + #NAME, &CLASS::acknowledge_static_array_drul_[START]); \ } \ ADD_SCM_INIT_FUNC (CLASS ## NAME ## _ack_adder_initclass, CLASS ## NAME ## _ack_adder); -#define ADD_END_ACKNOWLEDGER(CLASS, NAME) \ - void CLASS ## NAME ## _end_ack_adder () \ +#define ADD_END_ACKNOWLEDGER(CLASS, NAME) \ + void CLASS ## NAME ## _end_ack_adder () \ { \ - add_acknowledger (static_cast (&CLASS::acknowledge_end_ ## NAME), #NAME, &CLASS::acknowledge_static_array_drul_[STOP]); \ + add_acknowledger (CLASS::ack_finder<&CLASS::acknowledge_end_ ## NAME> (), \ + #NAME, &CLASS::acknowledge_static_array_drul_[STOP]); \ } \ ADD_SCM_INIT_FUNC (CLASS ## NAME ## _end_ack_adder_initclass, CLASS ## NAME ## _end_ack_adder); diff --git a/lily/kievan-ligature-engraver.cc b/lily/kievan-ligature-engraver.cc index 25582c6a39..791f0b1f1c 100644 --- a/lily/kievan-ligature-engraver.cc +++ b/lily/kievan-ligature-engraver.cc @@ -40,6 +40,7 @@ protected: public: TRANSLATOR_DECLARATIONS (Kievan_ligature_engraver); + TRANSLATOR_INHERIT (Coherent_ligature_engraver) private: void fold_up_primitives (vector const &primitives, Real padding, Real &min_length); diff --git a/lily/mensural-ligature-engraver.cc b/lily/mensural-ligature-engraver.cc index ac1eb1f10a..bfa30550e5 100644 --- a/lily/mensural-ligature-engraver.cc +++ b/lily/mensural-ligature-engraver.cc @@ -63,6 +63,7 @@ protected: public: TRANSLATOR_DECLARATIONS (Mensural_ligature_engraver); + TRANSLATOR_INHERIT (Coherent_ligature_engraver); private: void transform_heads (vector const &primitives); diff --git a/lily/phrasing-slur-engraver.cc b/lily/phrasing-slur-engraver.cc index 479be1df22..b1a2f23ea0 100644 --- a/lily/phrasing-slur-engraver.cc +++ b/lily/phrasing-slur-engraver.cc @@ -41,6 +41,7 @@ protected: public: SCM event_symbol (); TRANSLATOR_DECLARATIONS (Phrasing_slur_engraver); + TRANSLATOR_INHERIT (Slur_proto_engraver); }; Phrasing_slur_engraver::Phrasing_slur_engraver () : diff --git a/lily/slur-engraver.cc b/lily/slur-engraver.cc index 581136791d..31621844a9 100644 --- a/lily/slur-engraver.cc +++ b/lily/slur-engraver.cc @@ -42,6 +42,7 @@ protected: public: SCM event_symbol (); TRANSLATOR_DECLARATIONS (Slur_engraver); + TRANSLATOR_INHERIT (Slur_proto_engraver); }; Slur_engraver::Slur_engraver () : diff --git a/lily/translator-dispatch-list.cc b/lily/translator-dispatch-list.cc index 41d5a17182..208d8a501c 100644 --- a/lily/translator-dispatch-list.cc +++ b/lily/translator-dispatch-list.cc @@ -26,14 +26,15 @@ const char * const Engraver_dispatch_list::type_p_name_ = 0; void Engraver_dispatch_list::apply (Grob_info gi) { - Translator *origin = gi.origin_translator (); + SCM origin = gi.origin_translator ()->self_scm (); + SCM grob = gi.grob ()->self_scm (); for (vsize i = 0; i < dispatch_entries_.size (); i++) { - Engraver_dispatch_entry const &e (dispatch_entries_[i]); - if (e.engraver_ == origin) + Method_instance const &e (dispatch_entries_[i]); + if (scm_is_eq (e.instance (), origin)) continue; - (e.engraver_->*e.function_) (gi); + e (grob, origin); } } @@ -44,32 +45,24 @@ Engraver_dispatch_list::create (SCM trans_list, SCM retval = Engraver_dispatch_list ().smobbed_copy (); Engraver_dispatch_list *list = unsmob (retval); - Engraver_dispatch_entry entry; - bool found = false; for (SCM s = trans_list; scm_is_pair (s); s = scm_cdr (s)) { - Engraver *eng - = unsmob (scm_car (s)); + Engraver *eng = unsmob (scm_car (s)); if (!eng) continue; - entry.engraver_ = eng; for (SCM i = iface_list; scm_is_pair (i); i = scm_cdr (i)) { - Translator::Grob_info_callback ptr + SCM ptr = (start_end == START) - ? eng->get_acknowledger (scm_car (i)) - : eng->get_end_acknowledger (scm_car (i)); + ? eng->get_acknowledger (scm_car (i)) + : eng->get_end_acknowledger (scm_car (i)); - if (ptr) - { - entry.function_ = ptr; - list->dispatch_entries_.push_back (entry); - found = true; - } + if (!SCM_UNBNDP (ptr)) + list->dispatch_entries_.push_back (Method_instance (ptr, eng)); } } - return found ? retval : SCM_EOL; + return list->dispatch_entries_.empty () ? SCM_EOL : retval; } diff --git a/lily/translator.cc b/lily/translator.cc index 9c667a8a25..780ef1befc 100644 --- a/lily/translator.cc +++ b/lily/translator.cc @@ -230,7 +230,7 @@ Translator::print_smob (SCM port, scm_print_state *) const } void -add_acknowledger (Translator::Grob_info_callback ptr, +add_acknowledger (SCM ptr, char const *func_name, vector *ack_array) { @@ -249,7 +249,7 @@ add_acknowledger (Translator::Grob_info_callback ptr, ack_array->push_back (inf); } -Translator::Grob_info_callback +SCM generic_get_acknowledger (SCM sym, vector const *ack_array) { for (vsize i = 0; i < ack_array->size (); i++) @@ -257,7 +257,7 @@ generic_get_acknowledger (SCM sym, vector const *ack_ar if (ack_array->at (i).symbol_ == sym) return ack_array->at (i).function_; } - return 0; + return SCM_UNDEFINED; } Moment diff --git a/lily/vaticana-ligature-engraver.cc b/lily/vaticana-ligature-engraver.cc index 2d94c03892..a98471369c 100644 --- a/lily/vaticana-ligature-engraver.cc +++ b/lily/vaticana-ligature-engraver.cc @@ -77,7 +77,7 @@ private: public: TRANSLATOR_DECLARATIONS (Vaticana_ligature_engraver); - + TRANSLATOR_INHERIT (Gregorian_ligature_engraver) protected: virtual Spanner *create_ligature_spanner (); virtual void transform_heads (Spanner *ligature, -- 2.39.5