From: Reinhold Kainhofer Date: Wed, 20 Jul 2011 16:32:09 +0000 (+0200) Subject: Fix 153: \once\set properly restores the context property X-Git-Tag: release/2.15.7-1~13 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=d1db9b1d6ebb1014429974f22162b44bf9a03533;p=lilypond.git 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. --- 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