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 cursor_ = src.cursor_;
44 here_mom_ = src.here_mom_;
46 iter_p_ = src.iter_p_->clone ();
51 Sequential_music_iterator::~Sequential_music_iterator()
57 Sequential_music_iterator::construct_children()
59 cursor_ = dynamic_cast<Music_sequence const*> (music_l_)->music_list ();
61 iter_p_ = gh_pair_p (cursor_) ? get_iterator_p (unsmob_music (gh_car (cursor_))) : 0;
62 while (iter_p_ && !iter_p_->ok ())
68 iter_p_->ok () is tautology, but what the heck.
70 if (iter_p_ && iter_p_->ok())
77 maintain invariants: change cursor, iter and here_mom_ in one fell
81 Sequential_music_iterator::next_element ()
83 here_mom_ += iter_p_->music_length_mom ();
85 cursor_ = gh_cdr (cursor_);
87 if (gh_pair_p (cursor_))
88 iter_p_ = get_iterator_p (unsmob_music (gh_car (cursor_)));
94 move to context of child iterator if it is deeper down in the
99 Sequential_music_iterator::descend_to_child ()
101 Translator_group * child_report = child_report = iter_p_->report_to_l ();
102 Translator_group * me_report = report_to_l ();
104 if (dynamic_cast<Grace_iterator*> (iter_p_))
105 child_report = child_report->daddy_trans_l_;
107 Translator_group * c = child_report;
108 while (c && c != me_report)
110 c= c->daddy_trans_l_;
114 set_translator (child_report);
119 Retrieve all music (starting at HERE), until a music with length L >
120 0 is found. From the precondition, we know that UNTIL is later than
121 the earliest event. Hence we know
125 so something that comes after this thing with L > 0 happens after
127 HERE + L >= HERE + (UNTIL - HERE) = UNTIL
129 Hence all events after the one with L>0 are uninteresting, so we
135 Sequential_music_iterator::get_music (Moment until)const
138 if (until < pending_moment ())
141 Sequential_music_iterator * me =
142 dynamic_cast<Sequential_music_iterator*> (clone ());
145 SCM nm = me->iter_p_->get_music (until - me->here_mom_);
146 s = gh_append2 (nm, s);
149 for (SCM i = nm; gh_pair_p(i); i = gh_cdr (i))
150 m = m >? unsmob_music (gh_car (i))->length_mom ();
162 Skip events till UNTIL. We don't do any other side effects (such as
163 moving descending to child iterator contexts, because they might
164 depend on \context specs and \translator changes being executed
168 Sequential_music_iterator::skip (Moment until)
172 Moment l =iter_p_->music_length_mom ();
173 if (l >= until - here_mom_)
174 iter_p_->skip (until - here_mom_);
184 Sequential_music_iterator::process (Moment until)
188 iter_p_->process (until - here_mom_);
191 if the iter is still OK, there must be events left that have
205 Sequential_music_iterator::pending_moment() const
207 return iter_p_->pending_moment() + here_mom_;
212 Sequential_music_iterator::ok() const
218 Sequential_music_iterator::try_music_in_children (Music *m) const
220 return iter_p_ ? iter_p_->try_music (m) : 0;
222 IMPLEMENT_CTOR_CALLBACK(Sequential_music_iterator);