]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/translator-group.cc
Run `make grand-replace'.
[lilypond.git] / lily / translator-group.cc
index 172c5b2a3aed958b36c6508d89901270b0b60422..fb6d2580ed09bf2b50461104272e633bee972220 100644 (file)
@@ -3,7 +3,7 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>,
+  (c) 1997--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>,
                  Erik Sandberg <mandolaerik@gmail.com>
 */
 
 #include "output-def.hh"
 #include "performer-group.hh"
 #include "scm-hash.hh"
-#include "stream-event.hh"
 #include "warn.hh"
 
-Translator_group *
-Translator_group::get_daddy_translator () const
-{
-  return context ()->get_parent_context ()->implementation ();
-}
 
 void
 translator_each (SCM list, Translator_method method)
@@ -45,22 +39,33 @@ void
 Translator_group::connect_to_context (Context *c)
 {
   if (context_)
-    programming_error ("translator group is already connected to a context");
+    {
+      programming_error ("translator group is already connected to context "
+                        +  context_->context_name ());
+    }
+  
   context_ = c;
-  c->event_source ()->add_listener (GET_LISTENER (eat_event),
-                                   ly_symbol2scm ("MusicEvent"));
   c->event_source ()->add_listener (GET_LISTENER (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 = unsmob_translator (scm_car (tr_list));
+      tr->connect_to_context (c);
+    }
 }
 
 void
 Translator_group::disconnect_from_context ()
 {
-  context_->event_source ()->remove_listener (GET_LISTENER (eat_event),
-                                             ly_symbol2scm ("MusicEvent"));
+  for (SCM tr_list = simple_trans_list_; scm_is_pair (tr_list); tr_list = scm_cdr (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),
                                              ly_symbol2scm ("AnnounceNewContext"));
   context_ = 0;
+  protected_events_ = SCM_EOL;
 }
 
 void
@@ -68,33 +73,6 @@ Translator_group::finalize ()
 {
 }
 
-bool
-translator_accepts_any_of (Translator *tr, SCM ifaces)
-{
-  SCM ack_ifs = scm_assoc (ly_symbol2scm ("events-accepted"),
-                          tr->translator_description ());
-  ack_ifs = scm_cdr (ack_ifs);
-  for (SCM s = ifaces; scm_is_pair (s); s = scm_cdr (s))
-    if (scm_c_memq (scm_car (s), ack_ifs) != SCM_BOOL_F)
-      return true;
-  return false;
-}
-
-SCM
-find_accept_translators (SCM gravlist, SCM ifaces)
-{
-  SCM l = SCM_EOL;
-  for (SCM s = gravlist; scm_is_pair (s); s = scm_cdr (s))
-    {
-      Translator *tr = unsmob_translator (scm_car (s));
-      if (translator_accepts_any_of (tr, ifaces))
-       l = scm_cons (tr->self_scm (), l);
-    }
-  l = scm_reverse_x (l, SCM_EOL);
-
-  return l;
-}
-
 SCM
 filter_performers (SCM ell)
 {
@@ -123,6 +101,24 @@ filter_engravers (SCM ell)
   return ell;
 }
 
+/* 
+  Protects the parameter from being garbage collected. The object is
+  protected until the next disconnect_from_context call.
+
+  Whenever a child translator hears an event, the event is added to
+  this list. This eliminates the need for derived_mark methods in most
+  translators; all incoming events are instead protected by the
+  translator group.
+  TODO: Should the list also be flushed at the beginning of each new
+  moment?
+ */
+void
+Translator_group::protect_event (SCM ev)
+{
+  protected_events_ = scm_cons (ev, protected_events_);
+}
+
 /*
   Create a new translator for a newly created child context. Triggered
   by AnnounceNewContext events.
@@ -147,7 +143,7 @@ Translator_group::create_child_translator (SCM sev)
     {
       Translator *type = get_translator (scm_car (s));
       if (!type)
-       warning (_f ("can't find: `%s'", ly_symbol2string (scm_car (s)).c_str ()));
+       warning (_f ("cannot find: `%s'", ly_symbol2string (scm_car (s)).c_str ()));
       else
        {
          Translator *tr = type->clone ();
@@ -169,14 +165,12 @@ Translator_group::create_child_translator (SCM sev)
        }
     }
 
-  g->simple_trans_list_ = trans_list;
-
   /* Filter unwanted translator types. Required to make
      \with {\consists "..."} work. */
   if (dynamic_cast<Engraver_group *> (g))
-    g->simple_trans_list_ = filter_performers (g->simple_trans_list_);
+    g->simple_trans_list_ = filter_performers (trans_list);
   else if (dynamic_cast<Performer_group *> (g))
