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