diff --git a/libs/pbd/pbd/closure.h b/libs/pbd/pbd/closure.h index e5de2c10da..4151a347d2 100644 --- a/libs/pbd/pbd/closure.h +++ b/libs/pbd/pbd/closure.h @@ -86,7 +86,7 @@ struct Closure { /* will crash if impl is unset */ void operator() () const { (*impl)(); } -private: + protected: ClosureBaseImpl* impl; }; @@ -154,6 +154,46 @@ Closure closure (T& t, void (T::*m)(A1,A2), A1 a1, A2 a2) { return Closure (new template Closure closure (T& t, void (T::*m)(A1, A2, A3), A1 a1, A2 a2, A3 a3) { return Closure (new ClosureImpl3(t,m , a1, a2, a3)); } +/*---------*/ + +template +struct CTClosureBaseImpl : ClosureBaseImpl { + CTClosureBaseImpl() {} + + virtual void operator() () { operator() (A()); } + virtual void operator() (A arg) = 0; + +protected: + virtual ~CTClosureBaseImpl() { } +}; + +template +struct CTClosure : public Closure { + CTClosure() {} + CTClosure (CTClosureBaseImpl* i) : Closure (i) {} + CTClosure (const CTClosure& other) : Closure (other) {} + + /* will crash if impl is unset */ + void operator() (A arg) const { (*(dynamic_cast*> (impl))) (arg); } +}; + +template +struct CTClosureImpl1 : public CTClosureBaseImpl +{ + CTClosureImpl1 (T& obj, void (T::*m)(A)) + : object (obj), method (m) {} + void operator() (A call_time_arg) { (object.*method) (call_time_arg); } + + private: + T& object; + void (T::*method)(A); +}; + +/* functor wraps a method that takes 1 arg provided at call-time */ + +template +CTClosure closure (T& t, void (T::*m)(A)) { return CTClosure (new CTClosureImpl1(t,m)); } + } #endif /* __pbd_closure_h__ */