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 9 Jul 2006 12:11:34 -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_engraver, hear_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, hear_arpeggio, "ArpeggioEvent"); +void Arpeggio_engraver::hear_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 9 Jul 2006 12:11:35 -0000 @@ -80,7 +80,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 9 Jul 2006 12:11:36 -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 9 Jul 2006 12:11:36 -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,7 +36,8 @@ 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; } 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 9 Jul 2006 12:11:38 -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 9 Jul 2006 12:11:38 -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,15 @@ 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); + + Stream_event *e = new Stream_event (get_property ("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 9 Jul 2006 12:11:39 -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 9 Jul 2006 12:11:39 -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 ("#", 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 (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 9 Jul 2006 12:11:41 -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 (g)) - g->simple_trans_list_ = filter_performers (g->simple_trans_list_); + g->simple_trans_list_ = filter_performers (trans_list); else if (dynamic_cast (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.100 diff -u -r1.100 translator.cc --- lily/translator.cc 11 Feb 2006 11:35:17 -0000 1.100 +++ lily/translator.cc 9 Jul 2006 12:11:41 -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,28 @@ { } +void +Translator::connect_to_context (Context *c) +{ + for (translator_listener_record *r = get_listener_list (); r; r=r->next_) + { + if (!r->event_class_symbol_) + r->event_class_symbol_ = ly_symbol2scm (r->event_class_str_); + c->events_below ()->add_listener (r->get_listener_ (this), r->event_class_symbol_); + } +} + +void +Translator::disconnect_from_context (Context *c) +{ + for (translator_listener_record *r = get_listener_list (); r; r=r->next_) + { + if (!r->event_class_symbol_) + r->event_class_symbol_ = ly_symbol2scm (r->event_class_str_); + c->events_below ()->remove_listener (r->get_listener_ (this), r->event_class_symbol_); + } +} + /* 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 9 Jul 2006 12:11:42 -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 9 Jul 2006 12:11:42 -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 9 Jul 2006 12:11:42 -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.100 diff -u -r1.100 translator.hh --- lily/include/translator.hh 26 Jun 2006 22:11:39 -0000 1.100 +++ lily/include/translator.hh 9 Jul 2006 12:11:42 -0000 @@ -23,7 +23,22 @@ 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 *); + const char *event_class_str_; + SCM event_class_symbol_; + 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 +57,19 @@ } \ 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(cl, m) \ +public: \ +inline void m (Stream_event *); \ +static Listener get_ ## m ## _listener (void *); \ +DECLARE_LISTENER (m ## _scm); \ +friend class cl ## _ ## m ## _init; #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 +110,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,6 +127,7 @@ protected: // should be private. Context *daddy_context_; + void protect_event (SCM ev); virtual void derived_mark () const; 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 9 Jul 2006 12:11:43 -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,40 @@ } \ ADD_SCM_INIT_FUNC (CLASS ## NAME ## _end_ack_adder_initclass, CLASS ## NAME ## _end_ack_adder); +/* + Implement the method cl::m, and make it hear stream events in class + evclass. +*/ +#define IMPLEMENT_TRANSLATOR_LISTENER(cl, m, evclass) \ +static class cl ## _ ## m ## _init \ +{ \ +public: \ + cl ## _ ## m ## _init () \ + { \ + static translator_listener_record r; \ + r.get_listener_ = cl::get_ ## m ## _listener; \ + r.event_class_str_ = evclass; \ + r.event_class_symbol_ = 0; \ + r.next_ = cl::listener_list_; \ + cl::listener_list_ = &r; \ + } \ +} cl ## _ ## m ## _dummy; \ + \ +Listener \ +cl :: get_ ## m ## _listener (void *me) \ +{ \ + cl *obj = (cl *) me; \ + return obj->GET_LISTENER (m ## _scm); \ +} \ + \ +IMPLEMENT_LISTENER (cl, m ## _scm) \ +void \ +cl::m ## _scm(SCM sev) \ +{ \ + Stream_event *ev = unsmob_stream_event (sev); \ + protect_event (sev); \ + 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 9 Jul 2006 12:11:43 -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) + ((ArpeggioEvent) . MusicEvent) ((Announcement) . '()) ((AnnounceNewContext) . Announcement) ))