lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 4/5] Replace Engraver_dispatch_entry with Method_instance


From: David Kastrup
Subject: [PATCH 4/5] Replace Engraver_dispatch_entry with Method_instance
Date: Tue, 3 May 2016 00:58:31 +0200

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]