2 Translator_group.cc -- implement Translator_group
4 source file of the GNU LilyPond music typesetter
6 (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
9 #include "music-output-def.hh"
10 #include "translator-group.hh"
11 #include "translator.hh"
15 Translator_group::Translator_group (Translator_group
const&s
)
18 consists_str_arr_
= s
.consists_str_arr_
;
19 accepts_str_arr_
= s
.accepts_str_arr_
;
23 Translator_group::~Translator_group ()
25 assert (removable_b());
29 Translator_group::Translator_group()
35 Translator_group::check_removal()
37 for (int i
=0; i
< group_l_arr ().size();)
39 group_l_arr ()[i
]->check_removal();
40 if (group_l_arr ()[i
]->removable_b())
41 terminate_translator (group_l_arr ()[i
]);
49 IMPLEMENT_IS_TYPE_B1(Translator_group
, Translator
);
52 Translator_group::add (Translator
*trans_p
)
54 trans_p_list_
.bottom().add (trans_p
);
55 trans_p
->daddy_trans_l_
= this;
56 trans_p
->output_def_l_
= output_def_l_
;
57 trans_p
->add_processing ();
61 Translator_group::removable_b() const
63 return !(iterator_count_
|| group_l_arr ().size());
67 Translator_group::find_existing_translator_l (String n
, String id
)
69 if (is_alias_b (n
) && (id_str_
== id
|| id
.empty_b ()))
71 Translator_group
* r
= 0;
72 for (int i
=0; !r
&& i
< group_l_arr ().size(); i
++)
74 r
= group_l_arr ()[i
]->find_existing_translator_l (n
,id
);
80 Link_array
<Translator_group
>
81 Translator_group::path_to_acceptable_translator (String type
) const
83 Link_array
<Translator_group
> accepted_arr
;
84 for (int i
=0; i
< accepts_str_arr_
.size (); i
++)
86 Translator
*t
= output_def_l ()->find_translator_l (accepts_str_arr_
[i
]);
87 if (!t
|| !t
->group_l ())
89 accepted_arr
.push (t
->group_l());
93 for (int i
=0; i
< accepted_arr
.size (); i
++)
94 if (accepted_arr
[i
]->type_str_
== type
)
96 Link_array
<Translator_group
> retval
;
97 retval
.push (accepted_arr
[i
]);
101 Link_array
<Translator_group
> best_result
;
102 int best_depth
= INT_MAX
;
103 for (int i
=0; i
< accepted_arr
.size (); i
++)
105 Translator_group
* g
= accepted_arr
[i
];
107 Link_array
<Translator_group
> result
108 = g
->path_to_acceptable_translator (type
);
109 if (result
.size () && result
.size () < best_depth
)
112 best_result
= result
;
120 Translator_group::find_create_translator_l (String n
, String id
)
122 Translator_group
* existing
= find_existing_translator_l (n
,id
);
126 Link_array
<Translator_group
> path
= path_to_acceptable_translator (n
);
130 Translator_group
* current
= this;
132 // start at 1. The first one (index 0) will be us.
133 for (int i
=0; i
< path
.size (); i
++)
135 Translator_group
* new_group
= path
[i
]->clone ()->group_l ();
136 current
->add (new_group
);
139 current
->id_str_
= id
;
143 Translator_group
*ret
= 0;
145 ret
= daddy_trans_l_
->find_create_translator_l (n
,id
);
148 warning (_("Can't find or create `") + n
+ _("' called `") + id
+ "'\n");
156 Translator_group::do_try_request (Request
* req_l
)
158 bool hebbes_b
=false;
159 for (int i
=0; !hebbes_b
&& i
< nongroup_l_arr ().size() ; i
++)
160 hebbes_b
=nongroup_l_arr ()[i
]->try_request (req_l
);
161 if (!hebbes_b
&& daddy_trans_l_
)
162 hebbes_b
= daddy_trans_l_
->try_request (req_l
);
167 Translator_group::depth_i() const
169 return (daddy_trans_l_
) ? daddy_trans_l_
->depth_i() + 1 : 0;
173 Translator_group::ancestor_l (int level
)
175 if (!level
|| !daddy_trans_l_
)
178 return daddy_trans_l_
->ancestor_l (level
-1);
181 Link_array
<Translator_group
>
182 Translator_group::group_l_arr () const
184 Link_array
<Translator_group
> groups
;
185 for (PCursor
<Translator
*> i (trans_p_list_
.top ()); i
.ok (); i
++)
188 groups
.push (i
->group_l ());
193 Link_array
<Translator
>
194 Translator_group::nongroup_l_arr () const
196 Link_array
<Translator
> groups
;
197 for (PCursor
<Translator
*> i (trans_p_list_
.top ()); i
.ok (); i
++)
200 groups
.push (i
.ptr ());
206 Translator_group::terminate_translator (Translator
*r_l
)
208 DOUT
<< "Removing " << r_l
->name() << " at " << now_moment () << "\n";
209 r_l
->removal_processing();
210 Translator
* trans_p
=remove_translator_p (r_l
);
216 Translator_group::remove_translator_p (Translator
*trans_l
)
218 PCursor
<Translator
*> trans_cur (trans_p_list_
.find (trans_l
));
219 Translator
* t
= trans_cur
.remove_p();
221 For elegant design, we would do this too. Alas, it does not work yet..
223 t-> removal_processing ();
225 t
-> daddy_trans_l_
= 0;
231 Translator_group::get_simple_translator (char const *type
) const
233 for (int i
=0; i
< nongroup_l_arr ().size(); i
++)
235 if (nongroup_l_arr ()[i
]->name() == type
)
236 return nongroup_l_arr ()[i
];
239 return daddy_trans_l_
->get_simple_translator (type
);
245 Translator_group::is_bottom_translator_b () const
247 return !accepts_str_arr_
.size ();
253 Translator_group::get_default_interpreter()
255 if (accepts_str_arr_
.size())
257 Translator
*t
= output_def_l ()->find_translator_l (accepts_str_arr_
[0]);
258 Translator_group
* g
= t
->clone ()->group_l ();
261 if (!g
->is_bottom_translator_b ())
262 return g
->get_default_interpreter ();
270 Translator_group::each (Method_pointer method
)
272 for (PCursor
<Translator
*> i (trans_p_list_
.top ()); i
.ok (); i
++)
273 (i
.ptr()->*method
) ();
277 Translator_group::each (Const_method_pointer method
) const
279 for (PCursor
<Translator
*> i (trans_p_list_
.top ()); i
.ok (); i
++)
280 (i
.ptr()->*method
) ();
284 Translator_group::do_print() const
289 if (status
== ORPHAN
)
291 DOUT
<< "consists of: ";
292 for (int i
=0; i
< consists_str_arr_
.size (); i
++)
293 DOUT
<< consists_str_arr_
[i
] << ", ";
294 DOUT
<< "\naccepts: ";
295 for (int i
=0; i
< accepts_str_arr_
.size (); i
++)
296 DOUT
<< accepts_str_arr_
[i
] << ", ";
300 if (id_str_
.length_i ())
301 DOUT
<< "ID: " << id_str_
;
302 DOUT
<< " iterators: " << iterator_count_
<< "\n";
304 each (&Translator::print
);
309 Translator_group::do_pre_move_processing ()
311 each (&Translator::pre_move_processing
);
315 Translator_group::do_post_move_processing ()
317 each (&Translator::post_move_processing
);
321 Translator_group::do_process_requests ()
323 each (&Translator::process_requests
);
327 Translator_group::do_creation_processing ()
329 each (&Translator::creation_processing
);
333 Translator_group::do_removal_processing ()
335 each (&Translator::removal_processing
);
339 Translator_group::do_add_processing ()
341 for (int i
=0; i
< consists_str_arr_
.size(); i
++)
343 Translator
* t
= output_def_l ()->find_translator_l (consists_str_arr_
[i
]);
345 warning (_("Could not find `") +consists_str_arr_
[i
]+ "'");