2 Sequential_music_iterator.cc -- implement Sequential_music_iterator
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 #include "grace-iterator.hh"
9 #include "translator-group.hh"
11 #include "sequential-music-iterator.hh"
12 #include "music-list.hh"
13 #include "request-chord-iterator.hh"
16 Invariant for the data structure.
19 if (gh_pair_p (cursor_))
20 iter_p_->music_l_ == unsmob_music (gh_car (cursor_))
24 The length of musiclist from start to up to cursor_ (cursor_ not
27 here_mom_ = sum (length (musiclist [start ... cursor>)) %)
32 Sequential_music_iterator::Sequential_music_iterator ()
35 here_mom_ = Moment (0);
40 Sequential_music_iterator::Sequential_music_iterator (Sequential_music_iterator const &src)
41 : Music_iterator (src)
43 grace_skips_ = src.grace_skips_;
44 cursor_ = src.cursor_;
45 here_mom_ = src.here_mom_;
47 iter_p_ = src.iter_p_->clone ();
52 Sequential_music_iterator::~Sequential_music_iterator ()
59 get_grace_skips (SCM cursor)
64 Grace_skip **tail = &head;
68 for (; gh_pair_p (cursor); cursor = gh_cdr (cursor))
70 Music * mus = unsmob_music (gh_car (cursor));
71 Moment l =mus->length_mom ();
78 else if(l.grace_mom_ && !first)
80 assert (!l.main_part_);
81 Grace_skip *p =new Grace_skip;
83 p->length_ = (here - last).main_part_;
84 p->grace_length_ = l.grace_mom_;
87 tail = &(*tail)->next_;
94 Sequential_music_iterator::construct_children ()
96 cursor_ = dynamic_cast<Music_sequence const*> (music_l ())->music_list ();
98 iter_p_ = gh_pair_p (cursor_) ? get_iterator_p (unsmob_music (gh_car (cursor_))) : 0;
99 while (iter_p_ && !iter_p_->ok ())
104 grace_skips_ = get_grace_skips (cursor_);
106 here_mom_ = music_l ()->start_mom ();
109 iter_p_->ok () is tautology, but what the heck.
111 if (iter_p_ && iter_p_->ok ())
117 maintain invariants: change cursor, iter and here_mom_ in one fell
121 Sequential_music_iterator::next_element ()
123 Moment len =iter_p_->music_length_mom ();
124 Moment start = iter_p_->music_start_mom ();
125 assert (!grace_skips_ || grace_skips_->start_ >= here_mom_);
127 if (len.main_part_ && grace_skips_ && grace_skips_->start_ == here_mom_)
130 sk.main_part_ = grace_skips_->length_;
132 here_mom_.grace_mom_ = - grace_skips_->grace_length_;
134 Grace_skip * n =grace_skips_->next_;
138 else if (len.grace_mom_)
140 here_mom_.grace_mom_ =0;
144 here_mom_ += len - start;
148 cursor_ = gh_cdr (cursor_);
150 if (gh_pair_p (cursor_))
151 iter_p_ = get_iterator_p (unsmob_music (gh_car (cursor_)));
157 move to context of child iterator if it is deeper down in the
162 Sequential_music_iterator::descend_to_child ()
164 Translator_group * child_report = child_report = iter_p_->report_to_l ();
165 Translator_group * me_report = report_to_l ();
167 if (dynamic_cast<Grace_iterator*> (iter_p_))
168 child_report = child_report->daddy_trans_l_;
170 Translator_group * c = child_report;
171 while (c && c != me_report)
173 c= c->daddy_trans_l_;
177 set_translator (child_report);
182 Retrieve all music (starting at HERE), until a music with length L >
183 0 is found. From the precondition, we know that UNTIL is later than
184 the earliest event. Hence we know
188 so something that comes after this thing with L > 0 happens after
190 HERE + L >= HERE + (UNTIL - HERE) = UNTIL
192 Hence all events after the one with L>0 are uninteresting, so we
198 Sequential_music_iterator::get_music (Moment until)const
201 if (until < pending_moment ())
204 Sequential_music_iterator * me =
205 dynamic_cast<Sequential_music_iterator*> (clone ());
208 SCM nm = me->iter_p_->get_music (until - me->here_mom_);
209 s = gh_append2 (nm, s);
212 for (SCM i = nm; gh_pair_p (i); i = gh_cdr (i))
213 m = m >? unsmob_music (gh_car (i))->length_mom ();
225 Skip events till UNTIL. We don't do any other side effects such as
226 descending to child iterator contexts, because they might depend on
227 \context specs and \translator changes being executed
231 Sequential_music_iterator::skip (Moment until)
235 Moment l =iter_p_->music_length_mom ();
236 if (l >= until - here_mom_)
237 iter_p_->skip (until - here_mom_);
247 Sequential_music_iterator::process (Moment until)
252 grace_skips_->start_ == here_mom_
253 && (grace_skips_->start_ + grace_skips_->length_).main_part_ ==
257 do the stuff/note/rest preceding a grace.
261 iter_p_->process (u - here_mom_);
264 iter_p_->process (until - here_mom_ + iter_p_->music_start_mom ());
267 if the iter is still OK, there must be events left that have
281 Sequential_music_iterator::pending_moment () const
283 Moment cp = iter_p_->pending_moment ();
286 && here_mom_ == grace_skips_->start_
287 && cp.main_part_ >= grace_skips_->length_)
290 cp.grace_mom_ = - grace_skips_->grace_length_;
294 return cp + here_mom_ - iter_p_->music_start_mom ();
299 Sequential_music_iterator::ok () const
305 Sequential_music_iterator::try_music_in_children (Music *m) const
307 return iter_p_ ? iter_p_->try_music (m) : 0;
309 IMPLEMENT_CTOR_CALLBACK (Sequential_music_iterator);