2 quote-iterator.cc -- implement Quote_iterator
4 source file of the GNU LilyPond music typesetter
6 (c) 2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
12 #include "music-sequence.hh"
13 #include "lily-guile.hh"
14 #include "music-iterator.hh"
20 class Quote_iterator : public Music_iterator
30 DECLARE_SCHEME_CALLBACK(constructor, ());
33 virtual void construct_children ();
34 virtual Moment pending_moment () const;
35 virtual void process (Moment);
36 virtual bool ok () const;
39 Quote_iterator::Quote_iterator ()
41 event_vector_ = SCM_EOL;
47 moment_less (SCM a, SCM b)
49 return *unsmob_moment (a) < *unsmob_moment (b);
54 binsearch_scm_vector (SCM vec, SCM key, bool (*is_less)(SCM a,SCM b))
59 hi = SCM_VECTOR_LENGTH (vec);
64 int cmp = (lo + hi) / 2;
66 SCM when = gh_car (SCM_VECTOR_REF(vec, cmp));
67 bool result = (*is_less) (key, when);
80 Quote_iterator::construct_children ()
82 SCM tab = get_outlet()->get_property ("quotes");
83 if (scm_hash_table_p (tab) != SCM_BOOL_T)
85 get_music ()->origin ()->warning ("Context property `quotes' unset; cannot process quote.");
89 SCM name = get_music ()->get_mus_property ("quoted-name");
90 SCM dur = get_music ()->get_mus_property ("duration");
92 if (!unsmob_duration (dur))
95 set_translator (get_outlet ()->get_default_interpreter ());
97 Moment now = get_outlet ()->now_mom ();
98 Moment stop = now + unsmob_duration (dur)->get_length ();
102 event_vector_ = scm_hash_ref (tab, name, SCM_BOOL_F);
104 if (scm_vector_p (event_vector_) == SCM_BOOL_T)
106 event_idx_ = binsearch_scm_vector (event_vector_, now.smobbed_copy (), &moment_less);
107 end_idx_ = binsearch_scm_vector (event_vector_, stop.smobbed_copy (), &moment_less);
110 get_music ()->origin ()->warning ("Can't find requested source");
115 Quote_iterator::ok () const
117 return (event_idx_ < end_idx_);
122 Quote_iterator::pending_moment () const
124 SCM entry = SCM_VECTOR_REF (event_vector_, event_idx_);
125 return *unsmob_moment (gh_car (entry)) - start_moment_;
130 Quote_iterator::process (Moment m)
135 while (event_idx_ < end_idx_)
137 entry = SCM_VECTOR_REF (event_vector_, event_idx_);
139 Moment em = *unsmob_moment (gh_car (entry));
150 if (!gh_pair_p (entry))
153 for (SCM s = gh_cdr (entry); gh_pair_p (s); s = gh_cdr (s))
155 SCM ev_acc = gh_car (s);
158 Music * mus = unsmob_music (gh_car (ev_acc));
161 bool b = get_outlet ()->try_music (mus);
164 mus->origin ()->warning (_f ("In quotation: junking event %s", mus->name()));
167 programming_error ("need music in quote.");
173 IMPLEMENT_CTOR_CALLBACK (Quote_iterator);