]> git.donarmstrong.com Git - lilypond.git/blob - lily/simultaneous-music-iterator.cc
release: 1.5.29
[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--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "translator-group.hh"
10 #include "debug.hh"
11 #include "simultaneous-music-iterator.hh"
12 #include "music-list.hh"
13 #include "killing-cons.tcc"
14
15
16 Simultaneous_music_iterator::Simultaneous_music_iterator ()
17 {
18   separate_contexts_b_ = false;
19 }
20
21 Simultaneous_music_iterator::Simultaneous_music_iterator (Simultaneous_music_iterator const& src)
22   : Music_iterator (src)
23 {
24   separate_contexts_b_ = src.separate_contexts_b_;
25   for (Cons<Music_iterator> *p = src.children_p_list_.head_; p; p = p->next_)
26     {
27       Music_iterator *i = p->car_;
28       children_p_list_.append (new Killing_cons<Music_iterator> (i->clone (), 0));
29     }
30 }
31
32 Simultaneous_music_iterator::~Simultaneous_music_iterator ()
33 {
34   children_p_list_.junk ();
35 }
36
37 SCM
38 Simultaneous_music_iterator::get_music (Moment m)const
39 {
40   SCM s = SCM_EOL;
41   for (Cons<Music_iterator> *p = children_p_list_.head_; p; p = p->next_)
42     {
43       s = gh_append2 (p->car_->get_music (m), s);
44     }
45   return s;
46 }
47
48 void
49 Simultaneous_music_iterator::construct_children ()
50 {
51   int j = 0;
52
53   SCM i = music_l ()->get_mus_property ("elements");
54   for (; gh_pair_p (i); i = ly_cdr (i), j++)
55     {
56       Music *mus = unsmob_music (ly_car (i));
57       Music_iterator * mi = static_get_iterator_p (mus);
58
59       /* if separate_contexts_b_ is set, create a new context with the
60          number number as name */
61       
62       Translator_group * t = (j && separate_contexts_b_)
63         ? report_to_l ()->find_create_translator_l (report_to_l ()->type_str_,
64                                                     to_str (j))
65         : report_to_l ();
66
67       if (!t)
68         t = report_to_l ();
69
70       mi->init_translator (mus, t);
71       mi->construct_children ();
72       
73       if (mi->ok ()) 
74         {
75           children_p_list_.append (new Killing_cons<Music_iterator> (mi,0));
76         }
77       else
78         delete mi;
79     }
80 }
81
82
83 void
84 Simultaneous_music_iterator::process (Moment until)
85 {
86   for (Cons<Music_iterator> **pp = &children_p_list_.head_; *pp;)
87     {
88       Music_iterator * i = (*pp)->car_;
89       if (i->pending_moment () == until) 
90         {
91           i->process (until);
92         }
93       if (!i->ok ())
94         delete children_p_list_.remove_cons (pp);
95       else
96         pp = & (*pp)->next_;
97     }
98 }
99
100 void
101 Simultaneous_music_iterator::skip (Moment until)
102 {
103   for (Cons<Music_iterator> **pp = &children_p_list_.head_; *pp;)
104     {
105       Music_iterator * i = (*pp)->car_;
106       if (i->pending_moment () <= until) 
107         {
108           i->skip (until);
109         }
110       if (!i->ok ())
111         delete children_p_list_.remove_cons (pp);
112       else
113         pp = & (*pp)->next_;
114     }
115 }
116
117 Moment
118 Simultaneous_music_iterator::pending_moment () const
119 {
120   Moment next;
121   next.set_infinite (1);
122   
123   for (Cons<Music_iterator> *p = children_p_list_.head_; p; p = p->next_)
124     next = next <? p->car_->pending_moment () ;
125   return next;
126 }
127
128
129
130 bool
131 Simultaneous_music_iterator::ok () const
132 {
133   return children_p_list_.head_;
134 }
135
136 Music_iterator*
137 Simultaneous_music_iterator::try_music_in_children (Music *m) const
138 {
139   Music_iterator * b=0;
140   for (Cons<Music_iterator> *p = children_p_list_.head_; !b && p; p = p->next_)
141     b =p->car_->try_music (m);
142   return b;
143 }
144
145
146
147 IMPLEMENT_CTOR_CALLBACK (Simultaneous_music_iterator);