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() {
}
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 {
return helper_;
}
@ -52,6 +64,14 @@ void Unpack(QList<QGenericArgument>*) {}
} // 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) {
QTimer::singleShot(msec, receiver, slot);
}

View File

@ -150,6 +150,19 @@ class SharedClosure : public Closure<Args...> {
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
template <typename... Args>
@ -175,6 +188,11 @@ _detail::ClosureBase* NewClosure(
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 DoInAMinuteOrSo(QObject* receiver, const char* slot);

View File

@ -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);
}