]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/chord-tremolo-*.cc: Reworked how \repeat "tremolo"
authorErik Sandberg <mandolaerik@gmail.com>
Wed, 24 May 2006 07:00:42 +0000 (07:00 +0000)
committerErik Sandberg <mandolaerik@gmail.com>
Wed, 24 May 2006 07:00:42 +0000 (07:00 +0000)
works. More work is done by iterator now, and engraver has been
very much simplified.

* lily/translator-group.cc: try_music is now invoked through a
listener

* lily/*-iterator.cc: Massive cleanups. Junked
try_music_in_children globally. Renamed try_music to report_event,
and made that method descend to a bottom context automatically.

* lily/event-iterator.cc: New file.

* lily/output-property-iterator.cc,
lily/old-lyric-combine-music-iterator.cc: Removed.

43 files changed:
ChangeLog
input/regression/apply-output.ly
input/regression/balloon.ly
input/regression/generic-output-property.ly
input/test/ancient-font.ly
input/test/move-specific-text.ly
lily/chord-tremolo-engraver.cc
lily/chord-tremolo-iterator.cc
lily/context-def.cc
lily/context.cc
lily/event-chord-iterator.cc
lily/event-iterator.cc [new file with mode: 0644]
lily/folded-repeat-iterator.cc
lily/include/chord-tremolo-iterator.hh
lily/include/event-chord-iterator.hh
lily/include/event-iterator.hh [new file with mode: 0644]
lily/include/folded-repeat-iterator.hh
lily/include/lily-proto.hh
lily/include/music-iterator.hh
lily/include/music-wrapper-iterator.hh
lily/include/percent-repeat-iterator.hh
lily/include/sequential-iterator.hh
lily/include/simultaneous-music-iterator.hh
lily/include/time-scaled-music-iterator.hh
lily/include/translator-group.hh
lily/lyric-combine-music-iterator.cc
lily/music-iterator.cc
lily/music-wrapper-iterator.cc
lily/old-lyric-combine-music-iterator.cc [deleted file]
lily/output-property-engraver.cc
lily/output-property-music-iterator.cc [deleted file]
lily/part-combine-iterator.cc
lily/percent-repeat-iterator.cc
lily/quote-iterator.cc
lily/sequential-iterator.cc
lily/simple-music-iterator.cc
lily/simultaneous-music-iterator.cc
lily/time-scaled-music-iterator.cc
lily/translator-group.cc
ly/music-functions-init.ly
python/convertrules.py
scm/define-music-properties.scm
scm/define-music-types.scm

index 77a7204c2ea6a41258154f02ec0e460b12076754..150ba926183c56430f97faf954397dc18beafb58 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,27 @@
+2006-05-24  Erik Sandberg  <mandolaerik@gmail.com>
+
+       * lily/chord-tremolo-*.cc: Reworked how \repeat "tremolo"
+       works. More work is done by iterator now, and engraver has been
+       very much simplified.
+
+       * lily/translator-group.cc: try_music is now invoked through a
+       listener
+
+       * lily/*-iterator.cc: Massive cleanups. Junked
+       try_music_in_children globally. Renamed try_music to report_event,
+       and made that method descend to a bottom context automatically.
+
+       * lily/event-iterator.cc: New file.
+
+       * lily/output-property-iterator.cc,
+       lily/old-lyric-combine-music-iterator.cc: Removed.
+
+       * python/convert-rules.py: Modified the syntax for \applyOutput.
+
 2006-05-23  Graham Percival  <gpermus@gmail.com>
 
-       * stepmake/stepmake/texinfo-rules.make: added -E, allows
-       pdf doc creation.
+       * stepmake/stepmake/texinfo-rules.make: added -E, allows pdf doc
+       creation.
 
        * Documentation/user/ various: stuff that might have helped
        to fix the pdf creation, plus some minor doc additions.
        * lily/time-scaled-music-iterator.cc, lily/tuplet-engraver.cc:
        rework tuplets: send start/stop events to engraver
 
+       * lily/context.cc, lily/music.cc, lily/context-scheme.cc: Add
+       dispatchers event-source and events-below to Context
+       
 2006-05-15  Graham Percival  <gpermus@gmail.com>
 
        * Documentation/user/README.txt: update info for doc writers.
index 128c07f6f0ab9273bbd5c2f9d49fe46a98e8106e..56d515557055194ed0a04b31a56b9400d71cf9e9 100644 (file)
@@ -1,5 +1,5 @@
 
-\version "2.7.39
+\version "2.9.6
 \header {
 
   texidoc = "The @code{\applyOutput} expression is the most flexible way to
@@ -38,7 +38,7 @@ position.
   \stemUp
   \set autoBeaming =  ##f
   { <d f g b>8
-    \context Voice \applyOutput #mc-squared
+    \applyOutput #'Voice #mc-squared
 
     <d f g b>
   }
index 1d0c9a75889605de3919249e9cc28c3fdc76ffa3..8f1ab2b8e9aace3796e1dae716cfcf87ad1e5d56 100644 (file)
@@ -3,7 +3,7 @@
   texidoc = "With balloon texts, objects in the output can be marked,
 with lines and explanatory text added."
 }
-\version "2.7.39"
+\version "2.9.6"
 
 \layout{ ragged-right = ##t }
 
@@ -21,7 +21,7 @@ with lines and explanatory text added."
 
 
     %% use predefd function. 
-    \context Voice \applyOutput #(add-balloon-text
+    \applyOutput #'Voice #(add-balloon-text
                                  'NoteHead "heads, or tails?"
                                  '(0 . -3))
 
index 9f94467da69544c531dac9d888254f1b57fe7997..e3257d207914542641d796907ab23cc1529e4f7a 100644 (file)
@@ -1,5 +1,5 @@
 
-\version "2.7.39"
+\version "2.9.6"
 
 \header{
   texidoc="
@@ -12,15 +12,12 @@ setting the @code{extra-offset} of a grob.
 
 
 \relative c''{
-  \context Bottom
-  \applyOutput #(outputproperty-compatibility
+  \applyOutput #'Bottom #(outputproperty-compatibility
                 (make-type-checker 'note-head-interface)
                 'extra-offset '(2 . 3))
   c2
   c
-  \context Score {
-    \applyOutput #(outputproperty-compatibility (make-type-checker 'mark-interface) 'extra-offset '(-1 . 4))
-  }
+  \applyOutput #'Score #(outputproperty-compatibility (make-type-checker 'mark-interface) 'extra-offset '(-1 . 4))
   \mark A
   d1
   \mark \default
index cd6ccaa36c51604c9df6bb596e16aa92c2ec89e6..a295c68c377ed2c5fe6d4fbaf7f71d3a28739aad 100644 (file)
@@ -1,4 +1,4 @@
-\version "2.7.39"
+\version "2.9.6"
 % TODO: split ancient-font into seperate files; possibly in
 % different locations.
 \header {
@@ -117,7 +117,7 @@ lowerStaff = \new MensuralStaff =  "lowerStaff" <<
     
     % this is broken until further notice -- see refman
     % \override Staff.StaffSymbol  #'line-count = #5
-    \context Staff \applyOutput #(outputproperty-compatibility (make-type-checker 'staff-symbol-interface) 'line-count 5)
+    \applyOutput #'Staff #(outputproperty-compatibility (make-type-checker 'staff-symbol-interface) 'line-count 5)
 
      \transpose c c {
        \set autoBeaming = ##f
index 51c25f0d57308f5629ff9c1059f045b0e5cbb7d9..44db4d861d00bfc4614e4dd0889987766eedce04 100644 (file)
@@ -1,5 +1,5 @@
 
-\version "2.7.39"
+\version "2.9.6"
 % possible rename to scheme- or something like that.  -gp
 \header { texidoc = "@cindex Scheme Move Text
 Objects, like text, can be moved around by using some Scheme code.
@@ -11,7 +11,7 @@ Objects, like text, can be moved around by using some Scheme code.
 \score {
   \relative c''' {
     \stemUp
-    \applyOutput #(outputproperty-compatibility (make-text-checker (make-simple-markup "m.d."))
+    \applyOutput #'Voice #(outputproperty-compatibility (make-text-checker (make-simple-markup "m.d."))
       'extra-offset '(-3.5 . -4.5))
     a^2^"m.d."
   }
index dd1c040946f78a315f2ddc8bd357770ee567221c..60800064c91ae4dd91b60b35827377fbbafc4694 100644 (file)
@@ -4,12 +4,12 @@
   source file of the GNU LilyPond music typesetter
 
   (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+                Erik Sandberg <mandolaerik@gmail.com>
 */
 
 #include "math.h" // ceil
 
 #include "beam.hh"
-#include "chord-tremolo-iterator.hh"
 #include "engraver-group.hh"
 #include "international.hh"
 #include "item.hh"
