Not sure how anyone is using callAfterDelay().
In juce 8 the lambdaInvoker deletes itself upon first timerCallback(), and the destructor is supposed to stopTimer(). But in practice this never happens and the function is repeatedly called forever.
Here’s the fix which worked for me. Note that the stopTimer() MUST come before the NullCheckedInvocation::invoke():
struct LambdaInvoker final : private Timer,
private DeletedAtShutdown
{
LambdaInvoker (int milliseconds, std::function<void()> f)
: function (std::move (f))
{
startTimer (milliseconds);
}
~LambdaInvoker() final
{
stopTimer();
}
void timerCallback() final
{
stopTimer(); /// NEEDED OR TIMER REPEATEDLY FIRES
NullCheckedInvocation::invoke (function);
delete this;
}
std::function<void()> function;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LambdaInvoker)
};
I am unable to repro this issue, and were trying out a couple of things including twiddling the internal timeout values and making sure the lambda runs for a long time. So just to be sure
Is the issue present on develop?
Can you perhaps share an example project reproducing the issue?
If not, is there anything unusual about the code in question? Does the lambda run for a long time? How many milliseconds are you using for callAfterDelay?
This works for me. The big question is… what code is in the lambda you want to call after a delay?
Can your code potentially never finish or take longer than the delay time?
the callable code includes an alert via showOkCancelBox() which means execution time of the lambda is longer than the “after delay” value (1sec in this case).
So I guess it has the opportunity to fire another timer callback.
Yes, because you’re still blocking the message thread. By default, the #define disabled them, and the comment discourages their use. It’s only kept as an option for backward compatibility with old code. New code should not use modal anything.
Sure, but I believe that around here the word has a more specific meaning, what with the process of convincing everyone to stop using modal dialogs that block the message thread.