Nitpick: ly:spanner-bound grob name slur -> spanner.
[lilypond.git] / lily / simultaneous-music-iterator.cc
blob0631ba9e8dba8ed7ab59284f8cf71f20a5755ffa
1 /*
2 simultaneous-music-iterator.cc -- implement Simultaneous_music_iterator
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
9 #include "simultaneous-music-iterator.hh"
10 #include "music.hh"
11 #include "context.hh"
12 #include "warn.hh"
13 #include "context-def.hh"
15 Simultaneous_music_iterator::Simultaneous_music_iterator ()
17 create_separate_contexts_ = false;
18 children_list_ = SCM_EOL;
21 void
22 Simultaneous_music_iterator::derived_mark () const
24 scm_gc_mark (children_list_);
27 void
28 Simultaneous_music_iterator::derived_substitute (Context *f, Context *t)
30 for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
31 unsmob_iterator (scm_car (s))->substitute_outlet (f, t);
34 void
35 Simultaneous_music_iterator::construct_children ()
37 int j = 0;
39 SCM i = get_music ()->get_property ("elements");
41 children_list_ = SCM_EOL;
42 SCM *tail = &children_list_;
43 for (; scm_is_pair (i); i = scm_cdr (i), j++)
45 Music *mus = unsmob_music (scm_car (i));
47 SCM scm_iter = get_static_get_iterator (mus);
48 Music_iterator *mi = unsmob_iterator (scm_iter);
50 /* if create_separate_contexts_ is set, create a new context with the
51 number number as name */
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 ();
58 if (!c)
59 c = get_outlet ();
61 mi->init_context (mus, c);
62 mi->construct_children ();
64 if (mi->ok ())
66 *tail = scm_cons (scm_iter, *tail);
67 tail = SCM_CDRLOC (*tail);
69 else
70 mi->quit ();
74 void
75 Simultaneous_music_iterator::process (Moment until)
77 SCM *proc = &children_list_;
78 while (scm_is_pair (*proc))
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 ())
86 i->quit ();
87 *proc = scm_cdr (*proc);
89 else
90 proc = SCM_CDRLOC (*proc);
94 Moment
95 Simultaneous_music_iterator::pending_moment () const
97 Moment next;
98 next.set_infinite (1);
100 for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
102 Music_iterator *it = unsmob_iterator (scm_car (s));
103 next = min (next, it->pending_moment ());
106 return next;
109 bool
110 Simultaneous_music_iterator::ok () const
112 bool run_always_ok = false;
113 for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
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 ();
121 return run_always_ok;
124 bool
125 Simultaneous_music_iterator::run_always () const
127 for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
129 Music_iterator *it = unsmob_iterator (scm_car (s));
130 if (it->run_always ())
131 return true;
133 return false;
136 void
137 Simultaneous_music_iterator::do_quit ()
139 for (SCM s = children_list_; scm_is_pair (s); s = scm_cdr (s))
140 unsmob_iterator (scm_car (s))->quit ();
143 IMPLEMENT_CTOR_CALLBACK (Simultaneous_music_iterator);