2 part-combine-music-iterator.cc -- implement New_pc_iterator
4 source file of the GNU LilyPond music typesetter
6 (c) 2000--2003 Jan Nieuwenhuizen <janneke@gnu.org>
9 #include "part-combine-music-iterator.hh"
10 #include "translator-group.hh"
12 #include "music-sequence.hh"
13 #include "lily-guile.hh"
15 #include "music-iterator.hh"
16 #include "interpretation-context-handle.hh"
18 class New_pc_iterator : public Music_iterator
21 VIRTUAL_COPY_CONS (Music_iterator);
24 DECLARE_SCHEME_CALLBACK(constructor, ());
26 virtual void derived_substitute (Translator_group*f, Translator_group*t) ;
27 virtual void derived_mark () const;
28 New_pc_iterator (New_pc_iterator const &);
30 virtual void construct_children ();
31 virtual Moment pending_moment () const;
32 virtual void do_quit();
33 virtual void process (Moment);
35 virtual SCM get_pending_events (Moment)const;
36 virtual Music_iterator *try_music_in_children (Music *) const;
38 virtual bool ok () const;
41 Music_iterator * first_iter_;
42 Music_iterator * second_iter_;
46 Interpretation_context_handle one_;
47 Interpretation_context_handle two_;
48 Interpretation_context_handle shared_;
55 New_pc_iterator::New_pc_iterator ()
60 split_list_ = SCM_EOL;
64 New_pc_iterator::derived_mark () const
67 scm_gc_mark (first_iter_->self_scm());
69 scm_gc_mark(second_iter_->self_scm());
73 New_pc_iterator::derived_substitute (Translator_group*f,
77 first_iter_->substitute_outlet (f,t);
79 second_iter_->substitute_outlet (f,t);
83 New_pc_iterator::do_quit ()
90 one_ .set_translator (0);
91 two_.set_translator (0);
92 shared_.set_translator (0);
95 New_pc_iterator::New_pc_iterator (New_pc_iterator const &src)
96 : Music_iterator (src)
102 first_iter_ = src.first_iter_->clone ();
103 if (src.second_iter_)
104 second_iter_ = src.second_iter_->clone ();
106 split_list_ = src.split_list_;
109 scm_gc_unprotect_object (first_iter_->self_scm());
111 scm_gc_unprotect_object (second_iter_->self_scm());
115 New_pc_iterator::pending_moment () const
119 if (first_iter_->ok ())
120 p = p <? first_iter_->pending_moment ();
122 if (second_iter_->ok ())
123 p = p <? second_iter_->pending_moment ();
128 New_pc_iterator::ok () const
130 return first_iter_->ok () || second_iter_->ok ();
134 New_pc_iterator::together ()
136 first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
137 second_iter_->substitute_outlet (two_.report_to (), shared_.report_to ());
141 New_pc_iterator::apart ()
143 first_iter_->substitute_outlet (shared_.report_to (),one_.report_to ());
144 second_iter_->substitute_outlet (shared_.report_to (), two_.report_to ());
149 New_pc_iterator::construct_children ()
151 split_list_ = get_music ()->get_mus_property ("split-list");
152 SCM lst = get_music ()->get_mus_property ("elements");
155 = report_to ()->find_create_translator (ly_symbol2scm ("Voice"),
158 tr->execute_pushpop_property (ly_symbol2scm ("NoteHead"),
159 ly_symbol2scm ("font-size"), gh_int2scm (3));
162 shared_ .set_translator (tr);
165 Translator_group *one = tr->find_create_translator (ly_symbol2scm ("Voice"),
168 one_.set_translator (one);
169 one->execute_pushpop_property (ly_symbol2scm ("Stem"),
170 ly_symbol2scm ("direction"), gh_int2scm (1));
172 set_translator (one);
173 first_iter_ = unsmob_iterator (get_iterator (unsmob_music (gh_car (lst))));
176 Translator_group *two = tr->find_create_translator (ly_symbol2scm ("Voice"),
178 two_.set_translator (two);
179 two_.report_to ()->execute_pushpop_property (ly_symbol2scm ("Stem"),
180 ly_symbol2scm ("direction"), gh_int2scm (-1));
181 set_translator (two);
182 second_iter_ = unsmob_iterator (get_iterator (unsmob_music (gh_cadr (lst))));
189 New_pc_iterator::process (Moment m)
191 Moment now = report_to ()->now_mom ();
194 for (; gh_pair_p (split_list_); split_list_ = gh_cdr (split_list_))
196 splitm = unsmob_moment (gh_caar (split_list_));
200 if (gh_cdar (split_list_) == ly_symbol2scm ("together"))
202 else if (gh_cdar (split_list_) == ly_symbol2scm ("apart"))
205 programming_error ("Unknown split directive.");
208 if (first_iter_->ok ())
209 first_iter_->process (m);
211 if (second_iter_->ok ())
212 second_iter_->process (m);
216 New_pc_iterator::try_music_in_children (Music *m) const
218 Music_iterator * i = first_iter_->try_music (m);
222 return second_iter_->try_music (m);
227 New_pc_iterator::get_pending_events (Moment m)const
231 s = gh_append2 (s,first_iter_->get_pending_events (m));
233 s = gh_append2 (second_iter_->get_pending_events (m),s);
237 IMPLEMENT_CTOR_CALLBACK (New_pc_iterator);