]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/unfolded-repeat-iterator.cc
release: 1.5.19
[lilypond.git] / lily / unfolded-repeat-iterator.cc
index f9ac9ea0c451a35172ef5dc58ff7c1fb1c132ff2..7dd93bd1dcfa8ad4950ff6c8d93da9eb02c979f7 100644 (file)
   
   source file of the GNU LilyPond music typesetter
   
-  (c) 1999--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  (c) 1999--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
   
  */
 
-
+/*
+  This is too hairy.  Maybe split into subclasses for volta and full
+  unfold?
+  
+ */
+#include "music-iterator.hh"
 #include "repeated-music.hh"
 #include "music-list.hh"
-#include "unfolded-repeat-iterator.hh"
 #include "debug.hh"
 #include "translator-group.hh"
 
+/**
+   Iterate repeats.  First do body, then alternatives one by one,
+   optionally interspersed by the body.
+ */
+class Unfolded_repeat_iterator : public Music_iterator
+{
+  void add_repeat_command (SCM);
+
+public:
+  VIRTUAL_COPY_CONS (Music_iterator);
+  /**
+     How often have we done the body (assuming bodies are interspersed.)?
+
+     In volta: the number to print in the bracket.
+   */
+  int done_count_;
+  static SCM constructor_cxx_function; 
+
+  /*
+    are we now busy doing the body?
+
+   */
+  bool do_main_b_;
+
+  /*
+    are we doing volta's?
+   */
+  bool volta_b_;
+
+  /** How far have we progressed into the repeat.
+      This excludes the elt currently being iterated.
+  */
+  Moment here_mom_;
+  int alternative_count_i_;
+  Music_iterator * current_iter_p_;
+  
+  /// pointer to the alternative that will be processed next.
+  SCM alternative_cons_;
+  ~Unfolded_repeat_iterator ();
+  Unfolded_repeat_iterator ();
+  Unfolded_repeat_iterator (Unfolded_repeat_iterator const &);
+protected:  
+  virtual void construct_children ();
+  virtual Moment pending_moment () const;
+  virtual void process (Moment);
+  virtual Music_iterator *try_music_in_children (Music *) const;
+  virtual void skip (Moment);
+  virtual SCM get_music (Moment) const;
+  
+  virtual bool ok () const;
+  virtual void next_element (bool side_effect);
+};
+
+class Volta_repeat_iterator : public Unfolded_repeat_iterator
+{
+public:
+  Volta_repeat_iterator ();
+  static  SCM constructor_cxx_function;
+  VIRTUAL_COPY_CONS (Music_iterator);
+};
+
+
+
 Unfolded_repeat_iterator::~Unfolded_repeat_iterator ()
 {
   delete current_iter_p_;
 }
 
+Unfolded_repeat_iterator::Unfolded_repeat_iterator (Unfolded_repeat_iterator const &src)
+  : Music_iterator (src)
+{
+  done_count_ = src.done_count_;
+  current_iter_p_ = (src.current_iter_p_)? src.current_iter_p_->clone () : 0;
+  do_main_b_ = src.do_main_b_;
+  volta_b_ = src.volta_b_;
+  alternative_count_i_ = src.alternative_count_i_;
+  alternative_cons_ = src.alternative_cons_;
+}
+
 Unfolded_repeat_iterator::Unfolded_repeat_iterator ()
 {
   done_count_ =0;
   current_iter_p_ =0;
+  volta_b_ = false;
   do_main_b_ = false;
   alternative_count_i_ =0;
+  alternative_cons_ = SCM_EOL;
 }
 
 /**
@@ -40,11 +120,11 @@ the  alternative just set.
 void
 Unfolded_repeat_iterator::next_element (bool side_effect) 
 {
-  Repeated_music * repmus =dynamic_cast<Repeated_music *> (music_l_);
+  Repeated_music * repmus =dynamic_cast<Repeated_music *> (music_l ());
   delete current_iter_p_;
   current_iter_p_ =0;
 
-  bool do_repcommands = side_effect && repmus->volta_fold_b_;
+  bool do_repcommands = side_effect && volta_b_;
   
   if (do_main_b_)
     {
@@ -53,28 +133,47 @@ Unfolded_repeat_iterator::next_element (bool side_effect)
 
        - go to alternative if we're a volta
 
+       - make a :| if there are no alternatives   
+       
        - do something intelligent when we're fully unfolding (fixcomment)
        */
       
       here_mom_ += repmus->body ()->length_mom ();
 
