]> git.donarmstrong.com Git - lilypond.git/blob - lily/unfolded-repeat-iterator.cc
release: 1.2.12
[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 (!mus->volta_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->volta_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->volta_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->volta_fold_b_)
84             done_count_ ++;
85         }
86       
87       if (done_count_ < mus->repeats_i_ && alternative_cons_l_)
88         {
89           if (mus->volta_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   Repeated_music const* mus =dynamic_cast<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       Music_iterator *yeah = try_music (music_l_);
142       if (yeah)
143         set_translator (yeah->report_to_l ());
144       else
145         music_l_->warning ( _("no one to print a volta bracket"));
146     }
147   while (1)
148     {
149       while (!current_iter_p_->ok ())
150         {
151           next_element();
152
153           if (!current_iter_p_)
154             return;
155         }
156       
157       if (m - done_mom_ >= current_iter_p_->next_moment ())
158         current_iter_p_->process_and_next (m - done_mom_);
159       else
160         return;
161     }
162 }
163   
164 void
165 Unfolded_repeat_iterator::do_print () const
166 {
167 #ifndef NPRINT
168   DEBUG_OUT << "count " << done_count_ << "done time " << done_mom_ << '\n';
169   DEBUG_OUT << "current: ";
170   current_iter_p_->print();
171 #endif
172 }
173
174 Music_iterator* 
175 Unfolded_repeat_iterator::try_music_in_children (Music const * m) const
176 {
177   return  current_iter_p_->try_music (m);
178 }