2 unfolded-repeat-iterator.cc -- implement Unfolded_repeat_iterator
4 source file of the GNU LilyPond music typesetter
6 (c) 1999--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
11 #include "repeated-music.hh"
12 #include "music-list.hh"
13 #include "unfolded-repeat-iterator.hh"
15 #include "translator-group.hh"
17 Unfolded_repeat_iterator::~Unfolded_repeat_iterator ()
19 delete current_iter_p_;
22 Unfolded_repeat_iterator::Unfolded_repeat_iterator ()
27 alternative_count_i_ =0;
32 If we are in the body of the repeat always go to the current alternative.
34 If we are not in the body, then we are in an alternative. If we are
35 fully unfolding, advance the current alternative and go back to main.
36 If we are semi-unfolding, advance the current alternative, and go to
37 the alternative just set.
41 Unfolded_repeat_iterator::next_element (bool side_effect)
43 Repeated_music * repmus =dynamic_cast<Repeated_music *> (music_l_);
44 delete current_iter_p_;
47 bool do_repcommands = side_effect && repmus->volta_fold_b_;
52 we were busy doing the main body, so
54 - go to alternative if we're a volta
56 - do something intelligent when we're fully unfolding (fixcomment)
59 here_mom_ += repmus->body ()->length_mom ();
61 if (!repmus->volta_fold_b_)
64 if (gh_pair_p (alternative_cons_))
66 current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
69 if (repmus->volta_fold_b_)
71 String repstr = to_str (done_count_ + 1);
73 add_repeat_command (gh_list (ly_symbol2scm ("volta"),
74 ly_str02scm (repstr.ch_C()), SCM_UNDEFINED));
77 else if (done_count_ < repmus->repeats_i_ && !repmus->volta_fold_b_)
79 current_iter_p_ = get_iterator_p (repmus->body ());
86 we're not in the main part. So we're either in an alternative, or
91 we're in the alternatives. We move the pointer to the
94 if (alternative_cons_)
96 here_mom_ += unsmob_music (gh_car (alternative_cons_))->length_mom ();
98 if (repmus->volta_fold_b_ ||
99 repmus->repeats_i_ - done_count_ < alternative_count_i_)
100 alternative_cons_ = gh_cdr (alternative_cons_);
103 add_repeat_command (gh_list (ly_symbol2scm ("volta"), SCM_BOOL_F, SCM_UNDEFINED));
108 we've done the main body as well, but didn't go over the other
110 if (repmus->volta_fold_b_)
115 We still have alternatives left, so
117 if we're volta: traverse them
119 if we're full unfold: go back to main body.
122 if (done_count_ < repmus->repeats_i_ && gh_pair_p (alternative_cons_))
126 String repstr = to_str (done_count_ + 1);
127 add_repeat_command (gh_list (ly_symbol2scm ("volta"),
128 ly_str02scm (repstr.ch_C()), SCM_UNDEFINED));
129 add_repeat_command (ly_symbol2scm ("end-repeat"));
133 if (repmus->volta_fold_b_)
134 current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
137 current_iter_p_ = get_iterator_p (repmus->body ());
146 Unfolded_repeat_iterator::ok () const
148 return current_iter_p_ ;
152 Unfolded_repeat_iterator::pending_moment () const
154 return here_mom_ + current_iter_p_->pending_moment ();
158 Unfolded_repeat_iterator::construct_children ()
160 Repeated_music * mus =dynamic_cast<Repeated_music *> (music_l_);
162 alternative_cons_ = (mus->alternatives ())
163 ? mus->alternatives ()->music_list ()
166 for (SCM p = alternative_cons_; gh_pair_p (p); p = gh_cdr (p))
167 alternative_count_i_ ++;
171 current_iter_p_ = get_iterator_p (mus->body ());
174 else if (gh_pair_p (alternative_cons_))
176 current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
182 TODO: add source information for debugging
185 Unfolded_repeat_iterator::add_repeat_command (SCM what)
187 SCM reps = ly_symbol2scm ("repeatCommands");
188 SCM current_reps = report_to_l ()->get_property(reps);
190 Translator_group * where = report_to_l ()->where_defined (reps);
192 && current_reps == SCM_EOL || gh_pair_p (current_reps))
194 current_reps = gh_cons (what, current_reps);
195 where->set_property (reps, current_reps);
200 Unfolded_repeat_iterator::process (Moment m)
204 if (dynamic_cast<Repeated_music*> (music_l_)->volta_fold_b_)
205 add_repeat_command (ly_symbol2scm ("start-repeat"));
209 while (!current_iter_p_->ok ())
213 if (!current_iter_p_)
217 if (m - here_mom_ >= current_iter_p_->pending_moment ())
218 current_iter_p_->process (m - here_mom_);
225 Unfolded_repeat_iterator::skip (Moment until)
227 while (current_iter_p_)
229 Moment l =current_iter_p_->music_length_mom ();
230 if (l >= until - here_mom_)
231 current_iter_p_->skip (until - here_mom_);
233 if (current_iter_p_->ok ())
236 next_element (false);
241 Unfolded_repeat_iterator::get_music (Moment until)const
244 if (until < pending_moment ())
248 Unfolded_repeat_iterator * me
249 = dynamic_cast<Unfolded_repeat_iterator*> (this->clone ());
253 SCM nm = me->current_iter_p_->get_music (until -
256 s = gh_append2 (nm, s);
259 for (SCM i = nm; gh_pair_p(i); i = gh_cdr (i))
260 m = m >? unsmob_music (gh_car (i))->length_mom ();
265 me->next_element (false);
275 Unfolded_repeat_iterator::try_music_in_children (Music * m) const
277 return current_iter_p_->try_music (m);