lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Gets the beam collision engraver to handle autobeams (issue4287061)


From: mtsolo
Subject: Gets the beam collision engraver to handle autobeams (issue4287061)
Date: Sat, 19 Mar 2011 22:50:41 +0000

Reviewers: ,

Message:
This is my attempt to get the beam-collision-engraver to handle auto
beams, except...it doesn't work!  For some reason, in spite of the fact
that I'm creating AutoBeamStub grobs just fine, the acknowledger in the
beam collision engraver is not picking them up.  Can anyone suggest
where the system is broken?

Cheers,
Mike

Description:
Gets the beam collision engraver to handle autobeams

intermediary

Please review this at http://codereview.appspot.com/4287061/

Affected files:
  M lily/auto-beam-engraver.cc
  M lily/beam-collision-engraver.cc
  M scm/define-grobs.scm


Index: lily/auto-beam-engraver.cc
diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc
index dbff4e95a2f8803bfe87fa2b7afd18fe307422e9..e6c9b854060a21d7159c50cbfdd2728c85337487 100644
--- a/lily/auto-beam-engraver.cc
+++ b/lily/auto-beam-engraver.cc
@@ -71,6 +71,7 @@ private:
   Moment shortest_mom_;
   Spanner *finished_beam_;
   vector<Item *> *stems_;
+  Grob *stub_;

   int process_acknowledged_count_;
   Moment last_add_mom_;
@@ -147,6 +148,7 @@ Auto_beam_engraver::Auto_beam_engraver ()
   forbid_ = 0;
   process_acknowledged_count_ = 0;
   stems_ = 0;
+  stub_ = 0;
   shortest_mom_ = Moment (Rational (1, 4));
   finished_beam_ = 0;
   finished_grouping_ = 0;
@@ -217,6 +219,7 @@ Auto_beam_engraver::create_beam ()
   for (vsize i = 0; i < stems_->size (); i++)
     Beam::add_stem (beam, (*stems_)[i]);

+  beam->set_property ("auto-beam-stub", stub_->self_scm ());
   announce_grob (beam, (*stems_)[0]->self_scm ());

   return beam;
@@ -225,7 +228,7 @@ Auto_beam_engraver::create_beam ()
 void
 Auto_beam_engraver::begin_beam ()
 {
-  if (stems_ || grouping_)
+  if (stems_ || grouping_ || stub_)
     {
       programming_error ("already have autobeam");
       return;
@@ -251,6 +254,8 @@ Auto_beam_engraver::junk_beam ()
   stems_ = 0;
   delete grouping_;
   grouping_ = 0;
+  stub_->suicide ();
+  stub_ = 0;
   beam_settings_ = SCM_EOL;

   shortest_mom_ = Moment (Rational (1, 4));
@@ -274,6 +279,7 @@ Auto_beam_engraver::end_beam ()
       delete stems_;
       stems_ = 0;
       grouping_ = 0;
+      stub_ = 0;
       beam_settings_ = SCM_EOL;
     }

@@ -416,6 +422,8 @@ Auto_beam_engraver::acknowledge_stem (Grob_info info)
                       durlog - 2,
                       Stem::is_invisible (stem));
   stems_->push_back (stem);
+  if (stems_->size () == 1)
+    stub_ = make_item ("AutoBeamStub", (*stems_)[0]->self_scm ());
   last_add_mom_ = now;
   extend_mom_ = max (extend_mom_, now) + get_event_length (ev, now);
   if (recheck_needed)
