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