]> git.donarmstrong.com Git - lilypond.git/commitdiff
Fix 153: \once\set properly restores the context property
authorReinhold Kainhofer <reinhold@kainhofer.com>
Wed, 20 Jul 2011 16:32:09 +0000 (18:32 +0200)
committerReinhold Kainhofer <reinhold@kainhofer.com>
Thu, 28 Jul 2011 12:21:38 +0000 (14:21 +0200)
\once\set works by installing a finalization hook in the iterator.
To restore the context property value before the \once\set, we simply
cache the old value and pass it to the finalization hook as third
argument. The finalization hook then sends a SetProperty event with
the old value rather than an UnsetProperty event, which would revert
the value to the default.

input/regression/set-once.ly [new file with mode: 0644]
lily/include/property-iterator.hh
lily/property-iterator.cc

diff --git a/input/regression/set-once.ly b/input/regression/set-once.ly
new file mode 100644 (file)
index 0000000..186232c
--- /dev/null
@@ -0,0 +1,29 @@
+\version "2.15.7"
+
+\header {
+
+  texidoc = "@code{\once \set} should change a context property value for just one timestep
+and then return to the previous value."
+
+}
+\relative {
+  \set fingeringOrientations = #'(left)
+  <e-1>1 |
+  \once \set fingeringOrientations = #'(right)
+  <e-1> |
+  <e-1> -"left" |
+
+  \once \set fingeringOrientations = #'(right)
+  <e-1>
+  \once \set fingeringOrientations = #'(up)
+  <e-1>
+  <e-1>-"left"
+
+  \set fingeringOrientations = #'(left)
+  <e-1>
+  \once \set fingeringOrientations = #'(up)
+  \once \set fingeringOrientations = #'(right)
+  <e-1>-"right"
+  <e-1>-"left"
+}
index 8aa0cec11d23a64a3315dd60f1b13415a2f14193..c53a4d9648162c1a2aa07c78fbb9f8760b0ca1c0 100644 (file)
@@ -29,7 +29,7 @@ class Property_iterator : public Simple_music_iterator
 {
 public:
   DECLARE_SCHEME_CALLBACK (constructor, ());
-  DECLARE_SCHEME_CALLBACK (once_finalization, (SCM, SCM));
+  DECLARE_SCHEME_CALLBACK (once_finalization, (SCM, SCM, SCM));
   DECLARE_CLASSNAME(Property_iterator);
 
 protected:
index 62f316b7f1b7220e12d9e8bf773aa5921337fd00..2cb8b486800b2f502a4760e08967370479633fc9 100644 (file)
@@ -31,13 +31,26 @@ bool check_grob (Music *mus, SCM sym);
    translation unit, and set the property.
 */
 void
-Property_iterator::process (Moment m)
+Property_iterator::process (Moment mom)
 {
-  send_stream_event (get_outlet (), "SetProperty", get_music ()->origin (),
-                    ly_symbol2scm ("symbol"), get_music ()->get_property ("symbol"),
-                    ly_symbol2scm ("value"), get_music ()->get_property ("value"));
+  Context *o = get_outlet ();
+  Music *m = get_music ();
+  SCM previous_value = o->get_property (m->get_property ("symbol"));
+  send_stream_event (o, "SetProperty", m->origin (),
+                    ly_symbol2scm ("symbol"), m->get_property ("symbol"),
+                    ly_symbol2scm ("value"), m->get_property ("value"));
+
+  /* For \once \set install a finalization hook to reset the property to the
+   * previous value after the timestep */
+  if (to_boolean (m->get_property ("once")))
+    {
+      Global_context *tg = get_outlet ()->get_global_context ();
+      tg->add_finalization (scm_list_n (once_finalization_proc,
+                                       o->self_scm (), m->self_scm (),
+                                       ly_quote_scm (previous_value), SCM_UNDEFINED));
+    }
   
-  Simple_music_iterator::process (m);
+  Simple_music_iterator::process (mom);
 }
 
 void
@@ -50,30 +63,25 @@ Property_unset_iterator::process (Moment m)
   Simple_music_iterator::process (m);
 }
 
-MAKE_SCHEME_CALLBACK (Property_iterator, once_finalization, 2);
+MAKE_SCHEME_CALLBACK (Property_iterator, once_finalization, 3);
 SCM
-Property_iterator::once_finalization (SCM ctx, SCM music)
+Property_iterator::once_finalization (SCM ctx, SCM music, SCM previous_value)
 {
   Music *m = unsmob_music (music);
   Context *c = unsmob_context (ctx);
 
-  send_stream_event (c, "UnsetProperty", m->origin (),
-                    ly_symbol2scm ("symbol"), m->get_property ("symbol"));
+  // Do not use UnsetProperty, which sets the default, but rather
+  // cache the value before the \once \set command and restore it now
+  send_stream_event (c, "SetProperty", m->origin (),
+                    ly_symbol2scm ("symbol"), m->get_property ("symbol"),
+                    ly_symbol2scm ("value"), previous_value);
+
   return SCM_UNSPECIFIED;
 }
 
 void
 Property_iterator::do_quit ()
 {
-  if (to_boolean (get_music ()->get_property ("once")))
-    {
-      SCM trans = get_outlet ()->self_scm ();
-      SCM music = get_music ()->self_scm ();
-
-      Global_context *tg = get_outlet ()->get_global_context ();
-      tg->add_finalization (scm_list_n (once_finalization_proc,
-                                       trans, music, SCM_UNDEFINED));
-    }
 }
 
 bool