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