From 87bcea3a1d67afec13b49c2facd9fb28cc37277b Mon Sep 17 00:00:00 2001
From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Tue, 19 Jul 2005 10:20:21 +0000
Subject: [PATCH] * lily/break-substitution.cc (fast_substitute_grob_array): do
 fast_substitute_grob_array for all unordered grob_arrays. (substitute_grob):
 return Grob *. Saves packing/unpacking SCMs. (substitute_grob_array):
 optimize.

* lily/align-interface.cc (set_axis): set ordered_ for 'elements

* lily/include/grob-array.hh (class Grob_array): ordered_ member.

* lily/parser.yy: revert $globalheader patch.

* lily/engraver-group-engraver.cc: remove engraver_each,
recurse_down_engravers ()
---
 ChangeLog                  | 16 +++++++----
 lily/align-interface.cc    | 12 +++++++++
 lily/break-substitution.cc | 54 +++++++++++++++++++++-----------------
 lily/grob-array.cc         | 21 ++++-----------
 lily/include/grob-array.hh | 10 ++++---
 lily/parser.yy             | 12 ++-------
 6 files changed, 67 insertions(+), 58 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 78531bcef2..ea146f8047 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,16 +1,22 @@
-2005-07-18  Yoshinobu Isizaki  <isizaki@mte.biglobe.ne.jp>
+2005-07-19  Han-Wen Nienhuys  <hanwen@xs4all.nl>
 
-	* lily/parser.yy (lilypond_header_body): enables
-	multiple header definition.
+	* lily/break-substitution.cc (fast_substitute_grob_array): do
+	fast_substitute_grob_array for all unordered grob_arrays.
+	(substitute_grob): return Grob *. Saves packing/unpacking SCMs.
+	(substitute_grob_array): optimize.
 
-2005-07-19  Han-Wen Nienhuys  <hanwen@xs4all.nl>
+	* lily/align-interface.cc (set_axis): set ordered_ for 'elements
 
+	* lily/include/grob-array.hh (class Grob_array): ordered_ member.
+
+	* lily/parser.yy: revert $globalheader patch.
+	
 	* lily/include/translator.icc
 	(IMPLEMENT_FETCH_PRECOMPUTABLE_METHODS): directly jump into
 	Translator methods, without _static helper.
  
 	* lily/grob-smob.cc (derived_mark): rename from
-	do_derived_mark(). Don't return SCM.
+	do_derived_mark(). Return void.
 
 	* scm/define-context-properties.scm
 	(all-internal-translation-properties): remove tweakCount/tweakRank.
diff --git a/lily/align-interface.cc b/lily/align-interface.cc
index 8d09d98dca..ba4322d8bb 100644
--- a/lily/align-interface.cc
+++ b/lily/align-interface.cc
@@ -13,6 +13,7 @@
 #include "axis-group-interface.hh"
 #include "pointer-group-interface.hh"
 #include "hara-kiri-group-spanner.hh"
+#include "grob-array.hh"
 
 MAKE_SCHEME_CALLBACK (Align_interface, alignment_callback, 2);
 SCM
@@ -246,6 +247,17 @@ void
 Align_interface::set_axis (Grob *me, Axis a)
 {
   Axis_group_interface::set_axes (me, a, a);
+  SCM ga_scm = me->get_object ("elements");
+  Grob_array *ga = unsmob_grob_array (ga_scm);
+  if (!ga)
+    {
+      ga_scm = Grob_array::make_array ();
+      ga = unsmob_grob_array (ga_scm);
+      me->set_object ("elements", ga_scm);
+    }
+
+  ga->set_ordered (true);
+  
 }
 
 /*
diff --git a/lily/break-substitution.cc b/lily/break-substitution.cc
index ce1b41c6cc..b49aaffa39 100644
--- a/lily/break-substitution.cc
+++ b/lily/break-substitution.cc
@@ -24,7 +24,7 @@ set_break_subsititution (SCM criterion)
 /*
   Perform the substitution for a single grob.
 */
