]> git.donarmstrong.com Git - lilypond.git/blob - lily/sequential-music-iterator.cc
patch::: 1.3.87.jcn1
[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--2000 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 #include "request-chord-iterator.hh"
14
15 Sequential_music_iterator::Sequential_music_iterator ()
16 {
17   cursor_ = 0;
18   here_mom_ = 0;
19   iter_p_ =0;
20 }
21
22 Sequential_music_iterator::Sequential_music_iterator (Sequential_music_iterator const &src)
23   : Music_iterator (src)
24 {
25   cursor_ = src.cursor_;
26   here_mom_ = src.here_mom_;
27   iter_p_ = src.iter_p_->clone ();
28 }
29
30 Sequential_music_iterator::~Sequential_music_iterator()
31 {
32   if (iter_p_)
33     {
34       /*      if (iter_p_->ok () )
35         music_l_->origin ()->warning (_ ("Must stop before this music ends"));
36       */
37       delete iter_p_;
38       iter_p_ = 0;
39     }
40 }
41
42
43 void
44 Sequential_music_iterator::construct_children()
45 {
46   cursor_ = dynamic_cast<Music_sequence const*> (music_l_)->music_list ();
47   
48   while (gh_pair_p (cursor_ ))
49     {
50       start_next_element();
51       if (!iter_p_->ok()) 
52         {
53           leave_element();
54         }
55       else 
56         {
57           set_sequential_music_translator();
58           break;
59         }
60     }
61 }
62
63 void 
64 Sequential_music_iterator::leave_element()
65 {
66   delete iter_p_;
67   iter_p_ =0;
68   Moment elt_time = unsmob_music (gh_car (cursor_))->length_mom ();
69   here_mom_ += elt_time;
70   cursor_ =gh_cdr (cursor_);
71 }
72
73 void
74 Sequential_music_iterator::start_next_element()
75 {
76   assert (!iter_p_);
77   iter_p_ = get_iterator_p (unsmob_music (gh_car (cursor_)));
78 }
79
80 void
81 Sequential_music_iterator::set_sequential_music_translator()
82 {
83   Translator_group  * child_report = child_report = iter_p_->report_to_l ();
84   if (dynamic_cast<Grace_iterator*> (iter_p_))
85     child_report = child_report->daddy_trans_l_;
86     
87   if (report_to_l()->depth_i () < child_report->depth_i ())
88     set_translator (child_report);
89 }
90
91
92 SCM
93 Sequential_music_iterator::get_music (Moment until)const
94 {
95 #if 1
96   /*
97      FIXME: get_music () is const, so we must operate on a copy of child-iter.
98
99      hmm, part-combiner does work on a copy; why copy again?
100      Also, simply `working on a copy' doesn't work: if request-chord's
101      get_music doesn't do next (), we'll stay in this loop forever?
102   */
103   
104   Sequential_music_iterator* urg = (Sequential_music_iterator*)this;
105   SCM s = SCM_EOL;
106   while (1) 
107       {
108         Moment local_until = until - here_mom_;
109         while (urg->iter_p_->ok ()) 
110           {
111             Moment here = iter_p_->pending_moment ();
112             if (here != local_until)
113               return s;
114             
115             s = gh_append2 (urg->iter_p_->get_music (local_until), s);
116           }
117           
118           if (!urg->iter_p_->ok ()) 
119             {
120               urg->leave_element ();
121               
122               if (gh_pair_p (urg->cursor_))
123                 urg->start_next_element ();
124               else
125                 return s;
126             }
127         }
128   return s;
129 #else
130   return SCM_EOL;
131 #endif
132 }
133
134 void
135 Sequential_music_iterator::process (Moment until)
136 {
137   if (ok ())
138     {
139       while (1) 
140         {
141           Moment local_until = until - here_mom_;
142           while (iter_p_->ok ()) 
143             {
144               Moment here = iter_p_->pending_moment ();
145               if (here != local_until)
146                 return ;
147               
148               iter_p_->process (local_until);
149             }
150           
151           if (!iter_p_->ok ()) 
152             {
153               set_sequential_music_translator ();
154               leave_element ();
155               
156               if (gh_pair_p (cursor_))
157                 start_next_element ();
158               else 
159                 return ;
160             }
161         }
162     }
163 }
164
165 Moment
166 Sequential_music_iterator::pending_moment() const
167 {
168   return iter_p_->pending_moment() + here_mom_;
169 }
170
171
172 bool
173 Sequential_music_iterator::ok() const
174 {
175   return iter_p_;
176 }
177
178 Music_iterator*
179 Sequential_music_iterator::try_music_in_children (Music *m) const
180
181   return iter_p_ ? iter_p_->try_music (m) : 0;
182 }