@@ -39,92 +39,72 @@ create dependencies between engravers, which is bad.
 */
 class Chord_tremolo_engraver : public Engraver
 {
-  void typeset_beam ();
   TRANSLATOR_DECLARATIONS (Chord_tremolo_engraver);
 protected:
   Music *repeat_;
 
-  /// moment (global time) where beam started.
-  Moment start_mom_;
-  Moment stop_mom_;
   int flags_;
-  int total_duration_flags_;
+  // number of beams for short tremolos
+  int expected_beam_count_;
+  // current direction of beam (first RIGHT, then LEFT)
+  Direction beam_dir_;
 
-  /// location  within measure where beam started.
-  Moment beam_start_location_;
-
-  bool body_is_sequential_;
   Spanner *beam_;
-  Spanner *finished_beam_;
-  Item *stem_tremolo_;
 protected:
   virtual void finalize ();
   virtual bool try_music (Music *);
-  void stop_translation_timestep ();
-  void start_translation_timestep ();
   void process_music ();
   DECLARE_ACKNOWLEDGER (stem);
 };
 
 Chord_tremolo_engraver::Chord_tremolo_engraver ()
 {
-  beam_ = finished_beam_ = 0;
+  beam_ = 0;
   repeat_ = 0;
   flags_ = 0;
-  stem_tremolo_ = 0;
-  body_is_sequential_ = false;
+  expected_beam_count_ = 0;
+  beam_dir_ = CENTER;
 }
 
 bool
 Chord_tremolo_engraver::try_music (Music *m)
 {
-  if (m->is_mus_type ("repeated-music")
-      && m->get_property ("iterator-ctor") == Chord_tremolo_iterator::constructor_proc
-      && !repeat_)
+  if (m->is_mus_type ("tremolo-span-event"))
     {
-      Moment l = m->get_length ();
-      repeat_ = m;
-      start_mom_ = now_mom ();
-      stop_mom_ = start_mom_ + l;
-
-      Music *body = Repeated_music::body (m);
-      body_is_sequential_ = body->is_mus_type ("sequential-music");
-
-      int elt_count = body_is_sequential_ ? scm_ilength (body->get_property ("elements")) : 1;
-
-      if (body_is_sequential_ && elt_count != 2)
-       m->origin ()->warning (_f ("expect 2 elements for chord tremolo, found %d", elt_count));
-
-      if (elt_count <= 0)
-       elt_count = 1;
-
-      Rational total_dur = l.main_part_;
-      Rational note_dur = total_dur / Rational (elt_count * Repeated_music::repeat_count (repeat_));
-
-      total_duration_flags_ = max (0, (intlog2 (total_dur.den ()) - 2));
-
-      flags_ = intlog2 (note_dur.den ()) -2;
-
+      Direction span_dir = to_dir (m->get_property ("span-direction"));
+      if (span_dir == START)
+       {
+         repeat_ = m;
+         int type = scm_to_int (m->get_property ("tremolo-type"));
+         /* e.g. 1 for type 8, 2 for type 16 */
+         flags_ = intlog2 (type) - 2;
+         expected_beam_count_ = scm_to_int (m->get_property ("expected-beam-count"));
+         beam_dir_ = RIGHT;
+       }
+      if (span_dir == STOP)
+       {
+         repeat_ = 0;
+          beam_ = 0;
+          expected_beam_count_ = 0;
+          beam_dir_ = CENTER;
+       }
       return true;
     }
-
   return false;
 }
 
 void
 Chord_tremolo_engraver::process_music ()
 {
-  if (repeat_ && body_is_sequential_ && !beam_)
+  if (repeat_ && !beam_)
     {
       beam_ = make_spanner ("Beam", repeat_->self_scm ());
-      beam_start_location_ = robust_scm2moment (get_property ("measurePosition"), Moment (0));
     }
 }
 
 void
 Chord_tremolo_engraver::finalize ()
 {
-  typeset_beam ();
   if (beam_)
     {
       repeat_->origin ()->warning (_ ("unterminated chord tremolo"));
@@ -132,12 +112,6 @@ Chord_tremolo_engraver::finalize ()
     }
 }
 
-void
-Chord_tremolo_engraver::typeset_beam ()
-{
-  finished_beam_ = 0;
-}
-
 void
 Chord_tremolo_engraver::acknowledge_stem (Grob_info info)
 {
@@ -145,13 +119,13 @@ Chord_tremolo_engraver::acknowledge_stem (Grob_info info)
     {
       Grob *s = info.grob ();
 
-      if (start_mom_ == now_mom ())
-       Stem::set_beaming (s, flags_, RIGHT);
-      else
-       Stem::set_beaming (s, flags_, LEFT);
+      Stem::set_beaming (s, flags_, beam_dir_);
 
       if (Stem::duration_log (s) != 1)
-       beam_->set_property ("gap-count", scm_from_int (flags_ - total_duration_flags_));
+       beam_->set_property ("gap-count", scm_from_int (flags_ - expected_beam_count_));
+
+      if (beam_dir_ == RIGHT)
+        beam_dir_ = LEFT;
 
       if (info.ultimate_music_cause ()->is_mus_type ("rhythmic-event"))
        Beam::add_stem (beam_, s);
@@ -164,49 +138,12 @@ Chord_tremolo_engraver::acknowledge_stem (Grob_info info)
            ::warning (s);
        }
     }
-  else if (repeat_
-          && flags_
-          && !body_is_sequential_)
-    {
-      stem_tremolo_ = make_item ("StemTremolo", repeat_->self_scm ());
-      stem_tremolo_->set_property ("flag-count",
-                                  scm_from_int (flags_));
-      stem_tremolo_->set_object ("stem",
-                                info.grob ()->self_scm ());
-      stem_tremolo_->set_parent (info.grob (), X_AXIS);
-      info.grob ()->set_object ("tremolo-flag", stem_tremolo_->self_scm ());
-    }
-}
-
-void
-Chord_tremolo_engraver::start_translation_timestep ()
-{
-  if (beam_ && stop_mom_ == now_mom ())
-    {
-      finished_beam_ = beam_;
-      repeat_ = 0;
-      beam_ = 0;
-    }
-}
-
-void
-Chord_tremolo_engraver::stop_translation_timestep ()
-{
-  if (stem_tremolo_)
-    {
-      repeat_ = 0;
-      if (beam_)
-       programming_error ("beam and stem tremolo?");
-      stem_tremolo_ = 0;
-    }
-
-  typeset_beam ();
 }
 
 ADD_ACKNOWLEDGER (Chord_tremolo_engraver, stem);
 ADD_TRANSLATOR (Chord_tremolo_engraver,
-               /* doc */ "Generates beams for  tremolo repeats.",
+               /* doc */ "Generates beams for tremolo repeats.",
                /* create */ "Beam",
-               /* accept */ "repeated-music",
+               /* accept */ "tremolo-span-event",
                /* read */ "",
                /* write */ "");
