2 engraver-group.cc -- implement Engraver_group
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
10 #include "dispatcher.hh"
11 #include "engraver-group.hh"
13 #include "paper-score.hh"
14 #include "stream-event.hh"
15 #include "translator-dispatch-list.hh"
18 IMPLEMENT_LISTENER (Engraver_group, override);
20 Engraver_group::override (SCM sev)
22 Stream_event *ev = unsmob_stream_event (sev);
24 execute_general_pushpop_property (context (),
25 ev->get_property ("symbol"),
26 ev->get_property ("property-path"),
27 ev->get_property ("value"));
30 IMPLEMENT_LISTENER (Engraver_group, revert);
32 Engraver_group::revert (SCM sev)
34 Stream_event *ev = unsmob_stream_event (sev);
36 execute_general_pushpop_property (context (),
37 ev->get_property ("symbol"),
38 ev->get_property ("property-path"),
43 Engraver_group::connect_to_context (Context *c)
45 Translator_group::connect_to_context (c);
46 c->event_source ()->add_listener (GET_LISTENER (override), ly_symbol2scm ("Override"));
47 c->event_source ()->add_listener (GET_LISTENER (revert), ly_symbol2scm ("Revert"));
51 Engraver_group::disconnect_from_context ()
53 context ()->event_source ()->remove_listener (GET_LISTENER (override), ly_symbol2scm ("Override"));
54 context ()->event_source ()->remove_listener (GET_LISTENER (revert), ly_symbol2scm ("Revert"));
55 Translator_group::disconnect_from_context ();
59 Engraver_group::announce_grob (Grob_info info)
61 announce_infos_.push_back (info);
63 Engraver_group *dad_eng
64 = context_->get_parent_context ()
65 ? dynamic_cast<Engraver_group *> (context_->get_parent_context ()->implementation ())
69 dad_eng->announce_grob (info);
73 Engraver_group::acknowledge_grobs ()
75 if (!announce_infos_.size ())
78 SCM name_sym = ly_symbol2scm ("name");
79 SCM meta_sym = ly_symbol2scm ("meta");
81 for (vsize j = 0; j < announce_infos_.size (); j++)
83 Grob_info info = announce_infos_[j];
85 SCM meta = info.grob ()->internal_get_property (meta_sym);
86 SCM nm = scm_assoc (name_sym, meta);
92 SCM acklist = scm_hashq_ref (acknowledge_hash_table_drul_[info.start_end()],
95 Engraver_dispatch_list *dispatch
96 = Engraver_dispatch_list::unsmob (acklist);
98 if (acklist == SCM_BOOL_F)
101 = scm_cdr (scm_assoc (ly_symbol2scm ("interfaces"), meta));
102 acklist = Engraver_dispatch_list::create (get_simple_trans_list (),
103 ifaces, info.start_end ());
106 = Engraver_dispatch_list::unsmob (acklist);
108 scm_hashq_set_x (acknowledge_hash_table_drul_[info.start_end ()], nm, acklist);
112 dispatch->apply (info);
117 Ugh. This is slightly expensive. We could/should cache the value of
121 Engraver_group::pending_grob_count () const
123 int count = announce_infos_.size ();
124 for (SCM s = context_->children_contexts ();
125 scm_is_pair (s); s = scm_cdr (s))
127 Context *c = unsmob_context (scm_car (s));
128 Engraver_group *group
129 = dynamic_cast<Engraver_group *> (c->implementation ());
132 count += group->pending_grob_count ();
138 Engraver_group::do_announces ()
143 DOCME: why is this inside the loop?
145 for (SCM s = context ()->children_contexts ();
146 scm_is_pair (s); s = scm_cdr (s))
148 Context *c = unsmob_context (scm_car (s));
149 Engraver_group *group
150 = dynamic_cast<Engraver_group *> (c->implementation ());
152 group->do_announces ();
158 precomputed_translator_foreach (PROCESS_ACKNOWLEDGED);
159 if (announce_infos_.size () == 0)
162 acknowledge_grobs ();
163 announce_infos_.clear ();
166 while (pending_grob_count () > 0);
169 Engraver_group::Engraver_group ()
171 acknowledge_hash_table_drul_[LEFT]
172 = acknowledge_hash_table_drul_[RIGHT]
175 acknowledge_hash_table_drul_[LEFT] = scm_c_make_hash_table (61);
176 acknowledge_hash_table_drul_[RIGHT] = scm_c_make_hash_table (61);
179 #include "translator.icc"
181 ADD_TRANSLATOR_GROUP (Engraver_group,
182 /* doc */ "A group of engravers taken together",
189 Engraver_group::derived_mark () const
191 scm_gc_mark (acknowledge_hash_table_drul_[LEFT]);
192 scm_gc_mark (acknowledge_hash_table_drul_[RIGHT]);