On Wednesday 12 July 2006 13:59, Han-Wen Nienhuys wrote:
> Erik Sandberg schreef:
> > On Monday 10 July 2006 13:42, Erik Sandberg wrote:
> >> On 7/10/06, Han-Wen Nienhuys <[EMAIL PROTECTED]> wrote:
> > +/*
> > + Implement the method cl::listen_##m, and make it listen to stream
> > + events of class m.
> > + */
> > +#define IMPLEMENT_TRANSLATOR_LISTENER(cl, m) \
> > +static class cl ## _ ## m ## _init \
> > +{ \
> > +public: \
> > + cl ## _ ## m ## _init () \
> > + { \
> > + cl::_internal_declare_ ## m (); \
> > + } \
> > +} cl ## _ ## m ## _dummy; \
>
> why don't you use ADD_SCM_INIT_FUNCTION ?
Good idea. I've written an update, which is attached (only translator* has
changed since yesterday AFAIK). It cleans up stuff a bit more as well; some
code has been moved from the IMPLEMENT_TRANSLATOR_LISTENER macro to a
function in translator.cc.
May I commit if make web succeeds?
Plan for the next steps:
I'll take a bunch of engravers at a time, and convert them. I'll probably
proceed alphabetically or something, and perhaps send one patch for every 10
translators or so (65 translators are affected). Patches will be very
independent, so the job is very parallellizable.
--
Erik
Index: lily/arpeggio-engraver.cc
===================================================================
RCS file: /sources/lilypond/lilypond/lily/arpeggio-engraver.cc,v
retrieving revision 1.42
diff -u -r1.42 arpeggio-engraver.cc
--- lily/arpeggio-engraver.cc 6 Jan 2006 09:13:27 -0000 1.42
+++ lily/arpeggio-engraver.cc 12 Jul 2006 17:44:52 -0000
@@ -13,6 +13,7 @@
#include "stem.hh"
#include "rhythmic-head.hh"
#include "side-position-interface.hh"
+#include "stream-event.hh"
#include "note-column.hh"
#include "translator.icc"
@@ -28,10 +29,10 @@
protected:
void process_music ();
void stop_translation_timestep ();
- virtual bool try_music (Music *);
+ DECLARE_TRANSLATOR_LISTENER (arpeggio);
private:
Item *arpeggio_;
- Music *arpeggio_event_;
+ Stream_event *arpeggio_event_;
};
Arpeggio_engraver::Arpeggio_engraver ()
@@ -40,12 +41,11 @@
arpeggio_event_ = 0;
}
-bool
-Arpeggio_engraver::try_music (Music *m)
+IMPLEMENT_TRANSLATOR_LISTENER (Arpeggio_engraver, arpeggio);
+void Arpeggio_engraver::listen_arpeggio (Stream_event *ev)
{
- if (!arpeggio_event_)
- arpeggio_event_ = m;
- return true;
+ arpeggio_event_ = ev;
+ ev->protect ();
}
void
@@ -84,7 +84,10 @@
Arpeggio_engraver::process_music ()
{
if (arpeggio_event_)
- arpeggio_ = make_item ("Arpeggio", arpeggio_event_->self_scm ());
+ {
+ arpeggio_ = make_item ("Arpeggio", arpeggio_event_->self_scm ());
+ arpeggio_event_->unprotect ();
+ }
}
void
@@ -94,13 +97,13 @@
arpeggio_event_ = 0;
}
-ADD_ACKNOWLEDGER (Arpeggio_engraver, stem)
- ADD_ACKNOWLEDGER (Arpeggio_engraver, rhythmic_head)
- ADD_ACKNOWLEDGER (Arpeggio_engraver, note_column)
-
- ADD_TRANSLATOR (Arpeggio_engraver,
- /* doc */ "Generate an Arpeggio symbol",
- /* create */ "Arpeggio",
- /* accept */ "arpeggio-event",
- /* read */ "",
- /* write */ "");
+ADD_ACKNOWLEDGER (Arpeggio_engraver, stem);
+ADD_ACKNOWLEDGER (Arpeggio_engraver, rhythmic_head);
+ADD_ACKNOWLEDGER (Arpeggio_engraver, note_column);
+
+ADD_TRANSLATOR (Arpeggio_engraver,
+ /* doc */ "Generate an Arpeggio symbol",
+ /* create */ "Arpeggio",
+ /* accept */ "arpeggio-event",
+ /* read */ "",
+ /* write */ "");
Index: lily/dispatcher.cc
===================================================================
RCS file: /sources/lilypond/lilypond/lily/dispatcher.cc,v
retrieving revision 1.3
diff -u -r1.3 dispatcher.cc
--- lily/dispatcher.cc 26 Jun 2006 22:11:38 -0000 1.3
+++ lily/dispatcher.cc 12 Jul 2006 17:44:53 -0000
@@ -13,10 +13,6 @@
#include "stream-event.hh"
#include "warn.hh"
-// ES todo: move to lily-guile.hh
-SCM appendable_list ();
-void appendable_list_append (SCM l, SCM elt);
-
IMPLEMENT_SMOBS (Dispatcher);
IMPLEMENT_TYPE_P (Dispatcher, "dispatcher");
IMPLEMENT_DEFAULT_EQUAL_P (Dispatcher);
@@ -80,7 +76,8 @@
SCM class_list = scm_call_1 (ly_lily_module_constant ("ly:make-event-class"), class_symbol);
if (!scm_is_pair (class_list))
{
- ev->origin ()->warning (_f ("Unknown event class %s", ly_symbol2string (class_symbol).c_str ()));
+ // TODO: Re-enable this warning when the translator cleanup is finished
+ //ev->origin ()->warning (_f ("Unknown event class %s", ly_symbol2string (class_symbol).c_str ()));
return;
}
bool sent = false;
Index: lily/grob.cc
===================================================================
RCS file: /sources/lilypond/lilypond/lily/grob.cc,v
retrieving revision 1.171
diff -u -r1.171 grob.cc
--- lily/grob.cc 9 Jun 2006 02:20:22 -0000 1.171
+++ lily/grob.cc 12 Jul 2006 17:44:54 -0000
@@ -20,6 +20,7 @@
#include "output-def.hh"
#include "pointer-group-interface.hh"
#include "stencil.hh"
+#include "stream-event.hh"
#include "system.hh"
#include "warn.hh"
@@ -515,6 +516,8 @@
if (Music *m = unsmob_music (cause))
m->origin ()->warning (s);
+ else if (Stream_event *ev = unsmob_stream_event (cause))
+ ev->origin ()->warning (s);
else
::warning (s);
}
@@ -540,6 +543,8 @@
if (Music *m = unsmob_music (cause))
m->origin ()->message (s);
+ else if (Stream_event *ev = unsmob_stream_event (cause))
+ ev->origin ()->warning (s);
else
::message (s);
}
Index: lily/listener.cc
===================================================================
RCS file: /sources/lilypond/lilypond/lily/listener.cc,v
retrieving revision 1.2
diff -u -r1.2 listener.cc
--- lily/listener.cc 16 May 2006 11:30:55 -0000 1.2
+++ lily/listener.cc 12 Jul 2006 17:44:54 -0000
@@ -10,6 +10,12 @@
#include "ly-smobs.icc"
#include "warn.hh"
+Listener::Listener ()
+{
+ target_ = 0;
+ type_ = 0;
+}
+
Listener::Listener (const void *target, Listener_function_table *type)
{
target_ = (void *)target;
@@ -30,12 +36,13 @@
Listener::mark_smob (SCM sm)
{
Listener *me = (Listener *) SCM_CELL_WORD_1 (sm);
- (me->type_->mark_callback) (me->target_);
+ if (me->type_)
+ (me->type_->mark_callback) (me->target_);
return SCM_EOL;
}
int
-Listener::print_smob (SCM s, SCM p, scm_print_state*)
+Listener::print_smob (SCM, SCM p, scm_print_state*)
{
scm_puts ("#<Listener>", p);
return 1;
Index: lily/lyric-combine-music-iterator.cc
===================================================================
RCS file: /sources/lilypond/lilypond/lily/lyric-combine-music-iterator.cc,v
retrieving revision 1.56
diff -u -r1.56 lyric-combine-music-iterator.cc
--- lily/lyric-combine-music-iterator.cc 3 Jun 2006 12:25:27 -0000 1.56
+++ lily/lyric-combine-music-iterator.cc 12 Jul 2006 17:44:56 -0000
@@ -76,13 +76,13 @@
{
if (music_context_)
{
- music_context_->event_source()->remove_listener (GET_LISTENER (set_busy), ly_symbol2scm ("MusicEvent"));
+ music_context_->event_source()->remove_listener (GET_LISTENER (set_busy), ly_symbol2scm ("OldMusicEvent"));
lyrics_context_->unset_property (ly_symbol2scm ("associatedVoiceContext"));
}
music_context_ = to;
if (to)
{
- to->event_source()->add_listener (GET_LISTENER (set_busy), ly_symbol2scm ("MusicEvent"));
+ to->event_source()->add_listener (GET_LISTENER (set_busy), ly_symbol2scm ("OldMusicEvent"));
lyrics_context_->set_property ("associatedVoiceContext", to->self_scm ());
}
}
Index: lily/music.cc
===================================================================
RCS file: /sources/lilypond/lilypond/lily/music.cc,v
retrieving revision 1.152
diff -u -r1.152 music.cc
--- lily/music.cc 26 Jun 2006 22:11:38 -0000 1.152
+++ lily/music.cc 12 Jul 2006 17:44:56 -0000
@@ -21,11 +21,11 @@
#include "warn.hh"
/*
- Music is anything that has duration and supports both time compression
- and transposition.
+ Music is anything that has (possibly zero) duration and supports
+ both time compression and transposition.
In Lily, everything that can be thought to have a length and a pitch
- (which has a duration which can be transposed) is considered "music",
+ (which has a duration which can be transposed) is considered "music".
*/
bool
Music::internal_is_music_type (SCM k) const
@@ -239,8 +239,31 @@
void
Music::send_to_context (Context *c)
{
- send_stream_event (c, "MusicEvent", origin (),
+ /*
+ TODO: This is a work-in-progress solution. Send the event so it
+ can be read both by old-style translators and the new ones.
+ */
+ send_stream_event (c, "OldMusicEvent", origin (),
ly_symbol2scm("music"), self_scm (), 0);
+
+ /* UGH. This is a temp hack for Music->Stream_event transition */
+ SCM orig_sym = get_property ("name");
+ char out[200];
+ string in = ly_symbol2string (orig_sym);
+ /* don't add '-' before first character */
+ out[0] = tolower (in[0]);
+ size_t outpos = 1;
+ for (size_t inpos = 1; inpos < in.size () && outpos < 190; inpos++)
+ {
+ if (isupper (in[inpos]))
+ out[outpos++] = '-';
+ out[outpos++] = tolower (in[inpos]);
+ }
+ out[outpos] = 0;
+ SCM class_name = ly_symbol2scm (out);
+
+ Stream_event *e = new Stream_event (class_name, mutable_property_alist_);
+ c->event_source ()->broadcast (e);
}
Music *
Index: lily/part-combine-iterator.cc
===================================================================
RCS file: /sources/lilypond/lilypond/lily/part-combine-iterator.cc,v
retrieving revision 1.32
diff -u -r1.32 part-combine-iterator.cc
--- lily/part-combine-iterator.cc 26 Jun 2006 22:11:38 -0000 1.32
+++ lily/part-combine-iterator.cc 12 Jul 2006 17:44:57 -0000
@@ -373,7 +373,7 @@
Context *contexts[] = {one, two, solo_tr, tr, 0};
for (int i = 0; contexts[i]; i++)
{
- contexts[i]->event_source ()->add_listener (GET_LISTENER (set_busy), ly_symbol2scm ("MusicEvent"));
+ contexts[i]->event_source ()->add_listener (GET_LISTENER (set_busy), ly_symbol2scm ("OldMusicEvent"));
}
for (char const **p = syms; *p; p++)
Index: lily/stream-event.cc
===================================================================
RCS file: /sources/lilypond/lilypond/lily/stream-event.cc,v
retrieving revision 1.2
diff -u -r1.2 stream-event.cc
--- lily/stream-event.cc 26 Jun 2006 22:11:38 -0000 1.2
+++ lily/stream-event.cc 12 Jul 2006 17:44:57 -0000
@@ -13,46 +13,37 @@
#include "input.hh"
#include "input-smob.hh"
-Stream_event::~Stream_event ()
+Stream_event::Stream_event ()
+ : Prob (ly_symbol2scm ("Stream_event"), SCM_EOL)
{
}
-void
-Stream_event::init ()
+Stream_event::Stream_event (SCM event_class, SCM mutable_props)
+ : Prob (ly_symbol2scm ("Stream_event"),
+ scm_list_1 (scm_cons (ly_symbol2scm ("class"), event_class)))
{
- self_scm_ = SCM_EOL;
- property_alist_ = SCM_EOL;
-
- smobify_self ();
-}
-
-Stream_event::Stream_event ()
-{
- init ();
+ mutable_property_alist_ = mutable_props;
}
Stream_event::Stream_event (SCM property_alist)
+ : Prob (ly_symbol2scm ("Stream_event"), SCM_EOL)
{
- init ();
- property_alist_ = property_alist;
+ mutable_property_alist_ = property_alist;
}
-/*
- Hm. Perhaps Stream_event should be a prob, with class_name as an
- immutable property?
- */
Stream_event::Stream_event (SCM class_name, Input *origin)
+ : Prob (ly_symbol2scm ("Stream_event"),
+ scm_list_1 (scm_cons (ly_symbol2scm ("class"), class_name)))
{
- init ();
- set_property ("class", class_name);
if (origin)
set_spot (origin);
}
Stream_event::Stream_event (Stream_event *ev)
+ : Prob (ly_symbol2scm ("Stream_event"), SCM_EOL)
{
- init ();
- property_alist_ = scm_copy_tree (ev->property_alist_);
+ mutable_property_alist_ = scm_copy_tree (ev->mutable_property_alist_);
+ immutable_property_alist_ = ev->immutable_property_alist_;
}
Input *
@@ -67,24 +58,6 @@
set_property ("origin", make_input (*i));
}
-SCM
-Stream_event::mark_smob (SCM sm)
-{
- Stream_event *me = (Stream_event *) SCM_CELL_WORD_1 (sm);
- return me->property_alist_;
-}
-
-int
-Stream_event::print_smob (SCM s, SCM port, scm_print_state *)
-{
- scm_puts ("#<Stream_event ", port);
- scm_write (dump (s), port);
- scm_puts (" >", port);
- return 1;
-}
-
-IMPLEMENT_SMOBS (Stream_event);
-IMPLEMENT_DEFAULT_EQUAL_P (Stream_event);
IMPLEMENT_TYPE_P (Stream_event, "ly:stream-event?");
MAKE_SCHEME_CALLBACK (Stream_event, undump, 1);
@@ -95,28 +68,21 @@
{
Stream_event *ev = unsmob_stream_event (self);
// Reversed alists look prettier.
- return scm_reverse (ev->property_alist_);
+ return scm_cons (scm_reverse (ev->immutable_property_alist_),
+ scm_reverse (ev->mutable_property_alist_));
}
SCM
Stream_event::undump (SCM data)
{
Stream_event *obj = new Stream_event ();
- obj->property_alist_ = scm_reverse (data);
+ obj->immutable_property_alist_ = scm_reverse (scm_car (data));
+ obj->mutable_property_alist_ = scm_reverse (scm_cdr (data));
return obj->unprotect ();
}
-SCM
-Stream_event::internal_get_property (SCM sym) const
-{
- SCM s = scm_sloppy_assq (sym, property_alist_);
- if (s != SCM_BOOL_F)
- return scm_cdr (s);
- return SCM_EOL;
-}
-
-void
-Stream_event::internal_set_property (SCM prop, SCM val)
+Stream_event *
+unsmob_stream_event (SCM m)
{
- property_alist_ = scm_assq_set_x (property_alist_, prop, val);
+ return dynamic_cast<Stream_event*> (unsmob_prob (m));
}
Index: lily/translator-group.cc
===================================================================
RCS file: /sources/lilypond/lilypond/lily/translator-group.cc,v
retrieving revision 1.155
diff -u -r1.155 translator-group.cc
--- lily/translator-group.cc 26 Jun 2006 22:11:38 -0000 1.155
+++ lily/translator-group.cc 12 Jul 2006 17:44:58 -0000
@@ -48,19 +48,25 @@
programming_error ("translator group is already connected to a context");
context_ = c;
c->event_source ()->add_listener (GET_LISTENER (eat_event),
- ly_symbol2scm ("MusicEvent"));
+ ly_symbol2scm ("OldMusicEvent"));
c->event_source ()->add_listener (GET_LISTENER (create_child_translator),
ly_symbol2scm ("AnnounceNewContext"));
+ for (SCM tr_list = simple_trans_list_; scm_is_pair (tr_list); tr_list = scm_cdr (tr_list))
+ {
+ Translator *tr = unsmob_translator (scm_car (tr_list));
+ tr->connect_to_context (c);
+ }
}
void
Translator_group::disconnect_from_context ()
{
context_->event_source ()->remove_listener (GET_LISTENER (eat_event),
- ly_symbol2scm ("MusicEvent"));
+ ly_symbol2scm ("OldMusicEvent"));
context_->event_source ()->remove_listener (GET_LISTENER (create_child_translator),
ly_symbol2scm ("AnnounceNewContext"));
context_ = 0;
+ protected_events_ = SCM_EOL;
}
void
@@ -123,6 +129,24 @@
return ell;
}
+/*
+ Protects the parameter from being garbage collected. The object is
+ protected until the next disconnect_from_context call.
+
+ Whenever a child translator hears an event, the event is added to
+ this list. This eliminates the need for derived_mark methods in most
+ translators; all incoming events are instead protected by the
+ translator group.
+
+ TODO: Should the list also be flushed at the beginning of each new
+ moment?
+ */
+void
+Translator_group::protect_event (SCM ev)
+{
+ protected_events_ = scm_cons (ev, protected_events_);
+}
+
/*
Create a new translator for a newly created child context. Triggered
by AnnounceNewContext events.
@@ -169,14 +193,12 @@
}
}
- g->simple_trans_list_ = trans_list;
-
/* Filter unwanted translator types. Required to make
\with {\consists "..."} work. */
if (dynamic_cast<Engraver_group *> (g))
- g->simple_trans_list_ = filter_performers (g->simple_trans_list_);
+ g->simple_trans_list_ = filter_performers (trans_list);
else if (dynamic_cast<Performer_group *> (g))
- g->simple_trans_list_ = filter_engravers (g->simple_trans_list_);
+ g->simple_trans_list_ = filter_engravers (trans_list);
// TODO: scrap Context::implementation
new_context->implementation_ = g;
@@ -231,9 +253,12 @@
if (p->get_parent_context())
// ES todo: Make Translators listeners directly instead.
return p->implementation ()->try_music (m);
+ // 'junking event' warning is temporarily disabled during translator cleanup
+ /*
else
// We have tried all possible contexts. Give up.
m->origin ()->warning (_f ("junking event: `%s'", m->name ()));
+ */
return false;
}
@@ -295,6 +320,7 @@
{
simple_trans_list_ = SCM_EOL;
accept_hash_table_ = SCM_EOL;
+ protected_events_ = SCM_EOL;
context_ = 0;
smobify_self ();
@@ -376,5 +402,6 @@
me->derived_mark ();
scm_gc_mark (me->accept_hash_table_);
+ scm_gc_mark (me->protected_events_);
return me->simple_trans_list_;
}
Index: lily/translator.cc
===================================================================
RCS file: /sources/lilypond/lilypond/lily/translator.cc,v
retrieving revision 1.101
diff -u -r1.101 translator.cc
--- lily/translator.cc 11 Jul 2006 05:58:00 -0000 1.101
+++ lily/translator.cc 12 Jul 2006 17:44:58 -0000
@@ -11,6 +11,7 @@
#include "warn.hh"
#include "translator-group.hh"
#include "context-def.hh"
+#include "dispatcher.hh"
#include "global-context.hh"
#include "translator.icc"
@@ -74,6 +75,12 @@
return daddy_context_->implementation ();
}
+void
+Translator::protect_event (SCM ev)
+{
+ get_daddy_translator ()->protect_event (ev);
+}
+
SCM
Translator::internal_get_property (SCM sym) const
{
@@ -108,6 +115,46 @@
{
}
+void
+Translator::connect_to_context (Context *c)
+{
+ for (translator_listener_record *r = get_listener_list (); r; r=r->next_)
+ c->events_below ()->add_listener (r->get_listener_ (this), r->event_class_);
+}
+
+void
+Translator::disconnect_from_context (Context *c)
+{
+ for (translator_listener_record *r = get_listener_list (); r; r=r->next_)
+ c->events_below ()->remove_listener (r->get_listener_ (this), r->event_class_);
+}
+
+/*
+ Internally called once, statically, for each translator
+ listener. Connects the name of an event class with a procedure that
+ fetches the corresponding listener.
+
+ The method should only be called from the macro
+ IMPLEMENT_TRANSLATOR_LISTENER.
+ */
+void
+Translator::add_translator_listener (translator_listener_record **listener_list,
+ translator_listener_record *r,
+ Listener (*get_listener) (void *),
+ const char *ev_class)
+{
+ /* ev_class is the C++ identifier name. Convert to scm symbol */
+ string name = string (ev_class);
+ name = replace_all (name, '_', '-');
+ name = name + "-event";
+ /* It's OK to use scm_gc_protect_object for protection, because r is
+ statically allocated. */
+ r->event_class_ = scm_gc_protect_object (scm_str2symbol (name.c_str ()));
+ r->get_listener_ = get_listener;
+ r->next_ = *listener_list;
+ *listener_list = r;
+}
+
/*
SMOBS
*/
Index: lily/include/listener.hh
===================================================================
RCS file: /sources/lilypond/lilypond/lily/include/listener.hh,v
retrieving revision 1.1
diff -u -r1.1 listener.hh
--- lily/include/listener.hh 5 May 2006 15:59:21 -0000 1.1
+++ lily/include/listener.hh 12 Jul 2006 17:45:00 -0000
@@ -63,6 +63,8 @@
public:
Listener (const void *target, Listener_function_table *type);
Listener (Listener const &other);
+ Listener ();
+
void listen (SCM ev) const;
bool operator == (Listener const &other) const
@@ -72,29 +74,29 @@
};
DECLARE_UNSMOB (Listener, listener);
-#define IMPLEMENT_LISTENER(cl, method) \
-void \
-cl :: method ## _callback (void *self, SCM ev) \
-{ \
- cl *s = (cl *)self; \
- s->method (ev); \
-} \
-void \
-cl :: method ## _mark (void *self) \
-{ \
- cl *s = (cl *)self; \
- scm_gc_mark (s->self_scm ()); \
-} \
-Listener \
-cl :: method ## _listener () const \
-{ \
- static Listener_function_table callbacks; \
- callbacks.listen_callback = &cl::method ## _callback; \
- callbacks.mark_callback = &cl::method ## _mark; \
- return Listener (this, &callbacks); \
+#define IMPLEMENT_LISTENER(cl, method) \
+void \
+cl :: method ## _callback (void *self, SCM ev) \
+{ \
+ cl *s = (cl *)self; \
+ s->method (ev); \
+} \
+void \
+cl :: method ## _mark (void *self) \
+{ \
+ cl *s = (cl *)self; \
+ scm_gc_mark (s->self_scm ()); \
+} \
+Listener \
+cl :: method ## _listener () const \
+{ \
+ static Listener_function_table callbacks; \
+ callbacks.listen_callback = &cl::method ## _callback; \
+ callbacks.mark_callback = &cl::method ## _mark; \
+ return Listener (this, &callbacks); \
}
-#define GET_LISTENER(proc) ( proc ## _listener ())
+#define GET_LISTENER(proc) proc ## _listener ()
#define DECLARE_LISTENER(name) \
inline void name (SCM); \
Index: lily/include/stream-event.hh
===================================================================
RCS file: /sources/lilypond/lilypond/lily/include/stream-event.hh,v
retrieving revision 1.3
diff -u -r1.3 stream-event.hh
--- lily/include/stream-event.hh 26 Jun 2006 22:11:39 -0000 1.3
+++ lily/include/stream-event.hh 12 Jul 2006 17:45:00 -0000
@@ -13,12 +13,8 @@
#include "smobs.hh"
#include "prob.hh"
-class Stream_event
+class Stream_event : public Prob
{
- void init ();
- SCM property_alist_;
- Input *origin_;
-
public:
Stream_event ();
Input *origin () const;
@@ -28,18 +24,13 @@
DECLARE_SCHEME_CALLBACK (dump, (SCM));
// todo: remove unneeded constructors
+ Stream_event (SCM event_class, SCM mutable_props);
Stream_event (SCM property_alist);
Stream_event (SCM class_name, Input *);
Stream_event (Stream_event *ev);
-
- SCM internal_get_property (SCM) const;
- void internal_set_property (SCM prop, SCM val);
-
-protected:
- DECLARE_SMOBS (Stream_event,);
};
-DECLARE_UNSMOB (Stream_event, stream_event);
+Stream_event *unsmob_stream_event (SCM);
DECLARE_TYPE_P (Stream_event);
#endif /* STREAM_EVENT_HH */
Index: lily/include/translator-group.hh
===================================================================
RCS file: /sources/lilypond/lilypond/lily/include/translator-group.hh,v
retrieving revision 1.83
diff -u -r1.83 translator-group.hh
--- lily/include/translator-group.hh 26 Jun 2006 22:11:39 -0000 1.83
+++ lily/include/translator-group.hh 12 Jul 2006 17:45:00 -0000
@@ -47,6 +47,8 @@
Translator_group_void_method
precomputed_self_method_bindings_[TRANSLATOR_METHOD_PRECOMPUTE_COUNT];
+ SCM protected_events_;
+
DECLARE_LISTENER (create_child_translator);
DECLARE_LISTENER (eat_event);
@@ -63,6 +65,8 @@
virtual void initialize ();
virtual void finalize ();
+ void protect_event (SCM ev);
+
void stop_translation_timestep ();
void start_translation_timestep ();
Index: lily/include/translator.hh
===================================================================
RCS file: /sources/lilypond/lilypond/lily/include/translator.hh,v
retrieving revision 1.101
diff -u -r1.101 translator.hh
--- lily/include/translator.hh 11 Jul 2006 05:58:00 -0000 1.101
+++ lily/include/translator.hh 12 Jul 2006 17:45:00 -0000
@@ -23,7 +23,21 @@
Engraver_void_function_engraver_grob_info function_;
};
+
+/*
+ Each translator class has a static list of listener records. Each
+ record makes one explains how to register one of the class's stream event
+ listeners to a context.
+*/
+typedef struct translator_listener_record {
+ Listener (*get_listener_) (void *);
+ SCM event_class_;
+ struct translator_listener_record *next_;
+} translator_listener_record;
+
#define TRANSLATOR_DECLARATIONS(NAME) \
+private: \
+ static translator_listener_record *listener_list_; \
public: \
NAME (); \
VIRTUAL_COPY_CONSTRUCTOR (Translator, NAME); \
@@ -42,8 +56,21 @@
} \
static Engraver_void_function_engraver_grob_info static_get_acknowledger (SCM sym); \
static Engraver_void_function_engraver_grob_info static_get_end_acknowledger(SCM); \
+public: \
+ virtual translator_listener_record *get_listener_list () const \
+ { \
+ return listener_list_; \
+ } \
/* end #define */
+#define DECLARE_TRANSLATOR_LISTENER(m) \
+public: \
+inline void listen_ ## m (Stream_event *); \
+/* Should be private */ \
+static void _internal_declare_ ## m (); \
+private: \
+static Listener _get_ ## m ## _listener (void *); \
+DECLARE_LISTENER (_listen_scm_ ## m);
#define DECLARE_ACKNOWLEDGER(x) public : void acknowledge_ ## x (Grob_info); protected:
#define DECLARE_END_ACKNOWLEDGER(x) public : void acknowledge_end_ ## x (Grob_info); protected:
@@ -84,6 +111,10 @@
virtual void initialize ();
virtual void finalize ();
+ /*should maybe be virtual*/
+ void connect_to_context (Context *c);
+ void disconnect_from_context (Context *c);
+
void stop_translation_timestep ();
void start_translation_timestep ();
void process_music ();
@@ -97,7 +128,9 @@
protected: // should be private.
Context *daddy_context_;
+ void protect_event (SCM ev);
virtual void derived_mark () const;
+ static void add_translator_listener (translator_listener_record **listener_list, translator_listener_record *r, Listener (*get_listener) (void *), const char *ev_class);
friend class Translator_group;
};
Index: lily/include/translator.icc
===================================================================
RCS file: /sources/lilypond/lilypond/lily/include/translator.icc,v
retrieving revision 1.13
diff -u -r1.13 translator.icc
--- lily/include/translator.icc 30 May 2006 15:47:16 -0000 1.13
+++ lily/include/translator.icc 12 Jul 2006 17:45:01 -0000
@@ -9,6 +9,7 @@
#ifndef TRANSLATOR_ICC
#define TRANSLATOR_ICC
+#include "listener.hh"
#include "std-vector.hh"
#include "translator.hh"
@@ -16,6 +17,7 @@
A macro to automate administration of translators.
*/
#define ADD_THIS_TRANSLATOR(T) \
+ translator_listener_record *T::listener_list_; \
SCM T::static_description_ = SCM_EOL; \
static void _ ## T ## _adder () \
{ \
@@ -117,6 +119,34 @@
} \
ADD_SCM_INIT_FUNC (CLASS ## NAME ## _end_ack_adder_initclass, CLASS ## NAME ## _end_ack_adder);
+/*
+ Implement the method cl::listen_##m, and make it listen to stream
+ events of class m.
+ */
+#define IMPLEMENT_TRANSLATOR_LISTENER(cl, m) \
+void \
+cl :: _internal_declare_ ## m () \
+{ \
+ static translator_listener_record r; \
+ add_translator_listener (&listener_list_, &r, _get_ ## m ## _listener, #m); \
+} \
+ \
+ADD_SCM_INIT_FUNC (cl ## _declare_event_ ## m, cl::_internal_declare_ ## m); \
+ \
+Listener \
+cl :: _get_ ## m ## _listener (void *me) \
+{ \
+ cl *obj = (cl *) me; \
+ return obj->GET_LISTENER (_listen_scm_ ## m); \
+} \
+ \
+IMPLEMENT_LISTENER (cl, _listen_scm_ ## m) \
+void \
+cl::_listen_scm_ ## m (SCM sev) \
+{ \
+ Stream_event *ev = unsmob_stream_event (sev); \
+ protect_event (sev); \
+ listen_ ## m (ev); \
+}
#endif /* TRANSLATOR_ICC */
-
Index: scm/define-event-classes.scm
===================================================================
RCS file: /sources/lilypond/lilypond/scm/define-event-classes.scm,v
retrieving revision 1.3
diff -u -r1.3 define-event-classes.scm
--- scm/define-event-classes.scm 26 Jun 2006 22:11:39 -0000 1.3
+++ scm/define-event-classes.scm 12 Jul 2006 17:45:01 -0000
@@ -10,8 +10,10 @@
;; Event class hierarchy. Each line is on the form ((List of children) . Parent)
(define event-classes
'(((StreamEvent) . '())
- ((RemoveContext ChangeParent Override Revert UnsetProperty SetProperty
- MusicEvent CreateContext Prepare OneTimeStep Finish) . StreamEvent)
+ ((RemoveContext ChangeParent Override Revert UnsetProperty
+ SetProperty MusicEvent OldMusicEvent CreateContext Prepare
+ OneTimeStep Finish) . StreamEvent)
+ ((arpeggio-event) . MusicEvent)
((Announcement) . '())
((AnnounceNewContext) . Announcement)
))
_______________________________________________
lilypond-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/lilypond-devel