X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Finclude%2Flistener.hh;h=b9042ba301ac79f715b197ed22d159bbb47943df;hb=36fba3138858ee42ba3f03e3de0efa1d1f49d147;hp=27e7d85b719d70eb8f8d5aa101f60720ea3baeb5;hpb=f947f7e126ccaaea212a7e65ed458a05555c771e;p=lilypond.git diff --git a/lily/include/listener.hh b/lily/include/listener.hh index 27e7d85b71..b9042ba301 100644 --- a/lily/include/listener.hh +++ b/lily/include/listener.hh @@ -74,8 +74,8 @@ classes derived from Smob<...>. */ +#include "callback.hh" #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 @@ -125,80 +125,18 @@ public: return *unchecked_unsmob (a) == *unchecked_unsmob (b) ? SCM_BOOL_T : SCM_BOOL_F; } -}; -// A callback wrapper creates a Scheme-callable version of a -// non-static class member function callback which you can call with a -// class instance and an event. -// -// If you have a class member function -// void T::my_listen (SCM ev) -// then Callback_wrapper::make_smob () -// will return an SCM function roughly defined as -// (lambda (target ev) (target->my_listen ev)) -// -// The setup is slightly tricky since the make_smob quasi-constructor -// call is a template function templated on the given callback, and so -// is the trampoline it uses for redirecting the callback. The class -// itself, however, is not templated as that would create a wagonload -// of SCM types. - -class Callback_wrapper : public Simple_smob -{ - // We use an ordinary function pointer pointing to a trampoline - // function (templated on the callback in question) instead of - // storing a member function pointer to a common base class like - // Smob_core. The additional code for the trampolines is negligible - // and the performance implications of using member function - // pointers in connection with inheritance are somewhat opaque as - // this involves an adjustment of the this pointer from Smob_core to - // the scope containing the callback. - void (*trampoline_) (SCM, SCM); template - static void trampoline (SCM target, SCM ev) + static SCM trampoline (SCM target, SCM ev) { T *t = unsmob (target); LY_ASSERT_SMOB (T, target, 1); (t->*callback) (ev); - } - template - 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 = unsmob (target); - LY_ASSERT_SMOB (T, target, 1); - LY_ASSERT_SMOB (Stream_event, event, 2); - - t->protect_event (event); - (t->*callback) (unsmob (event)); - } - - Callback_wrapper (void (*trampoline) (SCM, SCM)) : trampoline_ (trampoline) - { } // Private constructor, use only in make_smob -public: - static const char * const type_p_name_; // = 0 - LY_DECLARE_SMOB_PROC (&Callback_wrapper::call, 2, 0, 0) - SCM call (SCM target, SCM ev) - { - trampoline_ (target, ev); - return SCM_UNSPECIFIED; - } - // Callback wrappers are for an unchanging entity, so we do the Lisp - // 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 - static SCM make_smob () - { - static SCM res = scm_permanent_object - (Callback_wrapper (trampoline).smobbed_copy ()); - return res; + return SCM_UNDEFINED; } }; -#define GET_LISTENER(cl, proc) get_listener (Callback_wrapper::make_smob ()) +#define GET_LISTENER(cl, proc) get_listener (Callback_wrapper::make_smob > ()) #endif /* LISTENER_HH */