]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/translator.icc
Update source file headers. Fixes using standard GNU package conventions.
[lilypond.git] / lily / include / translator.icc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2005--2009 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 #ifndef TRANSLATOR_ICC
21 #define TRANSLATOR_ICC
22
23 #include "listener.hh"
24 #include "std-vector.hh"
25 #include "translator.hh"
26
27 /*
28   TODO: derive "foo-bar-interface" from Foo_bar classname.
29  */
30
31 /**
32    A macro to automate administration of translators.
33 */
34 #define ADD_THIS_TRANSLATOR(T)                                          \
35   translator_listener_record *T::listener_list_;                        \
36   SCM T::static_description_ = SCM_EOL;                                 \
37   static void _ ## T ## _adder ()                                       \
38   {                                                                     \
39     T *t = new T;                                                       \
40     T::static_description_ = t->static_translator_description ();       \
41     scm_permanent_object (T::static_description_);                      \
42     add_translator (t);                                                 \
43   }                                                                     \
44   SCM T::translator_description () const                                \
45   {                                                                     \
46     return static_description_;                                         \
47   }                                                                     \
48   ADD_GLOBAL_CTOR (_ ## T ## _adder);
49
50 #define ADD_TRANSLATOR(classname, desc, grobs, read, write)             \
51   Drul_array< vector<Acknowledge_information> > classname::acknowledge_static_array_drul_;      \
52   IMPLEMENT_FETCH_PRECOMPUTABLE_METHODS (classname);                    \
53   ADD_THIS_TRANSLATOR (classname);                                      \
54   Engraver_void_function_engraver_grob_info                             \
55   classname::static_get_acknowledger (SCM sym)                          \
56   {                                                                     \
57     return generic_get_acknowledger (sym, &acknowledge_static_array_drul_[START]);      \
58   }                                                                     \
59   Engraver_void_function_engraver_grob_info                             \
60   classname::static_get_end_acknowledger (SCM sym)                              \
61   {                                                                     \
62     return generic_get_acknowledger (sym, &acknowledge_static_array_drul_[STOP]);       \
63   }                                                                     \
64   SCM                                                                   \
65   classname::static_translator_description () const                     \
66   {                                                                     \
67     return Translator::static_translator_description (grobs, desc, listener_list_, read, write); \
68   }
69
70 #define IMPLEMENT_FETCH_PRECOMPUTABLE_METHODS(T)                        \
71   void                                                                  \
72   T::fetch_precomputable_methods (Translator_void_method_ptr ptrs[])    \
73   {                                                                     \
74     ptrs[START_TRANSLATION_TIMESTEP] =                                  \
75       ((Translator_void_method_ptr) & T::start_translation_timestep ==  \
76        (Translator_void_method_ptr) & Translator::start_translation_timestep) \
77       ? 0                                                               \
78       : (Translator_void_method_ptr) & T::start_translation_timestep;   \
79                                                                         \
80     ptrs[STOP_TRANSLATION_TIMESTEP] =                                   \
81       ((Translator_void_method_ptr) & T::stop_translation_timestep == (Translator_void_method_ptr) & Translator::stop_translation_timestep) \
82       ? 0                                                               \
83       : (Translator_void_method_ptr) & T::stop_translation_timestep;    \
84                                                                         \
85     ptrs[PROCESS_MUSIC] =                                               \
86       ((Translator_void_method_ptr) & T::process_music == (Translator_void_method_ptr) & Translator::process_music) \
87       ? 0                                                               \
88       : (Translator_void_method_ptr) & T::process_music;                \
89                                                                         \
90     ptrs[PROCESS_ACKNOWLEDGED] =                                        \
91       ((Translator_void_method_ptr) & T::process_acknowledged == (Translator_void_method_ptr) & Translator::process_acknowledged) \
92       ? 0                                                               \
93       : (Translator_void_method_ptr) & T::process_acknowledged;         \
94   }
95
96 void add_acknowledger (Engraver_void_function_engraver_grob_info ptr,
97                        char const *func_name,
98                        vector<Acknowledge_information> *ack_array);
99
100 Engraver_void_function_engraver_grob_info
101 generic_get_acknowledger (SCM sym,
102                           vector<Acknowledge_information> const *ack_array);
103
104 #define ADD_ACKNOWLEDGER(CLASS, NAME)                                   \
105   void CLASS ## NAME ## _ack_adder ()                                   \
106   {                                                                     \
107     add_acknowledger ((Engraver_void_function_engraver_grob_info) & CLASS::acknowledge_ ## NAME, #NAME, &CLASS::acknowledge_static_array_drul_[START]); \
108   }                                                                     \
109   ADD_SCM_INIT_FUNC (CLASS ## NAME ## _ack_adder_initclass, CLASS ## NAME ## _ack_adder);
110
111 #define ADD_END_ACKNOWLEDGER(CLASS, NAME)                                       \
112   void CLASS ## NAME ## _end_ack_adder ()                                       \
113   {                                                                     \
114     add_acknowledger ((Engraver_void_function_engraver_grob_info) & CLASS::acknowledge_end_ ## NAME, #NAME, &CLASS::acknowledge_static_array_drul_[STOP]); \
115   }                                                                     \
116   ADD_SCM_INIT_FUNC (CLASS ## NAME ## _end_ack_adder_initclass, CLASS ## NAME ## _end_ack_adder);
117
118 /*
119   Implement the method cl::listen_##m, and make it listen to stream 
120   events of class m.
121  */
122 #define IMPLEMENT_TRANSLATOR_LISTENER(cl, m)            \
123 void                                                    \
124 cl :: _internal_declare_ ## m ()                        \
125 {                                                       \
126   static translator_listener_record r;                  \
127   add_translator_listener (&listener_list_, &r, _get_ ## m ## _listener, #m); \
128 }                                                       \
129                                                         \
130 ADD_SCM_INIT_FUNC (cl ## _declare_event_ ## m, cl::_internal_declare_ ## m);    \
131                                                         \
132 Listener                                                \
133 cl :: _get_ ## m ## _listener (void *me)                \
134 {                                                       \
135   cl *obj = (cl *) me;                                  \
136   return obj->GET_LISTENER (_listen_scm_ ## m);         \
137 }                                                       \
138                                                         \
139 IMPLEMENT_LISTENER (cl, _listen_scm_ ## m)              \
140 void                                                    \
141 cl::_listen_scm_ ## m (SCM sev)                         \
142 {                                                       \
143   Stream_event *ev = unsmob_stream_event (sev);         \
144   protect_event (sev);                                  \
145   listen_ ## m (ev);                                    \
146 }
147
148 #endif /* TRANSLATOR_ICC */