]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/include/callback.hh
Merge branch 'master' of /home/jcharles/GIT/Lily/. into translation
[lilypond.git] / lily / include / callback.hh
index b797baf062e7ba235ec9d8e8c793fd817d9b6973..671140673f5df0dd242c5ac883ff0b274128bb29 100644 (file)
@@ -44,10 +44,10 @@ class Callback_wrapper : public Simple_smob<Callback_wrapper>
   // this involves an adjustment of the this pointer from Smob_core to
   // the scope containing the callback.
   SCM (*trampoline_) (SCM, SCM);
-  Callback_wrapper (SCM (*trampoline) (SCM, SCM)) : trampoline_ (trampoline)
+  Callback_wrapper (SCM (*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 arg)
   {
@@ -66,5 +66,121 @@ public:
   }
 };
 
+class Callback2_wrapper : public Simple_smob<Callback2_wrapper>
+{
+  // See Callback_wrapper for the details.  Callback2_wrapper just
+  // supports an additional SCM argument as compared to
+  // Callback_wrapper but is otherwise identical.
+  SCM (*trampoline_) (SCM, SCM, SCM);
+  Callback2_wrapper (SCM (*trampoline) (SCM, SCM, SCM))
+    : trampoline_ (trampoline)
+  { } // Private constructor, use only in make_smob
+public:
+  LY_DECLARE_SMOB_PROC (&Callback2_wrapper::call, 3, 0, 0)
+  SCM call (SCM target, SCM arg1, SCM arg2)
+  {
+    return trampoline_ (target, arg1, arg2);
+  }
+
+  template <SCM (*trampoline) (SCM, SCM, SCM)>
+  static SCM make_smob ()
+  {
+    static SCM res =
+      scm_permanent_object (Callback2_wrapper (trampoline).smobbed_copy ());
+    return res;
+  }
+};
+
+class Callback0_wrapper : public Simple_smob<Callback0_wrapper>
+{
+  // See Callback_wrapper for the details.  Callback0_wrapper does not
+  // pass arguments but is otherwise identical to Callback_wrapper.
+  SCM (*trampoline_) (SCM);
+  Callback0_wrapper (SCM (*trampoline) (SCM))
+    : trampoline_ (trampoline)
+  { } // Private constructor, use only in make_smob
+public:
+  LY_DECLARE_SMOB_PROC (&Callback0_wrapper::call, 1, 0, 0)
+  SCM call (SCM target)
+  {
+    return trampoline_ (target);
+  }
+
+  template <SCM (*trampoline) (SCM)>
+  static SCM make_smob ()
+  {
+    static SCM res =
+      scm_permanent_object (Callback0_wrapper (trampoline).smobbed_copy ());
+    return res;
+  }
+  // Since there are no arguments at all, we might as well provide
+  // default trampolines
+  template <class T, SCM (T::*p)()>
+  static SCM trampoline (SCM target)
+  {
+    T *t = LY_ASSERT_SMOB (T, target, 1);
+    return (t->*p) ();
+  }
+
+  template <class T, void (T::*p)()>
+  static SCM trampoline (SCM target)
+  {
+    T *t = LY_ASSERT_SMOB (T, target, 1);
+    (t->*p) ();
+    return SCM_UNSPECIFIED;
+  }
+
+  template <class T, SCM (T::*p)()>
+  static SCM make_smob ()
+  {
+    return make_smob<trampoline<T, p> > ();
+  }
+
+  template <class T, void (T::*p)()>
+  static SCM make_smob ()
+  {
+    return make_smob<trampoline<T, p> > ();
+  }
+};
+
+// The following will usually be used unsmobbified, relying on its
+// constituents being protected independently.
+
+class Method_instance : public Simple_smob<Method_instance>
+{
+  SCM method_, instance_;
+public:
+  LY_DECLARE_SMOB_PROC (&Method_instance::call, 0, 0, 1)
+  SCM call (SCM rest)
+  {
+    return scm_apply_1 (method_, instance_, rest);
+  }
+
+  Method_instance (SCM method, SCM instance)
+    : method_ (method), instance_ (instance)
+  { }
+  Method_instance (SCM method, Smob_core *instance)
+    : method_ (method), instance_ (instance->self_scm ())
+  { }
+  SCM method () const { return method_; }
+  SCM instance () const { return instance_; }
+  SCM operator () () const
+  {
+    return scm_call_1 (method_, instance_);
+  }
+  SCM operator () (SCM arg) const
+  {
+    return scm_call_2 (method_, instance_, arg);
+  }
+  SCM operator () (SCM arg1, SCM arg2) const
+  {
+    return scm_call_3 (method_, instance_, arg1, arg2);
+  }
+  SCM mark_smob () const
+  {
+    scm_gc_mark (method_);
+    return instance_;
+  }
+};
 
 #endif