]> git.donarmstrong.com Git - lilypond.git/blob - lily/register-group.cc
release: 0.0.70pre
[lilypond.git] / lily / register-group.cc
1 /*
2   registergroup.cc -- implement Register_group_register
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9 #include "proto.hh"
10 #include "plist.hh"
11 #include "register-group.hh"
12 #include "register.hh"
13 #include "debug.hh"
14 #include "p-score.hh"
15 #include "score-elem.hh"
16 #include "input-register.hh"
17
18 Register_group_register::~Register_group_register()
19 {
20     assert(removable_b());
21 }
22
23 void
24 Register_group_register::check_removal()
25 {
26     for (int i =0; i < group_l_arr_.size(); ) {
27         group_l_arr_[i]->check_removal();
28         if (group_l_arr_[i]->removable_b())
29             terminate_register(group_l_arr_[i]);
30         else 
31             i++;
32     }
33     
34 }
35
36 bool
37 Register_group_register::removable_b()const
38 {
39     return !iterator_count_&& !group_l_arr_.size() ;
40 }
41
42 Register_group_register::Register_group_register()
43 {
44     ireg_l_ =0;
45     iterator_count_ =0;
46 }
47
48 void
49 Register_group_register::set_feature(Feature d)
50 {
51     iter_top(reg_list_, i);
52     while (i.ok()) {
53         // this construction to ensure clean deletion
54         Request_register *reg_l = i++; 
55         reg_l->set_feature(d);
56     }
57 }
58
59 void
60 Register_group_register::sync_features()
61 {
62     iter_top(reg_list_, i);
63     while (i.ok()) {
64
65         Request_register *reg_l = i++; 
66         reg_l->sync_features();
67     }
68 }
69
70 void
71 Register_group_register::do_pre_move_processing()
72 {
73     iter_top(reg_list_, i);
74     while (i.ok()) {
75         
76         Request_register *reg_l = i++; 
77         reg_l->pre_move_processing();
78     }
79 }
80
81 void
82 Register_group_register::do_process_requests()
83 {
84     iter_top(reg_list_, i);
85     while (i.ok()) {
86         
87         Request_register *reg_l = i++; 
88         reg_l->process_requests();
89     }
90 }
91
92
93 void
94 Register_group_register::do_post_move_processing()
95 {
96     iter_top(reg_list_, i);
97     while (i.ok()) {
98                 // this construction to ensure clean deletion
99         Request_register *reg_l = i++; 
100         reg_l->post_move_processing();
101     }
102 }
103
104
105 bool
106 Register_group_register::contains_b(Request_register* reg_l)const
107 {
108     bool parent_b = Request_register::contains_b(reg_l);
109     
110     if (parent_b)
111         return true;
112     for (iter_top(reg_list_, j); j.ok(); j++)
113         if (j->contains_b(reg_l))
114             return true;
115     return false;
116 }
117         
118
119
120 bool
121 Register_group_register::do_try_request(Request*req_l)
122 {
123     bool hebbes_b =false;
124     for (int i =0; !hebbes_b && i < nongroup_l_arr_.size() ; i++)
125         hebbes_b =nongroup_l_arr_[i]->try_request(req_l);
126     if (!hebbes_b)
127         hebbes_b = daddy_reg_l_->try_request(req_l);
128     return hebbes_b ;
129 }
130
131 void
132 Register_group_register::add(Request_register *reg_p)
133 {
134     reg_list_.bottom().add(reg_p);
135     reg_p->daddy_reg_l_ = this;
136
137     if (reg_p->is_type_b(Register_group_register::static_name())) {
138         group_l_arr_.push((Register_group_register*)reg_p);
139     } else {
140         nongroup_l_arr_ .push(reg_p);
141     }
142 }
143
144
145 Request_register *
146 Register_group_register::remove_register_p(Request_register*reg_l)
147 {
148     group_l_arr_.substitute((Register_group_register*)reg_l,0);
149     nongroup_l_arr_.substitute(reg_l,0);
150     iterator(reg_list_) reg_cur= reg_list_.find(reg_l);
151     
152     return reg_cur.remove_p();
153 }
154
155 void
156 Register_group_register::terminate_register(Request_register*r_l)
157 {
158     mtor << "Removing " << r_l->name() << " at " << get_staff_info().when() << "\n";
159     r_l->do_removal_processing();
160     Request_register * reg_p =remove_register_p(r_l);
161     
162     delete reg_p;
163 }
164
165 IMPLEMENT_IS_TYPE_B1(Register_group_register,Request_register);
166 IMPLEMENT_STATIC_NAME(Register_group_register);
167 ADD_THIS_REGISTER(Register_group_register);
168
169 void
170 Register_group_register::do_print()const
171 {
172 #ifndef NPRINT
173     mtor << "ID: " << id_str_ << "\n";
174     for (iter_top(reg_list_, i); i.ok(); i++) 
175         i->print();
176 #endif
177 }
178
179
180 Register_group_register*
181 Register_group_register::find_register_l(String n, String id)
182 {
183     if (name() == n && id_str_ == id)
184         return this;
185     Register_group_register * r = 0;
186     for (int i =0; !r && i<  group_l_arr_.size(); i++) {
187         r = group_l_arr_[i]->find_register_l(n,id);
188     }
189     
190     return r;
191 }
192
193 Register_group_register*
194 Register_group_register::find_get_reg_l(String n,String id)
195 {
196     Register_group_register * ret=0;
197     if (ireg_l_-> find_ireg_l( n )) {
198         ret = find_register_l(n,id);
199         if (!ret) {
200             ret = ireg_l_-> find_ireg_l(n) -> get_group_register_p();
201             add (  ret );
202             ret ->id_str_ = id;
203         }
204     } else if (daddy_reg_l_)
205         ret =daddy_reg_l_->find_get_reg_l(n,id);
206     else {
207         warning("Can't find or create `" + n + "' called `" + id + "'\n");
208         ret =0;
209     }
210     return ret;
211 }
212
213 int
214 Register_group_register::depth_i()const
215 {
216     return daddy_reg_l_->depth_i()  + 1;
217 }
218
219 Register_group_register*
220 Register_group_register::ancestor_l(int l)
221 {
222     if (!l || !daddy_reg_l_)
223         return this;
224     
225     return daddy_reg_l_->ancestor_l(l-1);
226 }
227
228 void
229 Register_group_register::announce_element(Score_elem_info info)
230 {
231     announce_info_arr_.push(info);
232     Request_register::announce_element(info);
233 }
234
235 void
236 Register_group_register::do_announces()
237 {
238     for (int i=0; i < group_l_arr_.size(); i++) {
239         group_l_arr_[i]->do_announces();
240     }
241     
242     Request dummy_req;
243  
244     for (int j =0; j < announce_info_arr_.size(); j++){
245        Score_elem_info info = announce_info_arr_[j];
246        
247        if (!info.req_l_)
248             info.req_l_ = &dummy_req;
249        for (int i=0; i < nongroup_l_arr_.size(); i++) {
250            if (nongroup_l_arr_[i] != info.origin_reg_l_arr_[0])
251                nongroup_l_arr_[i]->acknowledge_element(info);
252        }
253     }
254     announce_info_arr_.set_size(0);
255 }
256
257
258 void
259 Register_group_register::do_removal_processing()
260 {
261     for (iter( reg_list_.top(), i); i.ok(); i++)
262         i->do_removal_processing();
263 }
264
265 Staff_info
266 Register_group_register::get_staff_info()const
267 {
268     Staff_info inf = Request_register::get_staff_info();
269
270     for (int i=0; i < nongroup_l_arr_.size(); i++)
271         nongroup_l_arr_[i]->fill_staff_info(inf);
272     
273     return inf;
274 }
275
276 Register_group_register*
277 Register_group_register::get_default_interpreter()
278 {
279     if ( interpreter_l() )
280         return daddy_reg_l_->get_default_interpreter();
281
282     Register_group_register *reg_p= ireg_l_->
283         get_default_ireg_l()->get_group_register_p();
284     add(reg_p );
285     if (reg_p->interpreter_l())
286         return reg_p;
287     else
288         return reg_p->get_default_interpreter();
289 }