]> git.donarmstrong.com Git - lilypond.git/blob - lily/music-iterator.cc
* ly/engraver-init.ly: reindent.
[lilypond.git] / lily / music-iterator.cc
1 /*
2   music-iterator.cc -- implement Music_iterator
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 /*
10   UGH. too many includes.
11 */
12
13 #include "music-iterator.hh"
14
15 #include <cstdio>
16
17 #include "warn.hh"
18 #include "context.hh"
19 #include "music-wrapper.hh"
20 #include "music-wrapper-iterator.hh"
21 #include "simple-music-iterator.hh"
22
23 #include "ly-smobs.icc"
24
25 Music_iterator::Music_iterator ()
26 {
27   music_ = 0;
28   smobify_self ();
29 }
30
31 Music_iterator::Music_iterator (Music_iterator const &)
32 {
33   assert (false);
34 }
35
36 Music_iterator::~Music_iterator ()
37 {
38 }
39
40 Context *
41 Music_iterator::get_outlet () const
42 {
43   return handle_.get_outlet ();
44 }
45
46 void
47 Music_iterator::set_context (Context *trans)
48 {
49   handle_.set_context (trans);
50 }
51
52 void
53 Music_iterator::construct_children ()
54 {
55 }
56
57 Moment
58 Music_iterator::pending_moment () const
59 {
60   return 0;
61 }
62
63 void
64 Music_iterator::process (Moment)
65 {
66 }
67
68 bool
69 Music_iterator::ok () const
70 {
71   return false;
72 }
73
74 SCM
75 Music_iterator::get_static_get_iterator (Music *m)
76 {
77   Music_iterator *p = 0;
78
79   SCM ctor = m->get_property ("iterator-ctor");
80   SCM iter = SCM_EOL;
81   if (ly_c_procedure_p (ctor))
82     {
83       iter = scm_call_0 (ctor);
84       p = unsmob_iterator (iter);
85     }
86   else
87     {
88       if (dynamic_cast<Music_wrapper *> (m))
89         p = new Music_wrapper_iterator;
90       else
91         p = new Simple_music_iterator;
92
93       iter = p->self_scm ();
94       scm_gc_unprotect_object (iter);
95     }
96
97   p->music_ = m;
98   assert (m);
99   p->music_length_ = m->get_length ();
100   p->start_mom_ = m->start_mom ();
101
102   return iter;
103 }
104
105 Moment
106 Music_iterator::music_get_length () const
107 {
108   return music_length_;
109 }
110
111 Moment
112 Music_iterator::music_start_mom ()const
113 {
114   return start_mom_;
115 }
116
117 void
118 Music_iterator::init_translator (Music *m, Context *report)
119 {
120   music_ = m;
121   assert (m);
122   if (! get_outlet ())
123     set_context (report);
124 }
125
126 void
127 Music_iterator::substitute_outlet (Context *f, Context *t)
128 {
129   if (get_outlet () == f)
130     set_context (t);
131   derived_substitute (f, t);
132 }
133
134 void
135 Music_iterator::derived_substitute (Context *, Context *)
136 {
137 }
138
139 SCM
140 Music_iterator::get_iterator (Music *m) const
141 {
142   SCM ip = get_static_get_iterator (m);
143   Music_iterator *p = unsmob_iterator (ip);
144
145   p->init_translator (m, get_outlet ());
146
147   p->construct_children ();
148   return ip;
149 }
150
151 /*
152   TODO: rename to prevent confusion between Context::try_music and
153   Iterator::try_music
154 */
155 Music_iterator *
156 Music_iterator::try_music (Music *m) const
157 {
158   bool b = get_outlet ()->try_music ((Music *)m); // ugh
159   Music_iterator *it = b ? (Music_iterator *) this : 0; // ugh
160   if (!it)
161     it = try_music_in_children (m);
162   return it;
163 }
164
165 Music_iterator *
166 Music_iterator::try_music_in_children (Music *) const
167 {
168   return 0;
169 }
170
171 IMPLEMENT_CTOR_CALLBACK (Music_iterator);
172
173 Music *
174 Music_iterator::get_music () const
175 {
176   return music_;
177 }
178
179 /****************************************************************/
180
181 IMPLEMENT_TYPE_P (Music_iterator, "ly:iterator?");
182 IMPLEMENT_SMOBS (Music_iterator);
183 IMPLEMENT_DEFAULT_EQUAL_P (Music_iterator);
184
185 SCM
186 Music_iterator::mark_smob (SCM smob)
187 {
188   Music_iterator *mus = (Music_iterator *)SCM_CELL_WORD_1 (smob);
189
190   mus->derived_mark ();
191   /*
192     Careful with GC, although we intend the following as pointers
193     only, we _must_ mark them.
194   */
195   if (mus->get_outlet ())
196     scm_gc_mark (mus->get_outlet ()->self_scm ());
197   if (mus->music_)
198     scm_gc_mark (mus->music_->self_scm ());
199
200   return SCM_EOL;
201 }
202
203 int
204 Music_iterator::print_smob (SCM sm, SCM port, scm_print_state*)
205 {
206   char s[1000];
207
208   Music_iterator *iter = unsmob_iterator (sm);
209   sprintf (s, "#<%s>", classname (iter));
210   scm_puts (s, port);
211   return 1;
212 }
213
214 void
215 Music_iterator::derived_mark ()const
216 {
217 }
218
219 void
220 Music_iterator::quit ()
221 {
222   do_quit ();
223   handle_.set_context (0);
224 }
225
226 void
227 Music_iterator::do_quit ()
228 {
229 }
230
231 bool
232 Music_iterator::run_always ()const
233 {
234   return false;
235 }
236
237 bool
238 is_child_context (Context *me, Context *child)
239 {
240   while (child && child != me)
241     {
242       child = child->get_parent_context ();
243     }
244
245   return child == me;
246 }
247
248 /*
249   move to context of child iterator if it is deeper down in the
250   hierarchy.
251 */
252 void
253 Music_iterator::descend_to_child (Context *child_report)
254 {
255   Context *me_report = get_outlet ();
256   if (is_child_context (me_report, child_report))
257     set_context (child_report);
258 }