2 grob-pq-engraver.cc -- implement Grob_pq_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 2001--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "engraver.hh"
18 static int compare (Grob_pq_entry const &a,
19 Grob_pq_entry const &b)
21 return Moment::compare (a.end_, b.end_);
25 class Grob_pq_engraver : public Engraver
28 TRANSLATOR_DECLARATIONS (Grob_pq_engraver);
30 virtual void initialize ();
31 DECLARE_ACKNOWLEDGER (grob);
32 void start_translation_timestep ();
33 void stop_translation_timestep ();
35 Array<Grob_pq_entry> started_now_;
38 Grob_pq_engraver::Grob_pq_engraver ()
43 Grob_pq_engraver::initialize ()
45 context ()->set_property ("busyGrobs", SCM_EOL);
48 LY_DEFINE (ly_grob_pq_less_p, "ly:grob-pq-less?",
49 2, 0, 0, (SCM a, SCM b),
50 "Compare 2 grob priority queue entries. Internal")
52 if (Moment::compare (*unsmob_moment (scm_car (a)),
53 *unsmob_moment (scm_car (b))) < 0)
60 Grob_pq_engraver::acknowledge_grob (Grob_info gi)
62 Music *m = gi.music_cause ();
65 && !gi.grob ()->internal_has_interface (ly_symbol2scm ("multi-measure-interface")))
67 Moment n = now_mom ();
68 Moment l = m->get_length ();
75 l.grace_part_ = l.main_part_;
85 started_now_.push (e);
90 Grob_pq_engraver::stop_translation_timestep ()
92 Moment now = now_mom ();
93 SCM start_busy = get_property ("busyGrobs");
94 SCM busy = start_busy;
95 while (scm_is_pair (busy) && *unsmob_moment (scm_caar (busy)) == now)
96 busy = scm_cdr (busy);
98 started_now_.sort (Grob_pq_entry::compare);
101 for (int i = 0; i < started_now_.size (); i++)
103 *tail = scm_acons (started_now_[i].end_.smobbed_copy (),
104 started_now_[i].grob_->self_scm (),
106 tail = SCM_CDRLOC (*tail);
109 busy = scm_merge_x (lst, busy, ly_grob_pq_less_p_proc);
110 context ()->set_property ("busyGrobs", busy);
112 started_now_.clear ();
116 Grob_pq_engraver::start_translation_timestep ()
118 Moment now = now_mom ();
120 SCM start_busy = get_property ("busyGrobs");
121 SCM busy = start_busy;
122 while (scm_is_pair (busy) && *unsmob_moment (scm_caar (busy)) < now)
125 The grob-pq-engraver is not water tight, and stuff like
126 tupletSpannerDuration confuses it.
128 busy = scm_cdr (busy);
131 if (start_busy != busy)
132 context ()->set_property ("busyGrobs", busy);
135 #include "translator.icc"
136 ADD_ACKNOWLEDGER (Grob_pq_engraver, grob);
137 ADD_TRANSLATOR (Grob_pq_engraver,
139 /* doc */ "Administrate when certain grobs (eg. note heads) stop playing",
142 /* read */ "busyGrobs",
143 /* write */ "busyGrobs");