index b6f1c4f69a63ca8b6447f7864b9d2bc892e208b9..45ddbc443d65121fc4b1b7fcadf009fb67fef568 100644 (file)
@@ -4,82 +4,66 @@
   source file of the GNU LilyPond music typesetter
 
   (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+                Erik Sandberg <mandolaerik@gmail.com>
 */
 
 #include "chord-tremolo-iterator.hh"
 
 #include "input.hh"
 #include "international.hh"
+#include "misc.hh"
 #include "repeated-music.hh"
 
-void
-Chord_tremolo_iterator::construct_children ()
-{
-  Music *m = get_music ();
-
-  factor_ = Moment (Rational (1, 1));
-  child_iter_ = unsmob_iterator (get_iterator (Repeated_music::body (m)));
-}
-
 Chord_tremolo_iterator::Chord_tremolo_iterator ()
 {
-  factor_ = 1;
-  child_iter_ = 0;
-}
-
-void
-Chord_tremolo_iterator::do_quit ()
-{
-  if (child_iter_)
-    child_iter_->quit ();
-}
-
-void
-Chord_tremolo_iterator::derived_mark () const
-{
-  if (child_iter_)
-    scm_gc_mark (child_iter_->self_scm ());
 }
 
-void
-Chord_tremolo_iterator::derived_substitute (Context *f, Context *t)
+SCM
+Chord_tremolo_iterator::get_music_list () const
 {
-  if (child_iter_)
-    child_iter_->substitute_outlet (f, t);
-}
+  Music *mus = get_music ();
+  Input *origin = mus->origin ();
+  Moment l = mus->get_length ();
+  Music *body = Repeated_music::body (mus);
+  bool body_is_sequential = body->is_mus_type ("sequential-music");
 
-void
-Chord_tremolo_iterator::process (Moment m)
-{
-  if (!m.to_bool ())
-    {
-      Music_iterator *yeah = try_music (get_music ());
-      if (yeah)
-       set_context (yeah->get_outlet ());
-      else
-       get_music ()->origin ()->warning (_ ("no one to print a tremolos"));
-    }
+  int elt_count = body_is_sequential ? scm_ilength (body->get_property ("elements")) : 1;
 
-  child_iter_->process (factor_ * m);
-}
+  if (body_is_sequential && elt_count != 2)
+    mus->origin ()->warning (_f ("expect 2 elements for chord tremolo, found %d", elt_count));
 
-Moment
-Chord_tremolo_iterator::pending_moment () const
-{
-  return child_iter_->pending_moment () / factor_;
-}
+  if (elt_count <= 0)
+    elt_count = 1;
+      
+  Rational total_dur = l.main_part_;
+  Rational note_dur = total_dur / Rational (elt_count * Repeated_music::repeat_count (mus));
 
-bool
-Chord_tremolo_iterator::ok () const
-{
-  return child_iter_ && child_iter_->ok ();
-}
+  SCM tremolo_type = scm_int2num (note_dur.den ());
+  int expected_beaming_ = max (0, (intlog2 (total_dur.den ()) - 2));
 
-Music_iterator *
-Chord_tremolo_iterator::try_music_in_children (Music *m) const
-{
-  return child_iter_->try_music (m);
+  if (elt_count == 1)
+    {
+      Music *ev = make_music_by_name (ly_symbol2scm ("TremoloEvent"));
+      ev->set_spot (*origin);
+      ev->set_property ("tremolo-type", tremolo_type);
+      return scm_list_2 (ev->unprotect (), body->self_scm ());
+    }
+  else
+    { 
+      SCM tremolo_symbol = ly_symbol2scm ("TremoloSpanEvent");
+      SCM start_event_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"), tremolo_symbol, scm_from_int (START));
+      unsmob_music (start_event_scm)->set_spot (*origin);
+      SCM stop_event_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"), tremolo_symbol, scm_from_int (STOP));
+
+      Music *start_event = unsmob_music (start_event_scm);
+      Music *stop_event = unsmob_music (stop_event_scm);
+      start_event->set_spot (*origin);
+      stop_event->set_spot (*origin);
+      start_event->set_property ("tremolo-type", tremolo_type);
+      start_event->set_property ("expected-beam-count", scm_int2num (expected_beaming_));
+
+      return scm_list_3 (start_event_scm, body->self_scm (), stop_event_scm);
+    }
 }
 
 IMPLEMENT_CTOR_CALLBACK (Chord_tremolo_iterator);
-
index 05363e498c32279b0be00529d1d19fa643e12471..fee67b661d043ad86a7777039fd84c7fabc53bb4 100644 (file)
@@ -344,9 +344,8 @@ Context_def::instantiate (SCM ops, Object_key const *key)
   else if (dynamic_cast<Performer_group *> (g))
     g->simple_trans_list_ = filter_engravers (g->simple_trans_list_);
 
-  g->context_ = context;
   context->aliases_ = context_aliases_;
-
+  g->connect_to_context (context);
   g->unprotect ();
 
   context->accepts_list_ = get_accepted (ops);
index 010e07798bd9521f7836288c58f854452a7fb0db..5e97a6171de24c24830548e4c141ed763d587dac 100644 (file)
@@ -660,3 +660,16 @@ set_context_property_on_children (Context *trans, SCM sym, SCM val)
       set_context_property_on_children (trg, sym, ly_deep_copy (val));
     }
 }
+
+bool
+melisma_busy (Context *tr)
+{
+  SCM melisma_properties = tr->get_property ("melismaBusyProperties");
+  bool busy = false;
+
+  for (; scm_is_pair (melisma_properties);
+       melisma_properties = scm_cdr (melisma_properties))
+    busy = busy || to_boolean (tr->internal_get_property (scm_car (melisma_properties)));
+
+  return busy;
+}
index 2b1441a2756d862efde60cff2d5cc02e7c8db328..60e7e3081a0ba00fce334c5ec16f5527181ceae1 100644 (file)
@@ -20,22 +20,11 @@ Event_chord_iterator::Event_chord_iterator ()
 {
 }
 
-Context *
-Event_chord_iterator::get_bottom_context ()
-{
-  assert (get_outlet ());
-  if (get_outlet ()->is_bottom_context ())
-    return get_outlet ();
-
-  set_context (get_outlet ()->get_default_interpreter ());
-  return get_outlet ();
-}
-
 void
 Event_chord_iterator::construct_children ()
 {
   Simple_music_iterator::construct_children ();
-  get_bottom_context ();
+  descend_to_bottom_context ();
 }
 
 void
@@ -47,10 +36,7 @@ Event_chord_iterator::process (Moment m)
           scm_is_pair (s); s = scm_cdr (s))
        {
          Music *mus = unsmob_music (scm_car (s));
-
-         bool gotcha = try_music (mus);
-         if (!gotcha)
-           mus->origin ()->warning (_f ("junking event: `%s'", mus->name ()));
+         report_event (mus);
        }
     }
   Simple_music_iterator::process (m);
diff --git a/lily/event-iterator.cc b/lily/event-iterator.cc
new file mode 100644 (file)
index 0000000..8e6d6df
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+  event-chord-iterator.cc -- implement Event_chord_iterator
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+*/
+
+#include "event-iterator.hh"
+
+#include "context.hh"
+#include "duration.hh"
+#include "input.hh"
+#include "international.hh"
+#include "music.hh"
+#include "pitch.hh"
+#include "warn.hh"
+
+Event_iterator::Event_iterator ()
+{
+}
+
+void
+Event_iterator::construct_children ()
+{
+  descend_to_bottom_context ();
+  Simple_music_iterator::construct_children ();
+}
+
+void
+Event_iterator::process (Moment m)
+{
+  if (last_processed_mom_ < Moment (0))
+    report_event (get_music ());
+
+  Simple_music_iterator::process (m);
+}
+
+IMPLEMENT_CTOR_CALLBACK (Event_iterator);
index 6465f3399ad1982e876f13bef392411dc470d915..1a4de7c369b828618110634bad5797cd73f7acba 100644 (file)
@@ -107,15 +107,6 @@ Folded_repeat_iterator::enter_alternative ()
     }
 }
 
-Music_iterator *
-Folded_repeat_iterator::try_music_in_children (Music *m) const
-{
-  if (main_iter_)
-    return main_iter_->try_music (m);
-  if (alternative_iter_)
-    return alternative_iter_->try_music (m);
-  return 0;
-}
 void
 Folded_repeat_iterator::derived_mark () const
 {
index 12c12607f110b9393aed68a36eea487563ddf76f..d1d407dd1f002a7b05f807e835f434306013cc92 100644 (file)
@@ -9,28 +9,18 @@
 #ifndef CHORD_TREMOLO_ITERATOR_HH
 #define CHORD_TREMOLO_ITERATOR_HH
 
-#include "music-iterator.hh"
+#include "sequential-iterator.hh"
 
-class Chord_tremolo_iterator : public Music_iterator
+class Chord_tremolo_iterator : public Sequential_iterator
 {
 public:
-  DECLARE_CLASSNAME(Chord_tremolo_iterator);
   DECLARE_SCHEME_CALLBACK (constructor, ());
+  /* construction */
+  DECLARE_CLASSNAME(Chord_tremolo_iterator);
   Chord_tremolo_iterator ();
-  Chord_tremolo_iterator (Chord_tremolo_iterator const &);
 protected:
-  virtual void derived_substitute (Context *f, Context *t);
-
-  virtual void derived_mark () const;
-  virtual Moment pending_moment () const;
-  virtual void do_quit ();
-  virtual void construct_children ();
-  virtual bool ok () const;
-  virtual void process (Moment);
-  virtual Music_iterator *try_music_in_children (Music *) const;
+  virtual SCM get_music_list () const;
 private:
-  Moment factor_;
-  Music_iterator *child_iter_;
 };
 
 #endif /* CHORD_TREMOLO_ITERATOR_HH */
index 5dd293038f56685d5300177c31291b5d06065779..a252e871fe2af892bfd1de83f389a943eddf5d07 100644 (file)
@@ -1,13 +1,13 @@
 /*
-  event-iter.hh -- declare Event_chord_iterator
+  event-chord-iterator.hh -- declare Event_chord_iterator
 
   source file of the GNU LilyPond music typesetter
 
   (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
 */
 
-#ifndef EVENT_ITER_HH
-#define EVENT_ITER_HH
+#ifndef EVENT_CHORD_ITERATOR_HH
+#define EVENT_CHORD_ITERATOR_HH
 
 #include "simple-music-iterator.hh"
 
@@ -19,16 +19,8 @@ class Event_chord_iterator : public Simple_music_iterator
   /**
      Find a bottom notation context to deliver events to.
   */
-  virtual Context *get_bottom_context ();
   DECLARE_CLASSNAME(Event_chord_iterator);
 
-  /*
-    Since Event_chord_iterator has no list-cursor internally, we
-    must use a status variable to adminstrate where we are */
-
-  enum { NONE_DONE, START_DONE, END_DONE }
-    status_;
-
 public:
   DECLARE_SCHEME_CALLBACK (constructor, ());
   Event_chord_iterator ();
@@ -39,4 +31,4 @@ protected:
   virtual void construct_children ();
 };
 
