? .sconf_temp ? build-stamp ? context-unique.diff ? def-rel-music-funciton.diff ? delay-music-functions.diff ? exjobb.diff3 ? fonts ? lib ? lilypond.kdevelop ? lilypond.kdevelop.pcs ? lilypond.kdevses ? optimized ? os ? ref1.diff ? ref2.diff ? repeat.diff ? scons.cache ? Documentation/out ? Documentation/out-www ? Documentation/bibliography/out ? Documentation/misc/out ? Documentation/pictures/out ? Documentation/topdocs/out ? Documentation/user/out ? Documentation/user/out-www ? buildscripts/out ? buildscripts/out-www ? cygwin/out ? cygwin/out-www ? debian/out ? elisp/out ? elisp/out-www ? flower/out ? flower/out-scons ? flower/out-www ? flower/include/.sconsign ? flower/include/out ? flower/include/out-www ? input/Diagram1.dia.autosave ? input/les-nereides.pdf ? input/les-nereides.ps ? input/out ? input/out-www ? input/mutopia/out ? input/mutopia/out-www ? input/mutopia/E.Satie/out ? input/mutopia/E.Satie/out-www ? input/mutopia/F.Schubert/morgenlied.midi ? input/mutopia/F.Schubert/morgenlied.pdf ? input/mutopia/F.Schubert/morgenlied.ps ? input/mutopia/F.Schubert/out ? input/mutopia/F.Schubert/out-www ? input/mutopia/J.S.Bach/out ? input/mutopia/J.S.Bach/out-www ? input/mutopia/R.Schumann/out ? input/mutopia/R.Schumann/out-www ? input/mutopia/W.A.Mozart/out ? input/mutopia/W.A.Mozart/out-www ? input/no-notation/out ? input/no-notation/out-www ? input/no-notation/to-xml.pdf ? input/no-notation/to-xml.ps ? input/regression/chord-tremolo.pdf ? input/regression/chord-tremolo.ps ? input/regression/out ? input/regression/out-www ? input/template/out ? input/test/new ? input/test/out ? input/test/out-www ? input/tutorial/out ? input/tutorial/out-www ? kpath-guile/out ? kpath-guile/out-scons ? lily/On ? lily/busy-playing-listener.cc ? lily/foo.pdf ? lily/foo.ps ? lily/lilypond ? lily/lilypond.gdt ? lily/lilypond.gpr ? lily/out ? lily/out-scons ? lily/out-www ? lily/include/.sconsign ? lily/include/busy-playing-listener.hh ? lily/include/out ? lily/include/out-www ? ly/out ? ly/out-www ? make/out ? make/out-www ? mf/feta-alphabet11.600pk ? mf/feta-alphabet11.tfm ? mf/feta-alphabet13.600pk ? mf/feta-alphabet13.tfm ? mf/feta-alphabet14.600pk ? mf/feta-alphabet14.tfm ? mf/feta-alphabet16.600pk ? mf/feta-alphabet16.tfm ? mf/feta-alphabet18.600pk ? mf/feta-alphabet18.tfm ? mf/feta-alphabet20.600pk ? mf/feta-alphabet20.tfm ? mf/feta-alphabet23.600pk ? mf/feta-alphabet23.tfm ? mf/feta-alphabet26.600pk ? mf/feta-alphabet26.tfm ? mf/feta-braces-a.600pk ? mf/feta-braces-b.600pk ? mf/feta-braces-c.600pk ? mf/feta-braces-d.600pk ? mf/feta-braces-e.600pk ? mf/feta-braces-f.600pk ? mf/feta-braces-g.600pk ? mf/feta-braces-h.600pk ? mf/feta-braces-i.600pk ? mf/feta11.600pk ? mf/feta13.600pk ? mf/feta14.600pk ? mf/feta16.600pk ? mf/feta18.600pk ? mf/feta20.600pk ? mf/feta23.600pk ? mf/feta26.600pk ? mf/out ? mf/out-scons ? mf/out-www ? mf/parmesan11.600pk ? mf/parmesan13.600pk ? mf/parmesan14.600pk ? mf/parmesan16.600pk ? mf/parmesan18.600pk ? mf/parmesan20.600pk ? mf/parmesan23.600pk ? mf/parmesan26.600pk ? po/out ? po/out-www ? ps/out ? ps/out-www ? python/convertrules.pyc ? python/fontextract.pyc ? python/lilylib.pyc ? python/out ? python/out-www ? scm/out ? scm/out-www ? scripts/lilypond-book-36.py ? scripts/lilypond-book.py.new ? scripts/out ? scripts/out-www ? scripts/stat ? stepmake/out ? stepmake/out-www ? stepmake/bin/out ? stepmake/bin/out-www ? stepmake/bin/packagepython.pyc ? stepmake/stepmake/out ? stepmake/stepmake/out-www ? tex/out ? tex/out-www ? ttftool/out ? ttftool/out-scons ? ttftool/include/.sconsign ? ttftool/include/out ? vim/out ? vim/out-www Index: THANKS =================================================================== RCS file: /sources/lilypond/lilypond/THANKS,v retrieving revision 1.234 diff -u -r1.234 THANKS --- THANKS 7 Jun 2006 21:59:11 -0000 1.234 +++ THANKS 12 Jun 2006 21:54:54 -0000 @@ -52,6 +52,7 @@ Francisco Vila J. Leung Harald Wellmann +Karim Haddad Karl Hammar Keith Packard Michael Meixner Index: lily/auto-change-iterator.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/auto-change-iterator.cc,v retrieving revision 1.62 diff -u -r1.62 auto-change-iterator.cc --- lily/auto-change-iterator.cc 17 Feb 2006 01:42:58 -0000 1.62 +++ lily/auto-change-iterator.cc 12 Jun 2006 21:55:03 -0000 @@ -68,8 +68,9 @@ { Context *dest = it->get_outlet ()->find_create_context (to_type_sym, to_id, SCM_EOL); - current->remove_context (last); - dest->add_context (last); + + send_stream_event (last, "ChangeParent", get_music ()->origin (), + ly_symbol2scm ("context"), dest->self_scm ()); } else { @@ -90,6 +91,8 @@ Moment now = get_outlet ()->now_mom (); Moment *splitm = 0; + if (start_moment_.main_part_.is_infinity () && start_moment_ < 0) + start_moment_ = now; for (; scm_is_pair (split_list_); split_list_ = scm_cdr (split_list_)) { Index: lily/change-iterator.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/change-iterator.cc,v retrieving revision 1.50 diff -u -r1.50 change-iterator.cc --- lily/change-iterator.cc 22 Feb 2006 13:26:44 -0000 1.50 +++ lily/change-iterator.cc 12 Jun 2006 21:55:03 -0000 @@ -74,8 +74,8 @@ if (dest) { - current->remove_context (last); - dest->add_context (last); + send_stream_event (last, "ChangeParent", get_music ()->origin (), + ly_symbol2scm ("context"), dest->self_scm ()); } else /* FIXME: constant error message. */ Index: lily/context-def.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/context-def.cc,v retrieving revision 1.62 diff -u -r1.62 context-def.cc --- lily/context-def.cc 24 May 2006 07:00:41 -0000 1.62 +++ lily/context-def.cc 12 Jun 2006 21:55:03 -0000 @@ -11,14 +11,10 @@ #include "context-def.hh" -#include "engraver-group.hh" -#include "engraver.hh" #include "international.hh" #include "output-def.hh" -#include "performer-group.hh" -#include "performer.hh" #include "score-context.hh" -#include "translator-group.hh" +#include "translator.hh" #include "warn.hh" Context_def::Context_def () @@ -144,12 +140,6 @@ } SCM -Context_def::get_context_name () const -{ - return context_name_; -} - -SCM Context_def::get_accepted (SCM user_mod) const { SCM mods = scm_reverse_x (scm_list_copy (accept_mods_), user_mod); @@ -259,34 +249,6 @@ return l1; } -SCM -filter_performers (SCM ell) -{ - SCM *tail = ℓ - for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p)) - { - if (dynamic_cast (unsmob_translator (scm_car (*tail)))) - *tail = scm_cdr (*tail); - else - tail = SCM_CDRLOC (*tail); - } - return ell; -} - -SCM -filter_engravers (SCM ell) -{ - SCM *tail = ℓ - for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p)) - { - if (dynamic_cast (unsmob_translator (scm_car (*tail)))) - *tail = scm_cdr (*tail); - else - tail = SCM_CDRLOC (*tail); - } - return ell; -} - Context * Context_def::instantiate (SCM ops, Object_key const *key) { @@ -299,55 +261,7 @@ context->definition_ = self_scm (); context->definition_mods_ = ops; - - SCM trans_names = get_translator_names (ops); - - Translator_group *g = get_translator_group (translator_group_type_); - SCM trans_list = SCM_EOL; - - for (SCM s = trans_names; scm_is_pair (s); s = scm_cdr (s)) - { - Translator *t = get_translator (scm_car (s)); - if (!t) - warning (_f ("can't find: `%s'", ly_symbol2string (scm_car (s)).c_str ())); - else - { - Translator *tr = t->clone (); - SCM str = tr->self_scm (); - - if (tr->must_be_last ()) - { - SCM cons = scm_cons (str, SCM_EOL); - if (scm_is_pair (trans_list)) - scm_set_cdr_x (scm_last_pair (trans_list), cons); - else - trans_list = cons; - } - else - trans_list = scm_cons (str, trans_list); - - tr->daddy_context_ = context; - tr->unprotect (); - } - } - - /* - Ugh, todo: should just make a private - copy of Context_def with the user mods. - */ - - g->simple_trans_list_ = trans_list; - - context->implementation_ = g; - if (dynamic_cast (g)) - g->simple_trans_list_ = filter_performers (g->simple_trans_list_); - else if (dynamic_cast (g)) - g->simple_trans_list_ = filter_engravers (g->simple_trans_list_); - context->aliases_ = context_aliases_; - g->connect_to_context (context); - g->unprotect (); - context->accepts_list_ = get_accepted (ops); return context; Index: lily/context.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/context.cc,v retrieving revision 1.83 diff -u -r1.83 context.cc --- lily/context.cc 24 May 2006 07:00:41 -0000 1.83 +++ lily/context.cc 12 Jun 2006 21:55:05 -0000 @@ -33,15 +33,15 @@ { for (SCM p = context_list_; scm_is_pair (p); p = scm_cdr (p)) { - Context *trg = unsmob_context (scm_car (p)); + Context *ctx = unsmob_context (scm_car (p)); - trg->check_removal (); - if (trg->is_removable ()) + ctx->check_removal (); + if (ctx->is_removable ()) { - recurse_over_translators (trg, &Translator::finalize, + recurse_over_translators (ctx, &Translator::finalize, &Translator_group::finalize, UP); - remove_context (trg); + send_stream_event (ctx, "RemoveContext", 0, 0); } } } @@ -59,29 +59,13 @@ } void -Context::add_context (Context *t) +Context::add_context (Context *child) { - SCM ts = t->self_scm (); context_list_ = ly_append2 (context_list_, - scm_cons (ts, SCM_EOL)); - - t->daddy_context_ = this; - if (!t->init_) - { - t->init_ = true; - - t->unprotect (); - Context_def *td = unsmob_context_def (t->definition_); - - /* This cannot move before add_context (), because \override - operations require that we are in the hierarchy. */ - td->apply_default_property_operations (t); + scm_cons (child->self_scm (), SCM_EOL)); - recurse_over_translators (t, - &Translator::initialize, - &Translator_group::initialize, - DOWN); - } + child->daddy_context_ = this; + this->events_below_->register_as_listener (child->events_below_); } @@ -89,7 +73,6 @@ : key_manager_ (key) { daddy_context_ = 0; - init_ = false; aliases_ = SCM_EOL; iterator_count_ = 0; implementation_ = 0; @@ -98,7 +81,6 @@ context_list_ = SCM_EOL; definition_ = SCM_EOL; definition_mods_ = SCM_EOL; - unique_ = -1; event_source_ = 0; events_below_ = 0; @@ -235,36 +217,142 @@ return ret; } -Context * -Context::create_context (Context_def *cdef, - string id, - SCM ops) +IMPLEMENT_LISTENER (Context, acknowledge_infant); +void +Context::acknowledge_infant (SCM sev) +{ + infant_event_ = unsmob_stream_event (sev); +} + +IMPLEMENT_LISTENER (Context, set_property_from_event); +void +Context::set_property_from_event (SCM sev) { - int unique = get_global_context()->new_unique(); + Stream_event *ev = unsmob_stream_event (sev); + + SCM sym = ev->get_property ("symbol"); + if (scm_is_symbol (sym)) + { + SCM val = ev->get_property ("value"); + bool ok = true; + if (val != SCM_EOL) + ok = type_check_assignment (sym, val, ly_symbol2scm ("translation-type?")); + if (ok) + internal_set_property (sym, val); + } +} - // TODO: The following should be carried out by a listener. - string type = ly_symbol2string (cdef->get_context_name ()); +IMPLEMENT_LISTENER (Context, unset_property_from_event); +void +Context::unset_property_from_event (SCM sev) +{ + Stream_event *ev = unsmob_stream_event (sev); + + SCM sym = ev->get_property ("symbol"); + type_check_assignment (sym, SCM_EOL, ly_symbol2scm ("translation-type?")); + unset_property (sym); +} + +/* + Creates a new context from a CreateContext event, and sends an + AnnounceNewContext event to this context. +*/ +IMPLEMENT_LISTENER (Context, create_context_from_event); +void +Context::create_context_from_event (SCM sev) +{ + Stream_event *ev = unsmob_stream_event (sev); + + string id = ly_scm2string (ev->get_property ("id")); + SCM ops = ev->get_property ("ops"); + SCM type_scm = ev->get_property ("type"); + string type = ly_symbol2string (type_scm); Object_key const *key = key_manager_.get_context_key (now_mom(), type, id); - Context *new_context - = cdef->instantiate (ops, key); + + vector path + = unsmob_context_def (definition_)->path_to_acceptable_context (type_scm, get_output_def ()); + if (path.size () != 1) + { + programming_error (_f ("Invalid CreateContext event: Cannot create %s context", type.c_str ())); + return; + } + Context_def *cdef = path[0]; + + Context *new_context = cdef->instantiate (ops, key); new_context->id_string_ = id; - new_context->unique_ = unique; + /* Register various listeners: + - Make the new context hear events that universally affect contexts + - connect events_below etc. properly */ + /* We want to be the first ones to hear our own events. Therefore, wait + before registering events_below_ */ + new_context->event_source ()-> + add_listener (GET_LISTENER (new_context->create_context_from_event), + ly_symbol2scm ("CreateContext")); + new_context->event_source ()-> + add_listener (GET_LISTENER (new_context->remove_context), + ly_symbol2scm ("RemoveContext")); + new_context->event_source ()-> + add_listener (GET_LISTENER (new_context->change_parent), + ly_symbol2scm ("ChangeParent")); + new_context->event_source ()-> + add_listener (GET_LISTENER (new_context->set_property_from_event), + ly_symbol2scm ("SetProperty")); + new_context->event_source ()-> + add_listener (GET_LISTENER (new_context->unset_property_from_event), + ly_symbol2scm ("UnsetProperty")); + new_context->events_below_->register_as_listener (new_context->event_source_); - - add_context (new_context); + this->add_context (new_context); + + new_context->unprotect (); + + Context_def *td = unsmob_context_def (new_context->definition_); + + /* This cannot move before add_context (), because \override + operations require that we are in the hierarchy. */ + td->apply_default_property_operations (new_context); apply_property_operations (new_context, ops); - events_below_->register_as_listener (new_context->events_below_); - // TODO: The above operations should be performed by a listener to the following event. - send_stream_event (this, "CreateContext", - ly_symbol2scm ("unique"), scm_int2num (unique), + send_stream_event (this, "AnnounceNewContext", 0, + ly_symbol2scm ("context"), new_context->self_scm (), + ly_symbol2scm ("creator"), sev); +} + +Context * +Context::create_context (Context_def *cdef, + string id, + SCM ops) +{ + infant_event_ = 0; + /* TODO: This is fairly misplaced. We can fix this when we have taken out all + iterator specific stuff from the Context class */ + event_source_-> + add_listener (GET_LISTENER (acknowledge_infant), + ly_symbol2scm ("AnnounceNewContext")); + /* The CreateContext creates a new context, and sends an announcement of the + new context through another event. That event will be stored in + infant_event_ to create a return value. */ + send_stream_event (this, "CreateContext", 0, ly_symbol2scm ("ops"), ops, ly_symbol2scm ("type"), cdef->get_context_name (), ly_symbol2scm ("id"), scm_makfrom0str (id.c_str ())); + event_source_-> + remove_listener (GET_LISTENER (acknowledge_infant), + ly_symbol2scm ("AnnounceNewContext")); + + assert (infant_event_); + SCM infant_scm = infant_event_->get_property ("context"); + Context *infant = unsmob_context (infant_scm); - return new_context; + if (!infant || infant->get_parent_context () != this) + { + programming_error ("create_context: can't locate newly created context"); + return 0; + } + + return infant; } /* @@ -351,9 +439,9 @@ be called from any other place than the send_stream_event macro. */ void -Context::internal_send_stream_event (SCM type, SCM props[]) +Context::internal_send_stream_event (SCM type, Input *origin, SCM props[]) { - Stream_event *e = new Stream_event (this, type); + Stream_event *e = new Stream_event (type, origin); for (int i = 0; props[i]; i += 2) { e->internal_set_property (props[i], props[i+1]); @@ -400,19 +488,36 @@ properties_dict ()->remove (sym); } -/** - Remove a context from the hierarchy. -*/ -Context * -Context::remove_context (Context *trans) +IMPLEMENT_LISTENER (Context, change_parent); +void +Context::change_parent (SCM sev) { - assert (trans); + Stream_event *ev = unsmob_stream_event (sev); + Context *to = unsmob_context (ev->get_property ("context")); - context_list_ = scm_delq_x (trans->self_scm (), context_list_); - trans->daddy_context_ = 0; - return trans; + disconnect_from_parent (); + to->add_context (this); +} + +/* + Die. The next GC sweep should take care of the actual death. + */ +IMPLEMENT_LISTENER (Context, remove_context); +void +Context::remove_context (SCM) +{ + /* ugh, the translator group should listen to RemoveContext events by itself */ + implementation ()->disconnect_from_context (); + disconnect_from_parent (); } +void +Context::disconnect_from_parent () +{ + daddy_context_->events_below_->unregister_as_listener (this->events_below_); + daddy_context_->context_list_ = scm_delq_x (this->self_scm (), daddy_context_->context_list_); + daddy_context_ = 0; +} /* ID == "" means accept any ID. @@ -439,25 +544,6 @@ return found; } -Context * -find_context_below (Context *where, - int unique) -{ - if (where->get_unique () == unique) - return where; - - Context *found = 0; - for (SCM s = where->children_contexts (); - !found && scm_is_pair (s); s = scm_cdr (s)) - { - Context *tr = unsmob_context (scm_car (s)); - - found = find_context_below (tr, unique); - } - - return found; -} - SCM Context::properties_as_alist () const { Index: lily/dispatcher.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/dispatcher.cc,v retrieving revision 1.2 diff -u -r1.2 dispatcher.cc --- lily/dispatcher.cc 16 May 2006 11:30:54 -0000 1.2 +++ lily/dispatcher.cc 12 Jun 2006 21:55:06 -0000 @@ -7,6 +7,7 @@ */ #include "dispatcher.hh" +#include "input.hh" #include "international.hh" #include "ly-smobs.icc" #include "stream-event.hh" @@ -72,11 +73,16 @@ SCM class_symbol = ev->get_property ("class"); if (!scm_symbol_p (class_symbol)) { - warning (_f ("Unknown event class %s", ly_symbol2string (class_symbol).c_str ())); + warning (_f ("Event class should be a symbol")); return; } 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 ())); + return; + } bool sent = false; int num_classes = scm_ilength (class_list); @@ -171,9 +177,10 @@ Dispatcher::internal_add_listener (Listener l, SCM ev_class, int priority) { SCM list = scm_hashq_ref (listeners_, ev_class, SCM_EOL); - if (list == SCM_EOL) + if (!scm_is_pair (list)) { - /* Register with all dispatchers. */ + /* Tell all dispatchers that we listen to, that we want to hear ev_class + events */ for (SCM disp = dispatchers_; scm_is_pair(disp); disp = scm_cdr (disp)) { int priority = scm_to_int (scm_cdar (disp)); @@ -183,7 +190,7 @@ listen_classes_ = scm_cons (ev_class, listen_classes_); } SCM entry = scm_cons (scm_int2num (priority), l.smobbed_copy ()); - list = scm_merge_x (list, scm_list_1 (entry), ly_lily_module_constant ("car<")); + list = scm_merge (list, scm_list_1 (entry), ly_lily_module_constant ("car<")); scm_hashq_set_x (listeners_, ev_class, list); } @@ -213,10 +220,11 @@ else e = scm_cdr (e); list = scm_cdr (dummy); + scm_hashq_set_x (listeners_, ev_class, list); if (first) warning ("Attempting to remove nonexisting listener."); - else if (list == SCM_EOL) + else if (!scm_is_pair (list)) { /* Unregister with all dispatchers. */ for (SCM disp = dispatchers_; disp != SCM_EOL; disp = scm_cdr (disp)) @@ -256,9 +264,9 @@ { dispatchers_ = scm_assq_remove_x (dispatchers_, disp->self_scm ()); - Listener list = GET_LISTENER (dispatch); - for (SCM cl = listen_classes_; cl != SCM_EOL; cl = scm_cdr (cl)) + Listener listener = GET_LISTENER (dispatch); + for (SCM cl = listen_classes_; scm_is_pair (cl); cl = scm_cdr (cl)) { - disp->remove_listener (list, scm_car (cl)); + disp->remove_listener (listener, scm_car (cl)); } } Index: lily/engraver-group.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/engraver-group.cc,v retrieving revision 1.32 diff -u -r1.32 engraver-group.cc --- lily/engraver-group.cc 30 May 2006 15:47:16 -0000 1.32 +++ lily/engraver-group.cc 12 Jun 2006 21:55:06 -0000 @@ -6,13 +6,54 @@ (c) 1997--2006 Han-Wen Nienhuys */ +#include "context.hh" +#include "dispatcher.hh" #include "engraver-group.hh" - -#include "warn.hh" -#include "paper-score.hh" #include "grob.hh" -#include "context.hh" +#include "paper-score.hh" +#include "stream-event.hh" #include "translator-dispatch-list.hh" +#include "warn.hh" + +IMPLEMENT_LISTENER (Engraver_group, override); +void +Engraver_group::override (SCM sev) +{ + Stream_event *ev = unsmob_stream_event (sev); + + execute_general_pushpop_property (context (), + ev->get_property ("symbol"), + ev->get_property ("property-path"), + ev->get_property ("value")); +} + +IMPLEMENT_LISTENER (Engraver_group, revert); +void +Engraver_group::revert (SCM sev) +{ + Stream_event *ev = unsmob_stream_event (sev); + + execute_general_pushpop_property (context (), + ev->get_property ("symbol"), + ev->get_property ("property-path"), + SCM_UNDEFINED); +} + +void +Engraver_group::connect_to_context (Context *c) +{ + Translator_group::connect_to_context (c); + c->event_source ()->add_listener (GET_LISTENER (override), ly_symbol2scm ("Override")); + c->event_source ()->add_listener (GET_LISTENER (revert), ly_symbol2scm ("Revert")); +} + +void +Engraver_group::disconnect_from_context () +{ + context ()->event_source ()->remove_listener (GET_LISTENER (override), ly_symbol2scm ("Override")); + context ()->event_source ()->remove_listener (GET_LISTENER (revert), ly_symbol2scm ("Revert")); + Translator_group::disconnect_from_context (); +} void Engraver_group::announce_grob (Grob_info info) Index: lily/global-context-scheme.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/global-context-scheme.cc,v retrieving revision 1.13 diff -u -r1.13 global-context-scheme.cc --- lily/global-context-scheme.cc 26 Jan 2006 11:17:00 -0000 1.13 +++ lily/global-context-scheme.cc 12 Jun 2006 21:55:08 -0000 @@ -15,6 +15,7 @@ #include "music.hh" #include "object-key.hh" #include "output-def.hh" +#include "translator-group.hh" #include "warn.hh" LY_DEFINE (ly_format_output, "ly:format-output", @@ -31,6 +32,21 @@ return output; } +LY_DEFINE (ly_make_global_translator, "ly:make-global-translator", + 1, 0, 0, (SCM global), + "Create a translator group and connect it to the global context\n" + "@var{global}. The translator group is returned.") +{ + Global_context *g = dynamic_cast (unsmob_context (global)); + SCM_ASSERT_TYPE (g, global, SCM_ARG1, __FUNCTION__, "Global context"); + + Translator_group *tg = new Translator_group (); + tg->connect_to_context (g); + g->implementation_ = tg; + + return tg->unprotect (); +} + LY_DEFINE (ly_run_translator, "ly:run-translator", 2, 1, 0, (SCM mus, SCM output_def, SCM key), "Process @var{mus} according to @var{output_def}. \n" @@ -57,19 +73,21 @@ Cpu_timer timer; - Global_context *trans = new Global_context (odef, music->get_length (), - unsmob_key (key)); - if (!trans) + Global_context *glob = new Global_context (odef, unsmob_key (key)); + if (!glob) { - programming_error ("no toplevel translator"); + programming_error ("Couldn't create Global context"); return SCM_BOOL_F; } + SCM tgs = ly_make_global_translator (glob->self_scm ()); + Translator_group *tg = unsmob_translator_group (tgs); + message (_ ("Interpreting music... ")); SCM protected_iter = Music_iterator::get_static_get_iterator (music); Music_iterator *iter = unsmob_iterator (protected_iter); - iter->init_translator (music, trans); + iter->init_translator (music, glob); iter->construct_children (); if (!iter->ok ()) @@ -79,13 +97,13 @@ return SCM_BOOL_F; } - trans->run_iterator_on_me (iter); + glob->run_iterator_on_me (iter); iter->quit (); scm_remember_upto_here_1 (protected_iter); - trans->finish (); + send_stream_event (glob, "Finish", 0, 0); if (be_verbose_global) message (_f ("elapsed time: %.2f seconds", timer.read ())); - return trans->unprotect (); + return glob->unprotect (); } Index: lily/global-context.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/global-context.cc,v retrieving revision 1.41 diff -u -r1.41 global-context.cc --- lily/global-context.cc 5 May 2006 15:59:21 -0000 1.41 +++ lily/global-context.cc 12 Jun 2006 21:55:08 -0000 @@ -12,24 +12,33 @@ using namespace std; #include "context-def.hh" +#include "dispatcher.hh" #include "international.hh" #include "lilypond-key.hh" #include "music-iterator.hh" #include "music.hh" #include "output-def.hh" #include "score-context.hh" +#include "stream-event.hh" #include "warn.hh" -Global_context::Global_context (Output_def *o, Moment final, Object_key *key) +Global_context::Global_context (Output_def *o, Object_key *key) : Context (new Lilypond_context_key (key, Moment (0), "Global", "", 0)) { output_def_ = o; - final_mom_ = final; definition_ = find_context_def (o, ly_symbol2scm ("Global")); - unique_count_ = 0; - unique_ = 0; + + now_mom_.set_infinite (-1); + prev_mom_.set_infinite (-1); + + /* We only need the most basic stuff to bootstrap the context tree */ + event_source ()->add_listener (GET_LISTENER (create_context_from_event), + ly_symbol2scm ("CreateContext")); + event_source ()->add_listener (GET_LISTENER (prepare), + ly_symbol2scm ("Prepare")); + events_below ()->register_as_listener (event_source_); Context_def *globaldef = unsmob_context_def (definition_); if (!globaldef) @@ -48,9 +57,6 @@ void Global_context::add_moment_to_process (Moment m) { - if (m > final_mom_) - return; - if (m < now_mom_) programming_error ("trying to freeze in time"); @@ -74,15 +80,26 @@ return extra_mom_pq_.size (); } +IMPLEMENT_LISTENER (Global_context, prepare); void -Global_context::prepare (Moment m) +Global_context::prepare (SCM sev) { - prev_mom_ = now_mom_; - now_mom_ = m; + Stream_event *ev = unsmob_stream_event (sev); + Moment *mom = unsmob_moment (ev->get_property ("moment")); + assert (mom); + + if (prev_mom_.main_part_.is_infinity () && prev_mom_ < 0) + prev_mom_ = *mom; + else + prev_mom_ = now_mom_; + now_mom_ = *mom; + clear_key_disambiguations (); + + // should do nothing now if (get_score_context ()) - get_score_context ()->prepare (m); + get_score_context ()->prepare (now_mom_); } Moment @@ -109,8 +126,6 @@ Global_context::one_time_step () { get_score_context ()->one_time_step (); - apply_finalizations (); - check_removal (); } void @@ -123,8 +138,9 @@ void Global_context::run_iterator_on_me (Music_iterator *iter) { - if (iter->ok ()) - prev_mom_ = now_mom_ = iter->pending_moment (); + prev_mom_.set_infinite (-1); + now_mom_.set_infinite (-1); + Moment final_mom = iter->get_music ()->get_length (); bool first = true; while (iter->ok () || get_moments_left ()) @@ -135,7 +151,7 @@ w = iter->pending_moment (); w = sneaky_insert_extra_moment (w); - if (w.main_part_.is_infinity ()) + if (w.main_part_.is_infinity () || w > final_mom) break; if (first) @@ -147,13 +163,15 @@ set_property ("measurePosition", w.smobbed_copy ()); } - prepare (w); + send_stream_event (this, "Prepare", 0, + ly_symbol2scm ("moment"), w.smobbed_copy ()); if (iter->ok ()) iter->process (w); if (!get_score_context ()) { + error ("ES TODO: no score context, this shouldn't happen"); SCM sym = ly_symbol2scm ("Score"); Context_def *t = unsmob_context_def (find_context_def (get_output_def (), sym)); @@ -168,7 +186,9 @@ sc->prepare (w); } - one_time_step (); + send_stream_event (this, "OneTimeStep", 0, 0); + apply_finalizations (); + check_removal (); } } @@ -206,9 +226,3 @@ else return Context::get_default_interpreter (); } - -int -Global_context::new_unique () -{ - return ++unique_count_; -} Index: lily/music.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/music.cc,v retrieving revision 1.151 diff -u -r1.151 music.cc --- lily/music.cc 16 May 2006 12:36:54 -0000 1.151 +++ lily/music.cc 12 Jun 2006 21:55:11 -0000 @@ -239,7 +239,7 @@ void Music::send_to_context (Context *c) { - send_stream_event (c, "MusicEvent", + send_stream_event (c, "MusicEvent", origin (), ly_symbol2scm("music"), self_scm (), 0); } Index: lily/paper-column-engraver.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/paper-column-engraver.cc,v retrieving revision 1.17 diff -u -r1.17 paper-column-engraver.cc --- lily/paper-column-engraver.cc 10 May 2006 10:37:12 -0000 1.17 +++ lily/paper-column-engraver.cc 12 Jun 2006 21:55:11 -0000 @@ -53,10 +53,11 @@ */ Paper_column *p1 = make_paper_column ("NonMusicalPaperColumn"); Paper_column *p2 = make_paper_column ("PaperColumn"); - - SCM m = now_mom ().smobbed_copy (); - p1->set_property ("when", m); - p2->set_property ("when", m); + /* + The columns are timestamped with now_mom () in + stop_translation_timestep. Cannot happen now, because the + first column is sometimes created before now_mom is initialised. + */ set_columns (p1, p2); } @@ -172,6 +173,10 @@ void Paper_column_engraver::stop_translation_timestep () { + SCM m = now_mom ().smobbed_copy (); + command_column_->set_property ("when", m); + musical_column_->set_property ("when", m); + for (vsize i = 0; i < items_.size (); i++) { Item *elem = items_[i]; Index: lily/part-combine-iterator.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/part-combine-iterator.cc,v retrieving revision 1.31 diff -u -r1.31 part-combine-iterator.cc --- lily/part-combine-iterator.cc 24 May 2006 07:00:41 -0000 1.31 +++ lily/part-combine-iterator.cc 12 Jun 2006 21:55:12 -0000 @@ -424,6 +424,11 @@ Moment now = get_outlet ()->now_mom (); Moment *splitm = 0; + /* This is needed if construct_children was called before iteration + started */ + if (start_moment_.main_part_.is_infinity () && start_moment_ < 0) + start_moment_ = now; + for (; scm_is_pair (split_list_); split_list_ = scm_cdr (split_list_)) { splitm = unsmob_moment (scm_caar (split_list_)); Index: lily/property-iterator.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/property-iterator.cc,v retrieving revision 1.59 diff -u -r1.59 property-iterator.cc --- lily/property-iterator.cc 26 Jan 2006 11:16:48 -0000 1.59 +++ lily/property-iterator.cc 12 Jun 2006 21:55:12 -0000 @@ -22,16 +22,10 @@ void Property_iterator::process (Moment m) { - SCM sym = get_music ()->get_property ("symbol"); - if (scm_is_symbol (sym)) - { - SCM val = get_music ()->get_property ("value"); - bool ok = true; - if (val != SCM_EOL) - ok = type_check_assignment (sym, val, ly_symbol2scm ("translation-type?")); - if (ok) - get_outlet ()->internal_set_property (sym, val); - } + send_stream_event (get_outlet (), "SetProperty", get_music ()->origin (), + ly_symbol2scm ("symbol"), get_music ()->get_property ("symbol"), + ly_symbol2scm ("value"), get_music ()->get_property ("value")); + Simple_music_iterator::process (m); } @@ -39,22 +33,21 @@ Property_unset_iterator::process (Moment m) { SCM sym = get_music ()->get_property ("symbol"); - type_check_assignment (sym, SCM_EOL, ly_symbol2scm ("translation-type?")); - get_outlet ()->unset_property (sym); + send_stream_event (get_outlet (), "UnsetProperty", get_music ()->origin (), + ly_symbol2scm ("symbol"), sym); Simple_music_iterator::process (m); } MAKE_SCHEME_CALLBACK (Property_iterator, once_finalization, 2); SCM -Property_iterator::once_finalization (SCM translator, SCM music) +Property_iterator::once_finalization (SCM ctx, SCM music) { Music *m = unsmob_music (music); - Context *tg - = dynamic_cast (unsmob_context (translator)); - SCM sym = m->get_property ("symbol"); + Context *c = unsmob_context (ctx); - tg->unset_property (sym); + send_stream_event (c, "UnsetProperty", m->origin (), + ly_symbol2scm ("symbol"), m->get_property ("symbol")); return SCM_UNSPECIFIED; } @@ -109,27 +102,33 @@ if (to_boolean (get_music ()->get_property ("pop-first")) && !to_boolean (get_music ()->get_property ("once"))) - - execute_general_pushpop_property (get_outlet (), sym, grob_property_path, SCM_UNDEFINED); - - execute_general_pushpop_property (get_outlet (), sym, grob_property_path, val); + send_stream_event (get_outlet (), "Revert", get_music ()->origin (), + ly_symbol2scm ("symbol"), sym, + ly_symbol2scm ("property-path"), grob_property_path); + + send_stream_event (get_outlet (), "Override", get_music ()->origin (), + ly_symbol2scm ("symbol"), sym, + ly_symbol2scm ("property-path"), grob_property_path, + ly_symbol2scm ("value"), val); } Simple_music_iterator::process (m); } MAKE_SCHEME_CALLBACK (Push_property_iterator, once_finalization, 2); SCM -Push_property_iterator::once_finalization (SCM trans, SCM music) +Push_property_iterator::once_finalization (SCM ctx, SCM music) { Music *mus = unsmob_music (music); - Context *tg = dynamic_cast (unsmob_context (trans)); + Context *c = unsmob_context (ctx); SCM sym = mus->get_property ("symbol"); if (check_grob (mus, sym)) { SCM grob_property_path = get_property_path (mus); - execute_general_pushpop_property (tg, sym, grob_property_path, SCM_UNDEFINED); + send_stream_event (c, "Revert", mus->origin (), + ly_symbol2scm ("symbol"), sym, + ly_symbol2scm ("property-path"), grob_property_path); } return SCM_UNSPECIFIED; } @@ -156,7 +155,10 @@ if (check_grob (get_music (), sym)) { SCM grob_property_path = get_property_path (get_music ()); - execute_general_pushpop_property (get_outlet (), sym, grob_property_path, SCM_UNDEFINED); + + send_stream_event (get_outlet (), "Revert", get_music ()->origin (), + ly_symbol2scm ("symbol"), sym, + ly_symbol2scm ("property-path"), grob_property_path); } Simple_music_iterator::process (m); } @@ -165,4 +167,3 @@ IMPLEMENT_CTOR_CALLBACK (Push_property_iterator); IMPLEMENT_CTOR_CALLBACK (Property_iterator); IMPLEMENT_CTOR_CALLBACK (Property_unset_iterator); - Index: lily/score-context.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/score-context.cc,v retrieving revision 1.13 diff -u -r1.13 score-context.cc --- lily/score-context.cc 6 Jan 2006 09:13:25 -0000 1.13 +++ lily/score-context.cc 12 Jun 2006 21:55:12 -0000 @@ -11,29 +11,18 @@ #include "score-translator.hh" void -Score_context::prepare (Moment w) +Score_context::prepare (Moment) { - Translator_group *t = implementation (); - Score_translator *s = dynamic_cast (t); - - s->prepare (w); } void Score_context::finish () { - Translator_group *t = implementation (); - Score_translator *s = dynamic_cast (t); - - s->finish (); } void Score_context::one_time_step () { - Translator_group *t = implementation (); - Score_translator *s = dynamic_cast (t); - s->one_time_step (); } SCM Index: lily/score-engraver.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/score-engraver.cc,v retrieving revision 1.165 diff -u -r1.165 score-engraver.cc --- lily/score-engraver.cc 30 May 2006 15:47:16 -0000 1.165 +++ lily/score-engraver.cc 12 Jun 2006 21:55:12 -0000 @@ -11,6 +11,7 @@ #include "all-font-metrics.hh" #include "axis-group-interface.hh" #include "context-def.hh" +#include "dispatcher.hh" #include "global-context.hh" #include "international.hh" #include "main.hh" @@ -19,6 +20,7 @@ #include "paper-column-engraver.hh" #include "paper-column.hh" #include "paper-score.hh" +#include "stream-event.hh" #include "system.hh" #include "warn.hh" @@ -37,16 +39,16 @@ Engraver_group::derived_mark (); } +IMPLEMENT_LISTENER (Score_engraver, prepare); void -Score_engraver::prepare (Moment m) +Score_engraver::prepare (SCM) { - (void) m; - precomputed_recurse_over_translators (context (), START_TRANSLATION_TIMESTEP, DOWN); } +IMPLEMENT_LISTENER (Score_engraver, finish); void -Score_engraver::finish () +Score_engraver::finish (SCM) { recurse_over_translators (context (), &Translator::finalize, &Translator_group::finalize, @@ -88,6 +90,28 @@ } void +Score_engraver::connect_to_context (Context *c) +{ + Engraver_group::connect_to_context (c); + + Dispatcher *d = c->get_global_context ()->event_source (); + d->add_listener (GET_LISTENER (one_time_step), ly_symbol2scm ("OneTimeStep")); + d->add_listener (GET_LISTENER (prepare), ly_symbol2scm ("Prepare")); + d->add_listener (GET_LISTENER (finish), ly_symbol2scm ("Finish")); +} + +void +Score_engraver::disconnect_from_context () +{ + Dispatcher *d = context ()->get_global_context ()->event_source (); + d->remove_listener (GET_LISTENER (one_time_step), ly_symbol2scm ("OneTimeStep")); + d->remove_listener (GET_LISTENER (prepare), ly_symbol2scm ("Prepare")); + d->remove_listener (GET_LISTENER (finish), ly_symbol2scm ("Finish")); + + Engraver_group::disconnect_from_context (); +} + +void Score_engraver::finalize () { Score_translator::finalize (); @@ -95,8 +119,9 @@ typeset_all (); } +IMPLEMENT_LISTENER(Score_engraver, one_time_step); void -Score_engraver::one_time_step () +Score_engraver::one_time_step (SCM) { if (!to_boolean (context ()->get_property ("skipTypesetting"))) { Index: lily/score-performer.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/score-performer.cc,v retrieving revision 1.72 diff -u -r1.72 score-performer.cc --- lily/score-performer.cc 10 Mar 2006 09:43:17 -0000 1.72 +++ lily/score-performer.cc 12 Jun 2006 21:55:12 -0000 @@ -6,18 +6,20 @@ (c) 1996--2006 Jan Nieuwenhuizen */ -#include "moment.hh" #include "score-performer.hh" #include "audio-column.hh" #include "audio-item.hh" +#include "context-def.hh" +#include "context.hh" +#include "dispatcher.hh" +#include "global-context.hh" #include "performance.hh" #include "midi-stream.hh" +#include "moment.hh" +#include "output-def.hh" #include "string-convert.hh" #include "warn.hh" -#include "context-def.hh" -#include "output-def.hh" -#include "context.hh" ADD_TRANSLATOR_GROUP (Score_performer, /* doc */ "", @@ -51,15 +53,42 @@ } void -Score_performer::prepare (Moment m) +Score_performer::connect_to_context (Context *c) +{ + Performer_group::connect_to_context (c); + + Dispatcher *d = c->get_global_context ()->event_source (); + d->add_listener (GET_LISTENER (one_time_step), ly_symbol2scm ("OneTimeStep")); + d->add_listener (GET_LISTENER (prepare), ly_symbol2scm ("Prepare")); + d->add_listener (GET_LISTENER (finish), ly_symbol2scm ("Finish")); +} + +void +Score_performer::disconnect_from_context () +{ + Dispatcher *d = context ()->get_global_context ()->event_source (); + d->remove_listener (GET_LISTENER (one_time_step), ly_symbol2scm ("OneTimeStep")); + d->remove_listener (GET_LISTENER (prepare), ly_symbol2scm ("Prepare")); + d->remove_listener (GET_LISTENER (finish), ly_symbol2scm ("Finish")); + + Performer_group::disconnect_from_context (); +} + +IMPLEMENT_LISTENER (Score_performer, prepare); +void +Score_performer::prepare (SCM sev) { - audio_column_ = new Audio_column (m); + Stream_event *ev = unsmob_stream_event (sev); + SCM sm = ev->get_property ("moment"); + Moment *m = unsmob_moment (sm); + audio_column_ = new Audio_column (*m); play_element (audio_column_); precomputed_recurse_over_translators (context (), START_TRANSLATION_TIMESTEP, UP); } +IMPLEMENT_LISTENER (Score_performer, finish); void -Score_performer::finish () +Score_performer::finish (SCM) { recurse_over_translators (context (), &Translator::finalize, @@ -67,8 +96,9 @@ UP); } +IMPLEMENT_LISTENER (Score_performer, one_time_step); void -Score_performer::one_time_step () +Score_performer::one_time_step (SCM) { if (to_boolean (context ()->get_property ("skipTypesetting"))) { Index: lily/score-translator.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/score-translator.cc,v retrieving revision 1.8 diff -u -r1.8 score-translator.cc --- lily/score-translator.cc 6 Jan 2006 09:13:25 -0000 1.8 +++ lily/score-translator.cc 12 Jun 2006 21:55:12 -0000 @@ -9,23 +9,8 @@ #include "score-translator.hh" #include "moment.hh" -void -Score_translator::prepare (Moment) -{ -} - SCM Score_translator::get_output () { return SCM_EOL; } - -void -Score_translator::finish () -{ -} - -void -Score_translator::one_time_step () -{ -} Index: lily/stream-event.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/stream-event.cc,v retrieving revision 1.1 diff -u -r1.1 stream-event.cc --- lily/stream-event.cc 5 May 2006 15:59:21 -0000 1.1 +++ lily/stream-event.cc 12 Jun 2006 21:55:14 -0000 @@ -13,8 +13,6 @@ #include "input.hh" #include "input-smob.hh" -// ES todo: Add stuff to lily-proto.hh: Stream_event and its subclasses, Stream_creator, etc. - Stream_event::~Stream_event () { } @@ -24,7 +22,6 @@ { self_scm_ = SCM_EOL; property_alist_ = SCM_EOL; - origin_ = 0; smobify_self (); } @@ -34,39 +31,40 @@ init (); } -Stream_event::Stream_event (Context *c, Input *origin) -{ - init (); - set_property ("context", scm_int2num (c->get_unique())); - origin_ = origin; -} - Stream_event::Stream_event (SCM property_alist) { init (); property_alist_ = property_alist; - origin_ = &dummy_input_global; } -Stream_event::Stream_event (Context *c, SCM class_name) +/* + Hm. Perhaps Stream_event should be a prob, with class_name as an + immutable property? + */ +Stream_event::Stream_event (SCM class_name, Input *origin) { init (); - set_property ("context", scm_int2num (c->get_unique())); set_property ("class", class_name); - origin_ = &dummy_input_global; + if (origin) + set_spot (origin); } Stream_event::Stream_event (Stream_event *ev) { init (); property_alist_ = scm_copy_tree (ev->property_alist_); - origin_ = ev->origin_; } Input * Stream_event::origin () const { - return origin_; + Input *i = unsmob_input (get_property ("origin")); + return i ? i : &dummy_input_global; +} + +void Stream_event::set_spot (Input *i) +{ + set_property ("origin", make_input (*i)); } SCM Index: lily/translator-group.cc =================================================================== RCS file: /sources/lilypond/lilypond/lily/translator-group.cc,v retrieving revision 1.154 diff -u -r1.154 translator-group.cc --- lily/translator-group.cc 26 May 2006 10:42:10 -0000 1.154 +++ lily/translator-group.cc 12 Jun 2006 21:55:14 -0000 @@ -12,10 +12,12 @@ #include "context-def.hh" #include "context.hh" #include "dispatcher.hh" +#include "engraver-group.hh" #include "international.hh" #include "main.hh" #include "music.hh" #include "output-def.hh" +#include "performer-group.hh" #include "scm-hash.hh" #include "stream-event.hh" #include "warn.hh" @@ -43,9 +45,22 @@ Translator_group::connect_to_context (Context *c) { if (context_) - programming_error ("already connected to a context"); + programming_error ("translator group is already connected to a context"); context_ = c; - c->event_source ()->add_listener (GET_LISTENER (eat_event), ly_symbol2scm ("MusicEvent")); + c->event_source ()->add_listener (GET_LISTENER (eat_event), + ly_symbol2scm ("MusicEvent")); + c->event_source ()->add_listener (GET_LISTENER (create_child_translator), + ly_symbol2scm ("AnnounceNewContext")); +} + +void +Translator_group::disconnect_from_context () +{ + context_->event_source ()->remove_listener (GET_LISTENER (eat_event), + ly_symbol2scm ("MusicEvent")); + context_->event_source ()->remove_listener (GET_LISTENER (create_child_translator), + ly_symbol2scm ("AnnounceNewContext")); + context_ = 0; } void @@ -80,6 +95,101 @@ return l; } +SCM +filter_performers (SCM ell) +{ + SCM *tail = ℓ + for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p)) + { + if (dynamic_cast (unsmob_translator (scm_car (*tail)))) + *tail = scm_cdr (*tail); + else + tail = SCM_CDRLOC (*tail); + } + return ell; +} + +SCM +filter_engravers (SCM ell) +{ + SCM *tail = ℓ + for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p)) + { + if (dynamic_cast (unsmob_translator (scm_car (*tail)))) + *tail = scm_cdr (*tail); + else + tail = SCM_CDRLOC (*tail); + } + return ell; +} + +/* + Create a new translator for a newly created child context. Triggered + by AnnounceNewContext events. + */ +IMPLEMENT_LISTENER (Translator_group, create_child_translator); +void +Translator_group::create_child_translator (SCM sev) +{ + Stream_event *ev = unsmob_stream_event (sev); + // get from AnnounceNewContext + SCM cs = ev->get_property ("context"); + Context *new_context = unsmob_context (cs); + Context_def *def = unsmob_context_def (new_context->get_definition ()); + SCM ops = new_context->get_definition_mods (); + + SCM trans_names = def->get_translator_names (ops); + + Translator_group *g = get_translator_group (def->get_translator_group_type ()); + SCM trans_list = SCM_EOL; + + for (SCM s = trans_names; scm_is_pair (s); s = scm_cdr (s)) + { + Translator *type = get_translator (scm_car (s)); + if (!type) + warning (_f ("can't find: `%s'", ly_symbol2string (scm_car (s)).c_str ())); + else + { + Translator *tr = type->clone (); + SCM str = tr->self_scm (); + + if (tr->must_be_last ()) + { + SCM cons = scm_cons (str, SCM_EOL); + if (scm_is_pair (trans_list)) + scm_set_cdr_x (scm_last_pair (trans_list), cons); + else + trans_list = cons; + } + else + trans_list = scm_cons (str, trans_list); + + tr->daddy_context_ = new_context; + tr->unprotect (); + } + } + + 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_); + else if (dynamic_cast (g)) + g->simple_trans_list_ = filter_engravers (g->simple_trans_list_); + + // TODO: scrap Context::implementation + new_context->implementation_ = g; + + g->connect_to_context (new_context); + g->unprotect (); + + recurse_over_translators (new_context, + &Translator::initialize, + &Translator_group::initialize, + DOWN); +} + IMPLEMENT_LISTENER (Translator_group, eat_event); void Translator_group::eat_event (SCM sev) Index: lily/include/context-def.hh =================================================================== RCS file: /sources/lilypond/lilypond/lily/include/context-def.hh,v retrieving revision 1.17 diff -u -r1.17 context-def.hh --- lily/include/context-def.hh 16 Feb 2006 11:54:21 -0000 1.17 +++ lily/include/context-def.hh 12 Jun 2006 21:55:15 -0000 @@ -36,10 +36,11 @@ public: void add_context_mod (SCM); SCM get_default_child (SCM user_mods) const; - SCM get_context_name () const; + SCM get_context_name () const { return context_name_; } SCM get_accepted (SCM user_mods) const; SCM get_property_ops () const { return property_ops_; } SCM get_translator_names (SCM) const; + SCM get_translator_group_type () const { return translator_group_type_; } void set_acceptor (SCM accepts, bool add); vector path_to_acceptable_context (SCM type_string, Index: lily/include/context.hh =================================================================== RCS file: /sources/lilypond/lilypond/lily/include/context.hh,v retrieving revision 1.40 diff -u -r1.40 context.hh --- lily/include/context.hh 16 May 2006 11:30:55 -0000 1.40 +++ lily/include/context.hh 12 Jun 2006 21:55:15 -0000 @@ -9,12 +9,12 @@ #ifndef CONTEXT_HH #define CONTEXT_HH - -#include "std-vector.hh" -#include "moment.hh" +#include "context-key-manager.hh" #include "lily-proto.hh" +#include "listener.hh" +#include "moment.hh" +#include "std-vector.hh" #include "virtual-methods.hh" -#include "context-key-manager.hh" class Context { @@ -28,10 +28,11 @@ private: friend class Context_handle; int iterator_count_; - bool init_; + + /* Used internally by create_context */ + Stream_event *infant_event_; protected: - int unique_; Context *daddy_context_; /* The used Context_def */ SCM definition_; @@ -53,23 +54,28 @@ children, are sent to this dispatcher. */ Dispatcher *events_below_; + // Translator_group is allowed to set implementation_. + friend class Translator_group; + // Context_def::instantiate initialises some protected members. friend class Context_def; + // UGH! initialises implementation_ + friend SCM ly_make_global_translator (SCM); void clear_key_disambiguations (); + DECLARE_LISTENER (set_property_from_event); + DECLARE_LISTENER (unset_property_from_event); public: Object_key const *get_grob_key (string name); Object_key const *get_context_key (string name, string id); - Context *create_context (Context_def *, string, SCM); string id_string () const { return id_string_; } SCM children_contexts () const { return context_list_; } SCM default_child_context_name () const; - int get_unique() { return unique_; } Dispatcher *event_source () const { return event_source_; } Dispatcher *events_below () const { return events_below_; } - void internal_send_stream_event (SCM type, SCM props[]); + void internal_send_stream_event (SCM type, Input *origin, SCM props[]); SCM get_definition () const { return definition_; } SCM get_definition_mods () const { return definition_mods_; } @@ -85,7 +91,12 @@ Context *where_defined (SCM name_sym, SCM *value) const; void unset_property (SCM var_sym); - Context *remove_context (Context *trans); + Context *create_context (Context_def *, string, SCM); + DECLARE_LISTENER (create_context_from_event); + DECLARE_LISTENER (acknowledge_infant); + DECLARE_LISTENER (remove_context); + DECLARE_LISTENER (change_parent); + void disconnect_from_parent (); void check_removal (); string context_name () const; SCM context_name_symbol () const; @@ -134,10 +145,10 @@ void set_context_property_on_children (Context *trans, SCM sym, SCM val); /* Shorthand for creating and broadcasting stream events. */ -#define send_stream_event(ctx, type, ...) \ +#define send_stream_event(ctx, type, origin, ...) \ { \ SCM props[] = { __VA_ARGS__, 0 }; \ - ctx->internal_send_stream_event (ly_symbol2scm (type), props); \ + ctx->internal_send_stream_event (ly_symbol2scm (type), origin, props); \ } #endif /* CONTEXT_HH */ Index: lily/include/engraver-group.hh =================================================================== RCS file: /sources/lilypond/lilypond/lily/include/engraver-group.hh,v retrieving revision 1.25 diff -u -r1.25 engraver-group.hh --- lily/include/engraver-group.hh 30 May 2006 15:47:16 -0000 1.25 +++ lily/include/engraver-group.hh 12 Jun 2006 21:55:15 -0000 @@ -17,12 +17,15 @@ protected: vector announce_infos_; Drul_array acknowledge_hash_table_drul_; - + DECLARE_LISTENER (override); + DECLARE_LISTENER (revert); public: VIRTUAL_COPY_CONSTRUCTOR (Translator_group, Engraver_group); Engraver_group (); virtual void derived_mark () const; void do_announces (); + virtual void connect_to_context (Context *c); + virtual void disconnect_from_context (); virtual void announce_grob (Grob_info); int pending_grob_count () const; private: Index: lily/include/global-context.hh =================================================================== RCS file: /sources/lilypond/lilypond/lily/include/global-context.hh,v retrieving revision 1.14 diff -u -r1.14 global-context.hh --- lily/include/global-context.hh 5 May 2006 15:59:21 -0000 1.14 +++ lily/include/global-context.hh 12 Jun 2006 21:55:15 -0000 @@ -16,13 +16,12 @@ { PQueue extra_mom_pq_; Output_def *output_def_; - int unique_count_; DECLARE_CLASSNAME(Global_context); friend class Output_def; public: - Global_context (Output_def *, Moment final, Object_key *key); + Global_context (Output_def *, Object_key *key); int get_moments_left () const; Moment sneaky_insert_extra_moment (Moment); void add_moment_to_process (Moment); @@ -32,18 +31,16 @@ void apply_finalizations (); void add_finalization (SCM); - virtual SCM get_output (); - virtual void prepare (Moment); + DECLARE_LISTENER (prepare); virtual void one_time_step (); virtual void finish (); + virtual SCM get_output (); virtual Output_def *get_output_def () const; virtual Moment now_mom () const; virtual Context *get_default_interpreter (); - int new_unique (); Moment previous_moment () const; protected: - Moment final_mom_; Moment prev_mom_; Moment now_mom_; }; Index: lily/include/score-engraver.hh =================================================================== RCS file: /sources/lilypond/lilypond/lily/include/score-engraver.hh,v retrieving revision 1.42 diff -u -r1.42 score-engraver.hh --- lily/include/score-engraver.hh 9 May 2006 02:15:56 -0000 1.42 +++ lily/include/score-engraver.hh 12 Jun 2006 21:55:15 -0000 @@ -23,12 +23,13 @@ void typeset_all (); protected: - /* Score_translator */ - virtual void finish (); - virtual void prepare (Moment); - virtual void one_time_step (); + DECLARE_LISTENER (finish); + DECLARE_LISTENER (prepare); + DECLARE_LISTENER (one_time_step); /* Engraver_group_engraver interface */ + virtual void connect_to_context (Context *); + virtual void disconnect_from_context (); virtual bool try_music (Music *); virtual void initialize (); virtual void finalize (); Index: lily/include/score-performer.hh =================================================================== RCS file: /sources/lilypond/lilypond/lily/include/score-performer.hh,v retrieving revision 1.38 diff -u -r1.38 score-performer.hh --- lily/include/score-performer.hh 10 Mar 2006 09:43:17 -0000 1.38 +++ lily/include/score-performer.hh 12 Jun 2006 21:55:15 -0000 @@ -8,6 +8,7 @@ #ifndef SCORE_PERFORMER_HH #define SCORE_PERFORMER_HH +#include "moment.hh" #include "performer-group.hh" #include "score-translator.hh" @@ -24,9 +25,13 @@ Score_performer (); protected: - virtual void prepare (Moment mom); - virtual void finish (); - virtual void one_time_step (); + DECLARE_LISTENER (finish); + DECLARE_LISTENER (prepare); + DECLARE_LISTENER (one_time_step); + + /* Engraver_group_engraver interface */ + virtual void connect_to_context (Context *); + virtual void disconnect_from_context (); virtual void initialize (); virtual void announce_element (Audio_element_info); virtual int get_tempo () const; Index: lily/include/score-translator.hh =================================================================== RCS file: /sources/lilypond/lilypond/lily/include/score-translator.hh,v retrieving revision 1.5 diff -u -r1.5 score-translator.hh --- lily/include/score-translator.hh 6 Jan 2006 09:13:24 -0000 1.5 +++ lily/include/score-translator.hh 12 Jun 2006 21:55:15 -0000 @@ -16,9 +16,6 @@ friend class Score_context; protected: virtual SCM get_output (); - virtual void prepare (Moment); - virtual void finish (); - virtual void one_time_step (); }; #endif /* SCORE_TRANSLATOR_HH */ Index: lily/include/stream-event.hh =================================================================== RCS file: /sources/lilypond/lilypond/lily/include/stream-event.hh,v retrieving revision 1.2 diff -u -r1.2 stream-event.hh --- lily/include/stream-event.hh 16 May 2006 11:30:55 -0000 1.2 +++ lily/include/stream-event.hh 12 Jun 2006 21:55:16 -0000 @@ -22,14 +22,14 @@ public: Stream_event (); Input *origin () const; + void set_spot (Input *i); DECLARE_SCHEME_CALLBACK (undump, (SCM)); DECLARE_SCHEME_CALLBACK (dump, (SCM)); - // todo: make Input mandatory. + // todo: remove unneeded constructors Stream_event (SCM property_alist); - Stream_event (Context *c, SCM class_name); - Stream_event (Context *c, Input *); + Stream_event (SCM class_name, Input *); Stream_event (Stream_event *ev); SCM internal_get_property (SCM) const; Index: lily/include/translator-group.hh =================================================================== RCS file: /sources/lilypond/lilypond/lily/include/translator-group.hh,v retrieving revision 1.82 diff -u -r1.82 translator-group.hh --- lily/include/translator-group.hh 24 May 2006 07:00:41 -0000 1.82 +++ lily/include/translator-group.hh 12 Jun 2006 21:55:16 -0000 @@ -47,6 +47,7 @@ Translator_group_void_method precomputed_self_method_bindings_[TRANSLATOR_METHOD_PRECOMPUTE_COUNT]; + DECLARE_LISTENER (create_child_translator); DECLARE_LISTENER (eat_event); public: @@ -54,7 +55,8 @@ DECLARE_SMOBS (Translator_group, dummy); public: - void connect_to_context (Context *c); + virtual void connect_to_context (Context *c); + virtual void disconnect_from_context (); virtual Translator_group *get_daddy_translator ()const; virtual SCM get_simple_trans_list (); virtual bool try_music (Music *req); Index: lily/include/translator.hh =================================================================== RCS file: /sources/lilypond/lilypond/lily/include/translator.hh,v retrieving revision 1.99 diff -u -r1.99 translator.hh --- lily/include/translator.hh 30 May 2006 15:47:16 -0000 1.99 +++ lily/include/translator.hh 12 Jun 2006 21:55:16 -0000 @@ -99,8 +99,7 @@ Context *daddy_context_; virtual void derived_mark () const; - friend class Context_def; - friend class Context; + friend class Translator_group; }; void add_translator (Translator *trans); Index: scm/define-event-classes.scm =================================================================== RCS file: /sources/lilypond/lilypond/scm/define-event-classes.scm,v retrieving revision 1.2 diff -u -r1.2 define-event-classes.scm --- scm/define-event-classes.scm 16 May 2006 11:30:55 -0000 1.2 +++ scm/define-event-classes.scm 12 Jun 2006 21:55:17 -0000 @@ -12,6 +12,8 @@ '(((StreamEvent) . '()) ((RemoveContext ChangeParent Override Revert UnsetProperty SetProperty MusicEvent CreateContext Prepare OneTimeStep Finish) . StreamEvent) + ((Announcement) . '()) + ((AnnounceNewContext) . Announcement) )) ;; Maps event-class to a list of ancestors (inclusive)