Replacement for runDispatchLoopUntil()?

Maybe @dave96 or @RolandMR can answer that. They know at least the tracktion part.

It might be a good idea to change the category to #tracktion-engine or create a new topic in that category.

Thank you. I will probably do that after trying a few more things.

It is frustrating because it works just fine as a modal dialog, and has been for a couple of years. But I am refactoring my code to remove modal loops and this is one of the last ones to figure out.

I appreciate everyoneā€™s suggestions!

I imagine the ThreadPoolJobWithProgress is getting deleted when the runTaskWithProgressBar function returns?

Do you have to make this non-modal now?
I appreciate modal loops are bad and we should not be using them in new code but this codebase has relied on them for 20 years so itā€™s not simple to just remove them. Weā€™ll probably need to add alternative methods that request a task to be started and provide a callback to be notified when it ends.

There might be some way to hack it in the mean time but I donā€™t really have the bandwidth to look in to it right now Iā€™m afraid.

I can compile with the preprocessor value JUCE_MODAL_LOOPS_PERMITTED = 1 for the time being. I was just trying to be up-to-date.

As always, thank you for your help!

Iā€™m also stuck with this problem for different reasons - unit testing.

TEST_CASE("Testing async calls")
{
    juce::ScopedJuceInitialiser_GUI gui;
    int x = 0;
    juce::MessageManager::callAsync([&x = x] { x = 3; });

    //This following section used to be:
    //juce::MessageManager::getInstance()->runDispatchLoopUntil(1);

    //I tried to replace it with:
    while(x == 0)
    {
        juce::MessageManager::getInstance()->runDispatchLoop();
        juce::Thread::sleep(1);
        //But, that loop never ends...
    }

    REQUIRE(x == 3);
}

Any ideas?

My understanding is that there is no simple way to achieve the functionality of juce::MessageManager::getInstance()->runDispatchLoopUntil(1);, so you must use that, along with the JUCE_MODAL_LOOPS_PERMITTED = 1 flag for the time being.

1 Like

Thank you!
Hopefully that gets fixed one day so I can also turn the modal loops off. :slight_smile:

I just ran into a similar issue with some unit tests. This pattern seems to be working for me so far:

TEST_CASE("Testing async calls")
{
    juce::ScopedJuceInitialiser_GUI gui;
    int x = 0;
    juce::MessageManager::callAsync([&x = x] { x = 3; });

    //This following section used to be:
    //juce::MessageManager::getInstance()->runDispatchLoopUntil(1);

    //Replacing it with...
    juce::Timer::callAfterDelay (1, [=]
    {
        juce::MessageManager::getInstance()->stopDispatchLoop();
    });
    juce::MessageManager::getInstance()->runDispatchLoop();

    REQUIRE(x == 3);
}
3 Likes

Just tested and the above example isnā€™t working for me on Mac unfortunately. The message loop isnā€™t actually running when calling runDispatchLoop() so in the above example x remains at 0.

Can anyone from the JUCE team reply if thereā€™s a way to manually do that without modal loops?

Yeah same here, works on Linux, not on my Mac. It seems [NSApp run] is not starting the loop properly, with NSApp being nil. This is problematic for me as I need to run unit tests in this way. If anyone has updates let me know