]> git.donarmstrong.com Git - lilypond.git/blob - lily/unfolded-repeat-iterator.cc
release: 1.1.50
[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 "new-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   New_repeated_music const* mus =dynamic_cast<New_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 (!mus->semi_fold_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_ && !mus->semi_fold_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 (mus->semi_fold_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 (mus->semi_fold_b_)
84             done_count_ ++;
85         }
86       
87       if (done_count_ < mus->repeats_i_ && alternative_cons_l_)
88         {
89           if (mus->semi_fold_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   New_repeated_music const* mus =dynamic_cast<New_repeated_music const*> (music_l_);
117   alternative_cons_l_ = (mus->alternatives_p_)
118     ? mus->alternatives_p_->music_p_list_p_->head_
119     : 0;
120
121   for (Cons<Music> *p = alternative_cons_l_; p; p = p->next_)
122     alternative_count_i_ ++;
123
124   if (mus->repeat_body_p_)
125     {
126       current_iter_p_  = get_iterator_p (mus->repeat_body_p_);
127       do_main_b_ = true;
128     }
129   else if (alternative_cons_l_)
130     {
131       current_iter_p_ = get_iterator_p (alternative_cons_l_->car_);
132       do_main_b_ = false;
133     }
134 }
135
136 void
137 Unfolded_repeat_iterator::do_process_and_next (Moment m) 
138 {
139   if (!m)
140     {
141       bool success = report_to_l ()->try_music (music_l_);
142       if (!success)
143         music_l_->warning ( _("No one to print a volta bracket"));
144     }
145   while (1)
146     {
147       while (!current_iter_p_->ok ())
148         {
149           next_element();
150
151           if (!current_iter_p_)
152             return;
153         }
154       
155       if (m - done_mom_ >= current_iter_p_->next_moment ())
156         current_iter_p_->process_and_next (m - done_mom_);
157       else
158         return;
159     }
160 }
161   
162 void
163 Unfolded_repeat_iterator::do_print () const
164 {
165 #ifndef NPRINT
166   DOUT << "count " << done_count_ << "done time " << done_mom_ << '\n';
167   DOUT << "current: ";
168   current_iter_p_->print();
169 #endif
170 }