-#endif // EVENT_ITER_HH
+#endif // EVENT_CHORD_ITERATOR_HH
diff --git a/lily/include/event-iterator.hh b/lily/include/event-iterator.hh
new file mode 100644 (file)
index 0000000..ce2809c
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+  event-iter.hh -- declare Event_chord_iterator
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+          Erik Sandberg <mandolaerik@gmail.com>
+*/
+
+#ifndef EVENT_ITERATOR_HH
+#define EVENT_ITERATOR_HH
+
+#include "simple-music-iterator.hh"
+
+class Event_iterator : public Simple_music_iterator
+{
+  DECLARE_CLASSNAME(Event_iterator);
+
+public:
+  DECLARE_SCHEME_CALLBACK (constructor, ());
+  Event_iterator ();
+  Event_iterator (Event_iterator const &);
+  virtual void construct_children ();
+
+protected:
+  virtual void process (Moment);
+};
+
+#endif // EVENT_ITERATOR_HH
index 2d52a5cc84826c1e7472c9797a60da44ce428aab..239b7941f005aa8032a4f02d7f876cb3a14bf233 100644 (file)
@@ -36,7 +36,6 @@ protected:
   void leave_body ();
 
   virtual void process (Moment);
-  virtual Music_iterator *try_music_in_children (Music *) const;
 
 private:
   Music_iterator *main_iter_;
index d0410c7ae2630880c788d7ba6961ad81d112dd07..58e7cb4c84d897eea7440752a686d366c9dd636a 100644 (file)
@@ -51,6 +51,7 @@ class Engraver_group;
 class Event;
 class Event_chord;
 class Event_chord_iterator;
+class Event_iterator;
 class Folded_repeat_iterator;
 class Font_metric;
 class Font_size_engraver;
index 0b738aa0b338569bf7409d3a04c4606c6650a963..3c62205b90ce396359dd2d6ee75d66d883ac98be 100644 (file)
@@ -61,13 +61,14 @@ public:
   Moment music_get_length () const;
   Moment music_start_mom () const;
   Music_iterator ();
-  Music_iterator *try_music (Music *) const;
+  void report_event (Music *);
   Context *get_outlet () const;
   void set_context (Context *);
   static SCM get_static_get_iterator (Music *mus);
   void init_translator (Music *, Context *);
   void quit ();
   void substitute_outlet (Context *from, Context *to);
+  void descend_to_bottom_context ();
   virtual void derived_substitute (Context *, Context *);
   virtual Moment pending_moment () const;
   virtual bool ok () const;
@@ -78,8 +79,6 @@ public:
   DECLARE_SCHEME_CALLBACK (constructor, ());
   SCM get_iterator (Music *) const;
 
-  virtual Music_iterator *try_music_in_children (Music *) const;
-
   Music *get_music () const;
 protected:
   virtual void do_quit ();
index 41ede2711e4fed7e93ef6afa4d8395c2ae55644c..d249428654fe09715b15cf77b6fb2d941b340c5a 100644 (file)
@@ -33,7 +33,6 @@ public:
   virtual bool run_always () const;
 protected:
   virtual void process (Moment);
-  virtual Music_iterator *try_music_in_children (Music *) const;
 
   Music_iterator *child_iter_;
 };
index 7c510cd7ad3532425c334322fa84d57db5ee2b5f..8637d9f7aedc23eabed38e93e9e95fd3803c1d0e 100644 (file)
@@ -19,10 +19,7 @@ public:
   Percent_repeat_iterator ();
 protected:
   virtual SCM get_music_list () const;
-  virtual void derived_mark () const;
-  virtual void construct_children ();
 private:
-  SCM child_list_;
 };
 
 #endif /* PERCENT_REPEAT_ITERATOR_HH */
index 5015fb9a6af47a595922038a910c003f17167313..124461d99728cc1ddd53a9b09399c07164929d9d 100644 (file)
@@ -33,7 +33,6 @@ public:
 
 protected:
   virtual void process (Moment);
-  virtual Music_iterator *try_music_in_children (Music *) const;
   virtual bool run_always () const;
   
 protected:
index e98bc6feb21f7cad835afb8b2fa52079131ddc26..ae318f478bf5df3be3729cad6d03554ff056d754 100644 (file)
@@ -32,7 +32,6 @@ public:
 
 protected:
   virtual void process (Moment);
-  virtual Music_iterator *try_music_in_children (Music *) const;
 
 private:
   SCM children_list_;
index 34bd50cf6f54e20a1d6b12ce93dee7c3907cacff..f2b3d0bd180efb5a2a1a7c4a888f639b826985b3 100644 (file)
@@ -21,10 +21,7 @@ public:
   Time_scaled_music_iterator ();
 protected:
   virtual SCM get_music_list () const;
-  virtual void derived_mark () const;
-  virtual void construct_children ();
 private:
-  SCM child_list_;
 };
 
 #endif /* TIME_SCALED_MUSIC_ITERATOR_HH */
index 9a6940ac06be2fe26c9f3cdd56a70b5e284d428a..3bb6b4255f8787cb0d2493a7890dc9e6c09199eb 100644 (file)
@@ -9,6 +9,7 @@
 #ifndef TRANSLATOR_GROUP_HH
 #define TRANSLATOR_GROUP_HH
 
+#include "listener.hh"
 #include "translator.hh"
 #include "std-vector.hh"
 
@@ -46,11 +47,14 @@ private:
   Translator_group_void_method
   precomputed_self_method_bindings_[TRANSLATOR_METHOD_PRECOMPUTE_COUNT];
 
+  DECLARE_LISTENER (eat_event);
+
 public:
   VIRTUAL_COPY_CONSTRUCTOR (Translator_group, Translator_group);
   DECLARE_SMOBS (Translator_group, dummy);
 
 public:
+  void connect_to_context (Context *c);
   virtual Translator_group *get_daddy_translator ()const;
   virtual SCM get_simple_trans_list ();
   virtual bool try_music (Music *req);
index f812d1c952768d0a46f25f4448f44139d1112265..feb18d65590db03c0ae81108b70c7e72174b5ed7 100644 (file)
@@ -7,9 +7,12 @@
 */
 
 #include "context.hh"
+#include "dispatcher.hh"
+#include "global-context.hh"
 #include "grob.hh"
 #include "input.hh"
 #include "international.hh"
+#include "listener.hh"
 #include "music-iterator.hh"
 #include "music.hh"
 
@@ -24,69 +27,82 @@ protected:
   virtual Moment pending_moment () const;
   virtual void do_quit ();
   virtual void process (Moment);
-  virtual Music_iterator *try_music_in_children (Music *) const;
   virtual bool run_always ()const;
   virtual bool ok () const;
   virtual void derived_mark () const;
   virtual void derived_substitute (Context *, Context *);
+  void set_music_context (Context *to);
 private:
   bool start_new_syllable ();
-  void find_voice ();
+  Context *find_voice ();
+  DECLARE_LISTENER (set_busy);
+  DECLARE_LISTENER (check_new_context);
 
   bool pending_grace_lyric_;
   bool music_found_;
-  bool made_association_;
   Context *lyrics_context_;
   Context *music_context_;
   SCM lyricsto_voice_name_;
 
+  bool busy_;
   Music_iterator *lyric_iter_;
 };
 
-/*
-  Ugh; this is a hack, let's not export this hack, so static.
-*/
-static Music *busy_ev;
-static Music *start_ev;
-static Music *melisma_playing_ev;
-
 Lyric_combine_music_iterator::Lyric_combine_music_iterator ()
 {
   music_found_ = false;
-  made_association_ = false;
   pending_grace_lyric_ = false;
   lyric_iter_ = 0;
   music_context_ = 0;
   lyrics_context_ = 0;
+  busy_ = false;
+}
 
