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 daddy_context_->set_property ("busyGrobs", SCM_EOL);
36 LY_DEFINE(ly_grob_pq_less_p,
37 "ly:grob-pq-less?", 2 , 0 ,0, (SCM a, SCM b),
38 "Compare 2 Grob PQ entries. Internal")
40 if (Moment::compare (*unsmob_moment (gh_car (a)),
41 *unsmob_moment (gh_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 (),
72 SCM busy= get_property ("busyGrobs");
73 busy = scm_merge_x (lst, busy, ly_grob_pq_less_p_proc);
74 daddy_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 (gh_pair_p (busy) && *unsmob_moment (gh_caar (busy)) == now)
90 if (start_busy != busy)
91 daddy_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 (gh_pair_p (busy) && *unsmob_moment (gh_caar (busy)) < now)
104 Todo: do something sensible. The grob-pq-engraver is not water
105 tight, and stuff like tupletSpannerDuration confuses it.
107 programming_error (_f("Skipped something?\nGrob %s ended before "
108 "I expected it to end.",
109 unsmob_grob (gh_cdar (busy))->name().to_str0()));
111 busy = gh_cdr (busy);
114 if (start_busy != busy)
115 daddy_context_->set_property ("busyGrobs", busy);
120 ENTER_DESCRIPTION(Grob_pq_engraver,
122 /* descr */ "Administrate when certain grobs (eg. note heads) stop playing; this \
123 engraver is a sort-of a failure, since it doesn't handle all sorts of \
124 borderline cases very well. \
129 /* acks */ "grob-interface", \
130 /* reads */ "busyGrobs", \
131 /* write */ "busyGrobs");