Refactoring for non modal loops

I have been attempting to remove the modal loops from my DAW’s rendering code. The code below is the old code that has been working great for a couple of years.

void runTaskWithProgressBar(te::ThreadPoolJobWithProgress& t) override
{
	double progress{ 0.0 };
	TaskRunner runner(t, progress);

	AlertWindow w("Rendering", {}, AlertWindow::NoIcon);
	w.addProgressBarComponent(progress);
	w.setVisible(true);

	while (runner.isThreadRunning())
		if (!MessageManager::getInstance()->runDispatchLoopUntil(10))
			break;
}

//==============================================================================
struct TaskRunner : public Thread
{
	TaskRunner(te::ThreadPoolJobWithProgress& t, double& prog) : Thread(t.getJobName()), task(t), progress(prog)
	{
		startThread();
	}

	~TaskRunner()
	{
		task.signalJobShouldExit();
		while(!waitForThreadToExit(0));
	}

	void run() override
	{
		while (!threadShouldExit())
		{
			progress = task.getCurrentTaskProgress();
			if (task.runJob() == ThreadPoolJob::jobHasFinished)
				break;
		}
	}
	te::ThreadPoolJobWithProgress& task;
	double& progress;
};

In my refactoring effort, I have been trying the following (as well as a number of other things) and I am getting nowhere. This seems to simply freeze, as though the task never runs, and my knowledge of threads and tasks is too limited to know what to try to get it running.

void runTaskWithProgressBar(te::ThreadPoolJobWithProgress& t) override
{
	double progress{ 0.0 };
	TaskRunner taskRunner(t, progress);

	AlertWindow w("Rendering", {}, AlertWindow::NoIcon);
	w.addProgressBarComponent(progress);
	w.setVisible(true);

	while (taskRunner.isThreadRunning());
}

//==============================================================================
struct TaskRunner : public Thread
{
	TaskRunner(te::ThreadPoolJobWithProgress& t, double& prog) : Thread(t.getJobName()), task(t), progress(prog)
	{
		startThread();
	}

	~TaskRunner()
	{
		task.signalJobShouldExit();
		waitForThreadToExit(10000);
	}

	void run() override
	{
		while (!threadShouldExit())
		{
			progress = task.getCurrentTaskProgress();
			if (task.runJob() == ThreadPoolJob::jobHasFinished)
				break;
		}
	}
	te::ThreadPoolJobWithProgress& task;
	double& progress;
};

Any help is most appreciated!

Thank you!

See my reply here: Replacement for runDispatchLoopUntil()? - #23 by dave96

I don’t think this approach will work because you’re just trying to do the old thing without pumping the message loop so all the various UI events won’t get delivered.

For others arriving here, the code base needs quite a bit more refactoring before modal loops can be abandoned.

You can still compile by using the preprocessor value JUCE_MODAL_LOOPS_PERMITTED = 1 for the time being.

1 Like