-  /*
-    Ugh. out of place here.
-  */
-  if (!busy_ev)
+IMPLEMENT_LISTENER (Lyric_combine_music_iterator, set_busy)
+void
+Lyric_combine_music_iterator::set_busy (SCM se)
+{
+  Stream_event *e = unsmob_stream_event (se);
+  SCM mus = e->get_property ("music");
+  Music *m = unsmob_music (mus);
+  assert (m);
+
+  if (m->is_mus_type ("note-event") || m->is_mus_type ("cluster-note-event"))
+    busy_ = true;
+}
+
+void
+Lyric_combine_music_iterator::set_music_context (Context *to)
+{
+  if (music_context_)
+    {
+      music_context_->event_source()->remove_listener (GET_LISTENER (set_busy), ly_symbol2scm ("MusicEvent"));
+      lyrics_context_->unset_property (ly_symbol2scm ("associatedVoiceContext"));
+    }
+  music_context_ = to;
+  if (to)
     {
-      busy_ev
-       = make_music_by_name (ly_symbol2scm ("BusyPlayingEvent"));
-      start_ev
-       = make_music_by_name (ly_symbol2scm ("StartPlayingEvent"));
-      melisma_playing_ev
-       = make_music_by_name (ly_symbol2scm ("MelismaPlayingEvent"));
+      to->event_source()->add_listener (GET_LISTENER (set_busy), ly_symbol2scm ("MusicEvent"));
+      lyrics_context_->set_property ("associatedVoiceContext", to->self_scm ());
     }
 }
 
 bool
 Lyric_combine_music_iterator::start_new_syllable ()
 {
-  bool b = music_context_->try_music (busy_ev);
-
-  if (!b)
+  if (!busy_)
     return false;
 
+  busy_ = false;
+
+      scm_display (music_context_->now_mom().smobbed_copy(), scm_current_output_port ());
+
   if (!lyrics_context_)
     return false;
 
   if (!to_boolean (lyrics_context_->get_property ("ignoreMelismata")))
     {
-      bool m = music_context_->try_music (melisma_playing_ev);
+      bool m = melisma_busy (music_context_);
       if (m)
        return false;
     }
@@ -135,7 +151,7 @@ Lyric_combine_music_iterator::derived_substitute (Context *f, Context *t)
   if (lyrics_context_ && lyrics_context_ == f)
     lyrics_context_ = t;
   if (music_context_ && music_context_ == f)
-    music_context_ = t;
+    set_music_context (t);
 }
 
 void
@@ -143,14 +159,25 @@ Lyric_combine_music_iterator::construct_children ()
 {
   Music *m = unsmob_music (get_music ()->get_property ("element"));
   lyric_iter_ = unsmob_iterator (get_iterator (m));
+  if (!lyric_iter_)
+    return;
+  lyrics_context_ = find_context_below (lyric_iter_->get_outlet (),
+                                       ly_symbol2scm ("Lyrics"), "");
 
   lyricsto_voice_name_ = get_music ()->get_property ("associated-context");
 
-  find_voice ();
-
-  if (lyric_iter_)
-    lyrics_context_ = find_context_below (lyric_iter_->get_outlet (),
-                                         ly_symbol2scm ("Lyrics"), "");
+  Context *voice = find_voice ();
+  if (voice)
+    set_music_context (voice);
+  else
+    {
+      /*
+        Wait for a Create_context event. If this isn't done, lyrics can be 
+        delayed when voices are created implicitly.
+      */
+      Global_context *g = lyrics_context_->get_global_context ();
+      g->events_below ()->add_listener (GET_LISTENER (check_new_context), ly_symbol2scm ("CreateContext"));
+    }
 
   /*
     We do not create a Lyrics context, because the user might
@@ -159,7 +186,27 @@ Lyric_combine_music_iterator::construct_children ()
   */
 }
 
+IMPLEMENT_LISTENER (Lyric_combine_music_iterator, check_new_context)
 void
+Lyric_combine_music_iterator::check_new_context (SCM sev)
+{
+  // TODO: Check first if type=Voice and if id matches
+  (void)sev;
+
+  Context *voice = find_voice ();
+  if (voice)
+    {
+      set_music_context (voice);
+
+      Global_context *g = voice->get_global_context ();
+      g->events_below ()->remove_listener (GET_LISTENER (check_new_context), ly_symbol2scm ("CreateContext"));
+    }
+}
+
+/*
+Look for a suitable voice to align lyrics to.
+*/
+Context *
 Lyric_combine_music_iterator::find_voice ()
 {
   SCM voice_name = lyricsto_voice_name_;
@@ -173,40 +220,20 @@ Lyric_combine_music_iterator::find_voice ()
   if (scm_is_string (voice_name)
       && (!music_context_ || ly_scm2string (voice_name) != music_context_->id_string ()))
     {
-      /*
-       (spaghettini).
-
-       Need to set associatedVoiceContext again
-      */
-      if (music_context_)
-       made_association_ = false;
-
       Context *t = get_outlet ();
       while (t && t->get_parent_context ())
        t = t->get_parent_context ();
 
       string name = ly_scm2string (voice_name);
-      Context *voice = find_context_below (t, ly_symbol2scm ("Voice"), name);
-
-      if (voice)
-       music_context_ = voice;
+      return find_context_below (t, ly_symbol2scm ("Voice"), name);
     }
 
-  if (lyrics_context_ && music_context_)
-    {
-      if (!made_association_)
-       {
-         made_association_ = true;
-         lyrics_context_->set_property ("associatedVoiceContext",
-                                        music_context_->self_scm ());
-       }
-    }
+  return 0;
 }
 
 void
-Lyric_combine_music_iterator::process (Moment mom)
+Lyric_combine_music_iterator::process (Moment)
 {
-  (void) mom;
   find_voice ();
   if (!music_context_)
     return;
@@ -220,7 +247,7 @@ Lyric_combine_music_iterator::process (Moment mom)
       if (lyrics_context_)
        lyrics_context_->unset_property (ly_symbol2scm ("associatedVoiceContext"));
       lyric_iter_ = 0;
-      music_context_ = 0;
+      set_music_context (0);
     }
 
   if (music_context_
@@ -261,10 +288,4 @@ Lyric_combine_music_iterator::do_quit ()
     lyric_iter_->quit ();
 }
 
-Music_iterator *
-Lyric_combine_music_iterator::try_music_in_children (Music *m) const
-{
-  return lyric_iter_->try_music (m);
-}
-
 IMPLEMENT_CTOR_CALLBACK (Lyric_combine_music_iterator);
index 528fffb682817b2e6bb74dcbb669ff7324eb49e0..fcfd2fc1f45cfe31923730b7d957eb49b5dde9dc 100644 (file)
@@ -14,6 +14,9 @@ using namespace std;
 
 #include "warn.hh"
 #include "context.hh"
+#include "event-iterator.hh"
+#include "input.hh"
+#include "international.hh"
 #include "music-wrapper.hh"
 #include "music-wrapper-iterator.hh"
 #include "simple-music-iterator.hh"
@@ -85,6 +88,8 @@ Music_iterator::get_static_get_iterator (Music *m)
     {
       if (dynamic_cast<Music_wrapper *> (m))
        p = new Music_wrapper_iterator;
+      else if (m->is_mus_type ("event"))
+        p = new Event_iterator;
       else
        p = new Simple_music_iterator;
 
@@ -146,30 +151,24 @@ Music_iterator::get_iterator (Music *m) const
   return ip;
 }
 
-/*
-  TODO: rename to prevent confusion between Context::try_music and
-  Iterator::try_music
-*/
-Music_iterator *
-Music_iterator::try_music (Music *m) const
+/* Descend to a bottom context; implicitly create a new one if necessary */
+void
+Music_iterator::descend_to_bottom_context ()
 {
-  bool b = get_outlet ()->try_music ((Music *)m); // ugh
-  Music_iterator *it = b ? (Music_iterator *) this : 0;        // ugh
-  if (!it)
-    it = try_music_in_children (m);
-  else
-    /* TODO: try_music should only do the following:
-     - descend iterator to bottom context
-     - send music to a bottom context.
-     The function should also be renamed, and it should not return a value. */
-    m->send_to_context (get_outlet ());
-  return it;
+  assert (get_outlet ());
+  if (!get_outlet ()->is_bottom_context ())
+    set_context (get_outlet ()->get_default_interpreter ());
 }
 
-Music_iterator *
-Music_iterator::try_music_in_children (Music *) const
+void 
+Music_iterator::report_event (Music *m)
 {
-  return 0;
+  descend_to_bottom_context ();
+
+  if (!m->is_mus_type ("event"))
+    m->origin ()->warning (_f ("Sending non-event to context"));
+
+  m->send_to_context (get_outlet ());
 }
 
 IMPLEMENT_CTOR_CALLBACK (Music_iterator);
index 643d30f024ebdfb879d29b15f95ad1d27ecc09c0..c50a64c7c10f97082658bdaff72fada615b789b1 100644 (file)
@@ -60,12 +60,6 @@ Music_wrapper_iterator::pending_moment () const
   return child_iter_->pending_moment ();
 }
 
-Music_iterator *
-Music_wrapper_iterator::try_music_in_children (Music *m) const
-{
-  return child_iter_->try_music (m);
-}
-
 IMPLEMENT_CTOR_CALLBACK (Music_wrapper_iterator);
 
 bool
