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 3787257..68c61d9 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 e6ca4ca..554aeda 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 19e7318..b7f77f8 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 1f7e31c..d0f6e89 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 <class T, void (T::*callback)(Grob_info)> + 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 <class T, void (T::*callback)(Grob_info)> + static SCM ack_find_base () + { return Callback2_wrapper::make_smob<ack_trampoline<T, callback> > (); } + /** 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 5aea426..a29b9d6 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 6f53331..0c45f8c 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<Stream_event *> events_drul_; diff --git a/lily/include/scheme-engraver.hh b/lily/include/scheme-engraver.hh index d8265f9..66eb221 100644 --- a/lily/include/scheme-engraver.hh +++ b/lily/include/scheme-engraver.hh @@ -76,4 +76,3 @@ private: }; #endif /* SCHEME_ENGRAVER_HH */ - diff --git a/lily/include/slur-proto-engraver.hh b/lily/include/slur-proto-engraver.hh index c11926b..4ffeb60 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 6fd03be..eb74e74 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<Engraver_dispatch_list> { - vector<Engraver_dispatch_entry> dispatch_entries_; + vector<Method_instance> 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 5a93564..ea8b978 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<vector<Acknowledge_information> > 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 <void (NAME::*callback)(Grob_info)> \ + static SCM ack_finder () { return ack_find_base<NAME, callback> (); } \ + /* 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<Translator> { 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 <class T, void (T::*callback)(Grob_info)> + static SCM + ack_find_base () { return SCM_UNDEFINED; } + + template <void (Translator::*)(Grob_info)> + 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 3b700d8..cebfba5 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<Acknowledge_information> > 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<Callback> (&T::process_acknowledged); \ } -void add_acknowledger (Translator::Grob_info_callback ptr, +void add_acknowledger (SCM ptr, char const *func_name, vector<Acknowledge_information> *ack_array); -Translator::Grob_info_callback +SCM generic_get_acknowledger (SCM sym, vector<Acknowledge_information> const *ack_array); #define ADD_ACKNOWLEDGER(CLASS, NAME) \ void CLASS ## NAME ## _ack_adder () \ { \ - add_acknowledger (static_cast<Translator::Grob_info_callback> (&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<Translator::Grob_info_callback> (&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 25582c6..791f0b1 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<Grob_info> const &primitives, Real padding, Real &min_length); diff --git a/lily/mensural-ligature-engraver.cc b/lily/mensural-ligature-engraver.cc index ac1eb1f..bfa3055 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<Grob_info> const &primitives); diff --git a/lily/phrasing-slur-engraver.cc b/lily/phrasing-slur-engraver.cc index 479be1d..b1a2f23 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 5811367..3162184 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 41d5a17..208d8a5 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<Engraver_dispatch_list> (retval); - Engraver_dispatch_entry entry; - bool found = false; for (SCM s = trans_list; scm_is_pair (s); s = scm_cdr (s)) { - Engraver *eng - = unsmob<Engraver> (scm_car (s)); + Engraver *eng = unsmob<Engraver> (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 9c667a8..780ef1b 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<Acknowledge_information> *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<Acknowledge_information> const *ack_array) { for (vsize i = 0; i < ack_array->size (); i++) @@ -257,7 +257,7 @@ generic_get_acknowledger (SCM sym, vector<Acknowledge_information> 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 2d94c03..a984713 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.7.4 _______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel