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 "acceptor.hh"
13 #include "interpreter.hh"
16 IMPLEMENT_STATIC_NAME(Music_iterator);
17 IMPLEMENT_IS_TYPE_B(Music_iterator);
20 Music_iterator::do_print()const
26 Music_iterator::print() const
29 mtor << name() << "{";
30 mtor << "report to " << report_to_l_ << " (" << report_to_l_->name() << ")\n";
31 mtor << "next at " << next_moment() << " ";
38 Music_iterator::get_req_acceptor_l()
41 if (report_to_l_->interpreter_l() )
44 set_acceptor( report_to_l_->get_default_interpreter() );
49 Music_iterator::set_acceptor(Acceptor*reg)
51 if (report_to_l_==reg)
55 report_to_l_->iterator_count_ --;
60 report_to_l_->iterator_count_ ++;
64 Music_iterator::construct_children()
69 Music_iterator::~Music_iterator()
75 Music_iterator::next_moment()const
81 Music_iterator::next(Moment)
87 Music_iterator::ok()const
93 Music_iterator::static_get_iterator_p(Music *m,
96 Music_iterator * p =0;
97 if (m->is_type_b( Change_reg::static_name()))
98 p = new Change_iterator((Change_reg*)m);
99 else if (m->is_type_b( Voice_element::static_name()))
100 p = new Voice_element_iterator( (Voice_element*) m);
101 else if (m->is_type_b( Chord::static_name()))
102 p = new Chord_iterator( (Chord*) m);
103 else if (m->is_type_b( Voice::static_name()))
104 p = new Voice_iterator( (Voice*) m);
105 else if (m->is_type_b( Request::static_name() ))
106 p = new Request_iterator( (Request*) m );
108 if ( m->is_type_b( Music_list::static_name())) {
109 Music_list* ml = (Music_list*) m;
110 if (ml -> type_str_ != "") {
111 Acceptor * a =report_l->
112 find_get_acceptor_l(ml-> type_str_, ml->id_str_);
119 if (! p->report_to_l_ )
120 p ->set_acceptor(report_l);
126 Music_iterator::get_iterator_p(Music*m)const
128 Music_iterator*p = static_get_iterator_p(m,report_to_l_);
129 p->daddy_iter_l_ = (Music_iterator*)this;
130 p->construct_children();
134 Music_iterator::Music_iterator()
143 Chord_iterator::Chord_iterator(Chord const *chord_C)
149 Chord_iterator::construct_children()
152 for(iter(chord_C_->music_p_list_.top(), i); i.ok(); j++, i++) {
154 Music_iterator * mi = get_iterator_p( i.ptr());
155 set_acceptor(mi->report_to_l_->ancestor_l( chord_C_->multi_level_i_ ));
157 children_p_list_.bottom().add( mi );
163 Chord_iterator::do_print() const
166 for (iter(children_p_list_.top(), i); i.ok(); i++ ) {
173 Chord_iterator::next(Moment until)
175 for (iter(children_p_list_.top(), i); i.ok(); ) {
176 if (i->next_moment() == until) {
184 Music_iterator::next(until);
186 // assert(!ok() || next_moment() > until);
189 IMPLEMENT_STATIC_NAME(Chord_iterator);
190 IMPLEMENT_IS_TYPE_B1(Chord_iterator,Music_iterator);
193 Chord_iterator::next_moment()const
195 Moment next_ = INFTY;
196 for (iter(children_p_list_.top(), i); i.ok(); i++)
197 next_ = next_ <? i->next_moment() ;
204 Chord_iterator::ok()const
206 return children_p_list_.size();
212 Voice_iterator::do_print()const
218 Voice_iterator::Voice_iterator(Voice const*v)
219 : PCursor<Music*> ( v->music_p_list_)
221 here_mom_ = v->offset_mom_;
227 Voice_iterator::construct_children()
230 iter_p_ = Music_iterator::get_iterator_p( ptr() );
231 if (iter_p_->report_to_l_->depth_i() > report_to_l_->depth_i())
232 set_acceptor(iter_p_->report_to_l_);
237 Voice_iterator::next_element()
241 here_mom_ += ptr()->time_int().length();
242 PCursor<Music*>::next();
243 construct_children();
246 Voice_iterator::~Voice_iterator()
251 IMPLEMENT_STATIC_NAME(Voice_iterator);
252 IMPLEMENT_IS_TYPE_B1(Voice_iterator,Music_iterator);
255 Voice_iterator::next(Moment until)
258 Moment local_until = until - here_mom_;
259 while ( iter_p_ && iter_p_->ok() ) {
260 Moment here = iter_p_->next_moment();
261 if (here != local_until)
263 iter_p_->next(local_until);
266 iter_p_ = Music_iterator::get_iterator_p( ptr() );
267 else if (!iter_p_->ok() )
270 Music_iterator::next(until);
271 assert(!ok() || next_moment() > until);
275 Voice_iterator::next_moment()const
277 return iter_p_->next_moment() + here_mom_;
281 Voice_iterator::ok()const
283 return PCursor<Music*>::ok();
286 /* ***************** */
288 Request_iterator::do_print()const
290 mtor << req_l_->name() ;
292 Request_iterator::Request_iterator(Request const*c)
294 req_l_ = (Request*)c;
299 Request_iterator::next(Moment m)
302 bool gotcha = daddy_iter_l_->report_to_l_->
303 interpreter_l()->interpret_request_b(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
328 IMPLEMENT_STATIC_NAME(Request_iterator);
329 IMPLEMENT_IS_TYPE_B1(Request_iterator, Music_iterator);
331 /* ****************** */
333 Change_iterator::Change_iterator(Change_reg * ch)
338 IMPLEMENT_STATIC_NAME(Change_iterator);
339 IMPLEMENT_IS_TYPE_B1(Change_iterator,Music_iterator);
345 Change_iterator::next(Moment mom)
348 Register_group_register *group_l =
349 report_to_l_->find_get_reg_l(change_l_->type_str_,
352 report_to_l_->daddy_reg_l_->remove_register_p(report_to_l_);
353 group_l->add(report_to_l_);
355 Music_iterator::next(mom);
360 /* ******************** */
362 IMPLEMENT_STATIC_NAME(Voice_element_iterator);
363 IMPLEMENT_IS_TYPE_B1(Voice_element_iterator,Chord_iterator);
366 Voice_element_iterator::construct_children()
368 get_req_acceptor_l();
371 && daddy_iter_l_->is_type_b(Voice_iterator::static_name() )) {
372 set_acceptor(daddy_iter_l_-> get_req_acceptor_l());
373 } else if (daddy_iter_l_
374 && daddy_iter_l_-> is_type_b( Chord_iterator::static_name() )) {
376 get_req_acceptor_l();
379 Chord_iterator::construct_children();
382 Voice_element_iterator::Voice_element_iterator(Voice_element*el_l)
383 : Chord_iterator(el_l)