diff --git a/lily/old-lyric-combine-music-iterator.cc b/lily/old-lyric-combine-music-iterator.cc
deleted file mode 100644 (file)
index d1f68cc..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
-  lyric-combine-music-iterator.cc -- implement Old_lyric_combine_music_iterator
-
-  source file of the GNU LilyPond music typesetter
-
-  (c) 1999--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
-*/
-
-#include "context.hh"
-#include "music.hh"
-#include "note-head.hh"
-#include "grob.hh"
-#include "music-iterator.hh"
-
-class Old_lyric_combine_music_iterator : public Music_iterator
-{
-public:
-  Old_lyric_combine_music_iterator ();
-  Old_lyric_combine_music_iterator (Old_lyric_combine_music_iterator const &src);
-  DECLARE_SCHEME_CALLBACK (constructor, ());
-protected:
-  virtual void construct_children ();
-  virtual Moment pending_moment () const;
-  virtual void do_quit ();
-  virtual void process (Moment);
-  virtual Music_iterator *try_music_in_children (Music *) const;
-
-  virtual bool ok () const;
-  virtual void derived_mark () const;
-  virtual void derived_substitute (Context *, Context *);
-private:
-  bool get_busy_status () const;
-  bool melisma_busy ();
-  Music *get_combine_lyrics () const;
-  Music *get_combine_music () const;
-
-  Music_iterator *music_iter_;
-  Music_iterator *lyric_iter_;
-};
-
-bool
-melisma_busy (Context *tr)
-{
-  SCM melisma_properties = tr->get_property ("melismaBusyProperties");
-  bool busy = false;
-
-  for (; scm_is_pair (melisma_properties);
-       melisma_properties = scm_cdr (melisma_properties))
-    busy = busy || to_boolean (tr->internal_get_property (scm_car (melisma_properties)));
-
-  return busy;
-}
-
-/*
-  Ugh, why static?
-*/
-Music *busy_req;
-Music *melisma_playing_req;
-
-Old_lyric_combine_music_iterator::Old_lyric_combine_music_iterator ()
-{
-  music_iter_ = 0;
-  lyric_iter_ = 0;
-
-  if (!busy_req)
-    {
-      busy_req
-       = make_music_by_name (ly_symbol2scm ("BusyPlayingEvent"));
-      melisma_playing_req
-       = make_music_by_name (ly_symbol2scm ("MelismaPlayingEvent"));
-    }
-}
-
-Moment
-Old_lyric_combine_music_iterator::pending_moment () const
-{
-  Moment musnext = music_iter_->pending_moment ();
-  return musnext;
-}
-
-bool
-Old_lyric_combine_music_iterator::ok () const
-{
-  return music_iter_->ok ();
-}
-
-void
-Old_lyric_combine_music_iterator::derived_mark ()const
-{
-  if (music_iter_)
-    scm_gc_mark (music_iter_->self_scm ());
-  if (lyric_iter_)
-    scm_gc_mark (lyric_iter_->self_scm ());
-}
-
-void
-Old_lyric_combine_music_iterator::derived_substitute (Context *f, Context *t)
-{
-  if (music_iter_)
-    music_iter_->substitute_outlet (f, t);
-  if (lyric_iter_)
-    lyric_iter_->substitute_outlet (f, t);
-}
-
-Music *
-Old_lyric_combine_music_iterator::get_combine_music () const
-{
-  SCM l = get_music ()->get_property ("elements");
-  if (!scm_is_pair (l))
-    return 0;
-  return unsmob_music (scm_car (l));
-}
-
-Music *
-Old_lyric_combine_music_iterator::get_combine_lyrics () const
-{
-  SCM l = get_music ()->get_property ("elements");
-  if (!scm_is_pair (l))
-    return 0;
-  l = scm_cdr (l);
-  if (!scm_is_pair (l))
-    return 0;
-  return unsmob_music (scm_car (l));
-}
-
-void
-Old_lyric_combine_music_iterator::construct_children ()
-{
-  music_iter_ = unsmob_iterator (get_iterator (get_combine_music ()));
-  lyric_iter_ = unsmob_iterator (get_iterator (get_combine_lyrics ()));
-}
-
-bool
-Old_lyric_combine_music_iterator::get_busy_status () const
-{
-  /*
-    We have to use both the event and the busyGrobs queue.  The
-    busyGrobs queue doesn't contain any notes that have started this
-    instant.  */
-  if (try_music (busy_req))
-    return true;
-
-  Context *tr = music_iter_->get_outlet ();
-
-  SCM grobs = tr->get_property ("busyGrobs");
-  Moment now = tr->now_mom ();
-  for (; scm_is_pair (grobs); grobs = scm_cdr (grobs))
-    {
-      SCM grob = scm_cdar (grobs);
-      Moment end = *unsmob_moment (scm_caar (grobs));
-
-      /*
-       This is slightly ugh: we are now confunding the frontend
-       (iterators) and the backend (note heads) */
-      if (end > now
-         && Note_head::has_interface (unsmob_grob (grob)))
-       return true;
-    }
-
-  return false;
-}
-
-bool
-Old_lyric_combine_music_iterator::melisma_busy ()
-{
-  /* We cannot read the property, since music_iter_->get_outlet () might
-     not be the context that sets the melisma properties, but rather a
-     parent context.  */
-  return music_iter_->try_music (melisma_playing_req);
-}
-
-void
-Old_lyric_combine_music_iterator::process (Moment m)
-{
-  Moment my_next = music_iter_->pending_moment ();
-  if (my_next > m)
-    return;
-
-  music_iter_->process (m);
-
-  if (get_busy_status () && !melisma_busy () && lyric_iter_->ok ())
-    {
-      Moment m = lyric_iter_->pending_moment ();
-      lyric_iter_->process (m);
-    }
-}
-
-void
-Old_lyric_combine_music_iterator::do_quit ()
-{
-  if (music_iter_)
-    music_iter_->quit ();
-  if (lyric_iter_)
-    lyric_iter_->quit ();
-}
-
-Music_iterator *
-Old_lyric_combine_music_iterator::try_music_in_children (Music *m) const
-{
-  Music_iterator *i = music_iter_->try_music (m);
-  if (i)
-    return i;
-  else
-    return lyric_iter_->try_music (m);
-}
-
-IMPLEMENT_CTOR_CALLBACK (Old_lyric_combine_music_iterator);
index 74ee4494117904040680d2d5ee65100e247dcead..7f59d44430b7b433f17339c2fa2e70684e9848e4 100644 (file)
@@ -31,8 +31,15 @@ Output_property_engraver::try_music (Music* m)
 {
   if (m->is_mus_type ("layout-instruction"))
     {
-      props_.push_back (m);
-      return true;
+      /*
+       UGH. Only swallow the output property event in the context
+       it was intended for. This is inelegant but not inefficient.
+      */
+      if (context ()->is_alias (m->get_property ("context-type")))
+        {
+          props_.push_back (m);
+          return true;
+        }
     }
   return false;
 }
diff --git a/lily/output-property-music-iterator.cc b/lily/output-property-music-iterator.cc
deleted file mode 100644 (file)
index a08b884..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*   
-  output-property-music-iterator.cc -- implement Output_property_music_iterator
-  
-  source file of the GNU LilyPond music typesetter
-  
-  (c) 2000--2006 Jan Nieuwenhuizen <janneke@gnu.org>
- */
-
-#include "simple-music-iterator.hh"
-
-#include "input.hh"
-#include "international.hh"
-#include "music.hh"
-
-class Output_property_music_iterator : public Simple_music_iterator
-{
-public:  
-  DECLARE_SCHEME_CALLBACK (constructor, ());
-protected:
-  virtual void process (Moment);
-};
-
-
-void
-Output_property_music_iterator::process (Moment m)
-{
-  if (last_processed_mom_ < Moment (0))
-    {
-      bool accepted = try_music (get_music ());
-      if (!accepted)
-       get_music ()->origin ()->warning (_f ("junking event: `%s'",
-                                             get_music ()->class_name ()));
-    }
-  Simple_music_iterator::process (m);
-}
-
-IMPLEMENT_CTOR_CALLBACK (Output_property_music_iterator);
index caa6c73aa89c8e0d28abeb55dbdbcb140d41acae..65c7f1aac987a682b4873b37cda8463b00867f48 100644 (file)
@@ -7,11 +7,13 @@
 */
 
 #include "context.hh"
+#include "dispatcher.hh"
+#include "lily-guile.hh"
+#include "listener.hh"
 #include "music.hh"
+#include "music-iterator.hh"
 #include "music-sequence.hh"
-#include "lily-guile.hh"
 #include "warn.hh"
-#include "music-iterator.hh"
 
 class Part_combine_iterator : public Music_iterator
 {
@@ -29,11 +31,16 @@ protected:
   virtual void do_quit ();
   virtual void process (Moment);
 
-  virtual Music_iterator *try_music_in_children (Music *) const;
-
   virtual bool ok () const;
 
 private:
+  /* used by try_process */
+  DECLARE_LISTENER (set_busy);
+  bool busy_;
+  bool notice_busy_;
+  
+  bool try_process (Music_iterator *i, Moment m);
+  
   Music_iterator *first_iter_;
   Music_iterator *second_iter_;
   Moment start_moment_;
@@ -77,8 +84,6 @@ private:
   void unisono (bool silent);
 };
 
