]> git.donarmstrong.com Git - lilypond.git/blob - lily/unfolded-repeat-iterator.cc
patch::: 1.3.86.jcn2
[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--2000 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 * mus =dynamic_cast<Repeated_music *> (music_l_);
44   delete current_iter_p_;
45   current_iter_p_ =0;
46
47
48   if (do_main_b_)
49     {
50       done_mom_ += mus->body ()->length_mom ();
51
52       if (!mus->volta_fold_b_)
53         done_count_ ++;
54      
55       if (gh_pair_p (alternative_cons_))
56         {
57           current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
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->body ());
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_)
73         {
74           done_mom_ += unsmob_music (gh_car (alternative_cons_))->length_mom ();
75
76           if (mus->volta_fold_b_ || 
77               mus->repeats_i_ - done_count_  < alternative_count_i_)
78             alternative_cons_ = gh_cdr (alternative_cons_);
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_ && gh_pair_p (alternative_cons_))
88         {
89           if (mus->volta_fold_b_)
90             current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
91           else
92             {
93               current_iter_p_ = get_iterator_p (mus->body ());
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 * mus =dynamic_cast<Repeated_music *> (music_l_);
117   
118   alternative_cons_ = (mus->alternatives ())
119     ? mus->alternatives ()->music_list ()
120     : SCM_EOL;
121
122   for (SCM p = alternative_cons_; gh_pair_p (p); p = gh_cdr (p))
123     alternative_count_i_ ++;
124
125   if (mus->body ())
126     {
127       current_iter_p_  = get_iterator_p (mus->body ());
128       do_main_b_ = true;
129     }
130   else if (gh_pair_p (alternative_cons_))
131     {
132       current_iter_p_ = get_iterator_p (unsmob_music (gh_car (alternative_cons_)));
133       do_main_b_ = false;
134     }
135 }
136
137 void
138 Unfolded_repeat_iterator::do_process (Moment m) 
139 {
140   if (!m)
141     {
142       Music_iterator *yeah = try_music (music_l_);
143       if (yeah)
144         set_translator (yeah->report_to_l ());
145       else
146         music_l_->origin ()->warning ( _("no one to print a volta bracket"));
147     }
148   while (1)
149     {
150       while (!current_iter_p_->ok ())
151         {
152           next_element();
153
154           if (!current_iter_p_)
155             return;
156         }
157       
158       if (m - done_mom_ >= current_iter_p_->next_moment ())
159         current_iter_p_->process (m - done_mom_);
160       else
161         return;
162     }
163 }
164   
165 void
166 Unfolded_repeat_iterator::do_print () const
167 {
168 #ifndef NPRINT
169   DEBUG_OUT << "count " << done_count_ << "done time " << Rational (done_mom_) << '\n';
170   DEBUG_OUT << "current: ";
171   current_iter_p_->print();
172 #endif
173 }
174
175 Music_iterator* 
176 Unfolded_repeat_iterator::try_music_in_children (Music  * m) const
177 {
178   return  current_iter_p_->try_music (m);
179 }