From 11f664083ad98eed2ed1af768093aa0560d474b2 Mon Sep 17 00:00:00 2001 From: John Maguire Date: Mon, 26 Nov 2012 09:41:26 +0100 Subject: [PATCH] Add support for standard function callbacks in NewClosure (including C++11 lambdas). --- ext/libclementine-common/core/closure.cpp | 20 ++++++++++++++++++++ ext/libclementine-common/core/closure.h | 18 ++++++++++++++++++ tests/closure_test.cpp | 11 +++++++++++ 3 files changed, 49 insertions(+) diff --git a/ext/libclementine-common/core/closure.cpp b/ext/libclementine-common/core/closure.cpp index eccc81ea7..e2c27c13f 100644 --- a/ext/libclementine-common/core/closure.cpp +++ b/ext/libclementine-common/core/closure.cpp @@ -30,6 +30,18 @@ ClosureBase::ClosureBase(ObjectHelper* helper) ClosureBase::~ClosureBase() { } +CallbackClosure::CallbackClosure( + QObject* sender, + const char* signal, + std::function callback) + : ClosureBase(new ObjectHelper(sender, signal, this)), + callback_(callback) { +} + +void CallbackClosure::Invoke() { + callback_(); +} + ObjectHelper* ClosureBase::helper() const { return helper_; } @@ -52,6 +64,14 @@ void Unpack(QList*) {} } // namespace _detail +_detail::ClosureBase* NewClosure( + QObject* sender, + const char* signal, + std::function callback) { + return new _detail::CallbackClosure( + sender, signal, callback); +} + void DoAfter(QObject* receiver, const char* slot, int msec) { QTimer::singleShot(msec, receiver, slot); } diff --git a/ext/libclementine-common/core/closure.h b/ext/libclementine-common/core/closure.h index 59d05a7be..ca85ce91d 100644 --- a/ext/libclementine-common/core/closure.h +++ b/ext/libclementine-common/core/closure.h @@ -150,6 +150,19 @@ class SharedClosure : public Closure { QSharedPointer data_; }; +class CallbackClosure : public ClosureBase { + public: + CallbackClosure( + QObject* sender, + const char* signal, + std::function callback); + + virtual void Invoke(); + + private: + std::function callback_; +}; + } // namespace _detail template @@ -175,6 +188,11 @@ _detail::ClosureBase* NewClosure( sender, signal, receiver, slot, args...); } +_detail::ClosureBase* NewClosure( + QObject* sender, + const char* signal, + std::function callback); + void DoAfter(QObject* receiver, const char* slot, int msec); void DoInAMinuteOrSo(QObject* receiver, const char* slot); diff --git a/tests/closure_test.cpp b/tests/closure_test.cpp index 8d26ccfad..486a6d75b 100644 --- a/tests/closure_test.cpp +++ b/tests/closure_test.cpp @@ -62,3 +62,14 @@ TEST(ClosureTest, ClosureDoesNotCrashWithSharedPointerSender) { ASSERT_EQ(1, spy->count()); EXPECT_TRUE(closure.isNull()); } + +TEST(ClosureTest, ClosureCallsLambda) { + TestQObject sender; + bool called = false; + _detail::ClosureBase* closure = NewClosure( + &sender, SIGNAL(Emitted()), + [&called] () { called = true; }); + EXPECT_FALSE(called); + sender.Emit(); + EXPECT_TRUE(called); +}