Browse Source

thumbnail cache: implement more efficient and elegant way to update the thumbnails for folders and shows

Felix Paul Kühne 11 years ago
parent
commit
ebae0366fe

+ 4 - 10
Sources/VLCPlaylistCollectionViewCell.m

@@ -150,15 +150,12 @@
     } else if ([self.mediaObject isKindOfClass:[MLLabel class]]) {
         MLLabel *mediaObject = (MLLabel *)self.mediaObject;
         [self _configureForFolder:mediaObject];
-        BOOL forceRefresh = NO;
-        if ([keyPath isEqualToString:@"files"] || [keyPath isEqualToString:@"labels"] || !keyPath)
-            forceRefresh = YES;
 
-        if (forceRefresh || (!self.thumbnailView.image && [keyPath isEqualToString:@"editing"])) {
+        if ([keyPath isEqualToString:@"files"] || [keyPath isEqualToString:@"labels"] || !keyPath || (!self.thumbnailView.image && [keyPath isEqualToString:@"editing"])) {
             if (mediaObject.files.count == 0)
                 self.thumbnailView.image = [UIImage imageNamed:@"folderIcon"];
             else
-                self.thumbnailView.image = [VLCThumbnailsCache thumbnailForLabel:mediaObject forceRefresh:forceRefresh];
+                self.thumbnailView.image = [VLCThumbnailsCache thumbnailForLabel:mediaObject];
         }
     } else if ([self.mediaObject isKindOfClass:[MLAlbum class]]) {
         MLAlbum *mediaObject = (MLAlbum *)self.mediaObject;
@@ -179,12 +176,9 @@
     } else if ([self.mediaObject isKindOfClass:[MLShow class]]) {
         MLShow *mediaObject = (MLShow *)self.mediaObject;
         [self _configureForShow:mediaObject];
-        BOOL forceRefresh = NO;
-        if ([keyPath isEqualToString:@"episodes"])
-            forceRefresh = YES;
 
-        if ([keyPath isEqualToString:@"computedThumbnail"] || forceRefresh || !keyPath || (!self.thumbnailView.image && [keyPath isEqualToString:@"editing"])) {
-            self.thumbnailView.image = [VLCThumbnailsCache thumbnailForShow:mediaObject forceRefresh:forceRefresh];
+        if ([keyPath isEqualToString:@"computedThumbnail"] || [keyPath isEqualToString:@"episodes"] || !keyPath || (!self.thumbnailView.image && [keyPath isEqualToString:@"editing"])) {
+            self.thumbnailView.image = [VLCThumbnailsCache thumbnailForShow:mediaObject];
         }
     } else if ([self.mediaObject isKindOfClass:[MLShowEpisode class]]) {
         MLShowEpisode *mediaObject = (MLShowEpisode *)self.mediaObject;

+ 4 - 10
Sources/VLCPlaylistTableViewCell.m

@@ -128,15 +128,12 @@
     } else if (isFolder) {
         MLLabel *mediaObject = (MLLabel *)self.mediaObject;
         [self _configureForFolder:mediaObject];
-        BOOL forceRefresh = NO;
-        if ([keyPath isEqualToString:@"files"] || [keyPath isEqualToString:@"labels"] || !keyPath)
-            forceRefresh = YES;
 
-        if (forceRefresh || (!self.thumbnailView.image && [keyPath isEqualToString:@"editing"])) {
+        if ([keyPath isEqualToString:@"files"] || [keyPath isEqualToString:@"labels"] || !keyPath || (!self.thumbnailView.image && [keyPath isEqualToString:@"editing"])) {
             if (mediaObject.files.count == 0)
                 self.thumbnailView.image = [UIImage imageNamed:@"folderIcon"];
             else
-                self.thumbnailView.image = [VLCThumbnailsCache thumbnailForLabel:mediaObject forceRefresh:forceRefresh];
+                self.thumbnailView.image = [VLCThumbnailsCache thumbnailForLabel:mediaObject];
         }
     } else if ([self.mediaObject isKindOfClass:[MLAlbum class]]) {
         MLAlbum *mediaObject = (MLAlbum *)self.mediaObject;
@@ -157,12 +154,9 @@
     } else if ([self.mediaObject isKindOfClass:[MLShow class]]) {
         MLShow *mediaObject = (MLShow *)self.mediaObject;
         [self _configureForShow:mediaObject];
-        BOOL forceRefresh = NO;
-        if ([keyPath isEqualToString:@"episodes"])
-            forceRefresh = YES;
 
-        if ([keyPath isEqualToString:@"computedThumbnail"] || forceRefresh || !keyPath || (!self.thumbnailView.image && [keyPath isEqualToString:@"editing"])) {
-            self.thumbnailView.image = [VLCThumbnailsCache thumbnailForShow:mediaObject forceRefresh:forceRefresh];
+        if ([keyPath isEqualToString:@"computedThumbnail"] || [keyPath isEqualToString:@"episodes"] || !keyPath || (!self.thumbnailView.image && [keyPath isEqualToString:@"editing"])) {
+            self.thumbnailView.image = [VLCThumbnailsCache thumbnailForShow:mediaObject];
         }
     } else if ([self.mediaObject isKindOfClass:[MLShowEpisode class]]) {
         MLShowEpisode *mediaObject = (MLShowEpisode *)self.mediaObject;

+ 2 - 2
Sources/VLCThumbnailsCache.h

@@ -19,7 +19,7 @@
 
 + (UIImage *)thumbnailForMediaItemWithTitle:(NSString *)title Artist:(NSString*)artist andAlbumName:(NSString*)albumname;
 
-+ (UIImage *)thumbnailForShow:(MLShow *)mediaShow forceRefresh:(BOOL)forceRefresh;
-+ (UIImage *)thumbnailForLabel:(MLLabel *)mediaLabel forceRefresh:(BOOL)forceRefresh;
++ (UIImage *)thumbnailForShow:(MLShow *)mediaShow;
++ (UIImage *)thumbnailForLabel:(MLLabel *)mediaLabel;
 
 @end

+ 25 - 6
Sources/VLCThumbnailsCache.m

@@ -16,6 +16,7 @@
 
 static NSInteger MaxCacheSize;
 static NSCache *_thumbnailCache;
+static NSCache *_thumbnailCacheMetadata;
 
 @implementation VLCThumbnailsCache
 
@@ -28,7 +29,9 @@ static NSCache *_thumbnailCache;
                                 MAX_CACHE_SIZE_IPAD: MAX_CACHE_SIZE_IPHONE;
 
     _thumbnailCache = [[NSCache alloc] init];
+    _thumbnailCacheMetadata = [[NSCache alloc] init];
     [_thumbnailCache setCountLimit: MaxCacheSize];
+    [_thumbnailCacheMetadata setCountLimit: MaxCacheSize];
 }
 
 + (NSString *)_md5FromString:(NSString *)string
@@ -102,10 +105,17 @@ static NSCache *_thumbnailCache;
     return displayedImage;
 }
 
-+ (UIImage *)thumbnailForShow:(MLShow *)mediaShow forceRefresh:(BOOL)forceRefresh
++ (UIImage *)thumbnailForShow:(MLShow *)mediaShow
 {
     NSManagedObjectID *objID = mediaShow.objectID;
     UIImage *displayedImage;
+    BOOL forceRefresh = NO;
+
+    NSUInteger count = [mediaShow.episodes count];
+    NSNumber *previousCount = [_thumbnailCacheMetadata objectForKey:objID];
+
+    if (previousCount.unsignedIntegerValue != count)
+        forceRefresh = YES;
 
     if (!forceRefresh) {
         displayedImage = [_thumbnailCache objectForKey:objID];
@@ -113,7 +123,6 @@ static NSCache *_thumbnailCache;
             return displayedImage;
     }
 
-    NSUInteger count = [mediaShow.episodes count];
     NSUInteger fileNumber = count > 3 ? 3 : count;
     NSArray *episodes = [mediaShow.episodes allObjects];
     NSMutableArray *files = [[NSMutableArray alloc] init];
@@ -121,16 +130,25 @@ static NSCache *_thumbnailCache;
         [files addObject:[episodes[x] files].anyObject];
 
     displayedImage = [self clusterThumbFromFiles:files andNumber:fileNumber];
-    if (displayedImage)
+    if (displayedImage) {
         [_thumbnailCache setObject:displayedImage forKey:objID];
+        [_thumbnailCacheMetadata setObject:@(count) forKey:objID];
+    }
 
     return displayedImage;
 }
 
-+ (UIImage *)thumbnailForLabel:(MLLabel *)mediaLabel forceRefresh:(BOOL)forceRefresh
++ (UIImage *)thumbnailForLabel:(MLLabel *)mediaLabel
 {
     NSManagedObjectID *objID = mediaLabel.objectID;
     UIImage *displayedImage;
+    BOOL forceRefresh = NO;
+
+    NSUInteger count = [mediaLabel.files count];
+    NSNumber *previousCount = [_thumbnailCacheMetadata objectForKey:objID];
+
+    if (previousCount.unsignedIntegerValue != count)
+        forceRefresh = YES;
 
     if (!forceRefresh) {
         displayedImage = [_thumbnailCache objectForKey:objID];
@@ -138,12 +156,13 @@ static NSCache *_thumbnailCache;
             return displayedImage;
     }
 
-    NSUInteger count = [mediaLabel.files count];
     NSUInteger fileNumber = count > 3 ? 3 : count;
     NSArray *files = [mediaLabel.files allObjects];
     displayedImage = [self clusterThumbFromFiles:files andNumber:fileNumber];
-    if (displayedImage)
+    if (displayedImage) {
         [_thumbnailCache setObject:displayedImage forKey:objID];
+        [_thumbnailCacheMetadata setObject:@(count) forKey:objID];
+    }
 
     return displayedImage;
 }