2 music-iterator.cc -- implement {Music,Chord,Voice}_iterator
4 source file of the GNU LilyPond music typesetter
6 (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
9 #include "music-list.hh"
10 #include "music-iterator.hh"
11 #include "translator.hh"
15 IMPLEMENT_STATIC_NAME(Music_iterator);
16 IMPLEMENT_IS_TYPE_B(Music_iterator);
19 Music_iterator::do_print()const
25 Music_iterator::print() const
28 mtor << name() << "{";
29 mtor << "report to " << report_to_l_ << " (" << report_to_l_->name() << ")\n";
30 mtor << "next at " << next_moment() << " ";
37 Music_iterator::get_req_translator_l()
40 if (report_to_l_->is_bottom_engraver_b() )
43 set_translator( report_to_l_->get_default_interpreter() );
48 Music_iterator::set_translator(Translator*trans)
50 if (report_to_l_==trans)
54 report_to_l_->iterator_count_ --;
59 report_to_l_->iterator_count_ ++;
63 Music_iterator::construct_children()
68 Music_iterator::~Music_iterator()
74 Music_iterator::next_moment()const
80 Music_iterator::process_and_next(Moment)
86 Music_iterator::ok()const
92 Music_iterator::static_get_iterator_p(Music *m,
95 Music_iterator * p =0;
96 if (m->is_type_b( Change_reg::static_name()))
97 p = new Change_iterator((Change_reg*)m);
98 else if (m->is_type_b( Voice_element::static_name()))
99 p = new Voice_element_iterator( (Voice_element*) m);
100 else if (m->is_type_b( Chord::static_name()))
101 p = new Chord_iterator( (Chord*) m);
102 else if (m->is_type_b( Voice::static_name()))
103 p = new Voice_iterator( (Voice*) m);
104 else if (m->is_type_b( Request::static_name() ))
105 p = new Request_iterator( (Request*) m );
107 if ( m->is_type_b( Music_list::static_name())) {
108 Music_list* ml = (Music_list*) m;
109 if (ml -> type_str_ != "") {
110 Translator * a =report_l->
111 find_get_translator_l(ml-> type_str_, ml->id_str_);
114 p->set_translator( a);
118 if (! p->report_to_l_ )
119 p ->set_translator(report_l);
125 Music_iterator::get_iterator_p(Music*m)const
127 Music_iterator*p = static_get_iterator_p(m,report_to_l_);
128 p->daddy_iter_l_ = (Music_iterator*)this;
129 p->construct_children();
133 Music_iterator::Music_iterator()
142 Chord_iterator::Chord_iterator(Chord const *chord_C)
148 Chord_iterator::construct_children()
151 for(PCursor<Music*> i(chord_C_->music_p_list_.top()); //, int j = 0;
153 Music_iterator * mi = get_iterator_p( i.ptr());
154 set_translator(mi->report_to_l_->ancestor_l( chord_C_->multi_level_i_ ));
156 children_p_list_.bottom().add( mi );
162 Chord_iterator::do_print() const
165 for (PCursor<Music_iterator*> i(children_p_list_.top()); i.ok(); i++) {
172 Chord_iterator::process_and_next(Moment until)
174 for (PCursor<Music_iterator*> i(children_p_list_.top()); i.ok(); ) {
175 if (i->next_moment() == until) {
176 i->process_and_next(until);
183 Music_iterator::process_and_next(until);
185 // assert(!ok() || next_moment() > until);
188 IMPLEMENT_STATIC_NAME(Chord_iterator);
189 IMPLEMENT_IS_TYPE_B1(Chord_iterator,Music_iterator);
192 Chord_iterator::next_moment()const
194 Moment next_ = INFTY;
195 for (PCursor<Music_iterator*> i(children_p_list_.top()); i.ok(); i++)
196 next_ = next_ <? i->next_moment() ;
203 Chord_iterator::ok()const
205 return children_p_list_.size();
211 Voice_iterator::do_print()const
217 Voice_iterator::Voice_iterator(Voice const*v)
218 : PCursor<Music*> ( v->music_p_list_)
220 here_mom_ = v->offset_mom_;
226 Voice_iterator::construct_children()
229 iter_p_ = Music_iterator::get_iterator_p( ptr() );
230 if (iter_p_->report_to_l_->depth_i() > report_to_l_->depth_i())
231 set_translator(iter_p_->report_to_l_);
236 Voice_iterator::next_element()
240 here_mom_ += ptr()->time_int().length();
241 PCursor<Music*>::next();
242 construct_children();
245 Voice_iterator::~Voice_iterator()
250 IMPLEMENT_STATIC_NAME(Voice_iterator);
251 IMPLEMENT_IS_TYPE_B1(Voice_iterator,Music_iterator);
254 Voice_iterator::process_and_next(Moment until)
257 Moment local_until = until - here_mom_;
258 while ( iter_p_ && iter_p_->ok() ) {
259 Moment here = iter_p_->next_moment();
260 if (here != local_until)
262 iter_p_->process_and_next(local_until);
265 iter_p_ = Music_iterator::get_iterator_p( ptr() );
266 else if (!iter_p_->ok() )
269 Music_iterator::process_and_next(until);
270 assert(!ok() || next_moment() > until);
274 Voice_iterator::next_moment()const
276 return iter_p_->next_moment() + here_mom_;
280 Voice_iterator::ok()const
282 return PCursor<Music*>::ok();
285 /* ***************** */
288 Request_iterator::do_print()const
290 mtor << req_l_->name() ;
293 Request_iterator::Request_iterator(Request const*c)
295 req_l_ = (Request*)c;
300 Request_iterator::process_and_next(Moment m)
303 bool gotcha = daddy_iter_l_->report_to_l_->try_request(req_l_);
305 req_l_->warning("Junking request: " + String(req_l_->name()));
309 if ( m >= req_l_->duration() )
314 Request_iterator::next_moment()const
319 m = req_l_->duration();
324 Request_iterator::ok()const
326 return (req_l_->duration() && !last_b_) || first_b_; // ugh
329 IMPLEMENT_STATIC_NAME(Request_iterator);
330 IMPLEMENT_IS_TYPE_B1(Request_iterator, Music_iterator);
332 /* ****************** */
334 Change_iterator::Change_iterator(Change_reg * ch)
339 IMPLEMENT_STATIC_NAME(Change_iterator);
340 IMPLEMENT_IS_TYPE_B1(Change_iterator,Music_iterator);
346 Change_iterator::process_and_next(Moment mom)
349 Engraver_group_engraver *group_l =
350 report_to_l_->find_get_grav_l(change_l_->type_str_,
353 report_to_l_->daddy_grav_l_->remove_engraver_p(report_to_l_);
354 group_l->add(report_to_l_);
356 Music_iterator::process_and_next(mom);
361 /* ******************** */
363 IMPLEMENT_STATIC_NAME(Voice_element_iterator);
364 IMPLEMENT_IS_TYPE_B1(Voice_element_iterator,Chord_iterator);
367 Voice_element_iterator::construct_children()
369 get_req_translator_l();
370 Chord_iterator::construct_children();
373 Voice_element_iterator::Voice_element_iterator(Voice_element*el_l)
374 : Chord_iterator(el_l)