-SCM
+Grob *
 substitute_grob (Grob *sc)
 {
   if (scm_is_integer (break_criterion))
@@ -34,7 +34,7 @@ substitute_grob (Grob *sc)
       if (i && i->break_status_dir () != d)
 	{
 	  Item *br = i->find_prebroken_piece (d);
-	  return (br) ? br->self_scm () : SCM_UNDEFINED;
+	  return br;
 	}
     }
   else
@@ -48,11 +48,11 @@ substitute_grob (Grob *sc)
 
       /* now: !sc || (sc && sc->get_system () == line) */
       if (!sc)
-	return SCM_UNDEFINED;
+	return 0;
 
       /* now: sc && sc->get_system () == line */
       if (!line)
-	return sc->self_scm ();
+	return sc;
 
       /*
 	We don't return SCM_UNDEFINED for
@@ -67,12 +67,12 @@ substitute_grob (Grob *sc)
       if (sc->common_refpoint (line, X_AXIS)
 	  && sc->common_refpoint (line, Y_AXIS))
 	{
-	  return sc->self_scm ();
+	  return sc;
 	}
-      return SCM_UNDEFINED;
+      return 0;
     }
 
-  return sc->self_scm ();
+  return sc;
 }
 
 /*
@@ -95,7 +95,10 @@ do_break_substitution (SCM src)
  again:
 
   if (unsmob_grob (src))
-    return substitute_grob (unsmob_grob (src));
+    {
+      Grob * new_ptr = substitute_grob (unsmob_grob (src));
+      return new_ptr ? new_ptr->self_scm () : SCM_UNDEFINED;
+    }
   else if (scm_is_vector (src))
     {
       int len = scm_c_vector_length (src);
@@ -140,24 +143,29 @@ do_break_substitution (SCM src)
 /*
   Perform substitution on GROB_LIST using a constant amount of stack.
 */
