X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fsimultaneous-music-iterator.cc;h=1ce849077233686a24350c7bbcf1672588f4827f;hb=47db9a3883d726ca53e2133a3b2298f78dd6a32e;hp=3723c2695fe238ecf31a8d2f00e35df621e8d7e5;hpb=1c846b2c2348b4e0ca4a3c2e8fb267047ba2d203;p=lilypond.git diff --git a/lily/simultaneous-music-iterator.cc b/lily/simultaneous-music-iterator.cc index 3723c2695f..1ce8490772 100644 --- a/lily/simultaneous-music-iterator.cc +++ b/lily/simultaneous-music-iterator.cc @@ -1,7 +1,7 @@ /* This file is part of LilyPond, the GNU music typesetter. - Copyright (C) 1997--2011 Han-Wen Nienhuys + Copyright (C) 1997--2015 Han-Wen Nienhuys LilyPond is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -39,7 +39,7 @@ void Simultaneous_music_iterator::derived_substitute (Context *f, Context *t) { for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s)) - unsmob_iterator (scm_car (s))->substitute_outlet (f, t); + Music_iterator::unsmob (scm_car (s))->substitute_outlet (f, t); } void @@ -53,52 +53,79 @@ Simultaneous_music_iterator::construct_children () SCM *tail = &children_list_; for (; scm_is_pair (i); i = scm_cdr (i), j++) { - Music *mus = unsmob_music (scm_car (i)); + Music *mus = Music::unsmob (scm_car (i)); SCM scm_iter = get_static_get_iterator (mus); - Music_iterator *mi = unsmob_iterator (scm_iter); + Music_iterator *mi = Music_iterator::unsmob (scm_iter); /* if create_separate_contexts_ is set, create a new context with the - number number as name */ + number number as name */ 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 (); + ? get_outlet ()->find_create_context (name, ::to_string (j), SCM_EOL) + : get_outlet (); if (!c) - c = get_outlet (); + c = get_outlet (); mi->init_context (mus, c); mi->construct_children (); if (mi->ok ()) - { - *tail = scm_cons (scm_iter, *tail); - tail = SCM_CDRLOC (*tail); - } + { + *tail = scm_cons (scm_iter, *tail); + tail = SCM_CDRLOC (*tail); + } else - mi->quit (); + mi->quit (); } } +// If there are non-run-always iterators and all of them die, take the +// rest of them along. void Simultaneous_music_iterator::process (Moment until) { + bool had_good = false; + bool had_bad = false; SCM *proc = &children_list_; while (scm_is_pair (*proc)) { - Music_iterator *i = unsmob_iterator (scm_car (*proc)); - if (i->run_always () - || i->pending_moment () == until) - i->process (until); + Music_iterator *i = Music_iterator::unsmob (scm_car (*proc)); + bool run_always = i->run_always (); + if (run_always || i->pending_moment () == until) + i->process (until); if (!i->ok ()) - { - i->quit (); - *proc = scm_cdr (*proc); - } + { + if (!run_always) + had_bad = true; + i->quit (); + *proc = scm_cdr (*proc); + } else - proc = SCM_CDRLOC (*proc); + { + if (!run_always) + had_good = true; + proc = SCM_CDRLOC (*proc); + } + } + // If there were non-run-always iterators and all of them died, take + // the rest of the run-always iterators along with them. They have + // likely lost their reference iterators. Basing this on the actual + // music contexts is not reliable since something like + // \new Voice = blah { + // << \context Voice = blah { c4 d } + // \addlyrics { oh no } + // >> e f + // } + // cannot wait for the death of context blah before ending the + // simultaneous iterator. + if (had_bad && !had_good) + { + for (SCM p = children_list_; scm_is_pair (p); p = scm_cdr (p)) + Music_iterator::unsmob (scm_car (p))->quit (); + children_list_ = SCM_EOL; } } @@ -110,7 +137,7 @@ Simultaneous_music_iterator::pending_moment () const for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s)) { - Music_iterator *it = unsmob_iterator (scm_car (s)); + Music_iterator *it = Music_iterator::unsmob (scm_car (s)); next = min (next, it->pending_moment ()); } @@ -123,11 +150,11 @@ Simultaneous_music_iterator::ok () const bool run_always_ok = false; for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s)) { - Music_iterator *it = unsmob_iterator (scm_car (s)); + Music_iterator *it = Music_iterator::unsmob (scm_car (s)); if (!it->run_always ()) - return true; + return true; else - run_always_ok = run_always_ok || it->ok (); + run_always_ok = run_always_ok || it->ok (); } return run_always_ok; } @@ -137,9 +164,9 @@ Simultaneous_music_iterator::run_always () const { for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s)) { - Music_iterator *it = unsmob_iterator (scm_car (s)); + Music_iterator *it = Music_iterator::unsmob (scm_car (s)); if (it->run_always ()) - return true; + return true; } return false; } @@ -148,7 +175,7 @@ void Simultaneous_music_iterator::do_quit () { for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s)) - unsmob_iterator (scm_car (s))->quit (); + Music_iterator::unsmob (scm_car (s))->quit (); } IMPLEMENT_CTOR_CALLBACK (Simultaneous_music_iterator);