]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/new-part-combine-iterator.cc
(updated_grob_properties): new
[lilypond.git] / lily / new-part-combine-iterator.cc
index 48a8039e35cc03faf4f1d353b87a4280cc60fbcb..68c4b3434b89a7cba956259caa00f8297eab95ce 100644 (file)
@@ -1,12 +1,11 @@
 /*   
-  new-part-combine-music-iterator.cc -- implement New_pc_iterator
+     new-part-combine-music-iterator.cc -- implement New_pc_iterator
 
-  source file of the GNU LilyPond music typesetter
+     source file of the GNU LilyPond music typesetter
   
-  (c) 2004 Han-Wen Nienhuys
- */
+     (c) 2004 Han-Wen Nienhuys
+*/
 
-#include "part-combine-music-iterator.hh"
 #include "translator-group.hh"
 #include "event.hh"
 #include "music-sequence.hh"
@@ -18,7 +17,6 @@
 class New_pc_iterator : public Music_iterator
 {
 public:
-  VIRTUAL_COPY_CONS (Music_iterator);
   New_pc_iterator ();
 
   DECLARE_SCHEME_CALLBACK(constructor, ()); 
@@ -32,7 +30,6 @@ protected:
   virtual void do_quit(); 
   virtual void process (Moment);
 
-  virtual SCM get_pending_events (Moment)const;
   virtual Music_iterator *try_music_in_children (Music *) const;
 
   virtual bool ok () const;
@@ -40,28 +37,38 @@ protected:
 private:
   Music_iterator * first_iter_;
   Music_iterator * second_iter_;
-  bool is_shared_ ;
+  
   SCM split_list_;
 
+  enum Status  {
+    APART, TOGETHER,
+    SOLO1, SOLO2,
+    UNISONO, UNISILENCE,
+  };
+  Status state_;
+  Status playing_state_;
+
   Interpretation_context_handle one_;
   Interpretation_context_handle two_;
   Interpretation_context_handle null_;
   Interpretation_context_handle shared_;
 
+  void kill_mmrest (Translator_group*);
   void chords_together ();
-  void apart ();
   void solo1 ();
   void solo2 ();
-  void unisono ();
+  void apart (bool silent);
+  void unisono (bool silent);
 };
 
 
 New_pc_iterator::New_pc_iterator ()
 {
-  is_shared_  =false;
   first_iter_ = 0;
   second_iter_ = 0;
   split_list_ = SCM_EOL;
+  state_ = APART;
+  playing_state_ = APART;
 }
 
 void
@@ -96,24 +103,7 @@ New_pc_iterator::do_quit ()
   shared_.set_translator (0);
 }
 
-New_pc_iterator::New_pc_iterator (New_pc_iterator const &src)
-  : Music_iterator (src)
-{
-  first_iter_ = 0;
-  second_iter_ = 0;
 
-  if(src.first_iter_)
-    first_iter_ = src.first_iter_->clone ();
-  if (src.second_iter_)
-    second_iter_ = src.second_iter_->clone ();
-
-  split_list_ = src.split_list_;
-  
-  if (first_iter_)
-    scm_gc_unprotect_object (first_iter_->self_scm());
-  if (second_iter_)
-    scm_gc_unprotect_object (second_iter_->self_scm());
-}
 
 Moment
 New_pc_iterator::pending_moment () const
@@ -137,87 +127,171 @@ New_pc_iterator::ok () const
 void
 New_pc_iterator::chords_together ()
 {
-  first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
-  first_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
-  second_iter_->substitute_outlet (two_.report_to (), shared_.report_to ());
-  second_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
+  if (state_ == TOGETHER)
+    return;
+  else
+    {
+      playing_state_ = TOGETHER;
+      state_ = TOGETHER;
+      first_iter_->substitute_outlet (one_.get_outlet (), shared_.get_outlet ());
+      first_iter_->substitute_outlet (null_.get_outlet (), shared_.get_outlet ());
+      second_iter_->substitute_outlet (two_.get_outlet (), shared_.get_outlet ());
+      second_iter_->substitute_outlet (null_.get_outlet (), shared_.get_outlet ());
+    }
 }
 
 
 void
-New_pc_iterator::solo1 ()
+New_pc_iterator::kill_mmrest (Translator_group * tg)
 {
-  first_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
-  first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
+  static Music * mmrest;
+  if (!mmrest)
+    {
+      mmrest = make_music_by_name (ly_symbol2scm ("MultiMeasureRestEvent"));
+      mmrest->set_mus_property ("duration", SCM_EOL);
+    }
 
-  second_iter_->substitute_outlet (two_.report_to (), null_.report_to ());
-  second_iter_->substitute_outlet (shared_.report_to (), null_.report_to ());
+  tg->try_music (mmrest);
 }
 
 void
