i completely misunderstood how linq deferred execution worked... i'm surprised the whole thing didn't blow up with dozens of Gtk-CRITICALs every time you modified the watchlist 0uo

This commit is contained in:
Lynne Megido 2020-09-06 15:27:11 +10:00
parent 2da88f92f6
commit 9c983d82f4
Signed by: lynnesbian
GPG key ID: F0A184B5213D9F90
2 changed files with 65 additions and 31 deletions

View file

@ -54,8 +54,36 @@ namespace Buypeeb {
static SemaphoreSlim taskLimit = new SemaphoreSlim(6); static SemaphoreSlim taskLimit = new SemaphoreSlim(6);
private Queue<string> updateQueue = new Queue<string>(); private Queue<string> updateQueue = new Queue<string>();
private IEnumerable<YahooAuctionsItem> filterQuery; private IEnumerable<YahooAuctionsItem> filterQuery {
private IEnumerable<YahooAuctionsItem> outdatedItemQuery; get {
// father forgive me for i have lynned
return
from item in this.settings.watchlist.Values.ToList()
where (item.favourite != this.filterChecks["Favourites"].Active ||
item.favourite == this.filterChecks["NonFavourites"].Active) &&
(item.available != this.filterChecks["Active"].Active ||
item.available == this.filterChecks["Ended"].Active) &&
(item.endingToday != this.filterChecks["EndingToday"].Active ||
item.endingToday == this.filterChecks["EndingAfterToday"].Active) &&
(item.hasWinPrice != this.filterChecks["WithWinPrice"].Active ||
item.hasWinPrice == this.filterChecks["WithNoWinPrice"].Active) &&
(String.IsNullOrWhiteSpace(this.searchEntry.Text) ||
item.name.ToLower().Contains(this.searchEntry.Text.ToLower()) ||
item.originalName.ToLower().Contains(this.searchEntry.Text.ToLower()))
select item;
}
}
private IEnumerable<YahooAuctionsItem> outdatedItemQuery {
get {
// only returns items that meet all of the following:
// - marked as "ready", as in, they aren't in the process of updating
// - not updated since the interval
return
from item in this.settings.watchlist.Values.ToList()
where item.ready && this.settings.ItemNotUpdatedSinceInterval(item)
select item;
}
}
private YahooAuctionsItem selectedItem { private YahooAuctionsItem selectedItem {
get { get {
@ -121,30 +149,6 @@ namespace Buypeeb {
this.filterChecks[name].Active = false; this.filterChecks[name].Active = false;
} }
// only returns items that meet all of the following:
// - marked as "ready", as in, they aren't in the process of updating
// - not updated since the interval
this.outdatedItemQuery =
from item in this.settings.watchlist.Values.ToList()
where item.ready && this.settings.ItemNotUpdatedSinceInterval(item)
select item;
// father forgive me for i have lynned
this.filterQuery =
from item in this.settings.watchlist.Values.ToList()
where (item.favourite != this.filterChecks["Favourites"].Active ||
item.favourite == this.filterChecks["NonFavourites"].Active) &&
(item.available != this.filterChecks["Active"].Active ||
item.available == this.filterChecks["Ended"].Active) &&
(item.endingToday != this.filterChecks["EndingToday"].Active ||
item.endingToday == this.filterChecks["EndingAfterToday"].Active) &&
(item.hasWinPrice != this.filterChecks["WithWinPrice"].Active ||
item.hasWinPrice == this.filterChecks["WithNoWinPrice"].Active) &&
(String.IsNullOrWhiteSpace(this.searchEntry.Text) ||
item.name.ToLower().Contains(this.searchEntry.Text.ToLower()) ||
item.originalName.ToLower().Contains(this.searchEntry.Text.ToLower()))
select item;
// bind treeview columns to watchlist instead of needing to manually sync its liststore // bind treeview columns to watchlist instead of needing to manually sync its liststore
this.itemTreeView = (TreeView)builder.GetObject("TreeViewItems"); this.itemTreeView = (TreeView)builder.GetObject("TreeViewItems");
this.items = new ListStore(typeof(YahooAuctionsItem)); this.items = new ListStore(typeof(YahooAuctionsItem));
@ -266,9 +270,9 @@ namespace Buypeeb {
} }
} }
private void UpdateItem(string id, bool evenIfAlreadyUpdating = false, bool force = false) { private void UpdateItem(string id, bool refilterWhenDone = false) {
var item = this.settings.watchlist[id]; var item = this.settings.watchlist[id];
if (item.updatedRecently && !force) { if (item.updatedRecently) {
// the item has been updated recently, and force is not true // the item has been updated recently, and force is not true
return; return;
} }
@ -278,7 +282,13 @@ namespace Buypeeb {
taskLimit.Wait(); taskLimit.Wait();
var t = Task.Factory.StartNew(() => { var t = Task.Factory.StartNew(() => {
this.UpdateThread(id); this.UpdateThread(id);
}).ContinueWith(task => { taskLimit.Release(); }); }).ContinueWith(task => {
taskLimit.Release();
if (refilterWhenDone) {
var m = (TreeModelFilter)this.itemTreeView.Model;
m.Refilter();
}
});
} }
private void UpdateItems() { private void UpdateItems() {
@ -636,13 +646,30 @@ namespace Buypeeb {
} }
catch (Exception e) { catch (Exception e) {
Console.WriteLine(e); Console.WriteLine(e);
MsgBox($"Failed to write {sd.Filename}!\n{e.Message}.", ButtonsType.Ok); var md = MsgBox($"Failed to write {sd.Filename}!\n{e.Message}.", ButtonsType.Ok);
md.Run();
md.Dispose();
} }
} }
sd.Dispose(); sd.Dispose();
} }
private void ButtonHelpClicked(object sender, EventArgs args) {
Console.WriteLine("Watchlist:");
foreach (var item in this.settings.watchlist) {
Console.WriteLine(item);
}
Console.WriteLine("---\nFilter results:");
foreach (var item in this.filterQuery) {
Console.WriteLine(item);
}
Console.WriteLine("---\nListstore contents:");
foreach (object[] item in this.items) {
Console.WriteLine(item[0]);
}
}
private void ButtonQuitClicked(object sender, EventArgs a) { private void ButtonQuitClicked(object sender, EventArgs a) {
var md = this.MsgBox("Are you sure you want to quit?"); var md = this.MsgBox("Are you sure you want to quit?");
@ -846,6 +873,13 @@ namespace Buypeeb {
private bool ItemFilter(ITreeModel model, TreeIter iter) { private bool ItemFilter(ITreeModel model, TreeIter iter) {
var item = (YahooAuctionsItem)model.GetValue(iter, 0); var item = (YahooAuctionsItem)model.GetValue(iter, 0);
if (item == null) {
return true;
}
if (item.price == 0) {
// the item has only just been added, so we can't compare it against the filters, since it's missing most of its data
return true;
}
bool Filtered(string name) { bool Filtered(string name) {
return this.filterChecks[name].Active; return this.filterChecks[name].Active;

View file

@ -430,12 +430,12 @@
<child> <child>
<object class="GtkToolButton"> <object class="GtkToolButton">
<property name="visible">True</property> <property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Help</property> <property name="tooltip_text" translatable="yes">Help</property>
<property name="label" translatable="yes">Help</property> <property name="label" translatable="yes">Help</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="stock_id">gtk-help</property> <property name="stock_id">gtk-help</property>
<signal name="clicked" handler="ButtonHelpClicked" swapped="no"/>
<accelerator key="slash" signal="clicked" modifiers="GDK_CONTROL_MASK"/> <accelerator key="slash" signal="clicked" modifiers="GDK_CONTROL_MASK"/>
</object> </object>
<packing> <packing>