]> git.donarmstrong.com Git - lilypond.git/blob - lily/engraver-group.cc
* configure.in (--enable-std-vector): New option.
[lilypond.git] / lily / engraver-group.cc
1 /*
2   engraver-group.cc -- implement Engraver_group
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include "engraver-group.hh"
10
11 #include "warn.hh"
12 #include "paper-score.hh"
13 #include "grob.hh"
14 #include "context.hh"
15 #include "translator-dispatch-list.hh"
16
17 void
18 Engraver_group::announce_grob (Grob_info info)
19 {
20   announce_infos_.push_back (info);
21
22   Engraver_group *dad_eng
23     = context_->get_parent_context ()
24     ? dynamic_cast<Engraver_group *> (context_->get_parent_context ()->implementation ())
25     : 0;
26   if (dad_eng)
27     dad_eng->announce_grob (info);
28 }
29
30 void
31 Engraver_group::acknowledge_grobs ()
32 {
33   if (!announce_infos_.size ())
34     return;
35
36   SCM name_sym = ly_symbol2scm ("name");
37   SCM meta_sym = ly_symbol2scm ("meta");
38
39   for (vsize j = 0; j < announce_infos_.size (); j++)
40     {
41       Grob_info info = announce_infos_[j];
42
43       SCM meta = info.grob ()->internal_get_property (meta_sym);
44       SCM nm = scm_assoc (name_sym, meta);
45       if (scm_is_pair (nm))
46         nm = scm_cdr (nm);
47       else
48         continue;
49
50       SCM acklist = scm_hashq_ref (acknowledge_hash_table_, nm, SCM_BOOL_F);
51       Engraver_dispatch_list *dispatch
52         = Engraver_dispatch_list::unsmob (acklist);
53
54       if (acklist == SCM_BOOL_F)
55         {
56           SCM ifaces
57             = scm_cdr (scm_assoc (ly_symbol2scm ("interfaces"), meta));
58           acklist = Engraver_dispatch_list::create (get_simple_trans_list (),
59                                                     ifaces);
60
61           dispatch
62             = Engraver_dispatch_list::unsmob (acklist);
63
64           scm_hashq_set_x (acknowledge_hash_table_, nm, acklist);
65         }
66
67       if (dispatch)
68         dispatch->apply (info);
69     }
70 }
71
72 /*
73   Ugh. This is slightly expensive. We could/should cache the value of
74   the group count?
75 */
76 int
77 Engraver_group::pending_grob_count () const
78 {
79   int count = announce_infos_.size ();
80   for (SCM s = context_->children_contexts ();
81        scm_is_pair (s); s = scm_cdr (s))
82     {
83       Context *c = unsmob_context (scm_car (s));
84       Engraver_group *group
85         = dynamic_cast<Engraver_group *> (c->implementation ());
86
87       if (group)
88         count += group->pending_grob_count ();
89     }
90   return count;
91 }
92
93 void
94 Engraver_group::do_announces ()
95 {
96   do
97     {
98       /*
99         DOCME: why is this inside the loop? 
100        */
101       for (SCM s = context ()->children_contexts ();
102            scm_is_pair (s); s = scm_cdr (s))
103         {
104           Context *c = unsmob_context (scm_car (s));
105           Engraver_group *group
106             = dynamic_cast<Engraver_group *> (c->implementation ());
107           if (group)
108             group->do_announces ();
109         }
110
111       
112       while (1)
113         {
114           precomputed_translator_foreach (PROCESS_ACKNOWLEDGED);
115           if (announce_infos_.size () == 0)
116             break;
117
118           acknowledge_grobs ();
119           announce_infos_.clear ();
120         }
121     }
122   while (pending_grob_count () > 0);
123 }
124
125 Engraver_group::Engraver_group ()
126 {
127   acknowledge_hash_table_ = SCM_EOL;
128   acknowledge_hash_table_ = scm_c_make_hash_table (61);
129 }
130
131 #include "translator.icc"
132
133 ADD_TRANSLATOR_GROUP (Engraver_group,
134                       /* doc */ "A group of engravers taken together",
135                       /* create */ "",
136                       /* accept */ "",
137                       /* read */ "",
138                       /* write */ "");
139
140 void
141 Engraver_group::derived_mark () const
142 {
143   scm_gc_mark (acknowledge_hash_table_);
144 }