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