]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/simultaneous-music-iterator.cc
unsmob_pitch -> Pitch::unsmob and related
[lilypond.git] / lily / simultaneous-music-iterator.cc
index cc246f8a48a70f3c6e3125e828f60e9d113f9f55..7f7dd0e38c9a6ea20e85112ed691f3b35141fc66 100644 (file)
@@ -1,48 +1,45 @@
 /*
-  Simultaneous_music-iterator.cc -- implement Simultaneous_music_iterator
+  This file is part of LilyPond, the GNU music typesetter.
 
-  source file of the GNU LilyPond music typesetter
+  Copyright (C) 1997--2014 Han-Wen Nienhuys <hanwen@xs4all.nl>
 
-  (c)  1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include "translator-group.hh"
-#include "warn.hh"
 #include "simultaneous-music-iterator.hh"
-#include "music-list.hh"
-#include "killing-cons.tcc"
-
+#include "music.hh"
+#include "context.hh"
+#include "warn.hh"
+#include "context-def.hh"
 
 Simultaneous_music_iterator::Simultaneous_music_iterator ()
 {
-  separate_contexts_b_ = false;
+  create_separate_contexts_ = false;
+  children_list_ = SCM_EOL;
 }
 
-Simultaneous_music_iterator::Simultaneous_music_iterator (Simultaneous_music_iterator const& src)
-  : Music_iterator (src)
-{
-  separate_contexts_b_ = src.separate_contexts_b_;
-  for (Cons<Music_iterator> *p = src.children_p_list_.head_; p; p = p->next_)
-    {
-      Music_iterator *i = p->car_;
-      children_p_list_.append (new Killing_cons<Music_iterator> (i->clone (), 0));
-    }
-}
-
-Simultaneous_music_iterator::~Simultaneous_music_iterator ()
+void
+Simultaneous_music_iterator::derived_mark () const
 {
-  children_p_list_.junk ();
+  scm_gc_mark (children_list_);
 }
 
-SCM
-Simultaneous_music_iterator::get_music (Moment m)const
+void
+Simultaneous_music_iterator::derived_substitute (Context *f, Context *t)
 {
-  SCM s = SCM_EOL;
-  for (Cons<Music_iterator> *p = children_p_list_.head_; p; p = p->next_)
-    {
-      s = gh_append2 (p->car_->get_music (m), s);
-    }
-  return s;
+  for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
+    Music_iterator::unsmob (scm_car (s))->substitute_outlet (f, t);
 }
 
 void
@@ -50,67 +47,58 @@ Simultaneous_music_iterator::construct_children ()
 {
   int j = 0;
 
-  SCM i = music_l ()->get_mus_property ("elements");
-  for (; gh_pair_p (i); i = ly_cdr (i), j++)
+  SCM i = get_music ()->get_property ("elements");
+
+  children_list_ = SCM_EOL;
+  SCM *tail = &children_list_;
+  for (; scm_is_pair (i); i = scm_cdr (i), j++)
     {
-      Music *mus = unsmob_music (ly_car (i));
-      Music_iterator * mi = static_get_iterator_p (mus);
+      Music *mus = unsmob_music (scm_car (i));
 
-      /* if separate_contexts_b_ is set, create a new context with the
-        number number as name */
-      
-      Translator_group * t = (j && separate_contexts_b_)
-       ? report_to_l ()->find_create_translator_l (report_to_l ()->type_str_,
-                                                   to_str (j))
-       : report_to_l ();
+      SCM scm_iter = get_static_get_iterator (mus);
+      Music_iterator *mi = Music_iterator::unsmob (scm_iter);
 
-      if (!t)
-       t = report_to_l ();
+      /* if create_separate_contexts_ is set, create a new context with the
+         number number as name */
 
-      mi->init_translator (mus, t);
-      mi->construct_children ();
-      
-      if (mi->ok ()) 
-       {
-         children_p_list_.append (new Killing_cons<Music_iterator> (mi,0));
-       }
-      else
-       delete mi;
-    }
-}
+      SCM name = ly_symbol2scm (get_outlet ()->context_name ().c_str ());
+      Context *c = (j && create_separate_contexts_)
+                   ? get_outlet ()->find_create_context (name, ::to_string (j), SCM_EOL)
+                   : get_outlet ();
 
+      if (!c)
+        c = get_outlet ();
 
-void
-Simultaneous_music_iterator::process (Moment until)
-{
-  for (Cons<Music_iterator> **pp = &children_p_list_.head_; *pp;)
-    {
-      Music_iterator * i = (*pp)->car_;
-      if (i->pending_moment () == until) 
-       {
-         i->process (until);
-       }
-      if (!i->ok ())
-       delete children_p_list_.remove_cons (pp);
+      mi->init_context (mus, c);
+      mi->construct_children ();
+
+      if (mi->ok ())
+        {
+          *tail = scm_cons (scm_iter, *tail);
+          tail = SCM_CDRLOC (*tail);
+        }
       else
-       pp = & (*pp)->next_;
+        mi->quit ();
     }
 }
 
 void
-Simultaneous_music_iterator::skip (Moment until)
+Simultaneous_music_iterator::process (Moment until)
 {
-  for (Cons<Music_iterator> **pp = &children_p_list_.head_; *pp;)
+  SCM *proc = &children_list_;
+  while (scm_is_pair (*proc))
     {
-      Music_iterator * i = (*pp)->car_;
-      if (i->pending_moment () <= until) 
-       {
-         i->skip (until);
-       }
+      Music_iterator *i = Music_iterator::unsmob (scm_car (*proc));
+      if (i->run_always ()
+          || i->pending_moment () == until)
+        i->process (until);
       if (!i->ok ())
-       delete children_p_list_.remove_cons (pp);
+        {
+          i->quit ();
+          *proc = scm_cdr (*proc);
+        }
       else
-       pp = & (*pp)->next_;
+        proc = SCM_CDRLOC (*proc);
     }
 }
 
@@ -119,29 +107,48 @@ Simultaneous_music_iterator::pending_moment () const
 {
   Moment next;
   next.set_infinite (1);
-  
-  for (Cons<Music_iterator> *p = children_p_list_.head_; p; p = p->next_)
-    next = next <? p->car_->pending_moment () ;
-  return next;
-}
 
+  for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
+    {
+      Music_iterator *it = Music_iterator::unsmob (scm_car (s));
+      next = min (next, it->pending_moment ());
+    }
 
+  return next;
+}
 
 bool
 Simultaneous_music_iterator::ok () const
 {
-  return children_p_list_.head_;
+  bool run_always_ok = false;
+  for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
+    {
+      Music_iterator *it = Music_iterator::unsmob (scm_car (s));
+      if (!it->run_always ())
+        return true;
+      else
+        run_always_ok = run_always_ok || it->ok ();
+    }
+  return run_always_ok;
 }
 
-Music_iterator*
-Simultaneous_music_iterator::try_music_in_children (Music *m) const
+bool
+Simultaneous_music_iterator::run_always () const
 {
-  Music_iterator * b=0;
-  for (Cons<Music_iterator> *p = children_p_list_.head_; !b && p; p = p->next_)
-    b =p->car_->try_music (m);
-  return b;
+  for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
+    {
+      Music_iterator *it = Music_iterator::unsmob (scm_car (s));
+      if (it->run_always ())
+        return true;
+    }
+  return false;
 }
 
-
+void
+Simultaneous_music_iterator::do_quit ()
+{
+  for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
+    Music_iterator::unsmob (scm_car (s))->quit ();
+}
 
 IMPLEMENT_CTOR_CALLBACK (Simultaneous_music_iterator);