Bump version.
[lilypond.git] / lily / time-scaled-music-iterator.cc
blobe70c44a4854a3dfabf5d0709bd5b4e3782d0fd2a
1 /*
2 time-scaled-music-iterator.cc -- implement Time_scaled_music_iterator
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>,
7 Erik Sandberg <mandolaerik@gmail.com>
8 */
10 #include "context.hh"
11 #include "input.hh"
12 #include "international.hh"
13 #include "music.hh"
14 #include "music-wrapper-iterator.hh"
15 #include "stream-event.hh"
18 Iterates \times, by sending TupletSpanEvents at the start/end of each
19 tuplet bracket. Extra stop/start events are sent at regular
20 intervals if tupletSpannerDuration is set.
22 class Time_scaled_music_iterator : public Music_wrapper_iterator
24 public:
25 DECLARE_SCHEME_CALLBACK (constructor, ());
26 /* construction */
27 DECLARE_CLASSNAME (Time_scaled_music_iterator);
28 Time_scaled_music_iterator ();
29 protected:
30 virtual void process (Moment m);
31 virtual void construct_children ();
32 virtual void derived_mark () const;
33 virtual Moment pending_moment () const;
35 Music *create_event (Direction d);
37 private:
39 /* tupletSpannerDuration */
40 Moment spanner_duration_;
42 /* next time to add a stop/start pair */
43 Moment next_split_mom_;
45 /* Recycle start/stop events if tupletSpannerDuration is set. */
46 SCM synthesized_events_;
48 Context_handle tuplet_handler_;
51 Music*
52 Time_scaled_music_iterator::create_event (Direction d)
54 SCM ev_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"),
55 ly_symbol2scm ("TupletSpanEvent"),
56 scm_from_int (d));
58 Music *mus = get_music ();
60 Music *ev = unsmob_music (ev_scm);
61 ev->set_spot (*mus->origin ());
62 if (d == START)
64 ev->set_property ("numerator", mus->get_property ("numerator"));
65 ev->set_property ("denominator", mus->get_property ("denominator"));
66 ev->set_property ("tweaks", mus->get_property ("tweaks"));
67 ev->set_property ("length", spanner_duration_.smobbed_copy ());
70 synthesized_events_ = scm_cons (ev_scm, synthesized_events_);
71 return ev;
75 Time_scaled_music_iterator::Time_scaled_music_iterator ()
77 spanner_duration_ = next_split_mom_ = 0;
78 synthesized_events_ = SCM_EOL;
82 Moment
83 Time_scaled_music_iterator::pending_moment () const
85 Moment next_mom = Music_wrapper_iterator::pending_moment ();
86 next_mom = min (next_mom, next_split_mom_);
88 return next_mom;
92 void
93 Time_scaled_music_iterator::process (Moment m)
95 if (spanner_duration_.to_bool () &&
96 m.main_part_ == next_split_mom_)
98 descend_to_bottom_context ();
99 if (tuplet_handler_.get_outlet ())
100 create_event (STOP)->send_to_context (tuplet_handler_.get_outlet ());
102 if (m.main_part_ < music_get_length ().main_part_)
104 tuplet_handler_.set_context (get_outlet ());
105 report_event (create_event (START));
107 next_split_mom_ += spanner_duration_;
109 else
111 tuplet_handler_.set_context (0);
114 Music_wrapper_iterator::process (m);
115 if (child_iter_ && child_iter_->ok ())
116 descend_to_child (child_iter_->get_outlet ());
120 void
121 Time_scaled_music_iterator::construct_children ()
123 spanner_duration_ = music_get_length ();
125 Moment *mp = unsmob_moment (get_outlet ()->get_property ("tupletSpannerDuration"));
126 if (mp)
127 spanner_duration_ = min (mp->main_part_, spanner_duration_);
129 Music_wrapper_iterator::construct_children ();
131 if (child_iter_ && child_iter_->ok ())
132 descend_to_child (child_iter_->get_outlet ());
135 void
136 Time_scaled_music_iterator::derived_mark () const
138 scm_gc_mark (synthesized_events_);
139 Music_wrapper_iterator::derived_mark ();
142 IMPLEMENT_CTOR_CALLBACK (Time_scaled_music_iterator);