@@ -537,6 +545,7 @@ ADD_TRANSLATOR (Auto_beam_engraver,
                 " @code{stemRightBeamCount}.",

                 /* create */
+                "AutoBeamStub "
                 "Beam ",

                 /* read */
Index: lily/beam-collision-engraver.cc
diff --git a/lily/beam-collision-engraver.cc b/lily/beam-collision-engraver.cc index 39e614c2a15dea10f3b72f88110959c35dc389a1..04fcea78dbbcdccb28fccd4ac810b0e80e061a49 100644
--- a/lily/beam-collision-engraver.cc
+++ b/lily/beam-collision-engraver.cc
@@ -28,6 +28,7 @@ class Beam_collision_engraver : public Engraver
 protected:
   vector<Grob *> active_beams_;
   vector<Grob *> signaled_beams_;
+  vector<Grob *> signaled_beam_stubs_;
   vector<Grob *> end_beams_;
   vector<Grob *> covered_grobs_;
   vector<Grob *> covered_interior_grobs_;
@@ -35,6 +36,7 @@ protected:
   DECLARE_ACKNOWLEDGER (note_head);
   DECLARE_ACKNOWLEDGER (accidental);
   DECLARE_ACKNOWLEDGER (clef);
+  DECLARE_ACKNOWLEDGER (auto_beam_stub);
   DECLARE_ACKNOWLEDGER (key_signature);
   DECLARE_ACKNOWLEDGER (time_signature);
   DECLARE_ACKNOWLEDGER (beam);
@@ -47,8 +49,15 @@ public:
 void
 Beam_collision_engraver::stop_translation_timestep ()
 {
+  /*
+     Erase all beam stubs that have been suicided.
+  */
+  for (vsize i = signaled_beam_stubs_.size (); i--;)
+    if (!signaled_beam_stubs_[i]->is_live ())
+      signaled_beam_stubs_.erase (signaled_beam_stubs_.begin () + i);
+
   /*
-     First, for all grobs that fall to the left of a beam during
+     For all grobs that fall to the left of a beam during
      a timestep (i.e. clefs, time signatures), add these to
      the beams that are currently active.
   */
@@ -75,14 +84,25 @@ Beam_collision_engraver::stop_translation_timestep ()
      In auto beaming, beams both begin and end during the same timestep.
      This means that if there is a beam that is both in signaled_beams_ and
      end_beams_, it must either be an auto beam (likely) or a beam that
- has no notes under it (highly unlikely). In either case, we cannot account
-     for the grobs under this beam, and we erase it from signaled beams.
+     has no notes under it (highly unlikely).  In either case, we check for
+     a beam stub and assign covered-grobs accordingly.
   */
   for (vsize i = 0; i < end_beams_.size (); i++)
     for (vsize j = 0; j < signaled_beams_.size (); j++)
       if (end_beams_[i] == signaled_beams_[j])
         {
-          signaled_beams_.erase (signaled_beams_.begin () + j);
+ Grob *auto_beam_stub = unsmob_grob (end_beams_[i]->get_property ("auto-beam-stub"));
+          if (auto_beam_stub)
+            for (vsize k = 0; k < signaled_beam_stubs_.size (); k++)
+              {
+                if (signaled_beam_stubs_[k] == auto_beam_stub)
+                  {
+ extract_grob_set (auto_beam_stub, ly_symbol2scm ("covered-grobs"), covered_grobs);
+                    for (vsize l = 0; l < covered_grobs.size (); l++)
+ Pointer_group_interface::add_grob (end_beams_[i], ly_symbol2scm ("covered-grobs"), covered_grobs[l]);
+                    break;
+                  }
+              }
           break;
         }

@@ -140,7 +160,8 @@ Beam_collision_engraver::stop_translation_timestep ()
   */
   for (vsize i = 0; i < end_beams_.size (); i++)
     for (vsize j = 0; j < active_beams_.size (); j++)
-      if (end_beams_[i] == active_beams_[j])
+      if ((end_beams_[i] == active_beams_[j])
+ || (unsmob_grob (end_beams_[i]->get_property ("auto-beam-stub")) == active_beams_[j]))
         {
           active_beams_.erase (active_beams_.begin () + j);
           break;
@@ -188,6 +209,13 @@ Beam_collision_engraver::acknowledge_beam (Grob_info i)
 }

 void
+Beam_collision_engraver::acknowledge_auto_beam_stub (Grob_info i)
+{
+  signaled_beam_stubs_.push_back (i.grob ());
+  active_beams_.push_back (i.grob ());
+}
+
+void
 Beam_collision_engraver::acknowledge_end_beam (Grob_info i)
 {
   end_beams_.push_back (i.grob ());
@@ -201,6 +229,7 @@ ADD_ACKNOWLEDGER (Beam_collision_engraver, clef);
 ADD_ACKNOWLEDGER (Beam_collision_engraver, key_signature);
 ADD_ACKNOWLEDGER (Beam_collision_engraver, time_signature);
 ADD_ACKNOWLEDGER (Beam_collision_engraver, beam);
+ADD_ACKNOWLEDGER (Beam_collision_engraver, auto_beam_stub);
 ADD_END_ACKNOWLEDGER (Beam_collision_engraver, beam);

 ADD_TRANSLATOR (Beam_collision_engraver,
Index: scm/define-grobs.scm
diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm
index 8b9564f41e1776e00814887a7d4516b95dba4465..bf1f906927470b45e4ba482e7eedb066e900a82f 100644
--- a/scm/define-grobs.scm
+++ b/scm/define-grobs.scm
@@ -175,6 +175,10 @@
                                side-position-interface
                                staff-symbol-referencer-interface))))))

+    (AutoBeamStub
+     . ((meta . ((class . Item)
+                 (interfaces . (beam-interface))))))
+
     (BalloonTextItem
      . (
        (annotation-balloon . #t)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]