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 "register.hh"
12 #include "register-group.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_reg_l_ << " (" << report_to_reg_l_->name() << ")\n";
31 mtor << "next at " << next_moment() << " ";
37 Register_group_register *
38 Music_iterator::get_req_acceptor_l()
40 assert(report_to_reg_l_);
41 if (report_to_reg_l_->interpreter_l() )
42 return report_to_reg_l_;
44 set_reg( report_to_reg_l_->get_default_interpreter() );
45 return report_to_reg_l_;
49 Music_iterator::set_reg(Register_group_register*reg)
51 if (report_to_reg_l_==reg)
55 report_to_reg_l_->iterator_count_ --;
57 report_to_reg_l_ = reg;
60 report_to_reg_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,
94 Register_group_register *report_l)
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 p->set_reg(report_l->find_get_reg_l(ml-> type_str_, ml->id_str_));
115 if (! p->report_to_reg_l_ )
116 p ->set_reg(report_l);
122 Music_iterator::get_iterator_p(Music*m)const
124 Music_iterator*p = static_get_iterator_p(m,report_to_reg_l_);
125 p->daddy_iter_l_ = (Music_iterator*)this;
126 p->construct_children();
130 Music_iterator::Music_iterator()
133 report_to_reg_l_ = 0;
139 Chord_iterator::Chord_iterator(Chord const *chord_C)
145 Chord_iterator::construct_children()
148 for(iter(chord_C_->music_p_list_.top(), i); i.ok(); j++, i++) {
150 Music_iterator * mi = get_iterator_p( i.ptr());
151 set_reg(mi->report_to_reg_l_->ancestor_l( chord_C_->multi_level_i_ ));
152 children_p_list_.bottom().add( mi );
156 Chord_iterator::do_print() const
159 for (iter(children_p_list_.top(), i); i.ok(); i++ ) {
166 Chord_iterator::next(Moment until)
168 for (iter(children_p_list_.top(), i); i.ok(); ) {
169 if (i->next_moment() == until) {
177 Music_iterator::next(until);
179 // assert(!ok() || next_moment() > until);
182 IMPLEMENT_STATIC_NAME(Chord_iterator);
183 IMPLEMENT_IS_TYPE_B1(Chord_iterator,Music_iterator);
186 Chord_iterator::next_moment()const
188 Moment next_ = INFTY;
189 for (iter(children_p_list_.top(), i); i.ok(); i++)
190 next_ = next_ <? i->next_moment() ;
197 Chord_iterator::ok()const
199 return children_p_list_.size();
205 Voice_iterator::do_print()const
211 Voice_iterator::Voice_iterator(Voice const*v)
212 : PCursor<Music*> ( v->music_p_list_)
214 here_mom_ = v->offset_mom_;
220 Voice_iterator::construct_children()
223 iter_p_ = Music_iterator::get_iterator_p( ptr() );
224 if (iter_p_->report_to_reg_l_->depth_i() > report_to_reg_l_->depth_i())
225 set_reg(iter_p_->report_to_reg_l_);
230 Voice_iterator::next_element()
234 here_mom_ += ptr()->time_int().length();
235 PCursor<Music*>::next();
236 construct_children();
239 Voice_iterator::~Voice_iterator()
244 IMPLEMENT_STATIC_NAME(Voice_iterator);
245 IMPLEMENT_IS_TYPE_B1(Voice_iterator,Music_iterator);
248 Voice_iterator::next(Moment until)
251 Moment local_until = until - here_mom_;
252 while ( iter_p_ && iter_p_->ok() ) {
253 Moment here = iter_p_->next_moment();
254 if (here != local_until)
256 iter_p_->next(local_until);
259 iter_p_ = Music_iterator::get_iterator_p( ptr() );
260 else if (!iter_p_->ok() )
263 Music_iterator::next(until);
264 assert(!ok() || next_moment() > until);
268 Voice_iterator::next_moment()const
270 return iter_p_->next_moment() + here_mom_;
274 Voice_iterator::ok()const
276 return PCursor<Music*>::ok();
279 /* ***************** */
281 Request_iterator::do_print()const
283 mtor << req_l_->name() ;
285 Request_iterator::Request_iterator(Request const*c)
287 req_l_ = (Request*)c;
292 Request_iterator::next(Moment m)
295 bool gotcha = daddy_iter_l_->report_to_reg_l_->
296 interpreter_l()->interpret_request_b(req_l_);
298 req_l_->warning("Junking request: " + String(req_l_->name()));
302 if ( m >= req_l_->duration() )
307 Request_iterator::next_moment()const
312 m = req_l_->duration();
317 Request_iterator::ok()const
319 return (req_l_->duration() && !last_b_) || first_b_; // ugh
321 IMPLEMENT_STATIC_NAME(Request_iterator);
322 IMPLEMENT_IS_TYPE_B1(Request_iterator, Music_iterator);
324 /* ****************** */
326 Change_iterator::Change_iterator(Change_reg * ch)
331 IMPLEMENT_STATIC_NAME(Change_iterator);
332 IMPLEMENT_IS_TYPE_B1(Change_iterator,Music_iterator);
338 Change_iterator::next(Moment mom)
340 Register_group_register *group_l =
341 report_to_reg_l_->find_get_reg_l(change_l_->type_str_,
344 report_to_reg_l_->daddy_reg_l_->remove_register_p(report_to_reg_l_);
345 group_l->add(report_to_reg_l_);
347 Music_iterator::next(mom);
352 /* ******************** */
354 IMPLEMENT_STATIC_NAME(Voice_element_iterator);
355 IMPLEMENT_IS_TYPE_B1(Voice_element_iterator,Chord_iterator);
358 Voice_element_iterator::construct_children()
360 get_req_acceptor_l();
363 && daddy_iter_l_->is_type_b(Voice_iterator::static_name() )) {
364 set_reg(daddy_iter_l_-> get_req_acceptor_l());
365 } else if (daddy_iter_l_
366 && daddy_iter_l_-> is_type_b( Chord_iterator::static_name() )) {
368 get_req_acceptor_l();
371 Chord_iterator::construct_children();
374 Voice_element_iterator::Voice_element_iterator(Voice_element*el_l)
375 : Chord_iterator(el_l)