-      if (!repmus->volta_fold_b_)
+      if (!volta_b_)
        done_count_ ++;
      
       if (gh_pair_p (alternative_cons_))
        {
-         current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
+         current_iter_p_ = get_iterator_p (unsmob_music (ly_car (alternative_cons_)));
          do_main_b_ = false;
 
-         if (repmus->volta_fold_b_)
+         if (volta_b_)
            {
-             String repstr = to_str (done_count_ + 1);
+             String repstr = to_str (done_count_ + 1) + ".";
+
+             /*
+               we're coming in from main, so we're always on the first repeat.
+              */
+             assert (done_count_ == 0);
+
+             if (done_count_ == 0
+                 && alternative_count_i_ < repmus->repeat_count ())
+               {
+                 done_count_ += repmus->repeat_count () - alternative_count_i_;                  
+                 repstr = "1.--" + to_str (done_count_ + 1) + ".";               
+               }                 
+             
              if (do_repcommands)
-               add_repeat_command (gh_list (ly_symbol2scm ("volta"),
-                                            ly_str02scm (repstr.ch_C()), SCM_UNDEFINED));
+               add_repeat_command (scm_list_n (ly_symbol2scm ("volta"),
+                                            ly_str02scm (repstr.ch_C ()), SCM_UNDEFINED));
            }     
        }
