]> git.donarmstrong.com Git - lilypond.git/blob - lily/simultaneous-music-iterator.cc
* lily/include/music-iterator.hh (class Music_iterator): remove
[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 void
58 Simultaneous_music_iterator::construct_children ()
59 {
60   int j = 0;
61
62   SCM i = get_music ()->get_mus_property ("elements");
63
64   children_list_ = SCM_EOL;
65   SCM * tail = &children_list_;
66   for (; gh_pair_p (i); i = ly_cdr (i), j++)
67     {
68       Music *mus = unsmob_music (ly_car (i));
69
70       SCM scm_iter = get_static_get_iterator (mus);
71       Music_iterator * mi = unsmob_iterator (scm_iter);
72
73       /* if separate_contexts_b_ is set, create a new context with the
74          number number as name */
75
76       SCM name = unsmob_context_def (get_outlet ()->definition_)->get_context_name ();
77       Translator_group * t = (j && separate_contexts_b_)
78         ? get_outlet ()->find_create_translator (name, to_string (j), SCM_EOL)
79         : get_outlet ();
80
81       if (!t)
82         t = get_outlet ();
83
84       mi->init_translator (mus, t);
85       mi->construct_children ();
86
87       if (mi->ok ()) 
88         {
89           *tail = scm_cons (scm_iter, *tail);
90           tail = SCM_CDRLOC (*tail);
91         }
92       else
93         mi->set_translator (0);
94     }
95 }
96
97 void
98 Simultaneous_music_iterator::process (Moment until)
99 {
100   SCM *proc = &children_list_; 
101   while(gh_pair_p (*proc))
102     {
103       Music_iterator * i = unsmob_iterator (gh_car (*proc));
104       if (i->run_always ()
105           || i->pending_moment () == until) 
106         {
107           i->process (until);
108         }
109       if (!i->ok ())
110         {
111           i->quit ();
112           *proc = gh_cdr (*proc);
113         }
114       else
115         {
116           proc = SCM_CDRLOC(*proc);
117         }
118     }
119 }
120
121 Moment
122 Simultaneous_music_iterator::pending_moment () const
123 {
124   Moment next;
125   next.set_infinite (1);
126   
127   for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr(s))
128     {
129       Music_iterator * it = unsmob_iterator (gh_car (s));
130       next = next <? it->pending_moment ();
131     }
132   
133   return next;
134 }
135
136 bool
137 Simultaneous_music_iterator::ok () const
138 {
139   bool run_always_ok = false; 
140   for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr(s))
141     {
142       Music_iterator * it = unsmob_iterator (gh_car (s));
143       if (!it->run_always ())
144         return true;
145       else
146         run_always_ok =  run_always_ok || it->ok ();
147     }
148   return run_always_ok;
149 }
150
151 bool
152 Simultaneous_music_iterator::run_always () const
153 {
154   for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr(s))
155     {
156       Music_iterator * it = unsmob_iterator (gh_car (s));
157       if (it->run_always ())
158         return true;
159     }
160   return false;
161 }
162
163 Music_iterator*
164 Simultaneous_music_iterator::try_music_in_children (Music *m) const
165 {
166   Music_iterator * b=0;
167   for (SCM s = children_list_; !b && gh_pair_p (s); s = gh_cdr(s))
168     b =unsmob_iterator (gh_car (s))->try_music (m);
169   return b;
170 }
171
172 void
173 Simultaneous_music_iterator::do_quit ()
174 {
175   for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr(s))
176     unsmob_iterator (gh_car (s))->quit();
177 }
178
179
180 IMPLEMENT_CTOR_CALLBACK (Simultaneous_music_iterator);