]> git.donarmstrong.com Git - lilypond.git/blob - lily/simultaneous-music-iterator.cc
release: 1.3.131
[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--2001 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 Simultaneous_music_iterator::Simultaneous_music_iterator ()
16 {
17   separate_contexts_b_ = false;
18 }
19
20 Simultaneous_music_iterator::Simultaneous_music_iterator (Simultaneous_music_iterator const& src)
21   : Music_iterator (src)
22 {
23   separate_contexts_b_ = src.separate_contexts_b_;
24   for (Cons<Music_iterator> *p = src.children_p_list_.head_; p; p = p->next_)
25     {
26       Music_iterator *i = p->car_;
27       children_p_list_.append (new Killing_cons<Music_iterator> (i->clone (), 0));
28     }
29 }
30
31 Simultaneous_music_iterator::~Simultaneous_music_iterator ()
32 {
33   children_p_list_.junk ();
34 }
35
36 SCM
37 Simultaneous_music_iterator::get_music (Moment m)const
38 {
39   SCM s = SCM_EOL;
40   for (Cons<Music_iterator> *p = children_p_list_.head_; p; p = p->next_)
41     {
42       s = gh_append2 (p->car_->get_music (m), s);
43     }
44   return s;
45 }
46
47 void
48 Simultaneous_music_iterator::construct_children()
49 {
50   int j = 0;
51   Music_sequence const *sim = dynamic_cast<Music_sequence const*> (music_l_);
52
53   SCM i = sim->music_list ();
54   for (; gh_pair_p(i); i = gh_cdr(i), j++)
55     {
56       Music *mus = unsmob_music (gh_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);