]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/translator-group.cc
Improve doc-string for stringTunings
[lilypond.git] / lily / translator-group.cc
index 44b4e1fe0a1742dbb1e2fb34eeada2589004c2cd..f9812e9798f272a9c96caa85905bf69b08b38387 100644 (file)
 #include "context-def.hh"
 #include "context.hh"
 #include "dispatcher.hh"
+#include "engraver.hh"
 #include "engraver-group.hh"
 #include "international.hh"
 #include "main.hh"
 #include "music.hh"
 #include "output-def.hh"
+#include "performer.hh"
 #include "performer-group.hh"
 #include "scheme-engraver.hh"
 #include "scm-hash.hh"
@@ -52,7 +54,7 @@ Translator_group::connect_to_context (Context *c)
   if (context_)
     {
       programming_error ("translator group is already connected to context "
-                        +  context_->context_name ());
+                        + context_->context_name ());
     }
   
   context_ = c;
@@ -84,13 +86,22 @@ Translator_group::finalize ()
 {
 }
 
+/*
+  Both filter_performers and filter_engravers used to use a direct dynamic_cast
+  on the unsmobbed translator to be filtered, i.e.,
+
+  if (dynamic_cast<Performer *> (unsmob_translator (scm_car (*tail))))
+
+  but this caused mysterious optimisation issues in several GUB builds.  See
+  issue #818 for the background to this change.
+*/
 SCM
 filter_performers (SCM ell)
 {
   SCM *tail = &ell;
   for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p))
     {
-      if (dynamic_cast<Performer *> (unsmob_translator (scm_car (*tail))))
+      if (unsmob_performer (scm_car (*tail)))
        *tail = scm_cdr (*tail);
       else
        tail = SCM_CDRLOC (*tail);
@@ -104,7 +115,7 @@ filter_engravers (SCM ell)
   SCM *tail = &ell;
   for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p))
     {
-      if (dynamic_cast<Engraver *> (unsmob_translator (scm_car (*tail))))
+      if (unsmob_engraver (scm_car (*tail)))
        *tail = scm_cdr (*tail);
       else
        tail = SCM_CDRLOC (*tail);
@@ -153,25 +164,34 @@ Translator_group::create_child_translator (SCM sev)
   for (SCM s = trans_names; scm_is_pair (s); s = scm_cdr (s))
     {
       SCM definition = scm_car (s);
+      bool is_scheme = false;
 
       Translator *type = 0;
-      Translator *instance = type;
       if (ly_is_symbol (definition))
+       type = get_translator (definition);
+      else if (ly_is_pair (definition))
        {
-         type = get_translator (definition);
-         instance = type->clone ();
+         type = get_translator (ly_symbol2scm ("Scheme_engraver"));
+         is_scheme = true;
        }
-      else if (ly_is_pair (definition))
+      else if (ly_is_procedure (definition))
        {
+         // `definition' is a procedure, which takes the context as
+         // an argument and evaluates to an a-list scheme engraver
+         // definition.
+         definition = scm_call_1 (definition, cs);
          type = get_translator (ly_symbol2scm ("Scheme_engraver"));
-         instance = type->clone ();
-         dynamic_cast<Scheme_engraver*> (instance)->init_from_scheme (definition);
+         is_scheme = true;
        }
         
       if (!type)
        warning (_f ("cannot find: `%s'", ly_symbol2string (scm_car (s)).c_str ()));
       else
        {
+         Translator *instance = type->clone ();
+         if (is_scheme)
+           dynamic_cast<Scheme_engraver *> (instance)->init_from_scheme (definition);
+
          SCM str = instance->self_scm ();
 
          if (instance->must_be_last ())