*/
-#include "translator-group.hh"
-#include "context-def.hh"
#include "context.hh"
-#include "warn.hh"
+
+#include "context-def.hh"
+#include "ly-smobs.icc"
+#include "main.hh"
#include "output-def.hh"
#include "scm-hash.hh"
-#include "main.hh"
-#include "ly-smobs.icc"
#include "score-context.hh"
+#include "translator-group.hh"
+#include "warn.hh"
+#include "lilypond-key.hh"
bool
Context::is_removable () const
{
for (SCM p = context_list_; scm_is_pair (p); p = scm_cdr (p))
{
- Context *trg = unsmob_context (scm_car (p));
+ Context *trg = unsmob_context (scm_car (p));
trg->check_removal ();
if (trg->is_removable ())
assert (false);
}
-Scheme_hash_table*
+Scheme_hash_table *
Context::properties_dict () const
{
return Scheme_hash_table::unsmob (properties_scm_);
}
void
-Context::add_context (Context*t)
+Context::add_context (Context *t)
{
SCM ts = t->self_scm ();
context_list_ = ly_append2 (context_list_,
if (!t->init_)
{
t->init_ = true;
-
+
scm_gc_unprotect_object (ts);
- Context_def * td = unsmob_context_def (t->definition_);
+ Context_def *td = unsmob_context_def (t->definition_);
/*
this can not move before add_context (), because \override
}
}
-Context::Context ()
+Object_key const*
+Context::get_key () const
{
+ return key_;
+}
+
+Context::Context (Object_key const* key)
+{
+ key_ = key;
daddy_context_ = 0;
init_ = false;
aliases_ = SCM_EOL;
definition_ = SCM_EOL;
smobify_self ();
-
properties_scm_ = (new Scheme_hash_table)->self_scm ();
scm_gc_unprotect_object (properties_scm_);
+ scm_gc_unprotect_object (key_->self_scm ());
}
+/*
+ TODO: this shares code with find_create_context().
+ */
+Context*
+Context::create_unique_context (SCM n, SCM operations)
+{
+ /*
+ Don't create multiple score contexts.
+ */
+ if (dynamic_cast<Global_context*> (this)
+ && dynamic_cast<Global_context*> (this)->get_score_context ())
+ return get_score_context ()->create_unique_context (n, operations);
+
+ /*
+ TODO: use accepts_list_.
+ */
+ Link_array<Context_def> path
+ = unsmob_context_def (definition_)->path_to_acceptable_context (n, get_output_def ());
+ if (path.size ())
+ {
+ Context * current = this;
-Context*
-Context::find_create_context (SCM n, String id,
- SCM operations)
+ // start at 1. The first one (index 0) will be us.
+ for (int i = 0; i < path.size (); i++)
+ {
+ SCM ops = (i == path.size () -1) ? operations : SCM_EOL;
+
+ current = current->create_context (path[i],
+ "\\new",
+ ops);
+ }
+
+ return current;
+ }
+
+ /*
+ Don't go up to Global_context, because global goes down to
+ Score_context
+ */
+ Context *ret = 0;
+ if (daddy_context_ && !dynamic_cast<Global_context*> (daddy_context_))
+ ret = daddy_context_->create_unique_context (n, operations);
+ else
+ {
+ warning (_f ("Cannot find or create new `%s'",
+ ly_symbol2string (n).to_str0 ()));
+ ret = 0;
+ }
+ return ret;
+}
+
+
+Context *
+Context::find_create_context (SCM n, String id, SCM operations)
{
/*
Don't create multiple score contexts.
if (dynamic_cast<Global_context*> (this)
&& dynamic_cast<Global_context*> (this)->get_score_context ())
return get_score_context ()->find_create_context (n, id, operations);
-
-
- Context * existing = find_context_below (this, n,id);
- if (existing)
+
+ if (Context *existing = find_context_below (this, n, id))
return existing;
if (n == ly_symbol2scm ("Bottom"))
{
Context* tg = get_default_interpreter ();
- tg->id_string_ = id;
return tg;
}
Context * current = this;
// start at 1. The first one (index 0) will be us.
- for (int i=0; i < path.size (); i++)
+ for (int i = 0; i < path.size (); i++)
{
SCM ops = (i == path.size () -1) ? operations : SCM_EOL;
- Context * new_group
- = path[i]->instantiate (ops);
-
+ String this_id = "";
if (i == path.size () -1)
{
- new_group->id_string_ = id;
+ this_id = id;
}
- current->add_context (new_group);
- apply_property_operations (new_group, ops);
-
- current = new_group;
+
+ current = current->create_context (path[i],
+ this_id,
+ ops);
}
return current;
{
warning (_f ("Cannot find or create `%s' called `%s'",
ly_symbol2string (n).to_str0 (), id));
- ret =0;
+ ret = 0;
}
return ret;
}
+
+Context*
+Context::create_context (Context_def * cdef,
+ String id,
+ SCM ops)
+{
+ String type = ly_symbol2string (cdef->get_context_name());
+ Object_key const *key = get_context_key (type, id);
+ Context * new_group
+ = cdef->instantiate (ops, key);
+
+ new_group->id_string_ = id;
+ add_context (new_group);
+ apply_property_operations (new_group, ops);
+
+ return new_group;
+}
+
+
+
+Object_key const*
+Context::get_context_key (String type, String id)
+{
+ String now_key = type + "@" + id;
+
+ int disambiguation_count = 0;
+ if (context_counts_.find (now_key) != context_counts_.end ())
+ {
+ disambiguation_count = context_counts_[now_key];
+ }
+
+ context_counts_[now_key] = disambiguation_count + 1;
+
+
+ return new Lilypond_context_key (get_key (),
+ now_mom(),
+ type, id,
+ disambiguation_count);
+}
+
+Object_key const*
+Context::get_grob_key (String name)
+{
+ int disambiguation_count = 0;
+ if (grob_counts_.find (name) != grob_counts_.end ())
+ {
+ disambiguation_count = grob_counts_[name];
+ }
+ grob_counts_[name] = disambiguation_count + 1;
+
+ Object_key * k = new Lilypond_grob_key (get_key(),
+ now_mom(),
+ name,
+ disambiguation_count);
+
+ return k;
+}
+
+
+
/*
Default child context as a SCM string, or something else if there is
none.
SCM nm = default_child_context_name ();
SCM st = find_context_def (get_output_def (), nm);
+ String name = ly_symbol2string (nm);
Context_def *t = unsmob_context_def (st);
if (!t)
{
- warning (_f ("can't find or create: `%s'", ly_symbol2string (nm).to_str0 ()));
+ warning (_f ("can't find or create: `%s'", name.to_str0 ()));
t = unsmob_context_def (this->definition_);
}
- Context *tg = t->instantiate (SCM_EOL);
- add_context (tg);
+
+ Context *tg = create_context (t, "", SCM_EOL);
if (!tg->is_bottom_context ())
return tg->get_default_interpreter ();
else
SCM
Context::internal_get_property (SCM sym) const
{
- SCM val =SCM_EOL;
+ SCM val = SCM_EOL;
if (properties_dict ()->try_retrieve (sym, &val))
return val;
return where;
}
- Context * found = 0;
+ 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));
+ Context *tr = unsmob_context (scm_car (s));
found = find_context_below (tr, type, id);
}
SCM
Context::context_name_symbol () const
{
- Context_def * td = unsmob_context_def (definition_ );
+ Context_def *td = unsmob_context_def (definition_);
return td->get_context_name ();
}
String
Context::context_name () const
{
- return ly_symbol2string (context_name_symbol ());
+ return ly_symbol2string (context_name_symbol ());
}
Score_context*
Context::get_score_context () const
{
- if (Score_context *sc =dynamic_cast<Score_context*> ((Context*) this))
+ if (Score_context *sc = dynamic_cast<Score_context*> ((Context*) this))
return sc;
-
else if (daddy_context_)
return daddy_context_->get_score_context ();
else
Output_def *
Context::get_output_def () const
{
- return (daddy_context_)
- ? daddy_context_->get_output_def () : 0;
+ return daddy_context_ ? daddy_context_->get_output_def () : 0;
}
Context::~Context ()
scm_puts ("#<", port);
scm_puts (classname (sc), port);
- if (Context_def *d=unsmob_context_def (sc->definition_))
+ if (Context_def *d = unsmob_context_def (sc->definition_))
{
scm_puts (" ", port);
scm_display (d->get_context_name (), port);
}
- if (Context *td=dynamic_cast<Context *> (sc))
+ if (Context *td = dynamic_cast<Context *> (sc))
{
scm_puts ("=", port);
scm_puts (td->id_string_.to_str0 (), port);
SCM
Context::mark_smob (SCM sm)
{
- Context * me = (Context*) SCM_CELL_WORD_1 (sm);
-
+ Context *me = (Context*) SCM_CELL_WORD_1 (sm);
+ scm_gc_mark (me->key_->self_scm ());
scm_gc_mark (me->context_list_);
scm_gc_mark (me->aliases_);
scm_gc_mark (me->definition_);
{
return dynamic_cast<Translator_group*> (unsmob_translator (implementation_));
}
+
+void
+Context::clear_key_disambiguations ()
+{
+ grob_counts_.clear();
+ context_counts_.clear();
+ for (SCM s = context_list_; scm_is_pair (s); s = scm_cdr (s))
+ {
+ unsmob_context (scm_car (s))->clear_key_disambiguations();
+ }
+}