implementation_ = 0;
properties_scm_ = SCM_EOL;
accepts_list_ = SCM_EOL;
+ default_child_ = SCM_EOL;
context_list_ = SCM_EOL;
definition_ = SCM_EOL;
definition_mods_ = SCM_EOL;
event_source_ = 0;
events_below_ = 0;
+ ancestor_lookup_ = SCM_UNDEFINED;
smobify_self ();
Don't create multiple score contexts.
*/
Global_context *gthis = dynamic_cast<Global_context *> (this);
- if (gthis && gthis->get_score_context ())
- return gthis->get_score_context ()->find_create_context (n, id, operations);
+ if (gthis)
+ {
+ if (gthis->get_score_context ())
+ return gthis->get_score_context ()->find_create_context (n, id, operations);
+
+ // Special case: If we use \set Timing.xxx = whatever before
+ // Score is established, the alias of Score to Timing will not
+ // be taken into account. We check for this particular case
+ // here. Aliases apart from Score-level ones don't warrant
+ // context creation as they could create unwanted contexts, like
+ // RhythmicVoice instead of Voice. Creating a Score context,
+ // however, can't really do anything wrong.
+
+ SCM score_name = default_child_context_name ();
+ SCM score_def = find_context_def (get_output_def (), score_name);
+
+ if (Context_def *cd = unsmob_context_def (score_def))
+ {
+ if (cd->is_alias (n))
+ return create_context (cd, id, operations);
+ }
+ }
+
if (Context *existing = find_context_below (this, n, id))
return existing;
if (scm_is_symbol (sym))
{
SCM val = ev->get_property ("value");
+
+ if (SCM_UNBNDP (val)) {
+ unset_property (sym);
+ return;
+ }
+
bool ok = true;
if (val != SCM_EOL)
ok = type_check_assignment (sym, val, ly_symbol2scm ("translation-type?"));
return unsmob_context_def (definition_)->path_to_acceptable_context (name,
get_output_def (),
- scm_reverse_x (accepts, SCM_EOL));
+ scm_reverse_x (accepts, SCM_EOL));
}
SCM
Context::default_child_context_name () const
{
- return scm_is_pair (accepts_list_)
- ? scm_car (accepts_list_)
- : SCM_EOL;
+ return default_child_;
}
bool
void
Context::internal_send_stream_event (SCM type, Input *origin, SCM props[])
{
- Stream_event *e = new Stream_event (type, origin);
+ Stream_event *e = new Stream_event (make_event_class (type), origin);
for (int i = 0; props[i]; i += 2)
{
e->set_property (props[i], props[i + 1]);
bool
Context::is_alias (SCM sym) const
{
- if (sym == ly_symbol2scm ("Bottom")
- && !scm_is_pair (accepts_list_))
- return true;
- if (sym == unsmob_context_def (definition_)->get_context_name ())
+ if (scm_is_eq (sym, ly_symbol2scm ("Bottom")))
+ return is_bottom_context ();
+ if (scm_is_eq (sym, context_name_symbol ()))
return true;
return scm_c_memq (sym, aliases_) != SCM_BOOL_F;
return 0;
}
+SCM
+Context::make_event_class (SCM event_type)
+{
+ if (SCM_UNBNDP (ancestor_lookup_))
+ ancestor_lookup_ = get_global_context ()->ancestor_lookup_;
+ return scm_hashq_ref (ancestor_lookup_, event_type, SCM_EOL);
+}
+
Output_def *
Context::get_output_def () const
{
scm_gc_mark (me->definition_mods_);
scm_gc_mark (me->properties_scm_);
scm_gc_mark (me->accepts_list_);
+ scm_gc_mark (me->default_child_);
if (me->implementation_)
scm_gc_mark (me->implementation_->self_scm ());
if (me->events_below_)
scm_gc_mark (me->events_below_->self_scm ());
+ scm_gc_mark (me->ancestor_lookup_);
+
return me->properties_scm_;
}