GtkD code review - How to update a progressbar using data sharing concurrency
    Kagamin 
    spam at here.lot
       
    Sun Jun 21 11:41:33 UTC 2020
    
    
  
Not sure how much synchronization do you want to do.
import gio.Application : GioApplication = Application;
import gtk.Application : Application;
import gtk.ApplicationWindow : ApplicationWindow;
import gtk.ProgressBar : ProgressBar;
import glib.Timeout : Timeout;
import gtkc.gtktypes : GApplicationFlags, GPriority;
shared class Downloader
{
	import core.atomic;
	string[] links = [`link1`, `link2`, `link3`, `link4`];
	private size_t completed = 0;
	size_t count()
	{
		return atomicLoad(completed);
	}
	void increment()
	{
		atomicOp!"+="(completed, 1);
	}
	static void start(shared Downloader downloader)
	{
		import std.parallelism : parallel;
		import core.thread : Thread, seconds;
		{
			// emulate HTTP response overhead;
			Thread.sleep(seconds(2));
		}
		{
			// emulate random Download time
			import std.random : Random, uniform;
			auto rnd = Random(4361);
			foreach (ref link; downloader.links.parallel())
			{
				Thread.sleep(uniform(0, 6, rnd).seconds());
				downloader.increment();
			}
		}
	}
}
class ProgressIndicatorBar : ProgressBar
{
	this()
	{
		super.setShowText(true);
		super.setPulseStep(0.2);
	}
}
class PrimaryWindow : ApplicationWindow
{
	const int width = 320, height = 100;
	ProgressIndicatorBar pib;
	this(Application app)
	{
		super(app);
		super.setSizeRequest(width, height);
		scope (success)
			super.showAll();
		pib = new ProgressIndicatorBar();
		scope (success)
			add(pib);
		shared downloader = new shared Downloader();
		import std.parallelism : task;
		auto downloadTask = task!(Downloader.start)(downloader);
		downloadTask.executeInNewThread();
		auto timeout = new Timeout(100, delegate bool() {
			const long completed=downloader.count, 
total=downloader.links.length;
			if (completed < total)
			{
				if (completed == 0)
				{
					pib.setText(`Awaiting response...`);
					pib.pulse();
				}
				else
				{
					pib.setText(`Downloading...`);
					double fraction=completed; fraction/=total;
					pib.setFraction(fraction);
				}
				return true;
			}
			else
			{
				super.setTitle(`Downloading complete`);
				// pib.setShowText(false);
				pib.setVisible(false);
				return false;
			}
		}, GPriority.HIGH);
	}
}
int main(string[] args)
{
	auto application = new 
Application(`org.gitlab.helloprogressbar`, 
GApplicationFlags.FLAGS_NONE);
	application.addOnActivate(delegate void(GioApplication app) {
		auto appWindow = new PrimaryWindow(application);
	});
	return application.run(args);
}
    
    
More information about the Digitalmars-d-learn
mailing list