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 ()
28 alternative_count_i_ =0;
33 If we are in the body of the repeat always go to the current alternative.
35 If we are not in the body, then we are in an alternative. If we are
36 fully unfolding, advance the current alternative and go back to main.
37 If we are semi-unfolding, advance the current alternative, and go to
38 the alternative just set.
42 Unfolded_repeat_iterator::next_element (bool side_effect)
44 Repeated_music * repmus =dynamic_cast<Repeated_music *> (music_l_);
45 delete current_iter_p_;
48 bool do_repcommands = side_effect && volta_b_;
53 we were busy doing the main body, so
55 - go to alternative if we're a volta
57 - make a :| if there are no alternatives
59 - do something intelligent when we're fully unfolding (fixcomment)
62 here_mom_ += repmus->body ()->length_mom ();
67 if (gh_pair_p (alternative_cons_))
69 current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
74 String repstr = to_str (done_count_ + 1);
76 add_repeat_command (gh_list (ly_symbol2scm ("volta"),
77 ly_str02scm (repstr.ch_C()), SCM_UNDEFINED));
82 add_repeat_command (ly_symbol2scm ("end-repeat"));
84 else if (done_count_ < repmus->repeat_count ())
86 current_iter_p_ = get_iterator_p (repmus->body ());
93 we're not in the main part. So we're either in an alternative, or
98 we're in the alternatives. We move the pointer to the
101 if (alternative_cons_)
103 here_mom_ += unsmob_music (gh_car (alternative_cons_))->length_mom ();
106 repmus->repeat_count () - done_count_ < alternative_count_i_)
107 alternative_cons_ = gh_cdr (alternative_cons_);
110 add_repeat_command (gh_list (ly_symbol2scm ("volta"), SCM_BOOL_F, SCM_UNDEFINED));
115 we've done the main body as well, but didn't go over the other
122 We still have alternatives left, so
124 if we're volta: traverse them
126 if we're full unfold: go back to main body.
129 if (done_count_ < repmus->repeat_count () && gh_pair_p (alternative_cons_))
133 String repstr = to_str (done_count_ + 1);
134 add_repeat_command (gh_list (ly_symbol2scm ("volta"),
135 ly_str02scm (repstr.ch_C()), SCM_UNDEFINED));
136 add_repeat_command (ly_symbol2scm ("end-repeat"));
141 current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
144 current_iter_p_ = get_iterator_p (repmus->body ());
153 Unfolded_repeat_iterator::ok () const
155 return current_iter_p_ ;
159 Unfolded_repeat_iterator::pending_moment () const
161 return here_mom_ + current_iter_p_->pending_moment ();
165 Unfolded_repeat_iterator::construct_children ()
167 Repeated_music * mus =dynamic_cast<Repeated_music *> (music_l_);
169 alternative_cons_ = (mus->alternatives ())
170 ? mus->alternatives ()->music_list ()
173 for (SCM p = alternative_cons_; gh_pair_p (p); p = gh_cdr (p))
174 alternative_count_i_ ++;
178 current_iter_p_ = get_iterator_p (mus->body ());
181 else if (gh_pair_p (alternative_cons_))
183 current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
189 TODO: add source information for debugging
192 Unfolded_repeat_iterator::add_repeat_command (SCM what)
194 SCM reps = ly_symbol2scm ("repeatCommands");
195 SCM current_reps = report_to_l ()->get_property(reps);
197 Translator_group * where = report_to_l ()->where_defined (reps);
199 && current_reps == SCM_EOL || gh_pair_p (current_reps))
201 current_reps = gh_cons (what, current_reps);
202 where->set_property (reps, current_reps);
207 Unfolded_repeat_iterator::process (Moment m)
212 add_repeat_command (ly_symbol2scm ("start-repeat"));
216 while (!current_iter_p_->ok ())
220 if (!current_iter_p_)
224 if (m - here_mom_ >= current_iter_p_->pending_moment ())
225 current_iter_p_->process (m - here_mom_);
232 Unfolded_repeat_iterator::skip (Moment until)
234 while (current_iter_p_)
236 Moment l =current_iter_p_->music_length_mom ();
237 if (l >= until - here_mom_)
238 current_iter_p_->skip (until - here_mom_);
240 if (current_iter_p_->ok ())
243 next_element (false);
248 Unfolded_repeat_iterator::get_music (Moment until)const
251 if (until < pending_moment ())
255 Unfolded_repeat_iterator * me
256 = dynamic_cast<Unfolded_repeat_iterator*> (this->clone ());
260 SCM nm = me->current_iter_p_->get_music (until -
263 s = gh_append2 (nm, s);
266 for (SCM i = nm; gh_pair_p(i); i = gh_cdr (i))
267 m = m >? unsmob_music (gh_car (i))->length_mom ();
272 me->next_element (false);
282 Unfolded_repeat_iterator::try_music_in_children (Music * m) const
284 return current_iter_p_->try_music (m);
287 IMPLEMENT_CTOR_CALLBACK(Unfolded_repeat_iterator);
288 IMPLEMENT_CTOR_CALLBACK(Volta_repeat_iterator);
290 Volta_repeat_iterator::Volta_repeat_iterator ()