Support member function pointers in Closure.

Bonus: type-safe slots
This commit is contained in:
John Maguire 2012-12-13 16:27:00 +01:00
parent 94f76a9d08
commit 020f08438f
3 changed files with 40 additions and 5 deletions

View File

@ -213,6 +213,15 @@ _detail::ClosureBase* NewClosure(
return NewClosure(sender, signal, boost::bind(callback, args...));
}
template <typename T, typename... Args>
_detail::ClosureBase* NewClosure(
QObject* sender,
const char* signal,
T* receiver, void (T::*callback)(Args...),
const Args&... args) {
return NewClosure(sender, signal, boost::bind(callback, receiver, args...));
}
void DoAfter(QObject* receiver, const char* slot, int msec);
void DoInAMinuteOrSo(QObject* receiver, const char* slot);

View File

@ -44,8 +44,7 @@ void OAuthenticator::StartAuthorisation(
url.addQueryItem("scope", scope);
NewClosure(server, SIGNAL(Finished()),
this, SLOT(RedirectArrived(LocalRedirectServer*,QUrl)),
server, redirect_url);
this, &OAuthenticator::RedirectArrived, server, redirect_url);
QDesktopServices::openUrl(url);
}

View File

@ -78,7 +78,7 @@ TEST(ClosureTest, ClosureWorksWithFunctionPointers) {
bool called = false;
int question = 42;
int answer = 0;
_detail::ClosureBase* closure = NewClosure(
NewClosure(
&sender, SIGNAL(Emitted()),
&Foo, &called, question, &answer);
EXPECT_FALSE(called);
@ -93,7 +93,7 @@ TEST(ClosureTest, ClosureWorksWithStandardFunctions) {
int question = 42;
int answer = 0;
std::tr1::function<void(bool*,int,int*)> callback(&Foo);
_detail::ClosureBase* closure = NewClosure(
NewClosure(
&sender, SIGNAL(Emitted()),
callback, &called, question, &answer);
EXPECT_FALSE(called);
@ -102,11 +102,38 @@ TEST(ClosureTest, ClosureWorksWithStandardFunctions) {
EXPECT_EQ(question, answer);
}
namespace {
class Bar {
public:
explicit Bar(int a) : foo_(a) {}
void Foo(int* answer) {
*answer = foo_;
}
private:
int foo_;
};
}
TEST(ClosureTest, ClosureWorksWithMemberFunctionPointers) {
TestQObject sender;
Bar receiver(42);
int q = 1;
NewClosure(
&sender, SIGNAL(Emitted()),
&receiver, &Bar::Foo, &q);
EXPECT_EQ(1, q);
sender.Emit();
EXPECT_EQ(42, q);
}
#ifdef HAVE_LAMBDAS
TEST(ClosureTest, ClosureCallsLambda) {
TestQObject sender;
bool called = false;
_detail::ClosureBase* closure = NewClosure(
NewClosure(
&sender, SIGNAL(Emitted()),
[&called] () { called = true; });
EXPECT_FALSE(called);