]> git.donarmstrong.com Git - lilypond.git/blob - lily/translator.cc
Web-ja: update introduction
[lilypond.git] / lily / translator.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1997--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "translator.hh"
21
22 #include "context-def.hh"
23 #include "dispatcher.hh"
24 #include "global-context.hh"
25 #include "international.hh"
26 #include "translator-group.hh"
27 #include "warn.hh"
28
29 #include "translator.icc"
30
31 Translator::~Translator ()
32 {
33 }
34
35 void
36 Translator::process_music ()
37 {
38 }
39
40 void
41 Translator::process_acknowledged ()
42 {
43 }
44
45 Translator::Translator (Context *c)
46   : daddy_context_ (c)
47 {
48   smobify_self ();
49 }
50
51 Moment
52 Translator::now_mom () const
53 {
54   return daddy_context_->now_mom ();
55 }
56
57 Output_def *
58 Translator::get_output_def () const
59 {
60   return daddy_context_->get_output_def ();
61 }
62
63 Translator_group *
64 Translator::get_daddy_translator () const
65 {
66   return daddy_context_->implementation ();
67 }
68
69 void
70 Translator::protect_event (SCM ev)
71 {
72   get_daddy_translator ()->protect_event (ev);
73 }
74
75 SCM
76 Translator::internal_get_property (SCM sym) const
77 {
78   return daddy_context_->internal_get_property (sym);
79 }
80
81 void
82 Translator::stop_translation_timestep ()
83 {
84 }
85
86 /*
87   this function is called once each moment, before any user
88   information enters the translators.  (i.e. no \property or event has
89   been processed yet.)
90 */
91 void
92 Translator::start_translation_timestep ()
93 {
94 }
95
96 void
97 Translator::initialize ()
98 {
99 }
100
101 void
102 Translator::finalize ()
103 {
104 }
105
106 void
107 Translator::connect_to_context (Context *c)
108 {
109   for (SCM r = get_listener_list (); scm_is_pair (r); r = scm_cdr (r))
110     {
111       SCM event_class = scm_caar (r);
112       SCM callback = scm_cdar (r);
113
114       c->events_below ()->add_listener (get_listener (callback),
115                                         event_class);
116     }
117 }
118
119 void
120 Translator::disconnect_from_context (Context *c)
121 {
122   for (SCM r = get_listener_list (); scm_is_pair (r); r = scm_cdr (r))
123     {
124       SCM event_class = scm_caar (r);
125       SCM callback = scm_cdar (r);
126
127       c->events_below ()->remove_listener (get_listener (callback),
128                                            event_class);
129     }
130 }
131
132 SCM
133 Translator::event_class_symbol (const char *ev_class)
134 {
135   /* ev_class is the C++ identifier name. Convert to scm symbol */
136   string name = string (ev_class);
137   name = replace_all (&name, '_', '-');
138   name += "-event";
139
140   return scm_from_ascii_symbol (name.c_str ());
141 }
142
143 /*
144  Helps the individual static_translator_description methods of translators.
145 */
146 SCM
147 Translator::static_translator_description (const char *grobs,
148                                            const char *desc,
149                                            SCM listener_list,
150                                            const char *read,
151                                            const char *write)
152 {
153   SCM static_properties = SCM_EOL;
154
155   static_properties = scm_acons (ly_symbol2scm ("grobs-created"),
156                                  parse_symbol_list (grobs), static_properties);
157
158   static_properties = scm_acons (ly_symbol2scm ("description"),
159                                  scm_from_utf8_string (desc), static_properties);
160
161   SCM list = SCM_EOL;
162   for (; scm_is_pair (listener_list); listener_list = scm_cdr (listener_list))
163     list = scm_cons (scm_caar (listener_list), list);
164   static_properties = scm_acons (ly_symbol2scm ("events-accepted"),
165                                  list, static_properties);
166
167   static_properties = scm_acons (ly_symbol2scm ("properties-read"),
168                                  parse_symbol_list (read), static_properties);
169
170   static_properties = scm_acons (ly_symbol2scm ("properties-written"),
171                                  parse_symbol_list (write), static_properties);
172
173   return static_properties;
174 }
175
176 /*
177   SMOBS
178 */
179 SCM
180 Translator::mark_smob () const
181 {
182   derived_mark ();
183   return SCM_EOL;
184 }
185
186 Global_context *
187 Translator::get_global_context () const
188 {
189   return daddy_context_->get_global_context ();
190 }
191
192 Context *
193 Translator::get_score_context () const
194 {
195   return daddy_context_->get_score_context ();
196 }
197
198 const char * const Translator::type_p_name_ = "ly:translator?";
199
200 bool
201 Translator::must_be_last () const
202 {
203   return false;
204 }
205
206 void
207 Translator::derived_mark () const
208 {
209 }
210
211 int
212 Translator::print_smob (SCM port, scm_print_state *) const
213 {
214   scm_puts ("#<Translator ", port);
215   scm_puts (class_name (), port);
216   scm_puts (" >", port);
217   return 1;
218 }
219
220 void
221 add_acknowledger (SCM ptr,
222                   char const *func_name,
223                   SCM &ack_hash)
224 {
225   if (SCM_UNBNDP (ack_hash))
226     ack_hash = Scheme_hash_table::make_smob ();
227
228   string interface_name (func_name);
229
230   interface_name = replace_all (&interface_name, '_', '-');
231   interface_name += "-interface";
232
233   unsmob<Scheme_hash_table> (ack_hash)
234     ->set (ly_symbol2scm (interface_name.c_str ()), ptr);
235 }
236
237 SCM
238 generic_get_acknowledger (SCM sym, SCM ack_hash)
239 {
240   if (SCM_UNBNDP (ack_hash))
241     return SCM_UNDEFINED;
242
243   return unsmob<Scheme_hash_table> (ack_hash)->get (sym);
244 }
245
246 Moment
247 get_event_length (Stream_event *e)
248 {
249   Moment *m = unsmob<Moment> (e->get_property ("length"));
250   if (m)
251     return *m;
252   else
253     return Moment (0);
254 }
255
256 Moment
257 get_event_length (Stream_event *e, Moment now)
258 {
259   Moment len = get_event_length (e);
260
261   if (now.grace_part_)
262     {
263       len.grace_part_ = len.main_part_;
264       len.main_part_ = Rational (0);
265     }
266   return len;
267 }
268
269 /*
270   Helper, used through ASSIGN_EVENT_ONCE to throw warnings for
271   simultaneous events. The helper is only useful in listen_* methods
272   of translators.
273 */
274 bool
275 internal_event_assignment (Stream_event **old_ev, Stream_event *new_ev, const char *function)
276 {
277   if (*old_ev
278       && !to_boolean (scm_equal_p ((*old_ev)->self_scm (),
279                                    new_ev->self_scm ())))
280     {
281       /* extract event class from function name */
282       string ev_class = function;
283
284       /* This assertion fails if EVENT_ASSIGNMENT was called outside a
285          translator listener. Don't do that. */
286       const char *prefix = "listen_";
287       assert (0 == ev_class.find (prefix));
288
289       /* "listen_foo_bar" -> "foo-bar" */
290       ev_class.erase (0, strlen (prefix));
291       replace_all (&ev_class, '_', '-');
292
293       new_ev->origin ()->warning (_f ("Two simultaneous %s events, junking this one", ev_class.c_str ()));
294       (*old_ev)->origin ()->warning (_f ("Previous %s event here", ev_class.c_str ()));
295       return false;
296     }
297   else
298     {
299       *old_ev = new_ev;
300       return true;
301     }
302 }
303
304 // Base class.  Not instantiated.  No ADD_TRANSLATOR call.