*** empty log message ***
[lilypond.git] / lily / simultaneous-music-iterator.cc
blob766efa44e750b6c0fffeed2e53a2e67ec11d6593
1 /*
2 Simultaneous_music-iterator.cc -- implement Simultaneous_music_iterator
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
9 #include "context.hh"
10 #include "warn.hh"
11 #include "simultaneous-music-iterator.hh"
12 #include "music-list.hh"
13 #include "context-def.hh"
16 Simultaneous_music_iterator::Simultaneous_music_iterator ()
18 create_separate_contexts_ = false;
19 children_list_ = SCM_EOL;
23 void
24 Simultaneous_music_iterator::derived_mark () const
26 scm_gc_mark (children_list_);
29 void
30 Simultaneous_music_iterator::derived_substitute (Context *f,Context *t)
32 for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr (s))
33 unsmob_iterator (gh_car (s))-> substitute_outlet (f,t);
36 void
37 Simultaneous_music_iterator::construct_children ()
39 int j = 0;
41 SCM i = get_music ()->get_property ("elements");
43 children_list_ = SCM_EOL;
44 SCM * tail = &children_list_;
45 for (; gh_pair_p (i); i = ly_cdr (i), j++)
47 Music *mus = unsmob_music (ly_car (i));
49 SCM scm_iter = get_static_get_iterator (mus);
50 Music_iterator * mi = unsmob_iterator (scm_iter);
52 /* if create_separate_contexts_ is set, create a new context with the
53 number number as name */
55 SCM name = unsmob_context_def (get_outlet ()->definition_)->get_context_name ();
56 Context * t = (j && create_separate_contexts_)
57 ? get_outlet ()->find_create_context (name, to_string (j), SCM_EOL)
58 : get_outlet ();
60 if (!t)
61 t = get_outlet ();
63 mi->init_translator (mus, t);
64 mi->construct_children ();
66 if (mi->ok ())
68 *tail = scm_cons (scm_iter, *tail);
69 tail = SCM_CDRLOC (*tail);
71 else
72 mi->set_translator (0);
76 void
77 Simultaneous_music_iterator::process (Moment until)
79 SCM *proc = &children_list_;
80 while (gh_pair_p (*proc))
82 Music_iterator * i = unsmob_iterator (gh_car (*proc));
83 if (i->run_always ()
84 || i->pending_moment () == until)
86 i->process (until);
88 if (!i->ok ())
90 i->quit ();
91 *proc = gh_cdr (*proc);
93 else
95 proc = SCM_CDRLOC (*proc);
100 Moment
101 Simultaneous_music_iterator::pending_moment () const
103 Moment next;
104 next.set_infinite (1);
106 for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr (s))
108 Music_iterator * it = unsmob_iterator (gh_car (s));
109 next = next <? it->pending_moment ();
112 return next;
115 bool
116 Simultaneous_music_iterator::ok () const
118 bool run_always_ok = false;
119 for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr (s))
121 Music_iterator * it = unsmob_iterator (gh_car (s));
122 if (!it->run_always ())
123 return true;
124 else
125 run_always_ok = run_always_ok || it->ok ();
127 return run_always_ok;
130 bool
131 Simultaneous_music_iterator::run_always () const
133 for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr (s))
135 Music_iterator * it = unsmob_iterator (gh_car (s));
136 if (it->run_always ())
137 return true;
139 return false;
142 Music_iterator*
143 Simultaneous_music_iterator::try_music_in_children (Music *m) const
145 Music_iterator * b=0;
146 for (SCM s = children_list_; !b && gh_pair_p (s); s = gh_cdr (s))
147 b =unsmob_iterator (gh_car (s))->try_music (m);
148 return b;
151 void
152 Simultaneous_music_iterator::do_quit ()
154 for (SCM s = children_list_; gh_pair_p (s); s = gh_cdr (s))
155 unsmob_iterator (gh_car (s))->quit ();
158 IMPLEMENT_CTOR_CALLBACK (Simultaneous_music_iterator);