]> git.donarmstrong.com Git - lilypond.git/blob - lily/music-iterator.cc
release: 0.0.68pre
[lilypond.git] / lily / music-iterator.cc
1 /*
2   music-iterator.cc -- implement {Music,Chord,Voice}_iterator
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9 #include "music-list.hh"
10 #include "music-iterator.hh"
11 #include "register.hh"
12 #include "register-group.hh"
13 #include "interpreter.hh"
14
15 IMPLEMENT_STATIC_NAME(Music_iterator);
16 IMPLEMENT_IS_TYPE_B(Music_iterator);
17
18 Register_group_register * 
19 Music_iterator::get_req_acceptor_l()
20 {
21     assert(report_to_reg_l_);
22     if (report_to_reg_l_->interpreter_l() )
23         return report_to_reg_l_;
24
25     report_to_reg_l_ =  report_to_reg_l_->get_default_interpreter();
26     return report_to_reg_l_;
27 }
28
29 void
30 Music_iterator::construct_children()
31 {
32
33 }
34
35 Music_iterator::~Music_iterator(){
36 }
37
38 Moment
39 Music_iterator::next_moment()const
40 {
41     return 0;
42 }
43
44 void
45 Music_iterator::next(Moment)
46 {
47     first_b_ = false;
48 }
49
50 bool
51 Music_iterator::ok()const
52 {
53     return first_b_;
54 }
55
56 Music_iterator*
57 Music_iterator::static_get_iterator_p(Music *m,
58                                       Register_group_register *report_l)
59 {
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 );
71     
72      if ( m->is_type_b( Music_list::static_name())) {
73         Music_list* ml = (Music_list*) m;
74         if (ml -> type_str_ != "") {
75             p->report_to_reg_l_ =
76                 report_l->find_get_reg_l(ml-> type_str_, ml->id_str_);
77             
78         } 
79     } 
80      if (! p->report_to_reg_l_ )
81         p ->report_to_reg_l_ = report_l;
82     
83     return p;
84 }
85
86 Music_iterator*
87 Music_iterator::get_iterator_p(Music*m)const
88 {
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();
92     return p;
93 }
94
95 Music_iterator::Music_iterator()
96 {
97     daddy_iter_l_ =0;
98     report_to_reg_l_ = 0;
99     first_b_ = true;
100 }
101
102 /* ************** */
103
104 Chord_iterator::Chord_iterator(Chord const *chord_C)
105 {
106     chord_C_ = chord_C;
107 }
108
109 void
110 Chord_iterator::construct_children()
111 {
112     int j =0;
113     for(iter(chord_C_->music_p_list_.top(), i); i.ok(); j++, i++) {
114         
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 );
118     }
119 }
120
121 void
122 Chord_iterator::next(Moment until)
123 {
124     for (iter(children_p_list_.top(), i); i.ok(); ) {
125         if  (i->next_moment() == until) {
126             i->next(until);
127         }
128         if (!i->ok()) 
129             i.del();
130         else
131             i++;
132     }
133     Music_iterator::next(until);
134
135     assert(!ok() || next_moment() > until);
136 }
137
138 IMPLEMENT_STATIC_NAME(Chord_iterator);
139 IMPLEMENT_IS_TYPE_B1(Chord_iterator,Music_iterator);
140
141 Moment
142 Chord_iterator::next_moment()const
143 {
144     Moment next_ = INFTY;
145     for (iter(children_p_list_.top(), i); i.ok(); i++) 
146         next_ = next_ <? i->next_moment() ;
147     return next_;
148 }
149
150
151
152 bool
153 Chord_iterator::ok()const
154 {
155     return children_p_list_.size();
156 }
157
158 /* ************** */
159
160 Voice_iterator::Voice_iterator(Voice const*v)
161     : PCursor<Music*> ( v->music_p_list_)
162 {
163     here_mom_ = v->offset_mom_;
164     voice_C_ = v;
165     iter_p_ =0;
166 }
167
168 void
169 Voice_iterator::construct_children()
170 {
171     if (ok()) {
172         
173         iter_p_ = Music_iterator::get_iterator_p( ptr() );      
174         report_to_reg_l_ = 
175             iter_p_->report_to_reg_l_->ancestor_l( voice_C_ ->multi_level_i_ );
176     }
177 }
178
179 void
180 Voice_iterator::next_element()
181 {
182     delete iter_p_ ;
183     iter_p_ =0;
184     here_mom_ += ptr()->time_int().length();
185     PCursor<Music*>::next();
186     construct_children();
187 }
188
189 Voice_iterator::~Voice_iterator()
190 {
191     delete iter_p_;
192 }
193
194 IMPLEMENT_STATIC_NAME(Voice_iterator);
195 IMPLEMENT_IS_TYPE_B1(Voice_iterator,Music_iterator);
196
197 void
198 Voice_iterator::next(Moment until)
199 {
200     while (ok()) {
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)
205                 return;
206             iter_p_->next(local_until);
207         }
208         if (!iter_p_)
209             iter_p_ = Music_iterator::get_iterator_p( ptr() );
210         else if (!iter_p_->ok() )
211             next_element();
212     }
213     Music_iterator::next(until);
214     assert(!ok() || next_moment() > until);
215 }
216
217 Moment
218 Voice_iterator::next_moment()const
219 {
220     return iter_p_->next_moment() + here_mom_;
221 }
222
223 bool
224 Voice_iterator::ok()const
225 {
226     return PCursor<Music*>::ok();
227 }
228
229 /* ***************** */
230
231 Request_iterator::Request_iterator(Request const*c)
232 {
233     req_l_ = (Request*)c;
234 }
235
236 void
237 Request_iterator::next(Moment m)
238 {
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()));
242
243     
244     Music_iterator::next(m);
245 }
246
247 IMPLEMENT_STATIC_NAME(Request_iterator);
248 IMPLEMENT_IS_TYPE_B1(Request_iterator, Music_iterator);
249
250 /* ****************** */
251
252 Change_iterator::Change_iterator(Change_reg * ch)
253 {
254     change_l_ = ch;
255 }
256
257 IMPLEMENT_STATIC_NAME(Change_iterator);
258 IMPLEMENT_IS_TYPE_B1(Change_iterator,Music_iterator);
259
260 /*
261   TODO: pop/pushgroup
262  */
263 void
264 Change_iterator::next(Moment mom)
265 {
266     Register_group_register *group_l =
267         report_to_reg_l_->find_get_reg_l(change_l_->type_str_, 
268                                          change_l_->id_str_);
269
270     report_to_reg_l_->daddy_reg_l_->remove_register_p(report_to_reg_l_);
271     group_l->add(report_to_reg_l_);
272
273     Music_iterator::next(mom);
274 }
275
276
277
278 /* ******************** */
279
280 IMPLEMENT_STATIC_NAME(Voice_element_iterator);
281 IMPLEMENT_IS_TYPE_B1(Voice_element_iterator,Chord_iterator);
282
283 void
284 Voice_element_iterator::construct_children()
285 {
286     if ( daddy_iter_l_ 
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() )) {
291
292         get_req_acceptor_l();
293     }
294     Chord_iterator::construct_children();
295 }
296
297 Voice_element_iterator::Voice_element_iterator(Voice_element*el_l)
298     : Chord_iterator(el_l)
299 {
300     
301 }