-static Music *busy_playing_event;
-
 void
 Part_combine_iterator::do_quit ()
 {
@@ -101,12 +106,6 @@ Part_combine_iterator::Part_combine_iterator ()
   split_list_ = SCM_EOL;
   state_ = APART;
   playing_state_ = APART;
-
-  if (!busy_playing_event)
-    {
-      busy_playing_event
-       = make_music_by_name (ly_symbol2scm ("BusyPlayingEvent"));
-    }
 }
 
 void
@@ -169,7 +168,7 @@ Part_combine_iterator::kill_mmrest (Context *tg)
       mmrest->set_property ("duration", SCM_EOL);
     }
 
-  tg->try_music (mmrest);
+  mmrest->send_to_context (tg);
 }
 
 void
@@ -192,7 +191,7 @@ Part_combine_iterator::solo1 ()
          if (!event)
            event = make_music_by_name (ly_symbol2scm ("SoloOneEvent"));
 
-         first_iter_->try_music_in_children (event);
+         event->send_to_context (first_iter_->get_outlet ());
        }
       playing_state_ = SOLO1;
     }
@@ -255,8 +254,9 @@ Part_combine_iterator::unisono (bool silent)
          if (!event)
            event = make_music_by_name (ly_symbol2scm ("UnisonoEvent"));
 
-         (last_playing_ == SOLO2 ? second_iter_ : first_iter_)
-           ->try_music_in_children (event);
+         Context *out = (last_playing_ == SOLO2 ? second_iter_ : first_iter_)
+           ->get_outlet ();
+         event->send_to_context (out);
          playing_state_ = UNISONO;
        }
       state_ = newstate;
@@ -280,7 +280,7 @@ Part_combine_iterator::solo2 ()
          if (!event)
            event = make_music_by_name (ly_symbol2scm ("SoloTwoEvent"));
 
-         second_iter_->try_music_in_children (event);
+         event->send_to_context (second_iter_->get_outlet ());
          playing_state_ = SOLO2;
        }
     }
@@ -369,6 +369,13 @@ Part_combine_iterator::construct_children ()
     0
   };
 
+  // Add listeners to all contexts except Devnull.
+  Context *contexts[] = {one, two, solo_tr, tr, 0};
+  for (int i = 0; contexts[i]; i++)
+    {
+      contexts[i]->event_source ()->add_listener (GET_LISTENER (set_busy), ly_symbol2scm ("MusicEvent"));
+    }
+
   for (char const **p = syms; *p; p++)
     {
       SCM sym = ly_symbol2scm (*p);
@@ -380,6 +387,37 @@ Part_combine_iterator::construct_children ()
     }
 }
 
+IMPLEMENT_LISTENER (Part_combine_iterator, set_busy);
+void
+Part_combine_iterator::set_busy (SCM se)
+{
+  if (!notice_busy_)
+    return;
+
+  Stream_event *e = unsmob_stream_event (se);
+  SCM mus = e->get_property ("music");
+  Music *m = unsmob_music (mus);
+  assert (m);
+
+  if (m->is_mus_type ("note-event") || m->is_mus_type ("cluster-note-event"))
+    busy_ = true;
+}
+
+/*
+* Processes a moment in an iterator, and returns whether any new music was reported.
+*/
+bool
+Part_combine_iterator::try_process (Music_iterator *i, Moment m)
+{
+  busy_ = false;
+  notice_busy_ = true;
+
+  i->process (m);
+  
+  notice_busy_ = false;
+  return busy_;
+}
+
 void
 Part_combine_iterator::process (Moment m)
 {
@@ -418,27 +456,15 @@ Part_combine_iterator::process (Moment m)
 
   if (first_iter_->ok ())
     {
-      first_iter_->process (m);
-      if (first_iter_->try_music_in_children (busy_playing_event))
-       last_playing_ = SOLO1;
+      if (try_process (first_iter_, m))
+        last_playing_ = SOLO1;
     }
 
   if (second_iter_->ok ())
     {
-      second_iter_->process (m);
-      if (second_iter_->try_music_in_children (busy_playing_event))
+      if (try_process (second_iter_, m))
        last_playing_ = SOLO2;
     }
 }
 
-Music_iterator *
-Part_combine_iterator::try_music_in_children (Music *m) const
-{
-  Music_iterator *i = first_iter_->try_music (m);
-  if (i)
-    return i;
-  else
-    return second_iter_->try_music (m);
-}
-
 IMPLEMENT_CTOR_CALLBACK (Part_combine_iterator);
index 29021ee3964e7350a982f2b910b266ed37605281..7ba527da5d9aef489d8986046ca658c90810afc9 100644 (file)
@@ -3,13 +3,12 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 2001--2006  Han-Wen Nienhuys <hanwen@xs4all.nl>, Erik Sandberg <mandolaerik@gmail.com>
+  (c) 2001--2006  Han-Wen Nienhuys <hanwen@xs4all.nl>
+                  Erik Sandberg <mandolaerik@gmail.com>
 */
 
 #include "percent-repeat-iterator.hh"
-
 #include "input.hh"
-#include "international.hh"
 #include "music.hh"
 #include "repeated-music.hh"
 
@@ -17,17 +16,16 @@ IMPLEMENT_CTOR_CALLBACK (Percent_repeat_iterator);
 
 Percent_repeat_iterator::Percent_repeat_iterator ()
 {
-  child_list_ = SCM_EOL;
 }
 
-void
-Percent_repeat_iterator::construct_children ()
+SCM
+Percent_repeat_iterator::get_music_list () const
 {
-  /* TODO: Distinction between percent and slash */
+  /* TODO: Distinction between percent, double-percent and slash */
   Music *mus = get_music ();
   Music *child = Repeated_music::body (mus);
   SCM length = child->get_length ().smobbed_copy ();
-  child_list_ = SCM_EOL;
+  SCM child_list = SCM_EOL;
 
   int repeats = scm_to_int (mus->get_property ("repeat-count"));
   for (int i = repeats; i > 1; i--)
@@ -37,27 +35,9 @@ Percent_repeat_iterator::construct_children ()
     percent->set_property ("length", length);
     if (repeats > 1)
       percent->set_property ("repeat-count", scm_int2num (i - 1));
-    Music *percent_chord = make_music_by_name (ly_symbol2scm ("EventChord"));
-    percent_chord->set_spot (*mus->origin ());
-    percent_chord->set_property ("elements", scm_list_1 (percent->self_scm ()));
-    child_list_ = scm_cons (percent_chord->self_scm (), child_list_);
-    percent->unprotect ();
-    percent_chord->unprotect ();
+    child_list = scm_cons (percent->unprotect (), child_list);
   }
-  child_list_ = scm_cons (child->self_scm (), child_list_);
-  
-  Sequential_iterator::construct_children ();
-}
-
-SCM
-Percent_repeat_iterator::get_music_list () const
-{
-  return child_list_;
-}
+  child_list = scm_cons (child->self_scm (), child_list);
 
-void
-Percent_repeat_iterator::derived_mark () const
-{
-  scm_gc_mark (child_list_);
-  Sequential_iterator::derived_mark ();
+  return child_list;
 }
index 820d0ed1587fbd36826a2b7cf022e6ed6c36ef65..9ca8fd25b7ed4dacf22b551e35bf838350894f91 100644 (file)
@@ -252,10 +252,7 @@ Quote_iterator::process (Moment m)
                  mus->transpose (diff);
                }
 
-             bool b = quote_outlet_.get_outlet ()->try_music (mus);
-             if (!b)
-               mus->origin ()->warning (_f ("in quotation: junking event %s",
-                                            mus->name ()));
+             quote_outlet_.get_outlet ()->try_music (mus);
            }
        }
 
index 76b97efc39a3eb7e98fd87cadd70a06de229de36..86bacecf4826c557f35d1ba5fb6dac57522e89bc 100644 (file)
@@ -244,12 +244,6 @@ Sequential_iterator::ok () const
   return iter_;
 }
 
-Music_iterator *
-Sequential_iterator::try_music_in_children (Music *m) const
-{
-  return iter_ ? iter_->try_music (m) : 0;
-}
-
 IMPLEMENT_CTOR_CALLBACK (Sequential_iterator);
 
 bool
index f2661f4b720d1c2f038ac35f0f9bdfb077dd338c..b2d686b32eeff1fb633944e0709f4bedddd81e17 100644 (file)
@@ -43,7 +43,7 @@ void
 Simple_music_iterator::process (Moment m)
 {
   /*
-    don't do try_music (), since it would make the function useless for
+    don't do report_event (), since it would make the function useless for
     base classes
   */
 
index 16691c3e63170de25d9dfb7a5d7cc6d56fb115f2..a264d55ba9ab1174c80c4ce9001b4ea1c8687e83 100644 (file)
@@ -133,15 +133,6 @@ Simultaneous_music_iterator::run_always () const
   return false;
 }
 
