Since runDispatchLoopUntil() is not in the class anymore, I was hoping there would be some example code somewhere that would show what to use as an alternative.
To be honest, it is unclear to me how to achieve the same functionality. Any hints or suggestions will be most welcome!
I edited my post above to mention Juce’s ThreadWithProgressWindow. However, even when using that, you can’t just have a local instance of the class in some stand alone function. The object needs to stay alive somewhere else for the duration of the thread.
This loop is blocking. Instead you call enterModalState() and move the code that should happen on returning into the lambda.
The main difference is that you need the AlertWindow as member variable.
I’m still fighting this issue. I will restate the problem below.
The original code displays an AlertWindow with a progress bar that increments as the render progresses. When the render completes the AlertWindow goes away and another AlertWindow shows the render success/fail status.
Below is the original code, using runDispatchLookUntil(). This code works as expected.
To move away from using runDispatchLoopUntil(), I have tried many things. The code below shows the AlertWindow with the progress bar, and it goes away when the render is complete. And, in fact, the render does complete! However, runTaskWithPrgressBar() never returns. So, the render status AlertWindow does not display until the DAW is being shut down.
Regarding runDispatchLoop, the documentation says :
Also, I am a bit surprised it works to create and show the AlertWindow in your thread’s run() method. Generally, the Juce GUI objects are not designed to be used in other threads than the GUI/main thread.
Yes, I saw the note about using runDispatchLoop() on application startup. In my limited knowledge, I did not know of another way to initiate the thread. How would the thread be launched?
I moved the AlertWindow to the thread’s run() method in an attempt to simplify everything. I realize that is probably sketchy. It can easily be moved back to runTaskWithProgressBar().
I am sure this has a relatively simple solution. I have tried a number of things, but I do not have sufficient knowledge of threads to find the right code.
Make your AlertWindow and progress into class data members, to ensure that they will live at least as long as the long-running task.
When job is ready to start, call enterModalState on the alert window, and set the progress to zero, all from the message thread.
Run the task on a background thread, querying the progress periodically. You can use MessageManager::callAsync to update the progress variable on the main thread.
Once the task is complete, you can use MessageManager::callAsync again to signal that the job is done, and launch a new AlertWindow.
Your main problem seems to be that you apparently want to have a stand alone function (the runTaskWithProgressBar) that would handle everything locally inside the function. But that’s not really feasible to do when following the new recommended async/non-modal model in Juce. You need to have some object that holds both the AlertWindow and the thread for the duration of the thread task. (You could maybe hack together something with heap allocations and self-destructing objects in order to run it all within a stand alone function, but that feels a bit iffy to do…)
Well, similar to another code snippet you posted before, the main issue is that your TaskRunner is declared locally in a method that returns immediately (on purpose). In that moment the TaskRunner will be destroyed and the Task is terminated.
The TaskRunner stops the task in the destructor, that’s why you don’t see progress.
I don’t know why the window doesn’t immediately disappears though.
Try making the TaskRunner a member of the parent class.
vcruntime140d.dll!memcpy_repmovs() Line 40
at D:\agent\_work\61\s\src\vctools\crt\vcruntime\src\string\amd64\memcpy.asm(40)
[Inline Frame] TheDAW.exe!juce::ArrayBase<tracktion_engine::Clip *,juce::DummyCriticalSection>::addArrayInternal(tracktion_engine::Clip * const *) Line 406
at C:\SDKs\JUCE\modules\juce_core\containers\juce_ArrayBase.h(406)
[Inline Frame] TheDAW.exe!juce::ArrayBase<tracktion_engine::Clip *,juce::DummyCriticalSection>::addArray(tracktion_engine::Clip * const *) Line 283
at C:\SDKs\JUCE\modules\juce_core\containers\juce_ArrayBase.h(283)
TheDAW.exe!juce::Array<tracktion_engine::Clip *,juce::DummyCriticalSection,0>::Array<tracktion_engine::Clip *,juce::DummyCriticalSection,0>(const juce::Array<tracktion_engine::Clip *,juce::DummyCriticalSection,0> & other) Line 71
at C:\SDKs\JUCE\modules\juce_core\containers\juce_Array.h(71)
TheDAW.exe!tracktion_engine::Renderer::Parameters::Parameters(const tracktion_engine::Renderer::Parameters & __that) Line 40
at C:\SDKs\TracktionEngine\modules\tracktion_engine\model\export\tracktion_Renderer.h(40)
TheDAW.exe!tracktion_engine::Renderer::RenderTask::RendererContext::RendererContext(tracktion_engine::Renderer::RenderTask & owner_, tracktion_engine::Renderer::Parameters & p, tracktion_engine::AudioNode * n, juce::AudioFormatWriter::ThreadedWriter::IncomingDataReceiver * sourceToUpdate_) Line 191
at C:\SDKs\TracktionEngine\modules\tracktion_engine\model\export\tracktion_Renderer.cpp(191)
[External Code]
TheDAW.exe!tracktion_engine::MessageThreadCallback::handleAsyncUpdate() Line 201
at C:\SDKs\TracktionEngine\modules\tracktion_engine\utilities\tracktion_AsyncFunctionUtils.h(201)
[Inline Frame] TheDAW.exe!juce::InternalMessageQueue::dispatchMessage(juce::MessageManager::MessageBase *) Line 198
at C:\SDKs\JUCE\modules\juce_events\native\juce_win32_Messaging.cpp(198)
TheDAW.exe!juce::InternalMessageQueue::dispatchMessages() Line 240
at C:\SDKs\JUCE\modules\juce_events\native\juce_win32_Messaging.cpp(240)
TheDAW.exe!juce::InternalMessageQueue::dispatchNextMessage(bool returnIfNoPendingMessages) Line 124
at C:\SDKs\JUCE\modules\juce_events\native\juce_win32_Messaging.cpp(124)
[Inline Frame] TheDAW.exe!juce::dispatchNextMessageOnSystemQueue(bool) Line 266
at C:\SDKs\JUCE\modules\juce_events\native\juce_win32_Messaging.cpp(266)
[Inline Frame] TheDAW.exe!juce::MessageManager::runDispatchLoop() Line 107
at C:\SDKs\JUCE\modules\juce_events\messages\juce_MessageManager.cpp(107)
[Inline Frame] TheDAW.exe!juce::JUCEApplicationBase::main() Line 262
at C:\SDKs\JUCE\modules\juce_events\messages\juce_ApplicationBase.cpp(262)
TheDAW.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 103
at C:\AAXProjects2\TheDAW\Source\Main.cpp(103)
[External Code]