/*
This file is part of LilyPond, the GNU music typesetter.
- Copyright (C) 1997--2014 Han-Wen Nienhuys <hanwen@xs4all.nl>,
+ Copyright (C) 1997--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>,
Erik Sandberg <mandolaerik@gmail.com>
LilyPond is free software: you can redistribute it and/or modify
#include "warn.hh"
void
-translator_each (SCM list, Translator_method method)
+translator_each (SCM list, SCM method)
{
for (SCM p = list; scm_is_pair (p); p = scm_cdr (p))
- (Translator::unsmob (scm_car (p))->*method) ();
+ scm_call_1 (method, scm_car (p));
}
void
}
context_ = c;
- c->event_source ()->add_listener (GET_LISTENER (create_child_translator),
+ c->event_source ()->add_listener (GET_LISTENER (Translator_group, create_child_translator),
ly_symbol2scm ("AnnounceNewContext"));
for (SCM tr_list = simple_trans_list_; scm_is_pair (tr_list); tr_list = scm_cdr (tr_list))
{
- Translator *tr = Translator::unsmob (scm_car (tr_list));
+ Translator *tr = unsmob<Translator> (scm_car (tr_list));
tr->connect_to_context (c);
}
}
{
for (SCM tr_list = simple_trans_list_; scm_is_pair (tr_list); tr_list = scm_cdr (tr_list))
{
- Translator *tr = Translator::unsmob (scm_car (tr_list));
+ Translator *tr = unsmob<Translator> (scm_car (tr_list));
tr->disconnect_from_context (context_);
}
- context_->event_source ()->remove_listener (GET_LISTENER (create_child_translator),
+ context_->event_source ()->remove_listener (GET_LISTENER (Translator_group, create_child_translator),
ly_symbol2scm ("AnnounceNewContext"));
context_ = 0;
protected_events_ = SCM_EOL;
Both filter_performers and filter_engravers used to use a direct dynamic_cast
on the unsmobbed translator to be filtered, i.e.,
- if (dynamic_cast<Performer *> (Translator::unsmob (scm_car (*tail))))
+ if (unsmob<Performer> (scm_car (*tail)))
but this caused mysterious optimisation issues in several GUB builds. See
issue #818 for the background to this change.
SCM *tail = ℓ
for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p))
{
- if (Performer::unsmob (scm_car (*tail)))
+ if (unsmob<Performer> (scm_car (*tail)))
*tail = scm_cdr (*tail);
else
tail = SCM_CDRLOC (*tail);
SCM *tail = ℓ
for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p))
{
- if (Engraver::unsmob (scm_car (*tail)))
+ if (unsmob<Engraver> (scm_car (*tail)))
*tail = scm_cdr (*tail);
else
tail = SCM_CDRLOC (*tail);
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 = Stream_event::unsmob (sev);
+ Stream_event *ev = unsmob<Stream_event> (sev);
// get from AnnounceNewContext
SCM cs = ev->get_property ("context");
- Context *new_context = Context::unsmob (cs);
- Context_def *def = Context_def::unsmob (new_context->get_definition ());
+ 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);
for (SCM s = trans_names; scm_is_pair (s); s = scm_cdr (s))
{
- SCM definition = scm_car (s);
- bool is_scheme = false;
-
- Translator *type = 0;
- if (ly_is_symbol (definition))
- type = get_translator (definition);
- else if (ly_is_pair (definition))
- {
- type = get_translator (ly_symbol2scm ("Scheme_engraver"));
- is_scheme = true;
- }
- else if (ly_is_procedure (definition))
+ SCM trans = scm_car (s);
+
+ if (ly_is_symbol (trans))
+ trans = get_translator_creator (trans);
+ if (ly_is_procedure (trans))
+ trans = scm_call_1 (trans, cs);
+ if (ly_cheap_is_list (trans))
+ trans = (new Scheme_engraver (trans, new_context))->unprotect ();
+ Translator *instance = unsmob<Translator> (trans);
+ if (!instance)
{
- // `definition' is a procedure, which takes the context as
- // an argument and evaluates to an a-list scheme engraver
- // definition.
- definition = scm_call_1 (definition, cs);
- type = get_translator (ly_symbol2scm ("Scheme_engraver"));
- is_scheme = true;
+ warning (_f ("cannot find: `%s'", ly_scm_write_string (trans).c_str ()));
+ continue;
}
- if (!type)
- warning (_f ("cannot find: `%s'", ly_symbol2string (scm_car (s)).c_str ()));
- else
+ if (instance->must_be_last ())
{
- Translator *instance = type->clone ();
- if (is_scheme)
- dynamic_cast<Scheme_engraver *> (instance)->init_from_scheme (definition);
-
- SCM str = instance->self_scm ();
-
- if (instance->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;
- }
+ SCM cons = scm_cons (trans, SCM_EOL);
+ if (scm_is_pair (trans_list))
+ scm_set_cdr_x (scm_last_pair (trans_list), cons);
else
- trans_list = scm_cons (str, trans_list);
-
- instance->daddy_context_ = new_context;
- instance->unprotect ();
+ trans_list = cons;
}
+ else
+ trans_list = scm_cons (trans, trans_list);
+
}
/* Filter unwanted translator types. Required to make
g->connect_to_context (new_context);
g->unprotect ();
- recurse_over_translators (new_context,
- &Translator::initialize,
- &Translator_group::initialize,
- DOWN);
+ recurse_over_translators
+ (new_context,
+ Callback0_wrapper::make_smob<Translator, &Translator::initialize> (),
+ Callback0_wrapper::make_smob<Translator_group, &Translator_group::initialize> (),
+ DOWN);
}
SCM
if (tg && dir == DOWN)
{
tg->precomputed_translator_foreach (idx);
- tg->call_precomputed_self_method (idx);
}
for (SCM s = c->children_contexts (); scm_is_pair (s);
s = scm_cdr (s))
- precomputed_recurse_over_translators (Context::unsmob (scm_car (s)), idx, dir);
+ precomputed_recurse_over_translators (unsmob<Context> (scm_car (s)), idx, dir);
if (tg && dir == UP)
{
tg->precomputed_translator_foreach (idx);
- tg->call_precomputed_self_method (idx);
}
}
void
-recurse_over_translators (Context *c, Translator_method ptr,
- Translator_group_method tg_ptr, Direction dir)
+recurse_over_translators (Context *c, SCM ptr,
+ SCM tg_ptr, Direction dir)
{
- Translator_group *tg
- = dynamic_cast<Translator_group *> (c->implementation ());
+ Translator_group *tg = c->implementation ();
+ SCM tg_scm = tg ? tg->self_scm () : SCM_UNDEFINED;
if (tg && dir == DOWN)
{
- (tg->*tg_ptr) ();
+ scm_call_1 (tg_ptr, tg_scm);
translator_each (tg->get_simple_trans_list (), ptr);
}
for (SCM s = c->children_contexts (); scm_is_pair (s);
s = scm_cdr (s))
- recurse_over_translators (Context::unsmob (scm_car (s)), ptr, tg_ptr, dir);
+ recurse_over_translators (unsmob<Context> (scm_car (s)), ptr, tg_ptr, dir);
if (tg && dir == UP)
{
translator_each (tg->get_simple_trans_list (),
ptr);
- (tg->*tg_ptr) ();
+ scm_call_1 (tg_ptr, tg_scm);
}
}
{
for (SCM s = simple_trans_list_; scm_is_pair (s); s = scm_cdr (s))
{
- Translator *tr = Translator::unsmob (scm_car (s));
- Translator_void_method_ptr ptrs[TRANSLATOR_METHOD_PRECOMPUTE_COUNT];
+ Translator *tr = unsmob<Translator> (scm_car (s));
+ SCM ptrs[TRANSLATOR_METHOD_PRECOMPUTE_COUNT];
tr->fetch_precomputable_methods (ptrs);
assert (tr);
for (int i = 0; i < TRANSLATOR_METHOD_PRECOMPUTE_COUNT; i++)
{
- if (ptrs[i])
- precomputed_method_bindings_[i].push_back (Translator_method_binding (tr, ptrs[i]));
+ if (!SCM_UNBNDP (ptrs[i]))
+ precomputed_method_bindings_[i].push_back (Method_instance (ptrs[i], tr));
}
}
- fetch_precomputable_methods (precomputed_self_method_bindings_);
}
void
Translator_group::precomputed_translator_foreach (Translator_precompute_index idx)
{
- vector<Translator_method_binding> &bindings (precomputed_method_bindings_[idx]);
+ vector<Method_instance> &bindings (precomputed_method_bindings_[idx]);
for (vsize i = 0; i < bindings.size (); i++)
- bindings[i].invoke ();
-}
-
-void
-Translator_group::fetch_precomputable_methods (Translator_group_void_method ptrs[])
-{
- for (int i = 0; i < TRANSLATOR_METHOD_PRECOMPUTE_COUNT; i++)
- ptrs[i] = 0;
-}
-
-void
-Translator_group::call_precomputed_self_method (Translator_precompute_index idx)
-{
- if (precomputed_self_method_bindings_[idx])
- (*precomputed_self_method_bindings_[idx]) (this);
+ bindings[i]();
}
Translator_group::~Translator_group ()
}
-const char Translator_group::type_p_name_[] = "ly:translator-group?";
+const char * const Translator_group::type_p_name_ = "ly:translator-group?";
int
-Translator_group::print_smob (SCM s, SCM port, scm_print_state *)
+Translator_group::print_smob (SCM port, scm_print_state *) const
{
- Translator_group *me = (Translator_group *) SCM_CELL_WORD_1 (s);
scm_puts ("#<Translator_group ", port);
- scm_puts (me->class_name (), port);
- scm_display (me->simple_trans_list_, port);
+ scm_puts (class_name (), port);
+ scm_display (simple_trans_list_, port);
scm_puts (" >", port);
return 1;
}
SCM
-Translator_group::mark_smob (SCM smob)
+Translator_group::mark_smob () const
{
- Translator_group *me = (Translator_group *)SCM_CELL_WORD_1 (smob);
-
- me->derived_mark ();
- scm_gc_mark (me->protected_events_);
- return me->simple_trans_list_;
+ derived_mark ();
+ scm_gc_mark (protected_events_);
+ return simple_trans_list_;
}