]> git.donarmstrong.com Git - lilypond.git/blob - lily/simultaneous-music-iterator.cc
Run `make grand-replace'.
[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--2008 Han-Wen Nienhuys <hanwen@xs4all.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 ().c_str ());
54       Context *c = (j && create_separate_contexts_)
55         ? get_outlet ()->find_create_context (name, to_string (j), SCM_EOL)
56         : get_outlet ();
57
58       if (!c)
59         c = get_outlet ();
60
61       mi->init_context (mus, c);
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->quit ();
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         i->process (until);
84       if (!i->ok ())
85         {
86           i->quit ();
87           *proc = scm_cdr (*proc);
88         }
89       else
90         proc = SCM_CDRLOC (*proc);
91     }
92 }
93
94 Moment
95 Simultaneous_music_iterator::pending_moment () const
96 {
97   Moment next;
98   next.set_infinite (1);
99
100   for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
101     {
102       Music_iterator *it = unsmob_iterator (scm_car (s));
103       next = min (next, it->pending_moment ());
104     }
105
106   return next;
107 }
108
109 bool
110 Simultaneous_music_iterator::ok () const
111 {
112   bool run_always_ok = false;
113   for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
114     {
115       Music_iterator *it = unsmob_iterator (scm_car (s));
116       if (!it->run_always ())
117         return true;
118       else
119         run_always_ok = run_always_ok || it->ok ();
120     }
121   return run_always_ok;
122 }
123
124 bool
125 Simultaneous_music_iterator::run_always () const
126 {
127   for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
128     {
129       Music_iterator *it = unsmob_iterator (scm_car (s));
130       if (it->run_always ())
131         return true;
132     }
133   return false;
134 }
135
136 void
137 Simultaneous_music_iterator::do_quit ()
138 {
139   for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
140     unsmob_iterator (scm_car (s))->quit ();
141 }
142
143 IMPLEMENT_CTOR_CALLBACK (Simultaneous_music_iterator);