]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 4842/3: Replace Engraver_dispatch_entry with Method_instance
authorDavid Kastrup <dak@gnu.org>
Thu, 28 Apr 2016 08:08:43 +0000 (10:08 +0200)
committerDavid Kastrup <dak@gnu.org>
Sun, 8 May 2016 15:17:00 +0000 (17:17 +0200)
This also replaces a lot of C++-centric callback machinery (like the
Grob_info_callback type) with SCM-based code.

18 files changed:
lily/auto-beam-engraver.cc
lily/beam-engraver.cc
lily/include/coherent-ligature-engraver.hh
lily/include/engraver.hh
lily/include/gregorian-ligature-engraver.hh
lily/include/ligature-engraver.hh
lily/include/scheme-engraver.hh
lily/include/slur-proto-engraver.hh
lily/include/translator-dispatch-list.hh
lily/include/translator.hh
lily/include/translator.icc
lily/kievan-ligature-engraver.cc
lily/mensural-ligature-engraver.cc
lily/phrasing-slur-engraver.cc
lily/slur-engraver.cc
lily/translator-dispatch-list.cc
lily/translator.cc
lily/vaticana-ligature-engraver.cc

index 37872577387bd1750a5e30d24558e45b7ea1c8a8..68c61d97a8f011dd9d2ae7152a6b59c619671857 100644 (file)
@@ -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:
index e6ca4caf16d58586556a288fb7c915bb8e06659c..554aeda7a1858694432b226c47efe3f9313c75fd 100644 (file)
@@ -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:
index 19e731815af44cd598e1170f68335e3609f7913d..b7f77f84028210b4939a8c3643c710303410381e 100644 (file)
@@ -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,
index 1f7e31ce40eecc3eb9afd0d0dd9e1509f3b75fac..d0f6e8979ced98b1688462f03409d6936be10185 100644 (file)
@@ -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 ();
 };
 
index 5aea42662b29bd909471a9469b216ba097c222c1..a29b9d64e86aae55dd5580015bcc03e7053a811c 100644 (file)
@@ -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 ();
 
index 6f53331a4e5493627debd1ebea1bc48952f28726..0c45f8c2257817299637adc4be5cf4f7f01783d1 100644 (file)
@@ -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_;
index 286bcdd9952e0110a998eb6fd1644d0d9f741110..103176fc37c6b733636c318bb5611d6ce81d96dc 100644 (file)
@@ -74,4 +74,3 @@ private:
 };
 
 #endif /* SCHEME_ENGRAVER_HH */
-
index c11926b21a9bc8841b4b6e9ba5cdc115cdbbd412..4ffeb6007f0b860d2a5250c29791884bd3fd7eb7 100644 (file)
@@ -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
index 6fd03beecf050ce363338430753fb2a22991ac10..eb74e74cd69e2091d2e0714bd89c013852f2cf45 100644 (file)
 #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);
index 5a93564d9a468cfb311067d7d312318e10817c26..ea8b9782ae7bbceb3a21c0a3c0dfec88606bd40c 100644 (file)
@@ -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"
   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;
   }
 };
 
index 3b700d815c7d3181995866739f68f511a37d09ae..cebfba52e905541f66a3e145e3da4c7cd4f5e1b8 100644 (file)
@@ -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.
 
 #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]);       \
       : 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);
 
index 25582c6a395ebccaede5622c680ce4814663e576..791f0b1f1c956abd53ed93c84259bb98bb0dd0de 100644 (file)
@@ -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);
index ac1eb1f10af267f215b2385e723ff0ab361bf071..bfa30550e58efd99ff0605572d0f0f0db22101fd 100644 (file)
@@ -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);
index 479be1df22cdf87e9d02e47c18d5c72cc0733dcf..b1a2f23ea02aefc38018583b64c72a8bfab2d885 100644 (file)
@@ -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 () :
index 581136791d932daff6148c2ad80d2b82366c095b..31621844a9c568ce840bc0dcc3fe35edfd18720b 100644 (file)
@@ -42,6 +42,7 @@ protected:
 public:
   SCM event_symbol ();
   TRANSLATOR_DECLARATIONS (Slur_engraver);
+  TRANSLATOR_INHERIT (Slur_proto_engraver);
 };
 
 Slur_engraver::Slur_engraver () :
index 41d5a171827ceb5bdf065d3eaf5eeebd0bcf1884..208d8a501c661ed7e7196b06c28b8475421bf461 100644 (file)
@@ -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;
 }
index 9c667a8a251344877adb77d72544fef5306b78b5..780ef1befc17be217d884d9af43c374021cdc72d 100644 (file)
@@ -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
index 2d94c03892238855068ac6a8e735c7b4acf7bb2f..a98471369cb7baa3f77aa5f7a6c4995a7e5b1807 100644 (file)
@@ -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,