-Music_iterator *
-Simultaneous_music_iterator::try_music_in_children (Music *m) const
-{
-  Music_iterator *b = 0;
-  for (SCM s = children_list_; !b && scm_is_pair (s); s = scm_cdr (s))
-    b = unsmob_iterator (scm_car (s))->try_music (m);
-  return b;
-}
-
 void
 Simultaneous_music_iterator::do_quit ()
 {
index db4c616274da4b09ec97e13ccfe5094d93a00c2c..7406d884697f6508e9e09a231dbfea7b50917e35 100644 (file)
 
 Time_scaled_music_iterator::Time_scaled_music_iterator ()
 {
-  child_list_ = SCM_EOL;
 }
 
-void
-Time_scaled_music_iterator::construct_children ()
+SCM
+Time_scaled_music_iterator::get_music_list () const
 {
   Music *mus = get_music ();
   Input *origin = mus->origin ();
@@ -41,22 +40,7 @@ Time_scaled_music_iterator::construct_children ()
   stop_event = scm_call_1 (ly_lily_module_constant ("make-event-chord"), scm_list_1 (stop_event));
   unsmob_music (stop_event)->set_spot (*origin);
 
-  child_list_ = scm_list_3 (start_event, child->self_scm (), stop_event);
-
-  Sequential_iterator::construct_children ();
-}
-
-SCM
-Time_scaled_music_iterator::get_music_list () const
-{
-  return child_list_;
-}
-
-void
-Time_scaled_music_iterator::derived_mark () const
-{
-  scm_gc_mark (child_list_);
-  Sequential_iterator::derived_mark ();
+  return scm_list_3 (start_event, child->self_scm (), stop_event);
 }
 
 IMPLEMENT_CTOR_CALLBACK (Time_scaled_music_iterator);
index 529d0f997961d7c4462926aeeb2e6846a44a62d2..0fd2bc4d21a9866b7070f99d0f8b10869585ec6e 100644 (file)
@@ -3,18 +3,21 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>,
+                 Erik Sandberg <mandolaerik@gmail.com>
 */
 
 #include "translator-group.hh"
 
-#include "output-def.hh"
-#include "warn.hh"
-#include "scm-hash.hh"
 #include "context-def.hh"
 #include "context.hh"
+#include "dispatcher.hh"
 #include "main.hh"
 #include "music.hh"
+#include "output-def.hh"
+#include "scm-hash.hh"
+#include "stream-event.hh"
+#include "warn.hh"
 
 Translator_group *
 Translator_group::get_daddy_translator () const
@@ -35,6 +38,15 @@ Translator_group::initialize ()
   precompute_method_bindings ();
 }
 
+void
+Translator_group::connect_to_context (Context *c)
+{
+  if (context_)
+    programming_error ("already connected to a context");
+  context_ = c;
+  c->event_source ()->add_listener (GET_LISTENER (eat_event), ly_symbol2scm ("MusicEvent"));
+}
+
 void
 Translator_group::finalize ()
 {
@@ -67,6 +79,16 @@ find_accept_translators (SCM gravlist, SCM ifaces)
   return l;
 }
 
+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)
 {
@@ -235,4 +257,3 @@ Translator_group::mark_smob (SCM smob)
   scm_gc_mark (me->accept_hash_table_);
   return me->simple_trans_list_;
 }
-
index 030426ea1e84a402b7612ee074b5cce602e72a45..b2780027c72da8200d11510756dea89e831fc1f7 100644 (file)
@@ -107,10 +107,11 @@ displayLilyMusic =
    music)
 
 applyOutput =
-#(define-music-function (parser location proc) (procedure?)
-                (make-music 'ApplyOutputEvent 
+#(define-music-function (parser location ctx proc) (symbol? procedure?)
+                (make-music 'ApplyOutputEvent
                   'origin location
-                  'procedure proc))
+                  'procedure proc
+                  'context-type ctx))
 
 overrideProperty =
 #(define-music-function (parser location name property value)
@@ -140,8 +141,7 @@ or @code{\"GrobName\"}"
                    (if (equal?
                         (cdr (assoc 'name (ly:grob-property grob 'meta)))
                         grob-name)
-                       (set! (ly:grob-property grob property) value)
-                       )))
+                       (set! (ly:grob-property grob property) value))))
 
       context-name)))
 
index 3bc19ef5f8d8eaa1be93e404c77e04dd89497e90..d535ae8ce96dda13cfe17e895b6e5e460b35ce81 100644 (file)
@@ -2789,3 +2789,9 @@ def conv (str):
     return str
 
 conversions.append (((2, 9, 4), conv, """(page-)penalty -> (page-)break-penalty"""))
+
+def conv (str):
+    str = re.sub (r'\\context\s+\"?([a-zA-Z]+)\"?\s*\\applyOutput', r"\\applyOutput #'\1", str)
+    return str
+
+conversions.append (((2, 9, 6), conv, """\context Foo \applyOutput #bla -> \applyOutput #'Foo #bla """))
index b330534d75041ff4545938a34cb9bf7383f5bcdc..13a0da1f4e87bc283eacbaa4d5dd591fff4059b6 100644 (file)
@@ -50,6 +50,7 @@ TODO: consider making type into symbol ")
      (error-found ,boolean? "If true, a parsing error was found in this expression")
      (element ,ly:music? "The single child of a Music_wrapper music object, or the body of a repeat.")
      (elements ,ly:music-list? "A list of elements for sequential of simultaneous music, or the alternatives of repeated music. ")
+     (expected-beam-count ,integer? "Expected number of non-tremolo beams in a tremolo repeat")
      (force-accidental ,boolean? "If set, a cautionary accidental should always be printed on this note")
      (grob-property ,symbol? "The symbol of the grob property to set. ")
      (grob-property-path ,list? "A list of symbols, locating a nested grob property, e.g. (beamed-lengths details). ")
@@ -100,7 +101,7 @@ e.g. @code{\\tag #'part ...} could tag a piece of music as only being active in
      (text ,markup? "markup expression to be printed")
      (tempo-unit ,ly:duration? "The unit for the metronome count.")
      (tonic ,ly:pitch? "Base of the scale")
-     (tremolo-type ,integer? "")
+     (tremolo-type ,integer? "speed of tremolo, e.g. 16 for c4:16")
      (trill-pitch ,ly:pitch? "Pitch of other note of the trill.")
      (type ,symbol? "The type of this music object. Determines iteration in some cases.")
      (types ,list? "The types of this music object; determines by what
index 41d4609d493d1a0efef4c55a820b11a971d5b36c..69c654b019467e3c24515a3f663f75ddb01c3802 100644 (file)
@@ -30,14 +30,13 @@ Call the argument with all current grobs during interpreting phase.
 
 Syntax
 
-\\applyoutput FUNC
+\\applyOutput #'Context FUNC
 
 arguments to func are 1. the grob, 2. the originating context,
 3. context where FUNC is called.
 
 ")
-       (iterator-ctor . ,ly:output-property-music-iterator::constructor)
-       (types . (general-music layout-instruction))
+       (types . (general-music event layout-instruction))
        ))
     (ArpeggioEvent 
      . (
@@ -238,17 +237,6 @@ Syntax: @var{note}\\laissezVibrer.")
        (description .  "Allow, forbid or force a line break.")
        (types . (general-music break-event event))
        ))
-    (OldLyricCombineMusic
-     . (
-       (description .  "Align lyrics to the start of notes.
-
-Syntax @var{\\oldaddlyrics }@var{music} @var{lyrics}.")
-
-       (types . (general-music lyric-combine-music))
-       (length-callback . ,ly:lyric-combine-music::length-callback)
-       (start-callback . ,ly:music-sequence::first-start-callback)
-       (iterator-ctor . ,ly:old-lyric-combine-music-iterator::constructor)
-       ))
     
     (LyricCombineMusic
      . (
@@ -331,18 +319,6 @@ Syntax
        (types . (general-music event note-event rhythmic-event melodic-event))
        ))
     
-    (OutputPropertySetMusic
-     . (
-       (description .  "Set grob properties in objects
-individually. 
-
-Syntax @code{\\outputproperty @var{predicate} @var{prop}
-= @var{val}}.")
-
-       (iterator-ctor . ,ly:output-property-music-iterator::constructor)
-       (types . (general-music layout-instruction))
-       ))
-    
     (OverrideProperty
      . (
        (description .  "Extend the definition of a graphical object.
@@ -674,6 +650,12 @@ Syntax: @code{\\@var{number}}.")
        (types . (general-music event tremolo-event))
        ))
     
+    (TremoloSpanEvent
+     . (
+       (description . "Tremolo over two stems")
+       (types . (general-music event span-event tremolo-span-event))
+       ))
+
     (VoiceSeparator
      . (
        (description .  "Separate polyphonic voices in simultaneous music.