lilypond-1.3.124
[lilypond.git] / lily / sequential-music-iterator.cc
blob281b97c1671bc323ea52c1de0ab10501df9dfe7e
1 /*
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>
7 */
8 #include "grace-iterator.hh"
9 #include "translator-group.hh"
10 #include "debug.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_))
21 else
22 iter_p_ == 0;
24 The length of musiclist from start to up to cursor_ (cursor_ not
25 including), is summed
27 here_mom_ = sum (length (musiclist [start ... cursor> )) %)
32 Sequential_music_iterator::Sequential_music_iterator ()
34 cursor_ = SCM_EOL;
35 here_mom_ = Moment (0);
37 iter_p_ =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_;
45 if (src.iter_p_)
46 iter_p_ = src.iter_p_->clone ();
47 else
48 iter_p_ = 0;
51 Sequential_music_iterator::~Sequential_music_iterator()
53 delete iter_p_;
56 void
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 ())
64 next_element ();
68 iter_p_->ok () is tautology, but what the heck.
70 if (iter_p_ && iter_p_->ok())
71 descend_to_child ();
77 maintain invariants: change cursor, iter and here_mom_ in one fell
78 swoop.
80 void
81 Sequential_music_iterator::next_element ()
83 here_mom_ += iter_p_->music_length_mom ();
84 delete iter_p_;
85 cursor_ = gh_cdr (cursor_);
87 if (gh_pair_p (cursor_))
88 iter_p_ = get_iterator_p (unsmob_music (gh_car (cursor_)));
89 else
90 iter_p_ = 0;
94 move to context of child iterator if it is deeper down in the
95 hierarchy.
98 void
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
115 L >= (UNTIL - HERE)
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
122 ignore them.
127 Sequential_music_iterator::get_music (Moment until)const
129 SCM s = SCM_EOL;
130 if (until < pending_moment ())
131 return s;
133 Sequential_music_iterator * me =
134 dynamic_cast<Sequential_music_iterator*> (clone ());
135 while (me->ok ())
137 SCM nm = me->iter_p_->get_music (until - me->here_mom_);
138 s = gh_append2 (nm, s);
140 Moment m = 0;
141 for (SCM i = nm; gh_pair_p(i); i = gh_cdr (i))
142 m = m >? unsmob_music (gh_car (i))->length_mom ();
144 if (m > Moment (0))
145 break ;
146 else
147 me->next_element ();
149 delete me;
151 return s;
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
159 void
160 Sequential_music_iterator::skip (Moment until)
162 while (ok ())
164 Moment l =iter_p_->music_length_mom ();
165 if (l >= until - here_mom_)
166 iter_p_->skip (until - here_mom_);
168 if (iter_p_->ok ())
169 return ;
171 next_element ();
175 void
176 Sequential_music_iterator::process (Moment until)
178 while (iter_p_)
180 iter_p_->process (until - here_mom_);
183 if the iter is still OK, there must be events left that have
185 TIME > LEFT
188 if (iter_p_->ok ())
189 return ;
191 descend_to_child ();
192 next_element ();
196 Moment
197 Sequential_music_iterator::pending_moment() const
199 return iter_p_->pending_moment() + here_mom_;
203 bool
204 Sequential_music_iterator::ok() const
206 return iter_p_;
209 Music_iterator*
210 Sequential_music_iterator::try_music_in_children (Music *m) const
212 return iter_p_ ? iter_p_->try_music (m) : 0;
214 IMPLEMENT_CTOR_CALLBACK(Sequential_music_iterator);