X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fengraver-group.cc;h=8c5306f544c6e5737dde436ae22249e5e49b561c;hb=5b4b0d6e9a197e8f9eb085b7c2ad78b8be3e5cfc;hp=2c1b3d2d863502a5f705a997a5ad94f44659f5f1;hpb=9efbad2d9487a05b04423e7e9f062968e8f8eaf4;p=lilypond.git diff --git a/lily/engraver-group.cc b/lily/engraver-group.cc index 2c1b3d2d86..8c5306f544 100644 --- a/lily/engraver-group.cc +++ b/lily/engraver-group.cc @@ -1,95 +1,199 @@ /* - engravergroup.cc -- implement Engraver_group_engraver + engraver-group.cc -- implement Engraver_group source file of the GNU LilyPond music typesetter - (c) 1997--1998 Han-Wen Nienhuys + (c) 1997--2008 Han-Wen Nienhuys */ -#include "proto.hh" -#include "plist.hh" +#include "context.hh" +#include "dispatcher.hh" #include "engraver-group.hh" -#include "engraver.hh" -#include "debug.hh" -#include "p-score.hh" -#include "score-element.hh" +#include "grob.hh" +#include "paper-score.hh" +#include "translator-dispatch-list.hh" +#include "warn.hh" -IMPLEMENT_IS_TYPE_B2(Engraver_group_engraver,Engraver, Translator_group); -ADD_THIS_TRANSLATOR(Engraver_group_engraver); +IMPLEMENT_LISTENER (Engraver_group, override); +void +Engraver_group::override (SCM sev) +{ + Stream_event *ev = unsmob_stream_event (sev); + + sloppy_general_pushpop_property (context (), + ev->get_property ("symbol"), + ev->get_property ("property-path"), + ev->get_property ("value")); +} + +IMPLEMENT_LISTENER (Engraver_group, revert); +void +Engraver_group::revert (SCM sev) +{ + Stream_event *ev = unsmob_stream_event (sev); + + sloppy_general_pushpop_property (context (), + ev->get_property ("symbol"), + ev->get_property ("property-path"), + SCM_UNDEFINED); +} + +void +Engraver_group::connect_to_context (Context *c) +{ + Translator_group::connect_to_context (c); + c->event_source ()->add_listener (GET_LISTENER (override), ly_symbol2scm ("Override")); + c->event_source ()->add_listener (GET_LISTENER (revert), ly_symbol2scm ("Revert")); +} void -Engraver_group_engraver::announce_element (Score_element_info info) +Engraver_group::disconnect_from_context () { - announce_info_arr_.push (info); - Engraver::announce_element (info); + context ()->event_source ()->remove_listener (GET_LISTENER (override), ly_symbol2scm ("Override")); + context ()->event_source ()->remove_listener (GET_LISTENER (revert), ly_symbol2scm ("Revert")); + Translator_group::disconnect_from_context (); } void -Engraver_group_engraver::do_announces() +Engraver_group::announce_grob (Grob_info info) { - Link_array groups = group_l_arr (); - for (int i=0; i < groups.size(); i++) + announce_infos_.push_back (info); + + Engraver_group *dad_eng + = context_->get_parent_context () + ? dynamic_cast (context_->get_parent_context ()->implementation ()) + : 0; + + if (dad_eng) + dad_eng->announce_grob (info); +} + +void +Engraver_group::acknowledge_grobs () +{ + if (!announce_infos_.size ()) + return; + + SCM name_sym = ly_symbol2scm ("name"); + SCM meta_sym = ly_symbol2scm ("meta"); + + for (vsize j = 0; j < announce_infos_.size (); j++) { - Engraver * eng = dynamic_cast (groups[i]); - if (eng) + Grob_info info = announce_infos_[j]; + + SCM meta = info.grob ()->internal_get_property (meta_sym); + SCM nm = scm_assoc (name_sym, meta); + if (scm_is_pair (nm)) + nm = scm_cdr (nm); + else + continue; + + SCM acklist = scm_hashq_ref (acknowledge_hash_table_drul_[info.start_end ()], + nm, SCM_BOOL_F); + + Engraver_dispatch_list *dispatch + = Engraver_dispatch_list::unsmob (acklist); + + if (acklist == SCM_BOOL_F) { - Engraver_group_engraver * group = - (Engraver_group_engraver*) eng; - group->do_announces(); + SCM ifaces + = scm_cdr (scm_assoc (ly_symbol2scm ("interfaces"), meta)); + 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); } + + if (dispatch) + dispatch->apply (info); } - - Request dummy_req; +} - Link_array nongroups = nongroup_l_arr (); - while (announce_info_arr_.size ()) +/* + Ugh. This is slightly expensive. We could/should cache the value of + the group count? +*/ +int +Engraver_group::pending_grob_count () const +{ + int count = announce_infos_.size (); + for (SCM s = context_->children_contexts (); + scm_is_pair (s); s = scm_cdr (s)) { - for (int j =0; j < announce_info_arr_.size(); j++) + Context *c = unsmob_context (scm_car (s)); + Engraver_group *group + = dynamic_cast (c->implementation ()); + + if (group) + count += group->pending_grob_count (); + } + return count; +} + +void +Engraver_group::do_announces () +{ + do + { + /* + DOCME: why is this inside the loop? + */ + for (SCM s = context ()->children_contexts (); + scm_is_pair (s); s = scm_cdr (s)) { - Score_element_info info = announce_info_arr_[j]; - - if (!info.req_l_) - info.req_l_ = &dummy_req; - for (int i=0; i < nongroups.size(); i++) - { // Is this good enough? - Engraver * eng = dynamic_cast (nongroups[i]); - if (eng && eng!= info.origin_grav_l_arr_[0]) - eng->acknowledge_element (info); - } + Context *c = unsmob_context (scm_car (s)); + Engraver_group *group + = dynamic_cast (c->implementation ()); + if (group) + group->do_announces (); } - announce_info_arr_.clear (); - for (int i=0; i < nongroups.size(); i++) + + + while (1) { - Engraver * eng = dynamic_cast (nongroups[i]); - if (eng) - eng->process_acknowledged (); - } + precomputed_translator_foreach (PROCESS_ACKNOWLEDGED); + if (announce_infos_.size () == 0) + break; + acknowledge_grobs (); + announce_infos_.clear (); + } } + while (pending_grob_count () > 0); } - -Staff_info -Engraver_group_engraver::get_staff_info() const +Engraver_group::Engraver_group () { - Staff_info inf = Engraver::get_staff_info(); - - Link_array simple_translators = nongroup_l_arr (); - for (int i=0; i < simple_translators.size(); i++) - { - Engraver * eng = dynamic_cast (simple_translators[i]); - if (eng) - eng->fill_staff_info (inf); - } - return inf; + acknowledge_hash_table_drul_[LEFT] + = acknowledge_hash_table_drul_[RIGHT] + = SCM_EOL; + + acknowledge_hash_table_drul_[LEFT] = scm_c_make_hash_table (61); + acknowledge_hash_table_drul_[RIGHT] = scm_c_make_hash_table (61); } +#include "translator.icc" +ADD_TRANSLATOR_GROUP (Engraver_group, + /* doc */ + "A group of engravers taken together.", -Engraver_group_engraver::~Engraver_group_engraver () -{ -} + /* create */ + "", -Engraver_group_engraver::Engraver_group_engraver () + /* read */ + "", + + /* write */ + "" + ); + +void +Engraver_group::derived_mark () const { + scm_gc_mark (acknowledge_hash_table_drul_[LEFT]); + scm_gc_mark (acknowledge_hash_table_drul_[RIGHT]); }