Background download Thread Progress Windows problem


#6

If you don’t want a blocking window then this isn’t really the right class to use, it doesn’t add very much… Typically if you just have a background task that isn’t blocking, you’d just run it on a thread and show your own UI somewhere to give the user some feedback. Not sure how ThreadWithProgressWindow could help very much with that.


#7

Well, instead of it being a modal dialog window, it could just be a component that could be added to a GUI or to the desktop…


#8

My bad, I overlooked in the docs:

A thread that automatically pops up a modal dialog box with a progress bar

So launchThread will allow the message thread to run, but intentionally blocks user interaction.

The class to look at is probably ThreadPoolJob.

Just adding, have a look at this talk:
https://skillsmatter.com/skillscasts/11632-audio-developers-meet-up-april

…just realised, that the page doesn’t show the name, it was given by Dave Rowland


#9

Thank you all for help. I decided to create a new window with ProgressBar object. Is it a simple way to increment in loop through ProgressBar object to refresh progress variable without creating a new instance each time? I am looking for function similar to setProgress in ThreadProgressWindow.


#10

ProgressBar takes in a reference to the floating point number that is used as the progress amount. Then you can just change the referred to number to get the progress bar to change. (Obviously that number has to be a member variable somewhere so that it sticks around and doesn’t cause a dangling reference in the ProgressBar.)


#11

Hmm… I am incrementing progress value in a loop but it seems it passes only last value of progress. Most likely I am doing something wrong. Sample of code below:

class MainContentComponent : public URL,
							public Component,
							public Thread
{
public:
	MainContentComponent() : Thread("Background Download Thread"), pb(progress)
	{
	
	addAndMakeVisible(&downloadButton);
	downloadButton.setButtonText("Select folder to download file from URL...");
	downloadButton.onClick = [this] { downloadButtonClicked(); };
	
	addAndMakeVisible(pb);

	progress = 0.0;		

	setSize(300, 200);
}

~MainContentComponent()
{
	stopThread(3000);
}

void resized() override
{
	downloadButton.setBounds(10, 10, getWidth() - 20, 20);
	//Other buttons
	pb.setBounds(10, 130, getWidth() - 20, 20);
}
	
private:
	void downloadButtonClicked()
	{
		FileChooser chooser("Select path");
		(File::getCurrentWorkingDirectory());

	if (chooser.browseForDirectory())
	{
		//....			
		startThread();
	}
}

void run() override
{
	while (!threadShouldExit())
	{
		URL fileUrl("http://www.samplewebsite.com/file.mp3");

		String filename = fileUrl.getFileName();
		ScopedPointer<InputStream> fileStream = fileUrl.createInputStream(false);

		// Reading file into buffer...

		FileOutputStream out(localfile);

		double j = mem.getSize();

		for (int i = 0; i < mem.getSize(); ++i)
		{
			out.writeByte(mem[i]);
			progress += i / j; // HERE PROGRESSBAR SHOULD MOVE
		}

		//...

		signalThreadShouldExit();
	}
}

//==========================================================================
TextButton downloadButton;

ProgressBar pb;
double progress;

File chosenPath;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainContentComponent)

};


#12

Have you checked your progress calculation ends up producing floating point numbers between 0.0 and 1.0?


#13

I don’t see in your code, how a change in the progress variable would be either forwarded to a progressBar/Slider or a repaint is scheduled…


#14

The ProgressBar has an internal timer that does the repaints. (And it takes the progress variable as a reference.)


#15

I see, got it. Never used ProgressBar. I should read first :wink:


#16

There’s also the really annoying possibility the compiler decides to optimize the progress calculation away, are you testing with a debug or release build?


#17

In use with separate method i.e.

void ButtonClicked() {	progress += 0.1; }

progressBar is moving after each button click. When i try to loop this (from 0.0 to 1.0) it ends with 100%.


#18

Maybe the code is just so fast the progress bar never ends up showing anything else but the 100%? (The repaint timer in the progress bar doesn’t run at super fast intervals if I recall right.)


#19

I tested with Time::waitForMillisecondCounter(400); and same result. It seems that progress value is monitored only after it exits out of the range of function. I am wondering how it can be useful with such limitations.


#20

Thread::sleep seems more appropriate in this situation


#21

As a test (and only a test) try putting this in after you increment the progress value:

MessageManager::getInstance()->runDispatchLoopUntil (200);

Rail


#22

The problem is you probably have not initialized ‘progress = 0’. Then you’re adding values to ‘progress’ in the run() but until ‘progress’ reaches 1% you will wait for eternity.

Edit: Ah, sorry, I see it’s in the constructor. I’ve got almost identical code in my apps and it works perfectly fine.


#23
progress += i / j;

maybe you meant

progress = i / j;

#24

Shouldn‘t i be converted to float first before dividing? Otherwise it will return 0 al the time. Or am I wrong here?

Edit: sorry, j is double so never mind :wink:


#25

Personally I’d have written it with an explicit cast to double, just to make sure that’s clear to a reader, e.g.

progress = currentItem / (double) totalNumItems;