Skip to content

Commit 6fd9914

Browse files
committed
Add prefetching logic.
1 parent 878ab08 commit 6fd9914

File tree

5 files changed

+55
-7
lines changed

5 files changed

+55
-7
lines changed

PhotoCull/PhotoCullWindow.xaml.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,15 @@ private async void onClickSecond(object sender, RoutedEventArgs e) {
187187
await reject(true);
188188
}
189189

190+
private void prefetch() {
191+
var photos = this.Photos;
192+
if (photos.Count > 2) {
193+
foreach (var p in photos.Take(3)) {
194+
p.Prefetch();
195+
}
196+
}
197+
}
198+
190199
private async Task reject(bool first) {
191200
var photos = this.Photos;
192201
if (photos.Count == 0) {
@@ -224,6 +233,7 @@ private async Task reject(bool first) {
224233
good.MarkedForDeletion = false;
225234
this.deleteButton.IsEnabled = true;
226235
this.photoList.SelectedValue = null;
236+
this.prefetch();
227237
}
228238

229239
private async void onDistinctFirst(object sender, RoutedEventArgs e) {
@@ -277,6 +287,7 @@ private async Task distinct(bool moveFirst) {
277287
}
278288
this.deleteButton.IsEnabled = photos.Any(p => p.MarkedForDeletion);
279289
this.photoList.SelectedValue = null;
290+
this.prefetch();
280291
}
281292

282293
private static bool debugging() {

PhotoTagger.Imaging/Photo.cs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,23 @@ public Photo(string f) {
2323
SlidingExpiration = TimeSpan.FromSeconds(10),
2424
};
2525

26+
/// <summary>
27+
/// Begin the process of loading the full size image.
28+
/// </summary>
29+
public void Prefetch() {
30+
var imageRef = this.fullImageRef;
31+
if (this.setFrom == null ||
32+
this.loader == null) {
33+
// Queue this for prefetch as soon as the metadata is loaded.
34+
Interlocked.CompareExchange(ref this.fullIsLoading, -1, 0);
35+
} else if (!this.Disposed && (
36+
imageRef == null ||
37+
!imageRef.TryGetTarget(out BitmapImage _)) &&
38+
Interlocked.Exchange(ref this.fullIsLoading, 1) <= 0) {
39+
this.loader?.EnqueueFullSizeRead(this, this.setFrom);
40+
}
41+
}
42+
2643
public BitmapImage FullImage {
2744
get {
2845
var imageRef = this.fullImageRef;
@@ -36,7 +53,9 @@ public BitmapImage FullImage {
3653
return target;
3754
} else {
3855
if (this.setFrom != null &&
39-
Interlocked.Exchange(ref this.fullIsLoading, 1) == 0) {
56+
this.loader != null &&
57+
!this.Disposed &&
58+
Interlocked.Exchange(ref this.fullIsLoading, 1) <= 0) {
4059
this.loader?.EnqueueFullSizeRead(this, this.setFrom);
4160
}
4261
return this.ThumbImage;
@@ -49,20 +68,17 @@ public BitmapImage FullImage {
4968
new PropertyChangedEventArgs(nameof(FullImage)));
5069
}
5170
MemoryCache.Default.Remove(this.FileName);
71+
fullIsLoading = 0;
5272
return;
5373
} else if (this.fullImageRef == null) {
5474
this.fullImageRef = new WeakReference<BitmapImage>(value);
5575
} else {
5676
this.fullImageRef.SetTarget(value);
5777
}
58-
fullIsLoading = 0;
5978
Thread.MemoryBarrier();
79+
fullIsLoading = 0;
6080
this.PropertyChanged?.Invoke(this,
6181
new PropertyChangedEventArgs(nameof(FullImage)));
62-
MemoryCache.Default.Set(
63-
this.FileName,
64-
value,
65-
cachePolicy);
6682
}
6783
}
6884

@@ -72,6 +88,9 @@ public BitmapImage ThumbImage {
7288
}
7389
set {
7490
SetValue(ThumbImageProperty, value);
91+
if (fullIsLoading < 0) {
92+
this.Prefetch();
93+
}
7594
this.PropertyChanged?.Invoke(this,
7695
new PropertyChangedEventArgs(nameof(FullImage)));
7796
}

PhotoTagger.Wpf/PhotoList.xaml.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,16 @@ public ReadOnlyObservableCollection<Photo> Selected {
5050
}
5151
}
5252

53+
public event SelectionChangedEventHandler OnSelectionChanged;
54+
5355
private void onSelectionChanged(object sender, SelectionChangedEventArgs e) {
5456
foreach (var item in e.RemovedItems) {
5557
this.selected.Remove(item as Photo);
5658
}
5759
foreach (var item in e.AddedItems) {
5860
this.selected.Add(item as Photo);
5961
}
62+
OnSelectionChanged?.Invoke(sender, e);
6063
}
6164

6265

PhotoTagger/TaggerWindow.xaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
<ptwpf:PhotoList Grid.Row="0"
4646
x:Name="photoList"
4747
SelectionMode="Extended"
48-
Photos="{Binding Photos, ElementName=window}"/>
48+
Photos="{Binding Photos, ElementName=window}"
49+
OnSelectionChanged="onSelectionChanged" />
4950
<StackPanel Grid.Row="1">
5051
<Button Content="Add images..."
5152
Click="addImagesEvent" />

PhotoTagger/TaggerWindow.xaml.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,27 @@ void photoCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
3535
photo.PropertyChanged += photoChanged;
3636
}
3737
}
38+
foreach (var item in e.NewItems.OfType<Photo>().Take(3)) {
39+
item.Prefetch();
40+
}
3841
}
3942
if (e.OldItems != null) {
4043
// New items are always unchanged to begin.
4144
this.commitButton.IsEnabled = this.Photos.Any(p => p.IsChanged);
4245
}
4346
}
4447

48+
private void onSelectionChanged(object sender, SelectionChangedEventArgs e) {
49+
var photos = this.Photos;
50+
foreach (var photo in e.AddedItems.OfType<Photo>().Take(3)) {
51+
photo.Prefetch();
52+
var i = photos.IndexOf(photo);
53+
if (i >= 0 && i < photos.Count - 2) {
54+
photos[i + 1].Prefetch();
55+
}
56+
}
57+
}
58+
4559
void photoChanged(object sender, PropertyChangedEventArgs e) {
4660
this.commitButton.IsEnabled = this.Photos.Any(p => p.IsChanged);
4761
}

0 commit comments

Comments
 (0)