-    g->simple_trans_list_ = filter_engravers (g->simple_trans_list_);
+    g->simple_trans_list_ = filter_engravers (trans_list);
 
   // TODO: scrap Context::implementation
   new_context->implementation_ = g;
@@ -190,53 +184,6 @@ Translator_group::create_child_translator (SCM sev)
                            DOWN);
 }
 
-IMPLEMENT_LISTENER (Translator_group, eat_event);
-void
-Translator_group::eat_event (SCM sev)
-{
-  Stream_event *ev = unsmob_stream_event (sev);
-  SCM sm = ev->get_property ("music");
-  Music *m = unsmob_music (sm);
-  try_music (m);
-}
-
-bool
-Translator_group::try_music (Music *m)
-{
-  SCM name = scm_sloppy_assq (ly_symbol2scm ("name"),
-                             m->get_property_alist (false));
-
-  if (!scm_is_pair (name))
-    return false;
-
-  name = scm_cdr (name);
-  SCM accept_list = scm_hashq_ref (accept_hash_table_, name, SCM_UNDEFINED);
-  if (accept_list == SCM_BOOL_F)
-    {
-      accept_list = find_accept_translators (get_simple_trans_list (),
-                                            m->get_property ("types"));
-      scm_hashq_set_x (accept_hash_table_, name, accept_list);
-    }
-
-  for (SCM p = accept_list; scm_is_pair (p); p = scm_cdr (p))
-    {
-      Translator *t = unsmob_translator (scm_car (p));
-      if (t && t->try_music (m))
-       return true;
-    }
-    
-  // We couldn't swallow the event in this context. Try parent.
-  Context *p = context ()->get_parent_context ();
-  // Global context's translator group is a dummy, so don't try it.
-  if (p->get_parent_context())
-    // ES todo: Make Translators listeners directly instead.
-    return p->implementation ()->try_music (m);
-  else
-    // We have tried all possible contexts. Give up.
-    m->origin ()->warning (_f ("junking event: `%s'", m->name ()));
-  return false;
-}
-
 SCM
 Translator_group::get_simple_trans_list ()
 {
@@ -249,7 +196,7 @@ precomputed_recurse_over_translators (Context *c, Translator_precompute_index id
   Translator_group *tg
     = dynamic_cast<Translator_group *> (c->implementation ());
 
-  if (dir == DOWN)
+  if (tg && dir == DOWN)
     {
       tg->precomputed_translator_foreach (idx);
       tg->call_precomputed_self_method (idx);
@@ -259,7 +206,7 @@ precomputed_recurse_over_translators (Context *c, Translator_precompute_index id
        s = scm_cdr (s))
     precomputed_recurse_over_translators (unsmob_context (scm_car (s)), idx, dir);
 
-  if (dir == UP)
+  if (tg && dir == UP)
     {
       tg->precomputed_translator_foreach (idx);
       tg->call_precomputed_self_method (idx);
@@ -267,12 +214,13 @@ precomputed_recurse_over_translators (Context *c, Translator_precompute_index id
 }
 
 void
-recurse_over_translators (Context *c, Translator_method ptr, Translator_group_method tg_ptr, Direction dir)
+recurse_over_translators (Context *c, Translator_method ptr,
+                         Translator_group_method tg_ptr, Direction dir)
 {
   Translator_group *tg
     = dynamic_cast<Translator_group *> (c->implementation ());
 
-  if (dir == DOWN)
+  if (tg && dir == DOWN)
     {
       (tg->*tg_ptr) ();
       translator_each (tg->get_simple_trans_list (), ptr);
@@ -282,7 +230,7 @@ recurse_over_translators (Context *c, Translator_method ptr, Translator_group_me
        s = scm_cdr (s))
     recurse_over_translators (unsmob_context (scm_car (s)), ptr, tg_ptr, dir);
 
-  if (dir == UP)
+  if (tg && dir == UP)
     {
       translator_each (tg->get_simple_trans_list (),
                       ptr);
@@ -294,11 +242,9 @@ recurse_over_translators (Context *c, Translator_method ptr, Translator_group_me
 Translator_group::Translator_group ()
 {
   simple_trans_list_ = SCM_EOL;
-  accept_hash_table_ = SCM_EOL;
+  protected_events_ = SCM_EOL;
   context_ = 0;
   smobify_self ();
-
-  accept_hash_table_ = scm_c_make_hash_table (19);
 }
 
 void
@@ -375,6 +321,6 @@ Translator_group::mark_smob (SCM smob)
   Translator_group *me = (Translator_group *)SCM_CELL_WORD_1 (smob);
 
   me->derived_mark ();
-  scm_gc_mark (me->accept_hash_table_);
+  scm_gc_mark (me->protected_events_);
   return me->simple_trans_list_;
 }