-      else if (done_count_ <  repmus->repeats_i_ && !repmus->volta_fold_b_) 
+      else if (volta_b_)
+       {
+         add_repeat_command (ly_symbol2scm ("end-repeat"));
+       }
+      else if (done_count_ <  repmus->repeat_count ())
        {
          current_iter_p_ = get_iterator_p (repmus->body ());
          do_main_b_ = true;
@@ -93,21 +192,21 @@ Unfolded_repeat_iterator::next_element (bool side_effect)
        */
       if (alternative_cons_)
        {
-         here_mom_ += unsmob_music (gh_car (alternative_cons_))->length_mom ();
+         here_mom_ += unsmob_music (ly_car (alternative_cons_))->length_mom ();
 
-         if (repmus->volta_fold_b_ || 
-             repmus->repeats_i_ - done_count_  < alternative_count_i_)
-           alternative_cons_ = gh_cdr (alternative_cons_);
+         if (volta_b_ || 
+             repmus->repeat_count () - done_count_  < alternative_count_i_)
+           alternative_cons_ = ly_cdr (alternative_cons_);
          
          if (do_repcommands)
-           add_repeat_command (gh_list (ly_symbol2scm ("volta"), SCM_BOOL_F, SCM_UNDEFINED));
+           add_repeat_command (scm_list_n (ly_symbol2scm ("volta"), SCM_BOOL_F, SCM_UNDEFINED));
 
          
          
          /*
            we've done the main body as well, but didn't go over the other
            increment.  */
-         if (repmus->volta_fold_b_)
+         if (volta_b_)
            done_count_ ++;
        }
 
@@ -119,19 +218,19 @@ Unfolded_repeat_iterator::next_element (bool side_effect)
        if we're full unfold: go back to main body.
        */
       
-      if (done_count_ < repmus->repeats_i_ && gh_pair_p (alternative_cons_))
+      if (done_count_ < repmus->repeat_count () && gh_pair_p (alternative_cons_))
        {
          if (do_repcommands)
            {
-             String repstr = to_str (done_count_ + 1);
-             add_repeat_command (gh_list (ly_symbol2scm ("volta"),
-                                          ly_str02scm (repstr.ch_C()), SCM_UNDEFINED));
+             String repstr = to_str (done_count_ + 1) + ".";
+             add_repeat_command (scm_list_n (ly_symbol2scm ("volta"),
+                                          ly_str02scm (repstr.ch_C ()), SCM_UNDEFINED));
              add_repeat_command (ly_symbol2scm ("end-repeat"));
            }
 
          
-         if (repmus->volta_fold_b_)
-           current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
+         if (volta_b_)
+           current_iter_p_ = get_iterator_p (unsmob_music (ly_car (alternative_cons_)));
          else
            {
              current_iter_p_ = get_iterator_p (repmus->body ());
@@ -145,7 +244,7 @@ Unfolded_repeat_iterator::next_element (bool side_effect)
 bool
 Unfolded_repeat_iterator::ok () const
 {
-  return current_iter_p_ ;
+  return current_iter_p_;
 }
 
 Moment
@@ -157,13 +256,13 @@ Unfolded_repeat_iterator::pending_moment () const
 void
 Unfolded_repeat_iterator::construct_children ()
 {
-  Repeated_music * mus =dynamic_cast<Repeated_music *> (music_l_);
+  Repeated_music * mus =dynamic_cast<Repeated_music *> (music_l ());
   
   alternative_cons_ = (mus->alternatives ())
-    ? mus->alternatives ()->music_list ()
+    ? mus->alternatives ()
     : SCM_EOL;
 
-  for (SCM p = alternative_cons_; gh_pair_p (p); p = gh_cdr (p))
+  for (SCM p = alternative_cons_; gh_pair_p (p); p = ly_cdr (p))
     alternative_count_i_ ++;
 
   if (mus->body ())
@@ -173,39 +272,47 @@ Unfolded_repeat_iterator::construct_children ()
     }
   else if (gh_pair_p (alternative_cons_))
     {
-      current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
+      current_iter_p_ = get_iterator_p (unsmob_music (ly_car (alternative_cons_)));
       do_main_b_ = false;
     }
+
+  while (current_iter_p_ && !current_iter_p_-> ok ())
+    {
+      next_element (true);
+    }
 }
 
+/*
+  TODO: add source information for debugging
+ */
 void
 Unfolded_repeat_iterator::add_repeat_command (SCM what)
 {
   SCM reps = ly_symbol2scm ("repeatCommands");
-  SCM current_reps = report_to_l ()->get_property(reps);
+  SCM current_reps = report_to_l ()->get_property (reps);
 
   Translator_group * where = report_to_l ()->where_defined (reps);
   if (where
       && current_reps == SCM_EOL || gh_pair_p (current_reps))
     {
       current_reps = gh_cons (what, current_reps);
-      where->set_property (reps, current_reps);
+      where->internal_set_property (reps, current_reps);
     }
 }
 
 void
 Unfolded_repeat_iterator::process (Moment m) 
 {
-  if (!m)
+  if (!m.to_bool ())
     {
-      if (dynamic_cast<Repeated_music*> (music_l_)->volta_fold_b_)
+      if (volta_b_)
        add_repeat_command (ly_symbol2scm ("start-repeat"));
     }
   while (1)
     {
       while (!current_iter_p_->ok ())
        {
-         next_element(true);
+         next_element (true);
 
          if (!current_iter_p_)
            return;
@@ -253,8 +360,8 @@ Unfolded_repeat_iterator::get_music (Moment until)const
       s = gh_append2 (nm, s);
       
       Moment m = 0;
-      for (SCM i = nm; gh_pair_p(i); i = gh_cdr (i))
-       m = m >? unsmob_music (gh_car (i))->length_mom ();
+      for (SCM i = nm; gh_pair_p (i); i = ly_cdr (i))
+       m = m >? unsmob_music (ly_car (i))->length_mom ();
 
       if (m > Moment (0))
        break ;
@@ -273,3 +380,11 @@ Unfolded_repeat_iterator::try_music_in_children (Music  * m) const
 {
   return  current_iter_p_->try_music (m);
 }
+
+IMPLEMENT_CTOR_CALLBACK (Unfolded_repeat_iterator);
+IMPLEMENT_CTOR_CALLBACK (Volta_repeat_iterator);
+
+Volta_repeat_iterator::Volta_repeat_iterator ()
+{
+  volta_b_ = true;
+}