]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/translator.icc
* lily/input-smob.cc: add equal_p for Input
[lilypond.git] / lily / include / translator.icc
1 /*
2   translator.icc -- declare Translator glue wiring.
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2005--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #ifndef TRANSLATOR_ICC
10 #define TRANSLATOR_ICC
11
12 #include "listener.hh"
13 #include "std-vector.hh"
14 #include "translator.hh"
15
16 /**
17    A macro to automate administration of translators.
18 */
19 #define ADD_THIS_TRANSLATOR(T)                                          \
20   translator_listener_record *T::listener_list_;                        \
21   SCM T::static_description_ = SCM_EOL;                                 \
22   static void _ ## T ## _adder ()                                       \
23   {                                                                     \
24     T *t = new T;                                                       \
25     T::static_description_ = t->static_translator_description ();       \
26     scm_permanent_object (T::static_description_);                      \
27     add_translator (t);                                                 \
28   }                                                                     \
29   SCM T::translator_description () const                                \
30   {                                                                     \
31     return static_description_;                                         \
32   }                                                                     \
33   ADD_GLOBAL_CTOR (_ ## T ## _adder);
34
35 #define ADD_TRANSLATOR(classname, desc, grobs, accepted, read, write)   \
36   Drul_array< vector<Acknowledge_information> > classname::acknowledge_static_array_drul_;      \
37   IMPLEMENT_FETCH_PRECOMPUTABLE_METHODS (classname);                    \
38   ADD_THIS_TRANSLATOR (classname);                                      \
39   Engraver_void_function_engraver_grob_info                             \
40   classname::static_get_acknowledger (SCM sym)                          \
41   {                                                                     \
42     return generic_get_acknowledger (sym, &acknowledge_static_array_drul_[START]);      \
43   }                                                                     \
44   Engraver_void_function_engraver_grob_info                             \
45   classname::static_get_end_acknowledger (SCM sym)                              \
46   {                                                                     \
47     return generic_get_acknowledger (sym, &acknowledge_static_array_drul_[STOP]);       \
48   }                                                                     \
49   SCM                                                                   \
50   classname::static_translator_description () const                     \
51   {                                                                     \
52     return Translator::static_translator_description (grobs, desc, listener_list_, read, write); \
53   }
54
55 #define IMPLEMENT_FETCH_PRECOMPUTABLE_METHODS(T)                        \
56   void                                                                  \
57   T::fetch_precomputable_methods (Translator_void_method_ptr ptrs[])    \
58   {                                                                     \
59     ptrs[START_TRANSLATION_TIMESTEP] =                                  \
60       ((Translator_void_method_ptr) & T::start_translation_timestep ==  \
61        (Translator_void_method_ptr) & Translator::start_translation_timestep) \
62       ? 0                                                               \
63       : (Translator_void_method_ptr) & T::start_translation_timestep;   \
64                                                                         \
65     ptrs[STOP_TRANSLATION_TIMESTEP] =                                   \
66       ((Translator_void_method_ptr) & T::stop_translation_timestep == (Translator_void_method_ptr) & Translator::stop_translation_timestep) \
67       ? 0                                                               \
68       : (Translator_void_method_ptr) & T::stop_translation_timestep;    \
69                                                                         \
70     ptrs[PROCESS_MUSIC] =                                               \
71       ((Translator_void_method_ptr) & T::process_music == (Translator_void_method_ptr) & Translator::process_music) \
72       ? 0                                                               \
73       : (Translator_void_method_ptr) & T::process_music;                \
74                                                                         \
75     ptrs[PROCESS_ACKNOWLEDGED] =                                        \
76       ((Translator_void_method_ptr) & T::process_acknowledged == (Translator_void_method_ptr) & Translator::process_acknowledged) \
77       ? 0                                                               \
78       : (Translator_void_method_ptr) & T::process_acknowledged;         \
79   }
80
81 void add_acknowledger (Engraver_void_function_engraver_grob_info ptr,
82                        char const *func_name,
83                        vector<Acknowledge_information> *ack_array);
84
85 Engraver_void_function_engraver_grob_info
86 generic_get_acknowledger (SCM sym,
87                           vector<Acknowledge_information> const *ack_array);
88
89 #define ADD_ACKNOWLEDGER(CLASS, NAME)                                   \
90   void CLASS ## NAME ## _ack_adder ()                                   \
91   {                                                                     \
92     add_acknowledger ((Engraver_void_function_engraver_grob_info) & CLASS::acknowledge_ ## NAME, #NAME, &CLASS::acknowledge_static_array_drul_[START]); \
93   }                                                                     \
94   ADD_SCM_INIT_FUNC (CLASS ## NAME ## _ack_adder_initclass, CLASS ## NAME ## _ack_adder);
95
96 #define ADD_END_ACKNOWLEDGER(CLASS, NAME)                                       \
97   void CLASS ## NAME ## _end_ack_adder ()                                       \
98   {                                                                     \
99     add_acknowledger ((Engraver_void_function_engraver_grob_info) & CLASS::acknowledge_end_ ## NAME, #NAME, &CLASS::acknowledge_static_array_drul_[STOP]); \
100   }                                                                     \
101   ADD_SCM_INIT_FUNC (CLASS ## NAME ## _end_ack_adder_initclass, CLASS ## NAME ## _end_ack_adder);
102
103 /*
104   Implement the method cl::listen_##m, and make it listen to stream 
105   events of class m.
106  */
107 #define IMPLEMENT_TRANSLATOR_LISTENER(cl, m)            \
108 void                                                    \
109 cl :: _internal_declare_ ## m ()                        \
110 {                                                       \
111   static translator_listener_record r;                  \
112   add_translator_listener (&listener_list_, &r, _get_ ## m ## _listener, #m); \
113 }                                                       \
114                                                         \
115 ADD_SCM_INIT_FUNC (cl ## _declare_event_ ## m, cl::_internal_declare_ ## m);    \
116                                                         \
117 Listener                                                \
118 cl :: _get_ ## m ## _listener (void *me)                \
119 {                                                       \
120   cl *obj = (cl *) me;                                  \
121   return obj->GET_LISTENER (_listen_scm_ ## m);         \
122 }                                                       \
123                                                         \
124 IMPLEMENT_LISTENER (cl, _listen_scm_ ## m)              \
125 void                                                    \
126 cl::_listen_scm_ ## m (SCM sev)                         \
127 {                                                       \
128   Stream_event *ev = unsmob_stream_event (sev);         \
129   protect_event (sev);                                  \
130   listen_ ## m (ev);                                    \
131 }
132
133 /*
134   This helper is only meaningful inside listen_* methods.
135 */
136 extern bool internal_event_assignment (Stream_event **old_ev, Stream_event *new_ev, const char *function);
137 #define ASSIGN_EVENT_ONCE(o,n) internal_event_assignment (&o, n, __FUNCTION__)
138
139 #endif /* TRANSLATOR_ICC */