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 - make a :| if there are no alternatives
58 - do something intelligent when we're fully unfolding (fixcomment)
61 here_mom_ += repmus->body ()->length_mom ();
63 if (!repmus->volta_fold_b_)
66 if (gh_pair_p (alternative_cons_))
68 current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
71 if (repmus->volta_fold_b_)
73 String repstr = to_str (done_count_ + 1);
75 add_repeat_command (gh_list (ly_symbol2scm ("volta"),
76 ly_str02scm (repstr.ch_C()), SCM_UNDEFINED));
79 else if (repmus->volta_fold_b_)
81 add_repeat_command (ly_symbol2scm ("end-repeat"));
83 else if (done_count_ < repmus->repeats_i_)
85 current_iter_p_ = get_iterator_p (repmus->body ());
92 we're not in the main part. So we're either in an alternative, or
97 we're in the alternatives. We move the pointer to the
100 if (alternative_cons_)
102 here_mom_ += unsmob_music (gh_car (alternative_cons_))->length_mom ();
104 if (repmus->volta_fold_b_ ||
105 repmus->repeats_i_ - done_count_ < alternative_count_i_)
106 alternative_cons_ = gh_cdr (alternative_cons_);
109 add_repeat_command (gh_list (ly_symbol2scm ("volta"), SCM_BOOL_F, SCM_UNDEFINED));
114 we've done the main body as well, but didn't go over the other
116 if (repmus->volta_fold_b_)
121 We still have alternatives left, so
123 if we're volta: traverse them
125 if we're full unfold: go back to main body.
128 if (done_count_ < repmus->repeats_i_ && gh_pair_p (alternative_cons_))
132 String repstr = to_str (done_count_ + 1);
133 add_repeat_command (gh_list (ly_symbol2scm ("volta"),
134 ly_str02scm (repstr.ch_C()), SCM_UNDEFINED));
135 add_repeat_command (ly_symbol2scm ("end-repeat"));
139 if (repmus->volta_fold_b_)
140 current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
143 current_iter_p_ = get_iterator_p (repmus->body ());
152 Unfolded_repeat_iterator::ok () const
154 return current_iter_p_ ;
158 Unfolded_repeat_iterator::pending_moment () const
160 return here_mom_ + current_iter_p_->pending_moment ();
164 Unfolded_repeat_iterator::construct_children ()
166 Repeated_music * mus =dynamic_cast<Repeated_music *> (music_l_);
168 alternative_cons_ = (mus->alternatives ())
169 ? mus->alternatives ()->music_list ()
172 for (SCM p = alternative_cons_; gh_pair_p (p); p = gh_cdr (p))
173 alternative_count_i_ ++;
177 current_iter_p_ = get_iterator_p (mus->body ());
180 else if (gh_pair_p (alternative_cons_))
182 current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
188 TODO: add source information for debugging
191 Unfolded_repeat_iterator::add_repeat_command (SCM what)
193 SCM reps = ly_symbol2scm ("repeatCommands");
194 SCM current_reps = report_to_l ()->get_property(reps);
196 Translator_group * where = report_to_l ()->where_defined (reps);
198 && current_reps == SCM_EOL || gh_pair_p (current_reps))
200 current_reps = gh_cons (what, current_reps);
201 where->set_property (reps, current_reps);
206 Unfolded_repeat_iterator::process (Moment m)
210 if (dynamic_cast<Repeated_music*> (music_l_)->volta_fold_b_)
211 add_repeat_command (ly_symbol2scm ("start-repeat"));
215 while (!current_iter_p_->ok ())
219 if (!current_iter_p_)
223 if (m - here_mom_ >= current_iter_p_->pending_moment ())
224 current_iter_p_->process (m - here_mom_);
231 Unfolded_repeat_iterator::skip (Moment until)
233 while (current_iter_p_)
235 Moment l =current_iter_p_->music_length_mom ();
236 if (l >= until - here_mom_)
237 current_iter_p_->skip (until - here_mom_);
239 if (current_iter_p_->ok ())
242 next_element (false);
247 Unfolded_repeat_iterator::get_music (Moment until)const
250 if (until < pending_moment ())
254 Unfolded_repeat_iterator * me
255 = dynamic_cast<Unfolded_repeat_iterator*> (this->clone ());
259 SCM nm = me->current_iter_p_->get_music (until -
262 s = gh_append2 (nm, s);
265 for (SCM i = nm; gh_pair_p(i); i = gh_cdr (i))
266 m = m >? unsmob_music (gh_car (i))->length_mom ();
271 me->next_element (false);
281 Unfolded_repeat_iterator::try_music_in_children (Music * m) const
283 return current_iter_p_->try_music (m);