On Sun, 28 Jun 2020 07:27:28 GMT, Adnan wrote:
For the last couple weeks I have remained unsuccessful in emulating a download progressbar.
Everything usually works but in some cases my progressbar does not advance, and I have absolutely no idea why. I don't even know where to start so I need help here.
Because the code would only sometimes get stuck randomly, I have wrapped the main inside a loop.
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; debug import std.stdio; class Downloader { string[] links = [ `link1`, `link2`, `link3`, `link4`, `link1`, `link2`, `link3`, `link4`, `link1`, `link2`, `link3`, `link4`, `link1`, `link2`, `link3`, `link4`, `link1`, `link2`, `link3`, `link4`, `link1`, `link2`, `link3`, `link4`, `link1`, `link2`, `link3`, `link4`, `link1`, `link2`, `link3`, `link4`, `link1`, `link2`, `link3`, `link4`, ]; private shared size_t completed = 0; double getFraction() { return cast(double) completed / links.length; } size_t getCompleted() { return cast(size_t) completed; } static void start(ref Downloader downloader) { import std.parallelism : parallel; import core.thread : Thread, seconds; { // emulate HTTP response overhead; Thread.sleep(seconds(2)); } synchronized { // emulate random Download time import std.random : Random, uniform; auto rnd = Random(4361); foreach (_; downloader.links.parallel()) { Thread.sleep(uniform(0, 6, rnd).seconds()); ++cast() downloader.completed; } debug writeln(`Download finished`); } } } 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); auto downloader = new Downloader(); import std.parallelism : task; auto downloadTask = task!(Downloader.start)(downloader); downloadTask.executeInNewThread(); auto timeout = new Timeout(100, delegate bool() { const auto completed = downloader.getCompleted(); debug writefln!"Completed: %s of: %s"(completed, downloader.getCompleted()); if (completed < downloader.links.length) { if (completed == 0) { pib.setText(`Awaiting response...`); pib.pulse(); } else { pib.setText(`Downloading...`); pib.setFraction(downloader.getFraction()); } return true; } else { super.setTitle(`Downloading complete`); // pib.setShowText(false); pib.setVisible(false); super.destroy(); return false; } }, GPriority.HIGH); } } void main(string[] args) { while (true) { auto application = new Application(`org.gitlab.helloprogressbar`, GApplicationFlags.FLAGS_NONE); application.addOnActivate(delegate void(GioApplication app) { auto appWindow = new PrimaryWindow(application); }); const auto _ = application.run(args); } }
Now note that the cases where it gets stuck, the actual download function reports that the download finished (after the parallel foreach). Inside my timeout, I also see that completed == 34 of 34 in the stdout prints.
YET the progressbar gets stuck some times.
![]()
Note that those "Completed 34 of 34" lines are live, it keeps printing but the progressbar is stuck. The UI is still responsive.
Nevermind, I was printing the same value twice