Add support for standard function callbacks in NewClosure (including C++11 lambdas).

This commit is contained in:
John Maguire 2012-11-26 09:41:26 +01:00
parent 40081a97e7
commit 11f664083a
3 changed files with 49 additions and 0 deletions

View File

@ -30,6 +30,18 @@ ClosureBase::ClosureBase(ObjectHelper* helper)
ClosureBase::~ClosureBase() { ClosureBase::~ClosureBase() {
} }
CallbackClosure::CallbackClosure(
QObject* sender,
const char* signal,
std::function<void()> callback)
: ClosureBase(new ObjectHelper(sender, signal, this)),
callback_(callback) {
}
void CallbackClosure::Invoke() {
callback_();
}
ObjectHelper* ClosureBase::helper() const { ObjectHelper* ClosureBase::helper() const {
return helper_; return helper_;
} }
@ -52,6 +64,14 @@ void Unpack(QList<QGenericArgument>*) {}
} // namespace _detail } // namespace _detail
_detail::ClosureBase* NewClosure(
QObject* sender,
const char* signal,
std::function<void()> callback) {
return new _detail::CallbackClosure(
sender, signal, callback);
}
void DoAfter(QObject* receiver, const char* slot, int msec) { void DoAfter(QObject* receiver, const char* slot, int msec) {
QTimer::singleShot(msec, receiver, slot); QTimer::singleShot(msec, receiver, slot);
} }

View File

@ -150,6 +150,19 @@ class SharedClosure : public Closure<Args...> {
QSharedPointer<T> data_; QSharedPointer<T> data_;
}; };
class CallbackClosure : public ClosureBase {
public:
CallbackClosure(
QObject* sender,
const char* signal,
std::function<void()> callback);
virtual void Invoke();
private:
std::function<void()> callback_;
};
} // namespace _detail } // namespace _detail
template <typename... Args> template <typename... Args>
@ -175,6 +188,11 @@ _detail::ClosureBase* NewClosure(
sender, signal, receiver, slot, args...); sender, signal, receiver, slot, args...);
} }
_detail::ClosureBase* NewClosure(
QObject* sender,
const char* signal,
std::function<void()> callback);
void DoAfter(QObject* receiver, const char* slot, int msec); void DoAfter(QObject* receiver, const char* slot, int msec);
void DoInAMinuteOrSo(QObject* receiver, const char* slot); void DoInAMinuteOrSo(QObject* receiver, const char* slot);

View File

@ -62,3 +62,14 @@ TEST(ClosureTest, ClosureDoesNotCrashWithSharedPointerSender) {
ASSERT_EQ(1, spy->count()); ASSERT_EQ(1, spy->count());
EXPECT_TRUE(closure.isNull()); 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);
}