-New_pc_iterator::unisono ()
+New_pc_iterator::solo1 ()
 {
-  /*
-    like solo1, but should set a2 string.
-   */
-  first_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
-  first_iter_->substitute_outlet (one_.report_to (), shared_.report_to ());
-
-  second_iter_->substitute_outlet (two_.report_to (), null_.report_to ());
-  second_iter_->substitute_outlet (shared_.report_to (), null_.report_to ());
+  if (state_ == SOLO1)
+    return;
+  else
+    {
+      state_ = SOLO1;
+      first_iter_->substitute_outlet (null_.get_outlet (), shared_.get_outlet ());
+      first_iter_->substitute_outlet (one_.get_outlet (), shared_.get_outlet ());
+
+      second_iter_->substitute_outlet (two_.get_outlet (), null_.get_outlet ());
+      second_iter_->substitute_outlet (shared_.get_outlet (), null_.get_outlet ());
+      kill_mmrest (two_.get_outlet ());
+      kill_mmrest (shared_.get_outlet ());
+
+      if (playing_state_ != SOLO1)
+       {
+         static Music* event;
+         if (!event)
+           event = make_music_by_name (ly_symbol2scm ("SoloOneEvent"));
+
+         first_iter_-> try_music_in_children (event);
+       }
+      playing_state_ = SOLO1;
+    }
 }
+void
+New_pc_iterator::unisono (bool silent)
+{
+  Status newstate = (silent) ? UNISILENCE : UNISONO;
+  
+  if (newstate == state_)
+    return; 
+  else
+    {
+
+      first_iter_->substitute_outlet (null_.get_outlet (), shared_.get_outlet ());
+      first_iter_->substitute_outlet (one_.get_outlet (), shared_.get_outlet ());
+
+      second_iter_->substitute_outlet (two_.get_outlet (), null_.get_outlet ());
+      second_iter_->substitute_outlet (shared_.get_outlet (), null_.get_outlet ());
+      kill_mmrest (two_.get_outlet ());
+      kill_mmrest (shared_.get_outlet ());
+
+      if (playing_state_ != UNISONO
+         && newstate == UNISONO)
+       {
+         static Music* event;
+         if (!event)
+           event = make_music_by_name (ly_symbol2scm ("UnisonoEvent"));
 
+         first_iter_-> try_music_in_children (event);      
+         playing_state_ = UNISONO;
+       }
+      state_ = newstate;
+    }
+}
 
 void
 New_pc_iterator::solo2 ()
 {
-  second_iter_->substitute_outlet (null_.report_to (), shared_.report_to ());
-  second_iter_->substitute_outlet (two_.report_to (), shared_.report_to ());
+  if (state_ == SOLO2)
+    return;
+  else
+    {
+      state_ = SOLO2;
+      
+      second_iter_->substitute_outlet (null_.get_outlet (), shared_.get_outlet ());
+      second_iter_->substitute_outlet (two_.get_outlet (), shared_.get_outlet ());
 
-  first_iter_->substitute_outlet (one_.report_to (), null_.report_to ());
-  first_iter_->substitute_outlet (shared_.report_to (), null_.report_to ());
-}
+      first_iter_->substitute_outlet (one_.get_outlet (), null_.get_outlet ());
+      first_iter_->substitute_outlet (shared_.get_outlet (), null_.get_outlet ());
+      kill_mmrest (one_.get_outlet ());
+      kill_mmrest (shared_.get_outlet ());
+      
+      if (playing_state_ != SOLO2)
+       {
+         static Music* event;
+         if (!event)
+           event = make_music_by_name (ly_symbol2scm ("SoloTwoEvent"));
 
+         second_iter_-> try_music_in_children (event);
+         playing_state_ = SOLO2;
+       }
+    }
+}
 
 void
-New_pc_iterator::apart ()
+New_pc_iterator::apart (bool silent)
 {
-  first_iter_->substitute_outlet (null_.report_to (), one_.report_to ());
-  first_iter_->substitute_outlet (shared_.report_to (), one_.report_to ());
+  if (!silent)
+    playing_state_ = APART;
+
+  if (state_ == APART)
+    return;
+  else
+    {
+      state_ = APART;
+  
+      first_iter_->substitute_outlet (null_.get_outlet (), one_.get_outlet ());
+      first_iter_->substitute_outlet (shared_.get_outlet (), one_.get_outlet ());
   
-  second_iter_->substitute_outlet (null_.report_to (), two_.report_to ());
-  second_iter_->substitute_outlet (shared_.report_to (), two_.report_to ());
+      second_iter_->substitute_outlet (null_.get_outlet (), two_.get_outlet ());
+      second_iter_->substitute_outlet (shared_.get_outlet (), two_.get_outlet ());    }
 }
 
