I am using a pattern like this, C++11:
class FooViewController {
void build() {
auto label = ...
network->doWork([] (const Result& r) {
label->setText(r.text);
});
}
}
FooViewController may deconstruct before doWork
completes, causing crashes. Looking at boost::signals2, I'm thinking of using boost::signals2::trackable
, which works great for my single threaded purposes, with the benefit that I do not have to hold and manage my connections directly, however I'm not sure how to get such a solution working with lambdas.
Here is a working lambda free version:
class Foo : public boost::signals2::trackable {
public:
void bar() {
printf("Fire!");
}
};
Usage:
boost::signals2::signal<void()> signal;
{
Foo test;
signal.connect(boost::bind(&Foo::bar, &test));
signal();
}
signal();
Output:
Fired!
// Note a second 'Fired!' did not occur, which is correct behavior
Two goals:
1-- I'd like to do something like:
signal.connect(boost::bind([] {
printf("Fired!");
}, &test));
Which would NOT call the lambda after test
is torn down.
2-- I do not want to directly manage the connection objects returned by .connect
.
Found the answer referencing trackable_test.cpp:
struct short_lived : public boost::signals2::trackable {
~short_lived() {
cout << "I'm dying...!" << std::endl;
}
};
void main() {
typedef boost::signals2::signal<void()> sig_type;
sig_type s1;
short_lived* shorty = new short_lived();
s1.connect(boost::bind<void>([](const short_lived*) {
cout << "Fire!" << std::endl;
}, shorty));
s1();
delete shorty;
s1();
}
Output
Fire!
I'm dying...!
...and a multiple params example (boost::bind refresher):
typedef boost::signals2::signal<void(int)> sig_type;
// ...same...
s1.connect(boost::bind<void>([](const short_lived*, int cannon) {
cout << "Fire " << cannon << "!" << std::endl;
}, shorty, _1));
s(1);
delete shorty;
s(2);
Output
Fire 1!
I'm dying...!