Skip to content

Commit

Permalink
Smarter image loading logic
Browse files Browse the repository at this point in the history
- loads best resolution for selected image only
  • Loading branch information
mmllr committed Mar 26, 2014
1 parent dfb9c13 commit ddf4ccf
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 26 deletions.
3 changes: 2 additions & 1 deletion Classes/osx/MMFlowView+MMCoverFlowLayerDataSource.m
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,12 @@ - (void)coverFlowLayer:(MMCoverFlowLayer *)coverFlowLayer willShowLayer:(CALayer

CGImageRef cachedImage = [self.imageCache imageForUUID:itemUID];

if (cachedImage != NULL) {
if (cachedImage != NULL && itemIndex != self.selectedIndex) {
[self setImage:cachedImage forContentLayer:contentLayer];
return;
}

self.imageFactory.maxImageSize = self.coverFlowLayout.itemSize;
[self.imageFactory createCGImageFromRepresentation:[self imageRepresentationForItem:item]
withType:[self imageRepresentationTypeForItem:item]
completionHandler:^(CGImageRef anImage) {
Expand Down
1 change: 0 additions & 1 deletion Classes/osx/MMFlowView.m
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,6 @@ - (void)viewDidEndLiveResize
[super viewDidEndLiveResize];
self.coverFlowLayer.inLiveResize = NO;
self.imageFactory.maxImageSize = self.coverFlowLayout.itemSize;
[self.imageCache reset];
}

- (void)updateTrackingAreas
Expand Down
51 changes: 44 additions & 7 deletions Classes/osx/Specs/MMFlowViewMMCoverFlowLayerDataSourceSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ software and associated documentation files (the "Software"), to deal in the Sof
describe(NSStringFromProtocol(@protocol(MMFlowViewDataSource)), ^{
__block MMFlowView *sut = nil;
__block MMCoverFlowLayer *mockedCoverFlowLayer = nil;
__block id mockedImageFactory = nil;
__block MMFlowViewImageFactory *mockedImageFactory = nil;
__block MMCoverFlowLayout *mockedLayout = nil;

beforeEach(^{
sut = [[MMFlowView alloc] initWithFrame:NSMakeRect(0, 0, 400, 300)];

mockedCoverFlowLayer = [MMCoverFlowLayer nullMock];
mockedImageFactory = [MMFlowViewImageFactory nullMock];
mockedLayout = [MMCoverFlowLayout nullMock];
});
afterEach(^{
mockedCoverFlowLayer = nil;
Expand Down Expand Up @@ -147,19 +149,19 @@ software and associated documentation files (the "Software"), to deal in the Sof
});
afterAll(^{
testImage = nil;
SAFE_CGIMAGE_RELEASE(testImageRef);
SAFE_CGIMAGE_RELEASE(testImageRef)
});

beforeEach(^{
contentLayer = [CALayer nullMock];
sut.imageFactory = mockedImageFactory;
factorySpy = [mockedImageFactory captureArgument:@selector(createCGImageFromRepresentation:withType:completionHandler:) atIndex:2];

itemMock = [KWMock nullMockForProtocol:@protocol(MMFlowViewItem)];
[itemMock stub:@selector(imageItemUID) andReturn:testUID];
[itemMock stub:@selector(imageItemRepresentationType) andReturn:testRepresentationType];
[itemMock stub:@selector(imageItemRepresentation) andReturn:testImage];
[sut stub:@selector(imageItemForIndex:) andReturn:itemMock];

});
afterEach(^{
contentLayer = nil;
Expand All @@ -168,11 +170,15 @@ software and associated documentation files (the "Software"), to deal in the Sof
itemMock = nil;
});
context(@"image cache", ^{
const CGSize expectedItemSize = CGSizeMake(300, 300);
__block MMFlowViewImageCache *cacheMock = nil;

beforeEach(^{
cacheMock = [MMFlowViewImageCache nullMock];
sut.imageCache = cacheMock;

[mockedLayout stub:@selector(itemSize) andReturn:theValue(expectedItemSize)];
sut.coverFlowLayout = mockedLayout;
});
afterEach(^{
cacheMock = nil;
Expand All @@ -185,15 +191,46 @@ software and associated documentation files (the "Software"), to deal in the Sof
[[mockedImageFactory should] receive:@selector(createCGImageFromRepresentation:withType:completionHandler:)];
[sut coverFlowLayer:mockedCoverFlowLayer willShowLayer:contentLayer atIndex:0];
});
it(@"should set the maxImageSize on the image factory", ^{
[[mockedImageFactory should] receive:@selector(setMaxImageSize:) withArguments:theValue(expectedItemSize)];

[sut coverFlowLayer:mockedCoverFlowLayer willShowLayer:contentLayer atIndex:0];
});
});
context(@"when the image is in the cache", ^{
beforeEach(^{
[cacheMock stub:@selector(imageForUUID:) andReturn:(__bridge id)testImageRef withArguments:testUID];
[sut stub:@selector(selectedIndex) andReturn:0];
});
it(@"should not ask the image factory for the images", ^{
[[mockedImageFactory shouldNot] receive:@selector(createCGImageFromRepresentation:withType:completionHandler:)];
context(@"when setting the selected image", ^{
context(@"when the image in the cache is too small", ^{
beforeEach(^{
NSImage *smallImage = [NSImage imageWithSize:NSMakeSize(5, 5) flipped:NO drawingHandler:^BOOL(NSRect dstRect) {
return YES;
}];
CGImageRef smallImageRef = [smallImage CGImageForProposedRect:NULL context:NULL hints:nil];
[cacheMock stub:@selector(imageForUUID:) andReturn:(__bridge id)(smallImageRef)];
});
it(@"should ask the image factory for the images", ^{
[[mockedImageFactory should] receive:@selector(createCGImageFromRepresentation:withType:completionHandler:)];
[sut coverFlowLayer:mockedCoverFlowLayer willShowLayer:contentLayer atIndex:sut.selectedIndex];
});
it(@"should set the maxImageSize on the image factory", ^{
[[mockedImageFactory should] receive:@selector(setMaxImageSize:) withArguments:theValue(expectedItemSize)];

[sut coverFlowLayer:mockedCoverFlowLayer willShowLayer:contentLayer atIndex:sut.selectedIndex];
});
});
});
context(@"when not setting the selected index", ^{
beforeEach(^{
[cacheMock stub:@selector(imageForUUID:) andReturn:(__bridge id)testImageRef withArguments:testUID];
});
it(@"should not ask the image factory for the images", ^{
[[mockedImageFactory shouldNot] receive:@selector(createCGImageFromRepresentation:withType:completionHandler:)];

[sut coverFlowLayer:mockedCoverFlowLayer willShowLayer:contentLayer atIndex:sut.selectedIndex+1];
});

[sut coverFlowLayer:mockedCoverFlowLayer willShowLayer:contentLayer atIndex:0];
});
});
});
Expand Down
17 changes: 0 additions & 17 deletions Classes/osx/Specs/MMFlowViewSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -335,23 +335,6 @@ software and associated documentation files (the "Software"), to deal in the Sof
[[theValue(sut.coverFlowLayer.inLiveResize) should] beNo];
});
});
context(@"image cache interaction", ^{
__block MMFlowViewImageCache *imageCacheMock = nil;


beforeEach(^{
imageCacheMock = [MMFlowViewImageCache nullMock];
sut.imageCache = imageCacheMock;
});
afterEach(^{
imageCacheMock = nil;
});
it(@"should reset the image cache", ^{
[[imageCacheMock should] receive:@selector(reset)];

[sut viewDidEndLiveResize];
});
});
context(@"image factory interaction", ^{
__block MMCoverFlowLayout *layoutMock = nil;
__block MMFlowViewImageFactory *imageFactoryMock = nil;
Expand Down

0 comments on commit ddf4ccf

Please sign in to comment.