-
 void
 New_pc_iterator::construct_children ()
 {
   split_list_ =  get_music ()->get_mus_property ("split-list");
   SCM lst =  get_music ()->get_mus_property ("elements");
 
-  SCM props = scm_list_n (scm_list_n (ly_symbol2scm ("denies"), ly_symbol2scm ("Thread"), SCM_UNDEFINED),
-                         scm_list_n (ly_symbol2scm ("consists"), ly_symbol2scm ("Rest_engraver"), SCM_UNDEFINED),
-                         scm_list_n (ly_symbol2scm ("consists"), ly_symbol2scm ("Note_heads_engraver"), SCM_UNDEFINED),
+  SCM props = scm_list_n (/*
+                           used to have tweaks here.
+                          */
+                         
                          SCM_UNDEFINED);
 
   Translator_group *tr
-    =  report_to ()->find_create_translator (ly_symbol2scm ("Voice"),
+    =  get_outlet ()->find_create_translator (ly_symbol2scm ("Voice"),
                                             "shared",props);
 
   shared_ .set_translator (tr); 
   set_translator (tr);
   Translator_group *null
-    =  report_to ()->find_create_translator (ly_symbol2scm ("Devnull"),
+    =  get_outlet ()->find_create_translator (ly_symbol2scm ("Devnull"),
                                             "", SCM_EOL);
+
+  if (!null)
+    programming_error ("No Devnull found?");
+  
   null_.set_translator (null);
 
   Translator_group *one = tr->find_create_translator (ly_symbol2scm ("Voice"),
                                                      "one", props);
 
   one_.set_translator (one);
-  one->execute_pushpop_property (ly_symbol2scm ("Stem"),
-                                ly_symbol2scm ("direction"), gh_int2scm (1));
 
   set_translator (one);
   first_iter_ = unsmob_iterator (get_iterator (unsmob_music (gh_car (lst))));
@@ -226,19 +300,41 @@ New_pc_iterator::construct_children ()
   Translator_group *two = tr->find_create_translator (ly_symbol2scm ("Voice"),
                                                      "two", props);
   two_.set_translator (two);
-  two_.report_to ()->execute_pushpop_property (ly_symbol2scm ("Stem"),
-                                 ly_symbol2scm ("direction"), gh_int2scm (-1));
   set_translator (two);
   second_iter_ = unsmob_iterator (get_iterator (unsmob_music (gh_cadr (lst))));
 
 
   set_translator (tr);
+
+
+  char const * syms[] = {
+    "Stem",
+    "DynamicLineSpanner",
+    "Tie",
+    "Dots",
+    "Rest",
+    "Slur",
+    "TextScript",
+    "Script",
+    0
+  };
+  
+  for (char const**p = syms; *p; p++)
+    {
+      SCM sym = ly_symbol2scm (*p);
+      execute_pushpop_property (one, sym,
+                                    ly_symbol2scm ("direction"), gh_int2scm (1));
+
+      execute_pushpop_property (two, sym,
+                               ly_symbol2scm ("direction"), gh_int2scm (-1));
+    }
+
 }
 
 void
 New_pc_iterator::process (Moment m)
 {
-  Moment now = report_to ()->now_mom ();
+  Moment now = get_outlet ()->now_mom ();
   Moment *splitm = 0;
   
   for (; gh_pair_p (split_list_); split_list_ = gh_cdr (split_list_))
@@ -251,10 +347,14 @@ New_pc_iterator::process (Moment m)
       
       if (tag == ly_symbol2scm ("chords"))
        chords_together ();
-      else if (tag == ly_symbol2scm ("apart"))
-       apart ();
+      else if (tag == ly_symbol2scm ("apart")
+              || tag == ly_symbol2scm ("apart-silence")
+              || tag == ly_symbol2scm ("apart-spanner"))
+       apart (tag == ly_symbol2scm ("apart-silence"));
       else if (tag == ly_symbol2scm ("unisono"))
-       unisono ();
+       unisono (false);
+      else if (tag == ly_symbol2scm ("unisilence"))
+       unisono (true);
       else if (tag == ly_symbol2scm ("solo1"))
        solo1 ();
       else if (tag == ly_symbol2scm ("solo2"))
@@ -284,16 +384,4 @@ New_pc_iterator::try_music_in_children (Music *m) const
     return second_iter_->try_music (m);
 }
 
-
-SCM
-New_pc_iterator::get_pending_events (Moment m)const
-{
-  SCM s = SCM_EOL;
-  if (first_iter_)
-    s = gh_append2 (s,first_iter_->get_pending_events (m));
-  if (second_iter_)
-    s = gh_append2 (second_iter_->get_pending_events (m),s);
-  return s;
-}
-
 IMPLEMENT_CTOR_CALLBACK (New_pc_iterator);