2 time-scaled-music-iterator.cc -- implement Time_scaled_music_iterator
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>,
7 Erik Sandberg <mandolaerik@gmail.com>
12 #include "international.hh"
14 #include "music-wrapper-iterator.hh"
17 Iterates \times, by sending TupletSpanEvents at the start/end of each
18 tuplet bracket. Extra stop/start events are sent at regular
19 intervals if tupletSpannerDuration is set.
21 class Time_scaled_music_iterator : public Music_wrapper_iterator
24 DECLARE_SCHEME_CALLBACK (constructor, ());
26 DECLARE_CLASSNAME(Time_scaled_music_iterator);
27 Time_scaled_music_iterator ();
29 virtual void process (Moment m);
30 virtual void construct_children ();
31 virtual void derived_mark () const;
32 virtual Moment pending_moment () const;
35 /* tupletSpannerDuration */
36 Moment spanner_duration_;
38 /* next time to add a stop/start pair */
39 Moment next_split_mom_;
41 /* Recycle start/stop events if tupletSpannerDuration is set. */
47 Context_handle tuplet_handler_;
50 Time_scaled_music_iterator::Time_scaled_music_iterator ()
52 spanner_duration_ = next_split_mom_ = 0;
58 Time_scaled_music_iterator::pending_moment () const
63 Moment next_mom = Music_wrapper_iterator::pending_moment ();
65 if (spanner_duration_.to_bool () &&
66 next_mom.main_part_ > next_split_mom_)
68 next_mom = next_split_mom_;
76 Time_scaled_music_iterator::process (Moment m)
81 descend_to_bottom_context ();
82 report_event (start_);
83 tuplet_handler_.set_context (get_outlet());
86 if (spanner_duration_.to_bool () &&
87 m.main_part_ == next_split_mom_)
89 descend_to_bottom_context ();
90 stop_->send_to_context (tuplet_handler_.get_outlet ());
92 tuplet_handler_.set_context (get_outlet ());
93 report_event (start_);
95 next_split_mom_ += spanner_duration_;
96 /* avoid sending events twice at the end */
97 if (next_split_mom_ == get_music ()->get_length ().main_part_)
98 next_split_mom_.set_infinite (1);
101 Music_wrapper_iterator::process(m);
102 if (child_iter_ && child_iter_->ok ())
103 descend_to_child (child_iter_->get_outlet ());
105 if (m.main_part_ == music_get_length ().main_part_)
107 stop_->send_to_context (tuplet_handler_.get_outlet ());
108 tuplet_handler_.set_context (0);
113 Time_scaled_music_iterator::construct_children ()
116 Inheritance trickery:
117 Time_scaled_music_iterator::construct_children initialises start_
118 and stop_, and calls Sequential_music::construct_children, which
119 in turn calls Time_scaled_music_iterator::get_music which reads
123 Music *mus = get_music ();
124 Input *origin = mus->origin ();
126 SCM tuplet_symbol = ly_symbol2scm ("TupletSpanEvent");
127 SCM start_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"), tuplet_symbol, scm_from_int (START));
128 start_ = unsmob_music (start_scm);
129 start_->set_spot (*origin);
130 start_->set_property ("numerator", mus->get_property ("numerator"));
131 start_->set_property ("denominator", mus->get_property ("denominator"));
132 start_->set_property ("tweaks", mus->get_property ("tweaks"));
135 SCM stop_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"), tuplet_symbol, scm_from_int (STOP));
136 stop_ = unsmob_music (stop_scm);
137 stop_->set_spot (*origin);
139 Moment *mp = unsmob_moment (get_outlet ()->get_property ("tupletSpannerDuration"));
143 spanner_duration_ = mp->main_part_;
144 next_split_mom_ = spanner_duration_;
147 Music_wrapper_iterator::construct_children ();
149 if (child_iter_ && child_iter_->ok ())
150 descend_to_child (child_iter_->get_outlet ());
154 Time_scaled_music_iterator::derived_mark () const
157 scm_gc_mark (start_->self_scm ());
159 scm_gc_mark (stop_->self_scm ());
161 Music_wrapper_iterator::derived_mark ();
164 IMPLEMENT_CTOR_CALLBACK (Time_scaled_music_iterator);