#ifndef TRANSLATOR_ICC
#define TRANSLATOR_ICC
+#include "listener.hh"
#include "std-vector.hh"
#include "translator.hh"
A macro to automate administration of translators.
*/
#define ADD_THIS_TRANSLATOR(T) \
+ translator_listener_record *T::listener_list_; \
SCM T::static_description_ = SCM_EOL; \
static void _ ## T ## _adder () \
{ \
ADD_GLOBAL_CTOR (_ ## T ## _adder);
#define ADD_TRANSLATOR(classname, desc, grobs, accepted, read, write) \
- vector<Acknowledge_information> classname::acknowledge_static_array_; \
+ Drul_array< vector<Acknowledge_information> > classname::acknowledge_static_array_drul_; \
IMPLEMENT_FETCH_PRECOMPUTABLE_METHODS (classname); \
ADD_THIS_TRANSLATOR (classname); \
Engraver_void_function_engraver_grob_info \
classname::static_get_acknowledger (SCM sym) \
{ \
- return generic_get_acknowledger (sym, &acknowledge_static_array_); \
+ return generic_get_acknowledger (sym, &acknowledge_static_array_drul_[START]); \
+ } \
+ Engraver_void_function_engraver_grob_info \
+ classname::static_get_end_acknowledger (SCM sym) \
+ { \
+ return generic_get_acknowledger (sym, &acknowledge_static_array_drul_[STOP]); \
} \
SCM \
classname::static_translator_description () const \
#define ADD_ACKNOWLEDGER(CLASS, NAME) \
void CLASS ## NAME ## _ack_adder () \
{ \
- add_acknowledger ((Engraver_void_function_engraver_grob_info) & CLASS::acknowledge_ ## NAME, #NAME, &CLASS::acknowledge_static_array_); \
+ add_acknowledger ((Engraver_void_function_engraver_grob_info) & CLASS::acknowledge_ ## NAME, #NAME, &CLASS::acknowledge_static_array_drul_[START]); \
} \
ADD_SCM_INIT_FUNC (CLASS ## NAME ## _ack_adder_initclass, CLASS ## NAME ## _ack_adder);
+#define ADD_END_ACKNOWLEDGER(CLASS, NAME) \
+ void CLASS ## NAME ## _end_ack_adder () \
+ { \
+ add_acknowledger ((Engraver_void_function_engraver_grob_info) & CLASS::acknowledge_end_ ## NAME, #NAME, &CLASS::acknowledge_static_array_drul_[STOP]); \
+ } \
+ ADD_SCM_INIT_FUNC (CLASS ## NAME ## _end_ack_adder_initclass, CLASS ## NAME ## _end_ack_adder);
-#endif /* TRANSLATOR_ICC */
+/*
+ Implement the method cl::listen_##m, and make it listen to stream
+ events of class m.
+ */
+#define IMPLEMENT_TRANSLATOR_LISTENER(cl, m) \
+void \
+cl :: _internal_declare_ ## m () \
+{ \
+ static translator_listener_record r; \
+ add_translator_listener (&listener_list_, &r, _get_ ## m ## _listener, #m); \
+} \
+ \
+ADD_SCM_INIT_FUNC (cl ## _declare_event_ ## m, cl::_internal_declare_ ## m); \
+ \
+Listener \
+cl :: _get_ ## m ## _listener (void *me) \
+{ \
+ cl *obj = (cl *) me; \
+ return obj->GET_LISTENER (_listen_scm_ ## m); \
+} \
+ \
+IMPLEMENT_LISTENER (cl, _listen_scm_ ## m) \
+void \
+cl::_listen_scm_ ## m (SCM sev) \
+{ \
+ Stream_event *ev = unsmob_stream_event (sev); \
+ protect_event (sev); \
+ listen_ ## m (ev); \
+}
+/*
+ This helper is only meaningful inside listen_* methods.
+*/
+extern bool internal_event_assignment (Stream_event **old_ev, Stream_event *new_ev, const char *function);
+#define ASSIGN_EVENT_ONCE(o,n) internal_event_assignment (&o, n, __FUNCTION__)
+
+#endif /* TRANSLATOR_ICC */