*/
#include "smobs.hh"
+#include "stream-event.hh"
// A listener is essentially any procedure accepting a single argument
// (namely an event). The class Listener (or rather a smobbed_copy of
//
// If you have a class member function
// void T::my_listen (SCM ev)
-// then Callback_wrapper::make_smob<&T::my_listen> ()
+// then Callback_wrapper::make_smob<T, SCM, &T::my_listen> ()
// will return an SCM function roughly defined as
// (lambda (target ev) (target->my_listen ev))
//
(t->*callback) (ev);
}
+ template <class T, void (T::*callback)(Stream_event *)>
+ static void trampoline (SCM target, SCM event)
+ {
+ // The same, but for callbacks for translator listeners which get
+ // the unpacked event which, in turn, gets protected previously
+
+ T *t = derived_unsmob<T> (target);
+ LY_ASSERT_DERIVED_SMOB (T, target, 1);
+ LY_ASSERT_SMOB (Stream_event, event, 2);
+
+ t->protect_event (event);
+ (t->*callback) (Stream_event::unsmob (event));
+ }
Callback_wrapper (void (*trampoline) (SCM, SCM)) : trampoline_ (trampoline)
{ } // Private constructor, use only in make_smob
// creation just once on the first call of make_smob. So we only
// get a single Callback_wrapper instance for each differently
// templated make_smob call.
- template <class T, void (T::*callback)(SCM)>
+ template <class T, class Arg, void (T::*callback)(Arg)>
static SCM make_smob ()
{
static SCM res = scm_permanent_object
}
};
-#define GET_LISTENER(cl, proc) get_listener (Callback_wrapper::make_smob<cl, &cl::proc> ())
+#define GET_LISTENER(cl, proc) get_listener (Callback_wrapper::make_smob<cl, SCM, &cl::proc> ())
#endif /* LISTENER_HH */
/* Should be private */ \
static void _internal_declare_ ## m (); \
private: \
- static Listener _get_ ## m ## _listener (void *, SCM); \
-void _listen_scm_ ## m (SCM);
+ static Listener _get_ ## m ## _listener (void *, SCM);
#define DECLARE_ACKNOWLEDGER(x) public : void acknowledge_ ## x (Grob_info); protected:
#define DECLARE_END_ACKNOWLEDGER(x) public : void acknowledge_end_ ## x (Grob_info); protected:
protected: // should be private.
Context *daddy_context_;
void protect_event (SCM ev);
+ friend class Callback_wrapper;
virtual void derived_mark () const;
static void add_translator_listener (translator_listener_record **listener_list,
translator_listener_record *r,
\
ADD_SCM_INIT_FUNC (cl ## _declare_event_ ## m, cl::_internal_declare_ ## m); \
\
-Listener \
- cl :: _get_ ## m ## _listener (void *me, SCM unused) \
-{ \
- cl *obj = (cl *) me; \
- (void) unused; \
- return obj->GET_LISTENER (cl, _listen_scm_ ## m); \
-} \
- \
-void \
-cl::_listen_scm_ ## m (SCM sev) \
-{ \
- Stream_event *ev = Stream_event::unsmob (sev); \
- protect_event (sev); \
- listen_ ## m (ev); \
-}
+ Listener \
+ cl :: _get_ ## m ## _listener (void *me, SCM) \
+ { \
+ cl *obj = (cl *) me; \
+ return obj->get_listener \
+ (Callback_wrapper::make_smob<cl, Stream_event *, &cl::listen_ ## m> ()); \
+ }
#endif /* TRANSLATOR_ICC */