From d1db9b1d6ebb1014429974f22162b44bf9a03533 Mon Sep 17 00:00:00 2001 From: Reinhold Kainhofer Date: Wed, 20 Jul 2011 18:32:09 +0200 Subject: [PATCH] Fix 153: \once\set properly restores the context property \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 | 29 ++++++++++++++++++++ lily/include/property-iterator.hh | 2 +- lily/property-iterator.cc | 44 ++++++++++++++++++------------- 3 files changed, 56 insertions(+), 19 deletions(-) create mode 100644 input/regression/set-once.ly diff --git a/input/regression/set-once.ly b/input/regression/set-once.ly new file mode 100644 index 0000000000..186232c176 --- /dev/null +++ b/input/regression/set-once.ly @@ -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) + 1 | + \once \set fingeringOrientations = #'(right) + | + -"left" | + + \once \set fingeringOrientations = #'(right) + + \once \set fingeringOrientations = #'(up) + + -"left" + + \set fingeringOrientations = #'(left) + + \once \set fingeringOrientations = #'(up) + \once \set fingeringOrientations = #'(right) + -"right" + + -"left" +} diff --git a/lily/include/property-iterator.hh b/lily/include/property-iterator.hh index 8aa0cec11d..c53a4d9648 100644 --- a/lily/include/property-iterator.hh +++ b/lily/include/property-iterator.hh @@ -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: diff --git a/lily/property-iterator.cc b/lily/property-iterator.cc index 62f316b7f1..2cb8b48680 100644 --- a/lily/property-iterator.cc +++ b/lily/property-iterator.cc @@ -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 -- 2.39.2