diff --git a/MainWindow.cs b/MainWindow.cs index e42480d..9b0a7fe 100755 --- a/MainWindow.cs +++ b/MainWindow.cs @@ -28,23 +28,14 @@ using System.Diagnostics; using Gtk; namespace Buypeeb { - public struct ItemColumns { - public const int Name = 0; - public const int PriceYen = 1; - public const int PriceAUD = 2; - public const int Ending = 3; - public const int Id = 4; - } class MainWindow : Window { private string location; - // private Queue statuses; private ListStore items; private Settings settings; private TreeView itemTreeView; - private Label statusLabel; private Builder builder; // TODO: whenever we get something from the builder, cache it for later @@ -53,10 +44,12 @@ namespace Buypeeb { private Box selectionViewBox; private Label endingLabel; + private bool queueActive; // ...to here. - static SemaphoreSlim taskLimit = new SemaphoreSlim(4); + static SemaphoreSlim taskLimit = new SemaphoreSlim(2); + private Queue updateQueue = new Queue(); private YahooAuctionsItem selectedItem { get { @@ -104,7 +97,6 @@ namespace Buypeeb { this.builder = builder; builder.Autoconnect(this); - this.statusLabel = (Label)builder.GetObject("LabelStatus"); this.selectionViewBox = (Box)builder.GetObject("SelectionViewBox"); this.endingLabel = (Label)builder.GetObject("LabelSelectedEnding"); @@ -115,6 +107,7 @@ namespace Buypeeb { this.itemTreeView.Model = this.items; TreeCellDataFunc[] funcs = { + new TreeCellDataFunc(this.RenderColumnFavourite), new TreeCellDataFunc(this.RenderColumnName), new TreeCellDataFunc(this.RenderColumnPriceYen), new TreeCellDataFunc(this.RenderColumnPriceAUD), @@ -140,10 +133,6 @@ namespace Buypeeb { // general behaviour - private void SetStatus(string status) { - this.statusLabel.Text = status ?? "Buypeeb"; - } - private (TreePath path, TreeIter iter) GetRow(string id) { // TODO: surely there's a better way to do this TreeIter iter; @@ -179,7 +168,7 @@ namespace Buypeeb { private void UpdateThread(string id) { var item = this.settings.watchlist[id]; - Console.WriteLine($"Updating {id}..."); + // Console.WriteLine($"Updating {id}..."); // set item.ready to false to show that it's still being updated // this changes a few behaviours, such as displaying the price as "..." instead of whatever's currently stored item.ready = false; @@ -206,17 +195,31 @@ namespace Buypeeb { }); item.ready = true; - Console.WriteLine($"{id} updated."); + // Console.WriteLine($"{id} updated."); } - private void UpdateItem(string id, bool force = false) { - // don't start a new task if there are more than [tasklimit] tasks currently running - // this makes sure we don't make 1000 simultaneous requests to yahoo auctions if there are 1000 items on the watchlist - if (this.settings.watchlist[id].updatedRecently && !force) { + private void ProcessUpdateQueue() { + // recursively process the updatequeue + // this is a BLOCKING FUNCTION + this.queueActive = true; + this.UpdateItem(this.updateQueue.Dequeue()); + if (this.updateQueue.TryPeek(out string _)) { + this.ProcessUpdateQueue(); + } + else { + this.queueActive = false; + } + } + + private void UpdateItem(string id, bool evenIfAlreadyUpdating = false, bool force = false) { + var item = this.settings.watchlist[id]; + if (item.updatedRecently && !force) { // the item has been updated recently, and force is not true return; } + // don't start a new task if there are more than `tasklimit` tasks currently running + // this makes sure we don't make 1000 simultaneous requests to yahoo auctions if there are 1000 items on the watchlist taskLimit.Wait(); var t = Task.Factory.StartNew(() => { this.UpdateThread(id); @@ -224,12 +227,28 @@ namespace Buypeeb { } private void UpdateItems() { - this.selectionViewBox.Sensitive = false; + if (this.queueActive) { + return; + } - var t = Task.Factory.StartNew(() => { - foreach (var item in this.settings.watchlist) { - this.UpdateItem(item.Key); + this.selectionViewBox.Sensitive = false; + foreach (var item in this.settings.watchlist) { + if (!this.updateQueue.Contains(item.Key)) { + // set everything to not ready first + // ensures other actions don't attempt to display the items even if UpdateItem hasn't started yet + item.Value.ready = false; + this.updateQueue.Enqueue(item.Key); } + } + + if (!this.updateQueue.TryPeek(out string _)) { + // queue is empty + return; + } + + this.itemTreeView.QueueDraw(); + var t = Task.Factory.StartNew(() => { + this.ProcessUpdateQueue(); }); } @@ -444,12 +463,20 @@ namespace Buypeeb { private void ButtonSelectedUpdateClicked(object sender, EventArgs args) { this.selectionViewBox.Sensitive = false; + if (this.updateQueue.Contains(this.selectedItem.id)) { + // the item is already waiting to be updated + return; + } this.UpdateItem(this.selectedItem.id); } private void ButtonSelectedFavouriteToggled(object sender, EventArgs args) { ToggleButton s = (ToggleButton)sender; this.selectedItem.favourite = s.Active; + + // i don't know why this is necessary + var pathAndIter = this.GetRow(this.selectedItem.id); + this.items.EmitRowChanged(pathAndIter.path, pathAndIter.iter); } // timers @@ -488,6 +515,11 @@ namespace Buypeeb { // column renderers + private void RenderColumnFavourite(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.ITreeModel model, Gtk.TreeIter iter) { + YahooAuctionsItem item = (YahooAuctionsItem)model.GetValue(iter, 0); + (cell as Gtk.CellRendererText).Text = item.favourite ? "♥" : ""; + } + private void RenderColumnName(Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.ITreeModel model, Gtk.TreeIter iter) { YahooAuctionsItem item = (YahooAuctionsItem)model.GetValue(iter, 0); (cell as Gtk.CellRendererText).Text = item.name ?? "Loading..."; diff --git a/YahooAuctionsItem.cs b/YahooAuctionsItem.cs index a1b88a5..45c7fcc 100644 --- a/YahooAuctionsItem.cs +++ b/YahooAuctionsItem.cs @@ -50,7 +50,6 @@ namespace Buypeeb { public YahooAuctionsItem(string id, string name) { this.id = id; this.name = name; - this.ready = false; } public YahooAuctionsItem() { diff --git a/ui/main.glade b/ui/main.glade index 5e0c417..dbcec40 100644 --- a/ui/main.glade +++ b/ui/main.glade @@ -1,14 +1,11 @@ - + False - 700 - - - + 810 True @@ -115,7 +112,6 @@ True - True False Clear ended Clear ended @@ -172,7 +168,6 @@ True - True False Save Save @@ -287,11 +282,19 @@ + + + + + + + + True fixed - 50 + 100 Name True True @@ -807,47 +810,10 @@ 1 - - - True - False - 5 - 5 - 3 - 3 - - - True - False - start - True - Tracking 3 items - - - False - True - 0 - - - - - True - False - - - False - True - 1 - - - - - False - True - 2 - - + + +