2 Sequential_music_iterator.cc -- implement Sequential_music_iterator
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2000 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 if (dynamic_cast<Grace_iterator*> (iter_p_))
103 child_report = child_report->daddy_trans_l_;
105 if (report_to_l()->depth_i () < child_report->depth_i ())
106 set_translator (child_report);
111 Retrieve all music (starting at HERE), until a music with length L >
112 0 is found. From the precondition, we know that UNTIL is later than
113 the earliest event. Hence we know
117 so something that comes after this thing with L > 0 happens after
119 HERE + L >= HERE + (UNTIL - HERE) = UNTIL
121 Hence all events after the one with L>0 are uninteresting, so we
127 Sequential_music_iterator::get_music (Moment until)const
130 if (until < pending_moment ())
133 Sequential_music_iterator * me =
134 dynamic_cast<Sequential_music_iterator*> (clone ());
137 SCM nm = me->iter_p_->get_music (until - me->here_mom_);
138 s = gh_append2 (nm, s);
141 for (SCM i = nm; gh_pair_p(i); i = gh_cdr (i))
142 m = m >? unsmob_music (gh_car (i))->length_mom ();
154 Skip events till UNTIL. We don't do any other side effects (such as
155 moving descending to child iterator contexts, because they might
156 depend on \context specs and \translator changes being executed
160 Sequential_music_iterator::skip (Moment until)
164 Moment l =iter_p_->music_length_mom ();
165 if (l >= until - here_mom_)
166 iter_p_->skip (until - here_mom_);
176 Sequential_music_iterator::process (Moment until)
180 iter_p_->process (until - here_mom_);
183 if the iter is still OK, there must be events left that have
197 Sequential_music_iterator::pending_moment() const
199 return iter_p_->pending_moment() + here_mom_;
204 Sequential_music_iterator::ok() const
210 Sequential_music_iterator::try_music_in_children (Music *m) const
212 return iter_p_ ? iter_p_->try_music (m) : 0;