+Link_array<Grob> temporary_substition_array;
 void
 substitute_grob_array (Grob_array *grob_arr, Grob_array * new_arr)
 {
   Link_array<Grob> &old_grobs (grob_arr->array_reference ());
   Link_array<Grob> *new_grobs (new_arr == grob_arr
-			       ? new Link_array<Grob> 
+			       ? &temporary_substition_array
 			       : &new_arr->array_reference ());
-
+  
+  new_grobs->set_size (old_grobs.size ());
+  Grob **array =  (Grob**) new_grobs->accesses();
+  Grob **ptr = array; 
   for (int i = 0; i < old_grobs.size (); i++)
     {
-      Grob * orig = old_grobs[i];
-      SCM new_grob = substitute_grob (orig);
-      if (new_grob != SCM_UNDEFINED)
+      Grob *orig = old_grobs[i];
+      Grob *new_grob = substitute_grob (orig);
+      if (new_grob)
 	{
-	  new_grobs->push (unsmob_grob (new_grob));
+	  *ptr ++ = new_grob;
 	}
     }
 
+  new_grobs->set_size (ptr - array);  
   if (new_arr == grob_arr)
     {
       new_arr->set_array (*new_grobs);
@@ -316,13 +324,10 @@ Spanner::fast_substitute_grob_array (SCM sym,
 {
   int len = grob_array->size();
 
-  /*
-    Only do this complicated thing for large sets. This has the added
-    advantage that we won't screw up the ordering for elements in
-    alignments (which typically don't have more than 10 grobs.)
-  */
+  if (grob_array->ordered ())
+    return false;
 
-  if (len < 300)
+  if (len < 15)
     return false;
 
   /*
@@ -396,7 +401,8 @@ Spanner::fast_substitute_grob_array (SCM sym,
 
   assert (item_index <= spanner_index);
 
-  assert (broken_intos_.size () == system_range.length () + 1);
+  assert ((broken_intos_.size () == system_range.length () + 1)
+	  || (broken_intos_.is_empty () && system_range.length () == 0));
   for (int i = 0; i < broken_intos_.size (); i++)
     {
       Grob *sc = broken_intos_[i];
@@ -414,10 +420,10 @@ Spanner::fast_substitute_grob_array (SCM sym,
       for (int k = 0; k < 2;k++)
 	for (int j = (*arrs[k])[i][LEFT]; j <= (*arrs[k])[i][RIGHT]; j++)
 	  {
-	    SCM subs = substitute_grob (vec[j].grob_);
-	    if (subs != SCM_UNDEFINED)
+	    Grob *substituted = substitute_grob (vec[j].grob_);
+	    if (substituted)
 	      {
-		new_array->add (unsmob_grob (subs));
+		new_array->add (substituted);
 	      }
 	  }
 
diff --git a/lily/grob-array.cc b/lily/grob-array.cc
index c58ffd18bc..fa8d4cd65c 100644
--- a/lily/grob-array.cc
+++ b/lily/grob-array.cc
@@ -13,35 +13,21 @@
 
 #include "ly-smobs.icc"
 
-int
-Grob_array::size () const
-{
-  return grobs_.size();  
-}
-
 Item *
 Grob_array::item (int i)
 {
   return dynamic_cast<Item*> (grobs_.elem (i));
 }
 
-
 Spanner*
 Grob_array::spanner (int i)
 {
   return dynamic_cast<Spanner*> (grobs_.elem (i));
 }
 
-Grob*
-Grob_array::grob (int i)
+Grob_array::Grob_array ()
 {
-  return grobs_.elem (i);
-}
-
-void
-Grob_array::add (Grob *grob)
-{
-  grobs_.push (grob);
+  ordered_ = false;
 }
 
 Link_array<Grob> &
@@ -61,6 +47,8 @@ Grob_array::array () const
 SCM
 Grob_array::mark_smob (SCM s)
 {
+  (void) s;
+  
 #if 0
   // see System::derived_mark()
   Grob_array *ga = unsmob_grob_array (s); 
@@ -113,6 +101,7 @@ Grob_array::set_array (Link_array<Grob> const &src)
 
 IMPLEMENT_SIMPLE_SMOBS (Grob_array);
 IMPLEMENT_TYPE_P (Grob_array, "ly:grob-array?");
+
 IMPLEMENT_DEFAULT_EQUAL_P (Grob_array);
 
 
diff --git a/lily/include/grob-array.hh b/lily/include/grob-array.hh
index 8c5c4d54e2..f0f6b9072c 100644
--- a/lily/include/grob-array.hh
+++ b/lily/include/grob-array.hh
@@ -17,17 +17,21 @@
 class Grob_array
 {
   Link_array<Grob> grobs_;
+  bool ordered_;
   
   DECLARE_SIMPLE_SMOBS(Grob_array,);
 
+  Grob_array ();
 public:
+  bool ordered () const { return ordered_; }
+  void set_ordered (bool b) { ordered_ = b; }
   Item *item (int i);
   Spanner *spanner (int i);
-  Grob * grob (int i);
-  int size () const;
+  Grob * grob (int i) { return grobs_.elem (i); }
+  int size () const { return grobs_.size(); }
   bool is_empty () const;
   void clear ();  
-  void add (Grob *);
+  void add (Grob *x) { grobs_.push (x); }
   void set_array (Link_array<Grob> const &src);
   Link_array<Grob> &array_reference ();
   Link_array<Grob> const &array () const;
diff --git a/lily/parser.yy b/lily/parser.yy
index 03df3be127..2b5b6c0caa 100644
--- a/lily/parser.yy
+++ b/lily/parser.yy
@@ -626,16 +626,8 @@ embedded_scm:
 
 lilypond_header_body:
 	{
-		SCM id = THIS->lexer_->lookup_identifier("$globalheader");
-		if ( ly_is_module(id) ){
-			// if the header exists, then comes here.
-			THIS->lexer_->add_scope(id);
-			$$ = id;
-		}else{	
-			/* org code */
-			$$ = ly_make_anonymous_module (be_safe_global);
-			THIS->lexer_->add_scope ($$);
-		}
+		$$ = ly_make_anonymous_module (be_safe_global);
+		THIS->lexer_->add_scope ($$);
 	}
 	| lilypond_header_body assignment  {
 		
-- 
2.39.5