]> git.donarmstrong.com Git - lilypond.git/blob - lily/simultaneous-music-iterator.cc
Update.
[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--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "simultaneous-music-iterator.hh"
10 #include "music.hh"
11 #include "context.hh"
12 #include "warn.hh"
13 #include "context-def.hh"
14
15 Simultaneous_music_iterator::Simultaneous_music_iterator ()
16 {
17   create_separate_contexts_ = false;
18   children_list_ = SCM_EOL;
19 }
20
21 void
22 Simultaneous_music_iterator::derived_mark () const
23 {
24   scm_gc_mark (children_list_);
25 }
26
27 void
28 Simultaneous_music_iterator::derived_substitute (Context *f, Context *t)
29 {
30   for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
31     unsmob_iterator (scm_car (s))->substitute_outlet (f, t);
32 }
33
34 void
35 Simultaneous_music_iterator::construct_children ()
36 {
37   int j = 0;
38
39   SCM i = get_music ()->get_property ("elements");
40
41   children_list_ = SCM_EOL;
42   SCM *tail = &children_list_;
43   for (; scm_is_pair (i); i = scm_cdr (i), j++)
44     {
45       Music *mus = unsmob_music (scm_car (i));
46
47       SCM scm_iter = get_static_get_iterator (mus);
48       Music_iterator *mi = unsmob_iterator (scm_iter);
49
50       /* if create_separate_contexts_ is set, create a new context with the
51          number number as name */
52
53       SCM name = ly_symbol2scm (get_outlet ()->context_name ().to_str0 ());
54       Context *t = (j && create_separate_contexts_)
55         ? get_outlet ()->find_create_context (name, to_string (j), SCM_EOL)
56         : get_outlet ();
57
58       if (!t)
59         t = get_outlet ();
60
61       mi->init_translator (mus, t);
62       mi->construct_children ();
63
64       if (mi->ok ())
65         {
66           *tail = scm_cons (scm_iter, *tail);
67           tail = SCM_CDRLOC (*tail);
68         }
69       else
70         mi->set_context (0);
71     }
72 }
73
74 void
75 Simultaneous_music_iterator::process (Moment until)
76 {
77   SCM *proc = &children_list_;
78   while (scm_is_pair (*proc))
79     {
80       Music_iterator *i = unsmob_iterator (scm_car (*proc));
81       if (i->run_always ()
82           || i->pending_moment () == until)
83         {
84           i->process (until);
85         }
86       if (!i->ok ())
87         {
88           i->quit ();
89           *proc = scm_cdr (*proc);
90         }
91       else
92         {
93           proc = SCM_CDRLOC (*proc);
94         }
95     }
96 }
97
98 Moment
99 Simultaneous_music_iterator::pending_moment () const
100 {
101   Moment next;
102   next.set_infinite (1);
103
104   for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
105     {
106       Music_iterator *it = unsmob_iterator (scm_car (s));
107       next = next <? it->pending_moment ();
108     }
109
110   return next;
111 }
112
113 bool
114 Simultaneous_music_iterator::ok () const
115 {
116   bool run_always_ok = false;
117   for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
118     {
119       Music_iterator *it = unsmob_iterator (scm_car (s));
120       if (!it->run_always ())
121         return true;
122       else
123         run_always_ok = run_always_ok || it->ok ();
124     }
125   return run_always_ok;
126 }
127
128 bool
129 Simultaneous_music_iterator::run_always () const
130 {
131   for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
132     {
133       Music_iterator *it = unsmob_iterator (scm_car (s));
134       if (it->run_always ())
135         return true;
136     }
137   return false;
138 }
139
140 Music_iterator *
141 Simultaneous_music_iterator::try_music_in_children (Music *m) const
142 {
143   Music_iterator *b = 0;
144   for (SCM s = children_list_; !b && scm_is_pair (s); s = scm_cdr (s))
145     b = unsmob_iterator (scm_car (s))->try_music (m);
146   return b;
147 }
148
149 void
150 Simultaneous_music_iterator::do_quit ()
151 {
152   for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
153     unsmob_iterator (scm_car (s))->quit ();
154 }
155
156 IMPLEMENT_CTOR_CALLBACK (Simultaneous_music_iterator);