X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fengraver-group.cc;h=cf1832fe1fb73dd25f93e621e7a20d077485bbd0;hb=a670220b3bd83e8531ce5d2f655d379d9eb7511b;hp=b7de6e9e77ac67cbcda0bb2a21079362a4b044c2;hpb=18d9bcf40f630efefdeb42e3d15653c7aae73ec3;p=lilypond.git diff --git a/lily/engraver-group.cc b/lily/engraver-group.cc index b7de6e9e77..cf1832fe1f 100644 --- a/lily/engraver-group.cc +++ b/lily/engraver-group.cc @@ -20,6 +20,7 @@ #include "context.hh" #include "dispatcher.hh" #include "engraver-group.hh" +#include "global-context.hh" #include "grob.hh" #include "grob-properties.hh" #include "paper-score.hh" @@ -29,20 +30,49 @@ void Engraver_group::override (SCM sev) { - Stream_event *ev = Stream_event::unsmob (sev); + Stream_event *ev = unsmob (sev); + SCM sym = ev->get_property ("symbol"); + Grob_property_info gpi (context (), sym); - Grob_property_info (context (), ev->get_property ("symbol")) - .push (ev->get_property ("property-path"), - ev->get_property ("value")); + if (to_boolean (ev->get_property ("once"))) + { + SCM token = gpi.temporary_override (ev->get_property ("property-path"), + ev->get_property ("value")); + if (scm_is_pair (token)) + if (Global_context *g = context ()->get_global_context ()) + { + g->add_finalization (scm_list_4 (ly_context_matched_pop_property_proc, + context ()->self_scm (), + sym, + token)); + } + } + else + gpi.push (ev->get_property ("property-path"), + ev->get_property ("value")); } void Engraver_group::revert (SCM sev) { - Stream_event *ev = Stream_event::unsmob (sev); + Stream_event *ev = unsmob (sev); + SCM sym = ev->get_property ("symbol"); + Grob_property_info gpi (context (), sym); - Grob_property_info (context (), ev->get_property ("symbol")) - .pop (ev->get_property ("property-path")); + if (to_boolean (ev->get_property ("once"))) + { + SCM token = gpi.temporary_revert (ev->get_property ("property-path")); + if (scm_is_pair (token)) + if (Global_context *g = context ()->get_global_context ()) + { + g->add_finalization (scm_list_4 (ly_context_matched_pop_property_proc, + context ()->self_scm (), + sym, + token)); + } + } + else + gpi.pop (ev->get_property ("property-path")); } void @@ -101,11 +131,10 @@ Engraver_group::acknowledge_grobs () else continue; - SCM acklist = scm_hashq_ref (acknowledge_hash_table_drul_[info.start_end ()], - nm, SCM_BOOL_F); + SCM ackhandle = scm_hashq_create_handle_x (acknowledge_hash_table_drul_[info.start_end ()], + nm, SCM_BOOL_F); - Engraver_dispatch_list *dispatch - = Engraver_dispatch_list::unsmob (acklist); + SCM acklist = scm_cdr (ackhandle); if (scm_is_false (acklist)) { @@ -114,12 +143,12 @@ Engraver_group::acknowledge_grobs () acklist = Engraver_dispatch_list::create (get_simple_trans_list (), ifaces, info.start_end ()); - dispatch - = Engraver_dispatch_list::unsmob (acklist); - - scm_hashq_set_x (acknowledge_hash_table_drul_[info.start_end ()], nm, acklist); + scm_set_cdr_x (ackhandle, acklist); } + Engraver_dispatch_list *dispatch + = unsmob (acklist); + if (dispatch) dispatch->apply (info); } @@ -129,21 +158,22 @@ Engraver_group::acknowledge_grobs () Ugh. This is slightly expensive. We could/should cache the value of the group count? */ -int -Engraver_group::pending_grob_count () const +bool +Engraver_group::pending_grobs () const { - int count = announce_infos_.size (); + if (!announce_infos_.empty ()) + return true; for (SCM s = context_->children_contexts (); scm_is_pair (s); s = scm_cdr (s)) { - Context *c = Context::unsmob (scm_car (s)); + Context *c = unsmob (scm_car (s)); Engraver_group *group = dynamic_cast (c->implementation ()); - if (group) - count += group->pending_grob_count (); + if (group && group->pending_grobs ()) + return true; } - return count; + return false; } void @@ -157,7 +187,7 @@ Engraver_group::do_announces () for (SCM s = context ()->children_contexts (); scm_is_pair (s); s = scm_cdr (s)) { - Context *c = Context::unsmob (scm_car (s)); + Context *c = unsmob (scm_car (s)); Engraver_group *group = dynamic_cast (c->implementation ()); if (group) @@ -174,7 +204,7 @@ Engraver_group::do_announces () announce_infos_.clear (); } } - while (pending_grob_count () > 0); + while (pending_grobs ()); } Engraver_group::Engraver_group ()