handle updates with a queue, display favourite status, removed status bar
This commit is contained in:
parent
9c335a73d0
commit
ce92a99723
3 changed files with 71 additions and 74 deletions
|
@ -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<string> 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<string> updateQueue = new Queue<string>();
|
||||
|
||||
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;
|
||||
|
||||
var t = Task.Factory.StartNew(() => {
|
||||
foreach (var item in this.settings.watchlist) {
|
||||
this.UpdateItem(item.Key);
|
||||
if (this.queueActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
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...";
|
||||
|
|
|
@ -50,7 +50,6 @@ namespace Buypeeb {
|
|||
public YahooAuctionsItem(string id, string name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.ready = false;
|
||||
}
|
||||
|
||||
public YahooAuctionsItem() {
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.2 -->
|
||||
<!-- Generated with glade 3.36.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.22"/>
|
||||
<object class="GtkTextBuffer" id="TextBufferSelectedNotes"/>
|
||||
<object class="GtkWindow" id="wndMain">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="default_width">700</property>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<property name="default_width">810</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
|
@ -115,7 +112,6 @@
|
|||
<child>
|
||||
<object class="GtkToolButton" id="ButtonClearEnded">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Clear ended</property>
|
||||
<property name="label" translatable="yes">Clear ended</property>
|
||||
|
@ -172,7 +168,6 @@
|
|||
<child>
|
||||
<object class="GtkToolButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Save</property>
|
||||
<property name="label" translatable="yes">Save</property>
|
||||
|
@ -287,11 +282,19 @@
|
|||
<signal name="changed" handler="TreeViewItemsSelectionChanged" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="title" translatable="yes">♥</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn">
|
||||
<property name="resizable">True</property>
|
||||
<property name="sizing">fixed</property>
|
||||
<property name="fixed_width">50</property>
|
||||
<property name="fixed_width">100</property>
|
||||
<property name="title" translatable="yes">Name</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="clickable">True</property>
|
||||
|
@ -807,47 +810,10 @@
|
|||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_start">5</property>
|
||||
<property name="margin_end">5</property>
|
||||
<property name="margin_top">3</property>
|
||||
<property name="margin_bottom">3</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="LabelStatus">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="label" translatable="yes">Tracking 3 items</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinner">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
Loading…
Reference in a new issue