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"
15 IMPLEMENT_STATIC_NAME(Music_iterator);
16 IMPLEMENT_IS_TYPE_B(Music_iterator);
18 Register_group_register *
19 Music_iterator::get_req_acceptor_l()
21 assert(report_to_reg_l_);
22 if (report_to_reg_l_->interpreter_l() )
23 return report_to_reg_l_;
25 report_to_reg_l_ = report_to_reg_l_->get_default_interpreter();
26 return report_to_reg_l_;
30 Music_iterator::construct_children()
35 Music_iterator::~Music_iterator(){
39 Music_iterator::next_moment()const
45 Music_iterator::next(Moment)
51 Music_iterator::ok()const
57 Music_iterator::static_get_iterator_p(Music *m,
58 Register_group_register *report_l)
60 Music_iterator * p =0;
61 if (m->is_type_b( Change_reg::static_name()))
62 p = new Change_iterator((Change_reg*)m);
63 else if (m->is_type_b( Voice_element::static_name()))
64 p = new Voice_element_iterator( (Voice_element*) m);
65 else if (m->is_type_b( Chord::static_name()))
66 p = new Chord_iterator( (Chord*) m);
67 else if (m->is_type_b( Voice::static_name()))
68 p = new Voice_iterator( (Voice*) m);
69 else if (m->is_type_b( Request::static_name() ))
70 p = new Request_iterator( (Request*) m );
72 if ( m->is_type_b( Music_list::static_name())) {
73 Music_list* ml = (Music_list*) m;
74 if (ml -> type_str_ != "") {
76 report_l->find_get_reg_l(ml-> type_str_, ml->id_str_);
80 if (! p->report_to_reg_l_ )
81 p ->report_to_reg_l_ = report_l;
87 Music_iterator::get_iterator_p(Music*m)const
89 Music_iterator*p = static_get_iterator_p(m,report_to_reg_l_);
90 p->daddy_iter_l_ = (Music_iterator*)this;
91 p->construct_children();
95 Music_iterator::Music_iterator()
104 Chord_iterator::Chord_iterator(Chord const *chord_C)
110 Chord_iterator::construct_children()
113 for(iter(chord_C_->music_p_list_.top(), i); i.ok(); j++, i++) {
115 Music_iterator * mi = get_iterator_p( i.ptr());
116 report_to_reg_l_ = mi->report_to_reg_l_->ancestor_l( chord_C_->multi_level_i_ );
117 children_p_list_.bottom().add( mi );
122 Chord_iterator::next(Moment until)
124 for (iter(children_p_list_.top(), i); i.ok(); ) {
125 if (i->next_moment() == until) {
133 Music_iterator::next(until);
135 assert(!ok() || next_moment() > until);
138 IMPLEMENT_STATIC_NAME(Chord_iterator);
139 IMPLEMENT_IS_TYPE_B1(Chord_iterator,Music_iterator);
142 Chord_iterator::next_moment()const
144 Moment next_ = INFTY;
145 for (iter(children_p_list_.top(), i); i.ok(); i++)
146 next_ = next_ <? i->next_moment() ;
153 Chord_iterator::ok()const
155 return children_p_list_.size();
160 Voice_iterator::Voice_iterator(Voice const*v)
161 : PCursor<Music*> ( v->music_p_list_)
163 here_mom_ = v->offset_mom_;
169 Voice_iterator::construct_children()
173 iter_p_ = Music_iterator::get_iterator_p( ptr() );
175 iter_p_->report_to_reg_l_->ancestor_l( voice_C_ ->multi_level_i_ );
180 Voice_iterator::next_element()
184 here_mom_ += ptr()->time_int().length();
185 PCursor<Music*>::next();
186 construct_children();
189 Voice_iterator::~Voice_iterator()
194 IMPLEMENT_STATIC_NAME(Voice_iterator);
195 IMPLEMENT_IS_TYPE_B1(Voice_iterator,Music_iterator);
198 Voice_iterator::next(Moment until)
201 Moment local_until = until - here_mom_;
202 while ( iter_p_ && iter_p_->ok() ) {
203 Moment here = iter_p_->next_moment();
204 if (here != local_until)
206 iter_p_->next(local_until);
209 iter_p_ = Music_iterator::get_iterator_p( ptr() );
210 else if (!iter_p_->ok() )
213 Music_iterator::next(until);
214 assert(!ok() || next_moment() > until);
218 Voice_iterator::next_moment()const
220 return iter_p_->next_moment() + here_mom_;
224 Voice_iterator::ok()const
226 return PCursor<Music*>::ok();
229 /* ***************** */
231 Request_iterator::Request_iterator(Request const*c)
233 req_l_ = (Request*)c;
237 Request_iterator::next(Moment m)
239 if ( !daddy_iter_l_->report_to_reg_l_->
240 interpreter_l()->interpret_request_b(req_l_) )
241 req_l_->warning("Junking request: " + String(req_l_->name()));
244 Music_iterator::next(m);
247 IMPLEMENT_STATIC_NAME(Request_iterator);
248 IMPLEMENT_IS_TYPE_B1(Request_iterator, Music_iterator);
250 /* ****************** */
252 Change_iterator::Change_iterator(Change_reg * ch)
257 IMPLEMENT_STATIC_NAME(Change_iterator);
258 IMPLEMENT_IS_TYPE_B1(Change_iterator,Music_iterator);
264 Change_iterator::next(Moment mom)
266 Register_group_register *group_l =
267 report_to_reg_l_->find_get_reg_l(change_l_->type_str_,
270 report_to_reg_l_->daddy_reg_l_->remove_register_p(report_to_reg_l_);
271 group_l->add(report_to_reg_l_);
273 Music_iterator::next(mom);
278 /* ******************** */
280 IMPLEMENT_STATIC_NAME(Voice_element_iterator);
281 IMPLEMENT_IS_TYPE_B1(Voice_element_iterator,Chord_iterator);
284 Voice_element_iterator::construct_children()
287 && daddy_iter_l_->is_type_b(Voice_iterator::static_name() )) {
288 report_to_reg_l_ = daddy_iter_l_-> get_req_acceptor_l();
289 } else if (daddy_iter_l_
290 && daddy_iter_l_-> is_type_b( Chord_iterator::static_name() )) {
292 get_req_acceptor_l();
294 Chord_iterator::construct_children();
297 Voice_element_iterator::Voice_element_iterator(Voice_element*el_l)
298 : Chord_iterator(el_l)