2 grob-pq-engraver.cc -- implement Grob_pq_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 2001--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "translator-group.hh"
10 #include "engraver.hh"
19 Grob_mom (Grob*gr, Moment e)
26 int compare (Grob_mom const &a, Grob_mom const &b)
28 return Moment::compare (a.end_, b.end_);
31 class Grob_pq_engraver: public Engraver
34 TRANSLATOR_DECLARATIONS(Grob_pq_engraver);
36 Array<Grob_mom> current_grobs_;
38 virtual void initialize ();
39 virtual void acknowledge_grob (Grob_info);
40 virtual void start_translation_timestep ();
41 virtual void stop_translation_timestep ();
45 Grob_pq_engraver::Grob_pq_engraver()
51 Grob_pq_engraver::initialize ()
53 daddy_trans_l_->set_property ("busyGrobs", SCM_EOL);
57 Grob_pq_engraver::acknowledge_grob (Grob_info gi)
59 Music * m = gi.music_cause ();
63 Moment n = now_mom ();
64 Moment l = m->length_mom ();
71 l.grace_part_ = l.main_part_;
75 current_grobs_.push (Grob_mom (gi.grob_l_, n + l));
80 Grob_pq_engraver::stop_translation_timestep ()
82 Moment now = now_mom();
84 current_grobs_.sort (&compare);
86 SCM busy = get_property ("busyGrobs");
87 while (gh_pair_p (busy) && *unsmob_moment (gh_caar (busy)) == now)
93 SCM * current_cell = &start;
96 while (i < current_grobs_.size ())
99 stop.set_infinite (1);
101 if (gh_pair_p (busy))
103 SCM h = gh_car (busy);
104 stop = *unsmob_moment (gh_car (h));
107 Moment current_stop = current_grobs_[i].end_;
108 if (current_stop <= stop)
110 SCM new_entry = gh_cons (current_stop.smobbed_copy(),
111 current_grobs_[i].grob_->self_scm ());
117 *current_cell = gh_cons (new_entry, busy);
118 current_cell = SCM_CDRLOC(*current_cell);
123 if current_stop > stop, then stop != infty, and we
124 apparently have a next entry */
125 busy = gh_cdr (busy);
126 current_cell = SCM_CDRLOC(*current_cell);
130 current_grobs_.clear ();
131 daddy_trans_l_->set_property ("busyGrobs", start);
135 Grob_pq_engraver::start_translation_timestep ()
137 Moment now = now_mom();
139 SCM start_busy = get_property ("busyGrobs");
140 SCM busy = start_busy;
141 while (gh_pair_p (busy) && *unsmob_moment (gh_caar (busy)) < now)
143 programming_error ("Skipped something ?!");
145 busy = gh_cdr (busy);
148 if (start_busy != busy)
149 daddy_trans_l_->set_property ("busyGrobs", busy);
153 ENTER_DESCRIPTION(Grob_pq_engraver,
154 /* descr */ "Administrate when certain grobs (eg. note heads) stop playing.
157 /* acks */ "grob-interface",
158 /* reads */ "busyGrobs",
159 /* write */ "busyGrobs");