]> git.donarmstrong.com Git - lilypond.git/blob - lily/translator.cc
Added new system for how translators listen to events.
[lilypond.git] / lily / translator.cc
1 /*
2   translator.cc -- implement Translator
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 "translator.hh"
10
11 #include "warn.hh"
12 #include "translator-group.hh"
13 #include "context-def.hh"
14 #include "dispatcher.hh"
15 #include "global-context.hh"
16
17 #include "translator.icc"
18 #include "ly-smobs.icc"
19
20 Translator::~Translator ()
21 {
22 }
23
24 void
25 Translator::init ()
26 {
27   must_be_last_ = false;
28   self_scm_ = SCM_EOL;
29   daddy_context_ = 0;
30   smobify_self ();
31 }
32
33 void
34 Translator::process_music ()
35 {
36 }
37
38 void
39 Translator::process_acknowledged ()
40 {
41 }
42
43 Translator::Translator ()
44 {
45   init ();
46 }
47
48 Translator::Translator (Translator const &src)
49 {
50   init ();
51   must_be_last_ = src.must_be_last_;
52 }
53
54 bool
55 Translator::try_music (Music *)
56 {
57   return false;
58 }
59
60 Moment
61 Translator::now_mom () const
62 {
63   return daddy_context_->now_mom ();
64 }
65
66 Output_def *
67 Translator::get_output_def () const
68 {
69   return daddy_context_->get_output_def ();
70 }
71
72 Translator_group *
73 Translator::get_daddy_translator () const
74 {
75   return daddy_context_->implementation ();
76 }
77
78 void
79 Translator::protect_event (SCM ev)
80 {
81   get_daddy_translator ()->protect_event (ev);
82 }
83
84 SCM
85 Translator::internal_get_property (SCM sym) const
86 {
87   return daddy_context_->internal_get_property (sym);
88 }
89
90 void
91 Translator::stop_translation_timestep ()
92 {
93 }
94
95 /*
96   this function has 2 properties
97
98   - It is called before try_music ()
99
100   - It is called before any user information enters the translators.
101   (i.e. any \property or event is not processed yet.)
102 */
103 void
104 Translator::start_translation_timestep ()
105 {
106 }
107
108 void
109 Translator::initialize ()
110 {
111 }
112
113 void
114 Translator::finalize ()
115 {
116 }
117
118 void
119 Translator::connect_to_context (Context *c)
120 {
121   for (translator_listener_record *r = get_listener_list (); r; r=r->next_)
122     c->events_below ()->add_listener (r->get_listener_ (this), r->event_class_);
123 }
124
125 void
126 Translator::disconnect_from_context (Context *c)
127 {
128   for (translator_listener_record *r = get_listener_list (); r; r=r->next_)
129     c->events_below ()->remove_listener (r->get_listener_ (this), r->event_class_);
130 }
131
132 /*
133   Internally called once, statically, for each translator
134   listener. Connects the name of an event class with a procedure that
135   fetches the corresponding listener.
136
137   The method should only be called from the macro
138   IMPLEMENT_TRANSLATOR_LISTENER.
139  */
140 void
141 Translator::add_translator_listener (translator_listener_record **listener_list,
142                          translator_listener_record *r,
143                          Listener (*get_listener) (void *), 
144                          const char *ev_class)
145 {
146   /* ev_class is the C++ identifier name. Convert to scm symbol */
147   string name = string (ev_class);
148   name = replace_all (name, '_', '-');
149   name = name + "-event";
150   /* It's OK to use scm_gc_protect_object for protection, because r is
151      statically allocated. */
152   r->event_class_ = scm_gc_protect_object (scm_str2symbol (name.c_str ()));
153   r->get_listener_ = get_listener;
154   r->next_ = *listener_list;
155   *listener_list = r;
156 }
157
158 /*
159   SMOBS
160 */
161 SCM
162 Translator::mark_smob (SCM sm)
163 {
164   Translator *me = (Translator *) SCM_CELL_WORD_1 (sm);
165   me->derived_mark ();
166   return SCM_EOL;
167 }
168
169 Global_context *
170 Translator::get_global_context () const
171 {
172   return daddy_context_->get_global_context ();
173 }
174
175 Context *
176 Translator::get_score_context () const
177 {
178   return daddy_context_->get_score_context ();
179 }
180
181 IMPLEMENT_SMOBS (Translator);
182 IMPLEMENT_DEFAULT_EQUAL_P (Translator);
183 IMPLEMENT_TYPE_P (Translator, "ly:translator?");
184
185 bool
186 Translator::must_be_last () const
187 {
188   return must_be_last_;
189 }
190
191 void
192 Translator::derived_mark () const
193 {
194 }
195
196 int
197 Translator::print_smob (SCM s, SCM port, scm_print_state *)
198 {
199   Translator *me = (Translator *) SCM_CELL_WORD_1 (s);
200   scm_puts ("#<Translator ", port);
201   scm_puts (me->class_name (), port);
202   scm_puts (" >", port);
203   return 1;
204 }
205
206 void
207 add_acknowledger (Engraver_void_function_engraver_grob_info ptr,
208                   char const *func_name,
209                   vector<Acknowledge_information> *ack_array)
210 {
211   Acknowledge_information inf;
212   inf.function_ = ptr;
213
214   string interface_name (func_name);
215
216   interface_name = replace_all (interface_name, '_', '-');
217   interface_name += "-interface";
218
219   inf.symbol_ = scm_gc_protect_object (ly_symbol2scm (interface_name.c_str ()));
220   ack_array->push_back (inf);
221 }
222
223 Engraver_void_function_engraver_grob_info
224 generic_get_acknowledger (SCM sym, vector<Acknowledge_information> const *ack_array)
225 {
226   for (vsize i = 0; i < ack_array->size (); i++)
227     {
228       if (ack_array->at (i).symbol_ == sym)
229         return ack_array->at (i).function_;
230     }
231   return 0;
232 }
233
234 ADD_TRANSLATOR (Translator,
235                 "Base class. Unused",
236                 "",
237                 "",
238                 "",
239                 "");