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