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"
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 ();
25 Grob_pq_engraver::Grob_pq_engraver ()
30 Grob_pq_engraver::initialize ()
32 context ()->set_property ("busyGrobs", SCM_EOL);
35 LY_DEFINE (ly_grob_pq_less_p, "ly:grob-pq-less?",
36 2, 0, 0, (SCM a, SCM b),
37 "Compare 2 grob priority queue entries. Internal")
39 if (Moment::compare (*unsmob_moment (scm_car (a)),
40 *unsmob_moment (scm_car (b))) < 0)
47 Grob_pq_engraver::acknowledge_grob (Grob_info gi)
49 Music *m = gi.music_cause ();
52 && !gi.grob_->internal_has_interface (ly_symbol2scm ("multi-measure-interface")))
54 Moment n = now_mom ();
55 Moment l = m->get_length ();
62 l.grace_part_ = l.main_part_;
67 SCM lst = scm_acons (end.smobbed_copy (),
68 gi.grob_->self_scm (),
71 SCM busy = get_property ("busyGrobs");
72 busy = scm_merge_x (lst, busy, ly_grob_pq_less_p_proc);
73 context ()->set_property ("busyGrobs", busy);
78 Grob_pq_engraver::stop_translation_timestep ()
80 Moment now = now_mom ();
81 SCM start_busy = get_property ("busyGrobs");
82 SCM busy = start_busy;
83 while (scm_is_pair (busy) && *unsmob_moment (scm_caar (busy)) == now)
85 busy = scm_cdr (busy);
88 if (start_busy != busy)
89 context ()->set_property ("busyGrobs", busy);
93 Grob_pq_engraver::start_translation_timestep ()
95 Moment now = now_mom ();
97 SCM start_busy = get_property ("busyGrobs");
98 SCM busy = start_busy;
99 while (scm_is_pair (busy) && *unsmob_moment (scm_caar (busy)) < now)
102 The grob-pq-engraver is not water tight, and stuff like
103 tupletSpannerDuration confuses it.
105 busy = scm_cdr (busy);
108 if (start_busy != busy)
109 context ()->set_property ("busyGrobs", busy);
112 ADD_TRANSLATOR (Grob_pq_engraver,
114 /* descr */ "Administrate when certain grobs (eg. note heads) stop playing; this \
115 engraver is a sort-of a failure, since it doesn't handle all sorts of \
116 borderline cases very well. \
121 /* acks */ "grob-interface",\
122 /* reads */ "busyGrobs",\
123 /* write */ "busyGrobs");