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 (Unfolded_repeat_iterator const &src)
23 : Music_iterator (src)
25 done_count_ = src.done_count_;
26 current_iter_p_ = (src.current_iter_p_)? src.current_iter_p_->clone () : 0;
27 do_main_b_ = src.do_main_b_;
28 volta_b_ = src.volta_b_;
29 alternative_count_i_ = src.alternative_count_i_;
30 alternative_cons_ = src.alternative_cons_;
33 Unfolded_repeat_iterator::Unfolded_repeat_iterator ()
39 alternative_count_i_ =0;
40 alternative_cons_ = SCM_EOL;
45 If we are in the body of the repeat always go to the current alternative.
47 If we are not in the body, then we are in an alternative. If we are
48 fully unfolding, advance the current alternative and go back to main.
49 If we are semi-unfolding, advance the current alternative, and go to
50 the alternative just set.
54 Unfolded_repeat_iterator::next_element (bool side_effect)
56 Repeated_music * repmus =dynamic_cast<Repeated_music *> (music_l_);
57 delete current_iter_p_;
60 bool do_repcommands = side_effect && volta_b_;
65 we were busy doing the main body, so
67 - go to alternative if we're a volta
69 - make a :| if there are no alternatives
71 - do something intelligent when we're fully unfolding (fixcomment)
74 here_mom_ += repmus->body ()->length_mom ();
79 if (gh_pair_p (alternative_cons_))
81 current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
86 String repstr = to_str (done_count_ + 1);
88 add_repeat_command (gh_list (ly_symbol2scm ("volta"),
89 ly_str02scm (repstr.ch_C()), SCM_UNDEFINED));
94 add_repeat_command (ly_symbol2scm ("end-repeat"));
96 else if (done_count_ < repmus->repeat_count ())
98 current_iter_p_ = get_iterator_p (repmus->body ());
105 we're not in the main part. So we're either in an alternative, or
110 we're in the alternatives. We move the pointer to the
113 if (alternative_cons_)
115 here_mom_ += unsmob_music (gh_car (alternative_cons_))->length_mom ();
118 repmus->repeat_count () - done_count_ < alternative_count_i_)
119 alternative_cons_ = gh_cdr (alternative_cons_);
122 add_repeat_command (gh_list (ly_symbol2scm ("volta"), SCM_BOOL_F, SCM_UNDEFINED));
127 we've done the main body as well, but didn't go over the other
134 We still have alternatives left, so
136 if we're volta: traverse them
138 if we're full unfold: go back to main body.
141 if (done_count_ < repmus->repeat_count () && gh_pair_p (alternative_cons_))
145 String repstr = to_str (done_count_ + 1);
146 add_repeat_command (gh_list (ly_symbol2scm ("volta"),
147 ly_str02scm (repstr.ch_C()), SCM_UNDEFINED));
148 add_repeat_command (ly_symbol2scm ("end-repeat"));
153 current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
156 current_iter_p_ = get_iterator_p (repmus->body ());
165 Unfolded_repeat_iterator::ok () const
167 return current_iter_p_ ;
171 Unfolded_repeat_iterator::pending_moment () const
173 return here_mom_ + current_iter_p_->pending_moment ();
177 Unfolded_repeat_iterator::construct_children ()
179 Repeated_music * mus =dynamic_cast<Repeated_music *> (music_l_);
181 alternative_cons_ = (mus->alternatives ())
182 ? mus->alternatives ()->music_list ()
185 for (SCM p = alternative_cons_; gh_pair_p (p); p = gh_cdr (p))
186 alternative_count_i_ ++;
190 current_iter_p_ = get_iterator_p (mus->body ());
193 else if (gh_pair_p (alternative_cons_))
195 current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
201 TODO: add source information for debugging
204 Unfolded_repeat_iterator::add_repeat_command (SCM what)
206 SCM reps = ly_symbol2scm ("repeatCommands");
207 SCM current_reps = report_to_l ()->get_property(reps);
209 Translator_group * where = report_to_l ()->where_defined (reps);
211 && current_reps == SCM_EOL || gh_pair_p (current_reps))
213 current_reps = gh_cons (what, current_reps);
214 where->set_property (reps, current_reps);
219 Unfolded_repeat_iterator::process (Moment m)
224 add_repeat_command (ly_symbol2scm ("start-repeat"));
228 while (!current_iter_p_->ok ())
232 if (!current_iter_p_)
236 if (m - here_mom_ >= current_iter_p_->pending_moment ())
237 current_iter_p_->process (m - here_mom_);
244 Unfolded_repeat_iterator::skip (Moment until)
246 while (current_iter_p_)
248 Moment l =current_iter_p_->music_length_mom ();
249 if (l >= until - here_mom_)
250 current_iter_p_->skip (until - here_mom_);
252 if (current_iter_p_->ok ())
255 next_element (false);
260 Unfolded_repeat_iterator::get_music (Moment until)const
263 if (until < pending_moment ())
267 Unfolded_repeat_iterator * me
268 = dynamic_cast<Unfolded_repeat_iterator*> (this->clone ());
272 SCM nm = me->current_iter_p_->get_music (until -
275 s = gh_append2 (nm, s);
278 for (SCM i = nm; gh_pair_p(i); i = gh_cdr (i))
279 m = m >? unsmob_music (gh_car (i))->length_mom ();
284 me->next_element (false);
294 Unfolded_repeat_iterator::try_music_in_children (Music * m) const
296 return current_iter_p_->try_music (m);
299 IMPLEMENT_CTOR_CALLBACK(Unfolded_repeat_iterator);
300 IMPLEMENT_CTOR_CALLBACK(Volta_repeat_iterator);
302 Volta_repeat_iterator::Volta_repeat_iterator ()