I'm having a bit of an issue with C++ lambdas and variable capture (by reference). One lambda captures the variable to change its value while the other captures it to read the value. Everything is running on the same thread.
bool isRunning = true; // variable to be captured
Cedar::Input input;
input.registerOnQuit([&]()->void {
isRunning = false; // wrong address, value is constrained to lambda
});
Cedar::Platform platform;
platform.run([&](double t, double dt)->bool {
input.pump(); // internally fires the handler passed to registerOnQuit()
return isRunning; // correct address
});
If it's any help, internally the lambdas are being boxed into C callbacks using void pointers. However, I doubt that's where the problem lies because, essentially, the two lambdas are going through the exact same process and one works while the other doesn't.
// boxes the broken lambda
using OnQuit = std::function<void()>;
void registerOnQuit(OnQuit event) {
Cedar_Input_registerOnQuitC([](void *data)->void {
(*(OnQuit *)data)();
}, (void *)&event);
}
// boxes the working lambda
using Hook = std::function<bool(double, double)>;
void run(Hook hook) {
Cedar_Platform_runC([](double t, double dt, void *data)->bool {
return (*(Hook *)data)(t, dt);
}, (void *)&hook);
}
SOLUTION
I gave the Cedar::Input and Cedar::Platform classes fields to store a copy of the lambdas.
// fix to Cedar::Platform::run() is similar
using OnQuit = std::function<void()>;
void registerOnQuit(OnQuit event) {
m_onQuit = event;
Cedar_Input_registerOnQuitC([](void *data)->void {
(*(OnQuit *)data)();
}, (void *)&m_onQuit);
}