]> git.donarmstrong.com Git - lilypond.git/blob - lily/sequential-music-iterator.cc
6714625393c079a154c670dd5500331bbc05b19a
[lilypond.git] / lily / sequential-music-iterator.cc
1 /*
2   Sequential_music_iterator.cc -- implement Sequential_music_iterator
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8 #include "grace-iterator.hh"
9 #include "translator-group.hh"
10 #include "debug.hh"
11 #include "sequential-music-iterator.hh"
12 #include "music-list.hh"
13 #include "request-chord-iterator.hh"
14
15
16 void
17 Sequential_music_iterator::do_print() const
18 {
19   if (iter_p_)
20     iter_p_->print();
21 }
22
23 Sequential_music_iterator::Sequential_music_iterator ()
24 {
25   cursor_ = 0;
26   here_mom_ = 0;
27   iter_p_ =0;
28   per_elt_b_ = false;
29 }
30
31 void
32 Sequential_music_iterator::construct_children()
33 {
34   cursor_ = dynamic_cast<Music_sequence const*> (music_l_)->music_p_list_p_->head_;
35   
36   while (cursor_)
37     {
38       start_next_element();
39       if (!iter_p_->ok()) 
40         {
41           leave_element();
42         }
43       else 
44         {
45           set_sequential_music_translator();
46           break;
47         }
48     }
49 }
50
51 void 
52 Sequential_music_iterator::leave_element()
53 {
54   delete iter_p_;
55   iter_p_ =0;
56   Moment elt_time = cursor_->car_->length_mom ();
57   here_mom_ += elt_time;
58   cursor_ =cursor_->next_;
59 }
60
61 void
62 Sequential_music_iterator::start_next_element()
63 {
64   assert (!iter_p_);
65   iter_p_ = get_iterator_p (cursor_->car_);
66 }
67
68 void
69 Sequential_music_iterator::set_sequential_music_translator()
70 {
71   if (iter_p_->report_to_l()->depth_i () > report_to_l ()->depth_i ()
72       && ! dynamic_cast<Grace_iterator*> (iter_p_)) // UGH.!
73     set_translator (iter_p_->report_to_l());
74 }
75
76 Sequential_music_iterator::~Sequential_music_iterator()
77 {
78   assert (! iter_p_);
79 }
80
81
82
83
84 void
85 Sequential_music_iterator::do_process_and_next (Moment until)
86 {
87   if (!iter_p_)
88     return;
89
90   while (1) 
91     {
92       Moment local_until = until - here_mom_;
93       while (iter_p_->ok()) 
94         {
95           Moment here = iter_p_->next_moment();
96           if (here != local_until)
97             goto loopexit;
98             
99           iter_p_->process_and_next (local_until);
100         }
101       
102       if (!iter_p_->ok()) 
103         {
104           leave_element();
105           
106           if (cursor_)
107             {
108               start_next_element();
109               set_sequential_music_translator();
110
111               if (per_elt_b_)
112                 goto loopexit;  // ugh.
113             }
114           else 
115             {
116               goto loopexit;
117             }
118         }
119     }
120
121 loopexit:
122
123   Music_iterator::do_process_and_next (until);
124 }
125
126 Moment
127 Sequential_music_iterator::next_moment() const
128 {
129   return iter_p_->next_moment() + here_mom_;
130 }
131
132 Music*
133 Sequential_music_iterator::next_music_l ()
134 {
135   if (!iter_p_)
136     return 0;
137
138   while (1) 
139     {
140       if (Music* m = iter_p_->next_music_l ())
141         {
142           return m;
143         }
144       else
145         {
146           // urg FIXME: sequential children should be iterated to finish
147           if (dynamic_cast<Request_chord_iterator*> (iter_p_))
148             delete iter_p_;
149           iter_p_ = 0;
150           leave_element ();
151           
152           if (cursor_)
153             {
154               start_next_element ();
155               set_sequential_music_translator ();
156             }
157           else 
158             {
159               delete iter_p_;
160               iter_p_ = 0;
161               return 0;
162             }
163         }
164     }
165 }
166
167 bool
168 Sequential_music_iterator::ok() const
169 {
170   return iter_p_;
171 }
172