]> git.donarmstrong.com Git - lilypond.git/blob - lily/simultaneous-music-iterator.cc
lily/include/context-def.hh: rename from translator-def.hh
[lilypond.git] / lily / simultaneous-music-iterator.cc
1 /*
2   Simultaneous_music-iterator.cc -- implement Simultaneous_music_iterator
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "translator-group.hh"
10 #include "warn.hh"
11 #include "simultaneous-music-iterator.hh"
12 #include "music-list.hh"
13 #include "context-def.hh"
14
15
16 Simultaneous_music_iterator::Simultaneous_music_iterator ()
17 {
18   separate_contexts_b_ = false;
19   children_list_ = SCM_EOL;
20 }
21
22 Simultaneous_music_iterator::Simultaneous_music_iterator (Simultaneous_music_iterator const& src)
23   : Music_iterator (src)
24 {
25   separate_contexts_b_
26     = src.separate_contexts_b_;
27   children_list_ = SCM_EOL;
28   
29   SCM children_list = SCM_EOL;
30   SCM *tail  = &children_list; 
31   for (SCM s = src.children_list_; gh_pair_p (s); s = gh_cdr(s))
32     {
33       Music_iterator *i = unsmob_iterator (gh_car (s));
34       SCM cl = i->clone ()->self_scm();
35       *tail = scm_cons (cl, *tail);
36       tail = SCM_CDRLOC (*tail);
37       scm_gc_unprotect_object (cl);
38     }
39
40   children_list_ = children_list;
41   scm_remember_upto_here_1 (children_list);
42 }
43
44 void
45 Simultaneous_music_iterator::derived_mark()const
46 {
47   scm_gc_mark (children_list_);
48 }
49
50 void
51 Simultaneous_music_iterator::derived_substitute(Translator_group*f,Translator_group*t)
52 {
53   for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr(s))
54     unsmob_iterator (gh_car (s))-> substitute_outlet (f,t);
55 }
56
57 SCM
58 Simultaneous_music_iterator::get_pending_events (Moment m)const
59 {
60   SCM l = SCM_EOL;
61   for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr(s))
62     {
63       l = gh_append2 (unsmob_iterator (gh_car (s))->get_pending_events (m), l);
64     }
65   return l;
66 }
67
68 void
69 Simultaneous_music_iterator::construct_children ()
70 {
71   int j = 0;
72
73   SCM i = get_music ()->get_mus_property ("elements");
74
75   children_list_ = SCM_EOL;
76   SCM * tail = &children_list_;
77   for (; gh_pair_p (i); i = ly_cdr (i), j++)
78     {
79       Music *mus = unsmob_music (ly_car (i));
80
81       SCM scm_iter = get_static_get_iterator (mus);
82       Music_iterator * mi = unsmob_iterator (scm_iter);
83
84       /* if separate_contexts_b_ is set, create a new context with the
85          number number as name */
86
87       SCM name = unsmob_context_def (report_to ()->definition_)->get_context_name ();
88       Translator_group * t = (j && separate_contexts_b_)
89         ? report_to ()->find_create_translator (name, to_string (j), SCM_EOL)
90         : report_to ();
91
92       if (!t)
93         t = report_to ();
94
95       mi->init_translator (mus, t);
96       mi->construct_children ();
97
98       if (mi->ok ()) 
99         {
100           *tail = scm_cons (scm_iter, *tail);
101           tail = SCM_CDRLOC (*tail);
102         }
103       else
104         mi->set_translator (0);
105     }
106 }
107
108 void
109 Simultaneous_music_iterator::process (Moment until)
110 {
111   SCM *proc = &children_list_; 
112   while(gh_pair_p (*proc))
113     {
114       Music_iterator * i = unsmob_iterator (gh_car (*proc));
115       if (i->run_always ()
116           || i->pending_moment () == until) 
117         {
118           i->process (until);
119         }
120       if (!i->ok ())
121         {
122           i->quit ();
123           *proc = gh_cdr (*proc);
124         }
125       else
126         {
127           proc = SCM_CDRLOC(*proc);
128         }
129     }
130 }
131
132 void
133 Simultaneous_music_iterator::skip (Moment until)
134 {
135   SCM *proc = &children_list_; 
136   while(gh_pair_p (*proc))
137     {
138       Music_iterator * i = unsmob_iterator (gh_car (*proc));
139       if (i->pending_moment () <= until) 
140         {
141           i->skip (until);
142         }
143       if (!i->ok ())
144         {
145           i->quit ();
146           *proc = gh_cdr (*proc);
147         }
148       else
149         {
150           proc = SCM_CDRLOC(*proc);
151         }
152     }
153 }
154
155 Moment
156 Simultaneous_music_iterator::pending_moment () const
157 {
158   Moment next;
159   next.set_infinite (1);
160   
161   for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr(s))
162     {
163       Music_iterator * it = unsmob_iterator (gh_car (s));
164       next = next <? it->pending_moment ();
165     }
166   
167   return next;
168 }
169
170 bool
171 Simultaneous_music_iterator::ok () const
172 {
173   bool run_always_ok = false; 
174   for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr(s))
175     {
176       Music_iterator * it = unsmob_iterator (gh_car (s));
177       if (!it->run_always ())
178         return true;
179       else
180         run_always_ok =  run_always_ok || it->ok ();
181     }
182   return run_always_ok;
183 }
184
185 bool
186 Simultaneous_music_iterator::run_always () const
187 {
188   for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr(s))
189     {
190       Music_iterator * it = unsmob_iterator (gh_car (s));
191       if (it->run_always ())
192         return true;
193     }
194   return false;
195 }
196
197 Music_iterator*
198 Simultaneous_music_iterator::try_music_in_children (Music *m) const
199 {
200   Music_iterator * b=0;
201   for (SCM s = children_list_; !b && gh_pair_p (s); s = gh_cdr(s))
202     b =unsmob_iterator (gh_car (s))->try_music (m);
203   return b;
204 }
205
206 void
207 Simultaneous_music_iterator::do_quit ()
208 {
209   for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr(s))
210     unsmob_iterator (gh_car (s))->quit();
211 }
212
213
214 IMPLEMENT_CTOR_CALLBACK (Simultaneous_music_iterator);