2 grob-pq-engraver.cc -- implement Grob_pq_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 2001--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "engraver.hh"
14 class Grob_pq_engraver: public Engraver
17 TRANSLATOR_DECLARATIONS (Grob_pq_engraver);
19 virtual void initialize ();
20 virtual void acknowledge_grob (Grob_info);
21 virtual void start_translation_timestep ();
22 virtual void stop_translation_timestep ();
26 Grob_pq_engraver::Grob_pq_engraver ()
31 Grob_pq_engraver::initialize ()
33 context ()->set_property ("busyGrobs", SCM_EOL);
36 LY_DEFINE (ly_grob_pq_less_p, "ly:grob-pq-less?",
37 2, 0 ,0, (SCM a, SCM b),
38 "Compare 2 grob priority queue entries. Internal")
40 if (Moment::compare (*unsmob_moment (scm_car (a)),
41 *unsmob_moment (scm_car (b))) < 0)
48 Grob_pq_engraver::acknowledge_grob (Grob_info gi)
50 Music * m = gi.music_cause ();
53 && !gi.grob_->internal_has_interface (ly_symbol2scm ("multi-measure-interface")))
55 Moment n = now_mom ();
56 Moment l = m->get_length ();
63 l.grace_part_ = l.main_part_;
68 SCM lst = scm_acons (end.smobbed_copy (),
69 gi.grob_->self_scm (),
72 SCM busy = get_property ("busyGrobs");
73 busy = scm_merge_x (lst, busy, ly_grob_pq_less_p_proc);
74 context ()->set_property ("busyGrobs", busy);
80 Grob_pq_engraver::stop_translation_timestep ()
82 Moment now = now_mom ();
83 SCM start_busy = get_property ("busyGrobs");
84 SCM busy = start_busy;
85 while (scm_is_pair (busy) && *unsmob_moment (scm_caar (busy)) == now)
87 busy = scm_cdr (busy);
90 if (start_busy != busy)
91 context ()->set_property ("busyGrobs", busy);
95 Grob_pq_engraver::start_translation_timestep ()
97 Moment now = now_mom ();
99 SCM start_busy = get_property ("busyGrobs");
100 SCM busy = start_busy;
101 while (scm_is_pair (busy) && *unsmob_moment (scm_caar (busy)) < now)
104 The grob-pq-engraver is not water tight, and stuff like
105 tupletSpannerDuration confuses it.
107 busy = scm_cdr (busy);
110 if (start_busy != busy)
111 context ()->set_property ("busyGrobs", busy);
115 ADD_TRANSLATOR (Grob_pq_engraver,
117 /* descr */ "Administrate when certain grobs (eg. note heads) stop playing; this \
118 engraver is a sort-of a failure, since it doesn't handle all sorts of \
119 borderline cases very well. \
124 /* acks */ "grob-interface", \
125 /* reads */ "busyGrobs", \
126 /* write */ "busyGrobs");