]> git.donarmstrong.com Git - lilypond.git/blob - lily/unfolded-repeat-iterator.cc
release: 1.2.15
[lilypond.git] / lily / unfolded-repeat-iterator.cc
1 /*   
2   unfolded-repeat-iterator.cc --  implement Unfolded_repeat_iterator
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10
11 #include "repeated-music.hh"
12 #include "music-list.hh"
13 #include "unfolded-repeat-iterator.hh"
14 #include "debug.hh"
15 #include "translator-group.hh"
16
17 Unfolded_repeat_iterator::~Unfolded_repeat_iterator ()
18 {
19   delete current_iter_p_;
20 }
21
22 Unfolded_repeat_iterator::Unfolded_repeat_iterator ()
23 {
24   done_count_ =0;
25   current_iter_p_ =0;
26   do_main_b_ = false;
27   alternative_count_i_ =0;
28 }
29
30 /**
31
32 If we are in the body of the repeat always go to the current alternative.
33
34 If we are not in the body, then we are in an alternative.  If we are
35 fully unfolding, advance the current alternative and go back to main.
36 If we are semi-unfolding, advance the current alternative, and go to
37 the  alternative just set.
38    
39  */
40 void
41 Unfolded_repeat_iterator::next_element () 
42 {
43   Repeated_music const* mus =dynamic_cast<Repeated_music const*> (music_l_);
44   delete current_iter_p_;
45   current_iter_p_ =0;
46
47
48   if (do_main_b_)
49     {
50       done_mom_ += mus->repeat_body_p_->length_mom ();
51
52       if (full_unfold_b_)
53         done_count_ ++;
54      
55       if (alternative_cons_l_)
56         {
57           current_iter_p_ = get_iterator_p (alternative_cons_l_->car_);
58           do_main_b_ = false;
59         }
60       else if (done_count_ <  mus->repeats_i_ && full_unfold_b_)
61         {
62           current_iter_p_ = get_iterator_p (mus->repeat_body_p_);
63           do_main_b_ = true;
64         }
65     }
66   else
67     {
68       /*
69         we're not in the main part. So we're either in an alternative, or
70         we just finished.
71       */
72       if (alternative_cons_l_)
73         {
74           done_mom_ += alternative_cons_l_->car_->length_mom ();
75
76           if (!full_unfold_b_ || 
77               mus->repeats_i_ - done_count_  < alternative_count_i_)
78             alternative_cons_l_ = alternative_cons_l_->next_;
79           
80           /*
81             we've done the main body as well, but didn't go over the other
82             increment.  */
83           if (full_unfold_b_)
84             done_count_ ++;
85         }
86       
87       if (done_count_ < mus->repeats_i_ && alternative_cons_l_)
88         {
89           if (!full_unfold_b_)
90             current_iter_p_ = get_iterator_p (alternative_cons_l_->car_);
91           else
92             {
93               current_iter_p_ = get_iterator_p (mus->repeat_body_p_);
94               do_main_b_ = true;
95             }
96         }
97     }
98 }
99
100
101 bool
102 Unfolded_repeat_iterator::ok () const
103 {
104   return current_iter_p_ ;
105 }
106
107 Moment
108 Unfolded_repeat_iterator::next_moment () const
109 {
110   return done_mom_ + current_iter_p_->next_moment ();
111 }
112
113 void
114 Unfolded_repeat_iterator::construct_children ()
115 {
116   Repeated_music const* mus =dynamic_cast<Repeated_music const*> (music_l_);
117   full_unfold_b_ = playback_b_ || (!mus->volta_fold_b_);
118   
119   alternative_cons_l_ = (mus->alternatives_p_)
120     ? mus->alternatives_p_->music_p_list_p_->head_
121     : 0;
122
123   for (Cons<Music> *p = alternative_cons_l_; p; p = p->next_)
124     alternative_count_i_ ++;
125
126   if (mus->repeat_body_p_)
127     {
128       current_iter_p_  = get_iterator_p (mus->repeat_body_p_);
129       do_main_b_ = true;
130     }
131   else if (alternative_cons_l_)
132     {
133       current_iter_p_ = get_iterator_p (alternative_cons_l_->car_);
134       do_main_b_ = false;
135     }
136 }
137
138 void
139 Unfolded_repeat_iterator::do_process_and_next (Moment m) 
140 {
141   if (!m)
142     {
143       Music_iterator *yeah = try_music (music_l_);
144       if (yeah)
145         set_translator (yeah->report_to_l ());
146       else
147         music_l_->warning ( _("no one to print a volta bracket"));
148     }
149   while (1)
150     {
151       while (!current_iter_p_->ok ())
152         {
153           next_element();
154
155           if (!current_iter_p_)
156             return;
157         }
158       
159       if (m - done_mom_ >= current_iter_p_->next_moment ())
160         current_iter_p_->process_and_next (m - done_mom_);
161       else
162         return;
163     }
164 }
165   
166 void
167 Unfolded_repeat_iterator::do_print () const
168 {
169 #ifndef NPRINT
170   DEBUG_OUT << "count " << done_count_ << "done time " << done_mom_ << '\n';
171   DEBUG_OUT << "current: ";
172   current_iter_p_->print();
173 #endif
174 }
175
176 Music_iterator* 
177 Unfolded_repeat_iterator::try_music_in_children (Music const * m) const
178 {
179   return  current_iter_p_->try_music (m);
180 }