2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1997--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
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.
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.
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/>.
23 #include "global-ctor.hh"
24 #include "lily-proto.hh"
25 #include "virtual-methods.hh"
26 #include "callback.hh"
27 #include "input.hh" // for error reporting
29 #include "stream-event.hh"
30 #include "std-vector.hh"
31 #include "protected-scm.hh"
33 // The Translator_creator class is only for translators defined in C.
34 // Its elements are callable entities taking a context argument and
35 // returning a corresponding translator.
37 // Other translator-creating entities may be alists and functions returning
38 // such alists. Information for those, such as created grobs/properties
39 // is attached via object properties.
41 // Smob rather than Simple_smob since we want an entity for
44 class Translator_creator : public Smob<Translator_creator>
46 Translator_creator (Translator_creator const &); // don't define
47 Translator * (*allocate_)(Context *);
49 static Translator *allocate (Context *ctx);
51 Translator_creator (Translator * (*allocate)(Context *))
57 // This is stupid, but constructors cannot have explicit template
60 static Translator_creator *alloc()
62 return new Translator_creator(&allocate<T>);
65 LY_DECLARE_SMOB_PROC (&Translator_creator::call, 1, 0, 0);
68 template <class T> Translator *
69 Translator_creator::allocate (Context *ctx)
74 #define TRANSLATOR_FAMILY_DECLARATIONS(NAME) \
76 DECLARE_CLASSNAME (NAME); \
77 virtual void fetch_precomputable_methods (SCM methods[]); \
78 DECLARE_TRANSLATOR_CALLBACKS (NAME); \
79 TRANSLATOR_INHERIT (Translator); \
82 #define TRANSLATOR_INHERIT(BASE) \
83 using BASE::method_finder
85 #define DECLARE_TRANSLATOR_CALLBACKS(NAME) \
86 template <void (NAME::*mf)()> \
87 static SCM method_finder () \
89 return Callback0_wrapper::make_smob<NAME, mf> (); \
91 template <void (NAME::*mf)(Stream_event *)> \
92 static SCM method_finder () \
94 return Callback_wrapper::make_smob<trampoline<NAME, mf> > (); \
96 template <void (NAME::*mf)(Grob_info)> \
97 static SCM method_finder () { \
98 return Callback2_wrapper::make_smob<trampoline <NAME, mf> > (); \
103 Each translator class has a static alist of event class symbols
104 mapping to callbacks that are called with a translator instance and
105 a stream event when an event of the appropriate event class is
106 announced in a context.
109 #define TRANSLATOR_DECLARATIONS(NAME) \
111 TRANSLATOR_FAMILY_DECLARATIONS (NAME); \
112 static Drul_array<Protected_scm> acknowledge_static_array_drul_; \
113 static Protected_scm listener_list_; \
114 static SCM static_get_acknowledger (SCM sym, Direction start_end); \
115 virtual SCM get_acknowledger (SCM sym, Direction start_end) \
117 return static_get_acknowledger (sym, start_end); \
121 static void boot (); \
122 static SCM static_translator_description (); \
123 virtual SCM get_listener_list () const \
125 return listener_list_; \
129 enum Translator_precompute_index
131 START_TRANSLATION_TIMESTEP,
132 STOP_TRANSLATION_TIMESTEP,
134 PROCESS_ACKNOWLEDGED,
135 TRANSLATOR_METHOD_PRECOMPUTE_COUNT,
139 Translate music into grobs.
141 class Translator : public Smob<Translator>
144 int print_smob (SCM, scm_print_state *) const;
145 SCM mark_smob () const;
146 static const char * const type_p_name_;
147 virtual ~Translator ();
149 Context *context () const { return daddy_context_; }
152 Translator (Context *);
154 Translator (Translator const &); // not copyable
157 SCM internal_get_property (SCM symbol) const;
159 virtual Output_def *get_output_def () const;
160 virtual Translator_group *get_daddy_translator ()const;
161 virtual Moment now_mom () const;
162 virtual bool must_be_last () const;
164 virtual void initialize ();
165 virtual void finalize ();
167 virtual void connect_to_context (Context *c);
168 virtual void disconnect_from_context (Context *c);
170 void stop_translation_timestep ();
171 void start_translation_timestep ();
172 void process_music ();
173 void process_acknowledged ();
175 Context *get_score_context () const;
176 Global_context *get_global_context () const;
178 DECLARE_CLASSNAME (Translator);
180 virtual void fetch_precomputable_methods (SCM methods[]) = 0;
181 virtual SCM get_listener_list () const = 0;
182 virtual SCM get_acknowledger (SCM sym, Direction start_end) = 0;
184 protected: // should be private.
185 Context *daddy_context_;
186 void protect_event (SCM ev);
188 template <class T, void (T::*callback)(Stream_event *)>
189 static SCM trampoline (SCM target, SCM event)
191 T *t = unsmob<T> (target);
192 LY_ASSERT_SMOB (T, target, 1);
193 LY_ASSERT_SMOB (Stream_event, event, 2);
195 t->protect_event (event);
196 (t->*callback) (unsmob<Stream_event> (event));
197 return SCM_UNSPECIFIED;
200 // Fallback for non-overriden callbacks for which &T::x degrades to
202 template <void (Translator::*)()>
204 method_finder () { return SCM_UNDEFINED; }
206 virtual void derived_mark () const;
207 static SCM event_class_symbol (const char *ev_class);
209 static_translator_description (const char *grobs,
215 friend class Translator_group;
219 generic_get_acknowledger (SCM sym, SCM ack_hash);
221 void add_translator_creator (SCM creator, SCM name, SCM description);
223 SCM get_translator_creator (SCM s);
224 Moment get_event_length (Stream_event *s, Moment now);
225 Moment get_event_length (Stream_event *s);
228 This helper is only meaningful inside listen_* methods.
230 extern bool internal_event_assignment (Stream_event **old_ev, Stream_event *new_ev, const char *function);
231 #define ASSIGN_EVENT_ONCE(o,n) internal_event_assignment (&o, n, __FUNCTION__)
233 #endif // TRANSLATOR_HH