X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fcontext.cc;h=5e97a6171de24c24830548e4c141ed763d587dac;hb=9f3572d98bb948c9689cd1f75401a029451fa001;hp=629dfadc4f8aa061155c4361be57e2ecdfe5a568;hpb=04265f11d1f21416ccebd2dcaa1d903dc781b36e;p=lilypond.git diff --git a/lily/context.cc b/lily/context.cc index 629dfadc4f..5e97a6171d 100644 --- a/lily/context.cc +++ b/lily/context.cc @@ -10,7 +10,6 @@ #include "context-def.hh" #include "dispatcher.hh" -#include "global-context.hh" #include "international.hh" #include "ly-smobs.icc" #include "main.hh" @@ -18,6 +17,7 @@ #include "profile.hh" #include "program-option.hh" #include "scm-hash.hh" +#include "score-context.hh" #include "translator-group.hh" #include "warn.hh" @@ -33,15 +33,15 @@ Context::check_removal () { for (SCM p = context_list_; scm_is_pair (p); p = scm_cdr (p)) { - Context *ctx = unsmob_context (scm_car (p)); + Context *trg = unsmob_context (scm_car (p)); - ctx->check_removal (); - if (ctx->is_removable ()) + trg->check_removal (); + if (trg->is_removable ()) { - recurse_over_translators (ctx, &Translator::finalize, + recurse_over_translators (trg, &Translator::finalize, &Translator_group::finalize, UP); - send_stream_event (ctx, "RemoveContext", 0, 0); + remove_context (trg); } } } @@ -59,13 +59,29 @@ Context::properties_dict () const } void -Context::add_context (Context *child) +Context::add_context (Context *t) { + SCM ts = t->self_scm (); context_list_ = ly_append2 (context_list_, - scm_cons (child->self_scm (), SCM_EOL)); + scm_cons (ts, SCM_EOL)); + + t->daddy_context_ = this; + if (!t->init_) + { + t->init_ = true; - child->daddy_context_ = this; - this->events_below_->register_as_listener (child->events_below_); + 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); + + recurse_over_translators (t, + &Translator::initialize, + &Translator_group::initialize, + DOWN); + } } @@ -73,6 +89,7 @@ Context::Context (Object_key const *key) : key_manager_ (key) { daddy_context_ = 0; + init_ = false; aliases_ = SCM_EOL; iterator_count_ = 0; implementation_ = 0; @@ -81,6 +98,7 @@ Context::Context (Object_key const *key) context_list_ = SCM_EOL; definition_ = SCM_EOL; definition_mods_ = SCM_EOL; + unique_ = -1; event_source_ = 0; events_below_ = 0; @@ -140,8 +158,8 @@ Context::create_unique_context (SCM name, string id, SCM operations) } /* - Don't go up to Global_context, because global goes down to the - Score context + Don't go up to Global_context, because global goes down to + Score_context */ Context *ret = 0; if (daddy_context_ && !dynamic_cast (daddy_context_)) @@ -202,8 +220,8 @@ Context::find_create_context (SCM n, string id, SCM operations) } /* - Don't go up to Global_context, because global goes down to the - Score context + Don't go up to Global_context, because global goes down to + Score_context */ Context *ret = 0; if (daddy_context_ && !dynamic_cast (daddy_context_)) @@ -217,142 +235,36 @@ Context::find_create_context (SCM n, string id, SCM operations) return ret; } -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) +Context * +Context::create_context (Context_def *cdef, + string id, + SCM ops) { - 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) - set_property (sym, val); - } -} + int unique = get_global_context()->new_unique(); -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); + // TODO: The following should be carried out by a listener. + string type = ly_symbol2string (cdef->get_context_name ()); Object_key const *key = key_manager_.get_context_key (now_mom(), type, id); - - 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); + 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_); - 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); + + add_context (new_context); apply_property_operations (new_context, ops); + events_below_->register_as_listener (new_context->events_below_); - 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, + // 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), 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); - - if (!infant || infant->get_parent_context () != this) - { - programming_error ("create_context: can't locate newly created context"); - return 0; - } - return infant; + return new_context; } /* @@ -439,12 +351,12 @@ properties and corresponding values, interleaved. This method should not be called from any other place than the send_stream_event macro. */ void -Context::internal_send_stream_event (SCM type, Input *origin, SCM props[]) +Context::internal_send_stream_event (SCM type, SCM props[]) { - Stream_event *e = new Stream_event (type, origin); + Stream_event *e = new Stream_event (this, type); for (int i = 0; props[i]; i += 2) { - e->set_property (props[i], props[i+1]); + e->internal_set_property (props[i], props[i+1]); } event_source_->broadcast (e); e->unprotect (); @@ -469,14 +381,12 @@ Context::add_alias (SCM sym) } void -Context::internal_set_property (SCM sym, SCM val -#ifndef NDEBUG - , char const *file, int line, char const *fun -#endif - ) +Context::internal_set_property (SCM sym, SCM val) { +#ifndef NDEBUG if (do_internal_type_checking_global) assert (type_check_assignment (sym, val, ly_symbol2scm ("translation-type?"))); +#endif properties_dict ()->set (sym, val); } @@ -490,36 +400,19 @@ Context::unset_property (SCM sym) properties_dict ()->remove (sym); } -IMPLEMENT_LISTENER (Context, change_parent); -void -Context::change_parent (SCM sev) +/** + Remove a context from the hierarchy. +*/ +Context * +Context::remove_context (Context *trans) { - Stream_event *ev = unsmob_stream_event (sev); - Context *to = unsmob_context (ev->get_property ("context")); + assert (trans); - disconnect_from_parent (); - to->add_context (this); + context_list_ = scm_delq_x (trans->self_scm (), context_list_); + trans->daddy_context_ = 0; + return trans; } -/* - 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. @@ -546,6 +439,25 @@ find_context_below (Context *where, 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 { @@ -565,10 +477,12 @@ Context::context_name () const return ly_symbol2string (context_name_symbol ()); } -Context * +Score_context * Context::get_score_context () const { - if (daddy_context_) + if (Score_context *sc = dynamic_cast ((Context *) this)) + return sc; + else if (daddy_context_) return daddy_context_->get_score_context (); else return 0; @@ -657,6 +571,20 @@ IMPLEMENT_SMOBS (Context); IMPLEMENT_DEFAULT_EQUAL_P (Context); IMPLEMENT_TYPE_P (Context, "ly:context?"); +bool +Context::try_music (Music *m) +{ + Translator_group *t = implementation (); + if (!t) + return false; + + bool b = t->try_music (m); + if (!b && daddy_context_) + b = daddy_context_->try_music (m); + + return b; +} + Global_context * Context::get_global_context () const { @@ -725,7 +653,7 @@ measure_position (Context const *context) void set_context_property_on_children (Context *trans, SCM sym, SCM val) { - trans->set_property (sym, ly_deep_copy (val)); + trans->internal_set_property (sym, ly_deep_copy (val)); for (SCM p = trans->children_contexts (); scm_is_pair (p); p = scm_cdr (p)) { Context *trg = unsmob_context (scm_car (p));