return name;
}
+/*
+ Given a name of a context that we want to create, finds a list of context
+ definitions such that:
+ - the first element in the list defines a context that is a valid child of
+ the context defined by this Context_def
+ - each subsequent element in the list defines a context that is a valid child
+ of the the context defined by the preceding element in the list
+ - the last element in the list defines a context with the given name
+
+ The ADDITIONAL_ACCEPTS parameter is a list of additional contexts that this
+ specific output def (but not and of the child output defs) should accept.
+*/
vector<Context_def*>
-Context_def::path_to_acceptable_context (SCM type_sym, Output_def *odef) const
+Context_def::path_to_acceptable_context (SCM type_sym, Output_def *odef, SCM additional_accepts) const
{
assert (scm_is_symbol (type_sym));
- SCM accepted = get_accepted (SCM_EOL);
+ SCM accepted = get_accepted (additional_accepts);
vector<Context_def*> accepteds;
for (SCM s = accepted; scm_is_pair (s); s = scm_cdr (s))
Context_def *g = accepteds[i];
vector<Context_def*> result
- = g->path_to_acceptable_context (type_sym, odef);
+ = g->path_to_acceptable_context (type_sym, odef, SCM_EOL);
if (result.size () && result.size () < best_depth)
{
best_depth = result.size ();
if (gthis && gthis->get_score_context ())
return gthis->get_score_context ()->create_unique_context (name, id, operations);
- /*
- TODO: use accepts_list_.
- */
- vector<Context_def*> path
- = unsmob_context_def (definition_)->path_to_acceptable_context (name, get_output_def ());
-
+ vector<Context_def*> path = path_to_acceptable_context (name);
if (path.size ())
{
Context *current = this;
- // start at 1. The first one (index 0) will be us.
+ // Iterate through the path and create all of the implicit contexts.
for (vsize i = 0; i < path.size (); i++)
{
SCM ops = SCM_EOL;
/*
TODO: use accepts_list_.
*/
- vector<Context_def*> path
- = unsmob_context_def (definition_)->path_to_acceptable_context (n, get_output_def ());
+ vector<Context_def*> path = path_to_acceptable_context (n);
if (path.size ())
{
SCM type_scm = ev->get_property ("type");
string type = ly_symbol2string (type_scm);
- vector<Context_def*> path
- = unsmob_context_def (definition_)->path_to_acceptable_context (type_scm, get_output_def ());
+ vector<Context_def*> path = path_to_acceptable_context (type_scm);
+
if (path.size () != 1)
{
programming_error (_f ("Invalid CreateContext event: Cannot create %s context", type.c_str ()));
ly_symbol2scm ("creator"), sev);
}
+vector<Context_def*>
+Context::path_to_acceptable_context (SCM name) const
+{
+ // definition_mods_ is a list of (symbol string), but the Context_def expects
+ // to see a list of (symbol symbol).
+ SCM accepts = SCM_EOL;
+ for (SCM s = scm_reverse (definition_mods_); scm_is_pair (s); s = scm_cdr (s))
+ if (scm_caar (s) == ly_symbol2scm ("accepts"))
+ {
+ SCM elt = scm_list_2 (scm_caar (s), scm_string_to_symbol (scm_cadar (s)));
+ accepts = scm_cons (elt, accepts);
+ }
+
+ return unsmob_context_def (definition_)->path_to_acceptable_context (name,
+ get_output_def (),
+ accepts);
+
+}
+
Context *
Context::create_context (Context_def *cdef,
string id,
VIRTUAL_COPY_CONSTRUCTOR(Context_def, Context_def);
vector<Context_def*> path_to_acceptable_context (SCM type_string,
- Output_def *) const;
+ Output_def *, SCM) const;
Context *instantiate (SCM extra_ops);
SCM to_alist () const;
string id, SCM ops);
Context *create_unique_context (SCM context_name, string context_id,
SCM ops);
- vector<Context*> path_to_acceptable_context (SCM alias,
- Output_def *) const;
+ vector<Context_def*> path_to_acceptable_context (SCM alias) const;
};
/*
/* find the translator for NAME. NAME must be a symbol. */
SCM
find_context_def (Output_def const *m, SCM name)
-{
+{
Context_def *cd = unsmob_context_def (m->lookup_variable (name));
return cd ? cd->self_scm () : SCM_EOL;
}