Created
June 8, 2015 21:00
-
-
Save donholly/934f52eacf510943a110 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// EAImageCacheEntity.h | |
// Pods | |
// | |
// Created by Don Holly on 3/4/15. | |
// | |
// | |
#import <FastImageCache/FICEntity.h> | |
#import "EAImageCacheFormat.h" | |
@protocol EAImageCacheEntity <FICEntity> | |
@required | |
- (CGFloat)aspectRatioForFormatFamily:(NSString *)formatFamily; | |
- (NSURL *)sourceImageURLForFormatFamily:(NSString *)formatFamily; | |
- (EAImageCacheFormat *)imageFormatForFormatFamily:(NSString *)formatFamily; | |
@end | |
// | |
// EAFastDiskImageCache.h | |
// Pods | |
// | |
// Created by Don Holly on 3/11/15. | |
// | |
// | |
#import "FICImageCache.h" | |
#import "EAImageCacheImports.h" | |
@interface EAFastDiskImageCache : FICImageCache | |
+ (unsigned long long)currentCacheSize; | |
+ (void)setDirectoryPath:(NSString *)directoryPath; | |
- (void)addFormat:(EAImageCacheFormat *)imageFormat; | |
- (EAImageCacheFormat *)formatWithName:(NSString *)formatName; | |
- (EAImageCacheFormat *)existingFormatForEntity:(id<EAImageCacheEntity>)entity | |
inFormatFamily:(NSString *)formatFamily; | |
- (BOOL)removeImageForEntity:(id<EAImageCacheEntity>)entity | |
inFormatFamily:(NSString *)formatFamily; | |
@end | |
// | |
// EAFastDiskImageCache.m | |
// Pods | |
// | |
// Created by Don Holly on 3/11/15. | |
// | |
// | |
#import "EAFastDiskImageCache.h" | |
#import "FICImageTable.h" | |
@interface EAFastDiskImageCache () | |
@property (nonatomic, strong) NSMutableDictionary *imageAspectRatioToFormat; | |
@end | |
@implementation EAFastDiskImageCache | |
- (id)init { | |
if (self = [super init]) { | |
} | |
return self; | |
} | |
+ (instancetype)sharedImageCache { | |
return (EAFastDiskImageCache *)[super sharedImageCache]; | |
} | |
+ (unsigned long long)currentCacheSize { | |
return [FICImageTable currentCacheSize]; | |
} | |
+ (void)setDirectoryPath:(NSString *)directoryPath { | |
[FICImageTable setDirectoryPath:directoryPath]; | |
} | |
- (void)addFormat:(EAImageCacheFormat *)imageFormat { | |
[super addFormat:imageFormat]; | |
} | |
- (NSArray *)formatsWithFamily:(NSString *)family { | |
NSArray *formats = [super formatsWithFamily:family]; | |
NSMutableArray *eaFormats = @[].mutableCopy; | |
for (FICImageFormat *format in formats) { | |
EAImageCacheFormat *eaFormat = ((EAImageCacheFormat *)format); | |
[eaFormats addObject:eaFormat]; | |
} | |
return [eaFormats copy]; | |
} | |
- (FICImageFormat *)formatWithName:(NSString *)formatName { | |
return ((EAImageCacheFormat *)[super formatWithName:formatName]); | |
} | |
- (EAImageCacheFormat *)existingFormatForEntity:(id<EAImageCacheEntity>)entity | |
inFormatFamily:(NSString *)formatFamily { | |
NSString *imageAspectRatio = [NSString stringWithFormat:@"%.2f", | |
roundedTrucatedAspectRatio([entity aspectRatioForFormatFamily:formatFamily])]; | |
// Check our cache first. | |
EAImageCacheFormat *format = [self imageAspectRatioToFormat][imageAspectRatio][formatFamily]; | |
if (format) { | |
return format; | |
} | |
NSArray *imageFormats = [self formatsWithFamily:formatFamily]; | |
// Iterate the formats if it hasn't been cached yet. | |
for (EAImageCacheFormat *f in imageFormats) { | |
NSString *formatAspectRatio = f.entityAspectRatio; | |
if ([imageAspectRatio isEqualToString:formatAspectRatio]) { | |
[self imageAspectRatioToFormat][imageAspectRatio][formatFamily] = f; | |
return f; | |
} | |
} | |
return nil; | |
} | |
- (NSMutableDictionary *)imageAspectRatioToFormat { | |
if (!_imageAspectRatioToFormat) { | |
_imageAspectRatioToFormat = @{}.mutableCopy; | |
} | |
return _imageAspectRatioToFormat; | |
} | |
- (BOOL)removeImageForEntity:(id<EAImageCacheEntity>)entity | |
inFormatFamily:(NSString *)formatFamily { | |
NSUInteger count = 0; | |
NSArray *formats = [self formatsWithFamily:formatFamily]; | |
for (EAImageCacheFormat *format in formats) { | |
[self deleteImageForEntity:entity withFormatName:format.name]; | |
count++; | |
} | |
return count > 0; | |
} | |
@end | |
// | |
// EAImageCacheFormat.h | |
// Pods | |
// | |
// Created by Don Holly on 3/4/15. | |
// | |
// | |
#import "FICImageFormat.h" | |
typedef NS_OPTIONS(NSUInteger, EAImageCacheFormatDevices) { | |
EAImageCacheFormatDevicePhone = 1 << UIUserInterfaceIdiomPhone, | |
EAImageCacheFormatDevicePad = 1 << UIUserInterfaceIdiomPad, | |
}; | |
typedef NS_ENUM(NSUInteger, EAImageCacheFormatStyle) { | |
EAImageCacheFormatStyle32BitBGRA, | |
EAImageCacheFormatStyle32BitBGR, | |
EAImageCacheFormatStyle16BitBGR, | |
EAImageCacheFormatStyle8BitGrayscale, | |
}; | |
static inline CGFloat roundedTrucatedAspectRatio(CGFloat aspectRatio) { | |
CGFloat truncated = truncf(round(100 * aspectRatio)) / 100; // round to 2 decimal places; | |
return truncated; | |
}; | |
static inline CGFloat roundedAspectRatio(CGFloat width, CGFloat height) { | |
return roundedTrucatedAspectRatio((width/height)); | |
}; | |
@interface EAImageCacheFormat : FICImageFormat | |
@property (nonatomic, copy, readonly) NSString *entityAspectRatio; | |
@property (nonatomic) BOOL cacheInMemory; | |
@property (nonatomic) BOOL cacheInFastDisk; | |
@property (nonatomic) BOOL cacheOnDisk; | |
+ (instancetype)formatWithFamily:(NSString *)family | |
entityAspectRatio:(CGFloat)entityAspectRatio | |
imageSize:(CGSize)imageSize | |
style:(EAImageCacheFormatStyle)style | |
cacheInMemory:(BOOL)cacheInMemory | |
cacheInFastDisk:(BOOL)cacheInFastDisk | |
cacheOnDisk:(BOOL)cacheOnDisk | |
maximumCount:(NSInteger)maximumCount | |
devices:(EAImageCacheFormatDevices)devices; | |
@end | |
// | |
// EAImageCacheFormat.m | |
// Pods | |
// | |
// Created by Don Holly on 3/4/15. | |
// | |
// | |
#import "EAImageCacheFormat.h" | |
#import "EAFastDiskImageCache.h" | |
@implementation EAImageCacheFormat | |
@synthesize entityAspectRatio = _entityAspectRatio; | |
- (id)initWithFamily:(NSString *)family | |
entityAspectRatio:(CGFloat)entityAspectRatio | |
imageSize:(CGSize)imageSize | |
style:(EAImageCacheFormatStyle)style | |
cacheInMemory:(BOOL)cacheInMemory | |
cacheInFastDisk:(BOOL)cacheInFastDisk | |
cacheOnDisk:(BOOL)cacheOnDisk | |
maximumCount:(NSInteger)maximumCount | |
devices:(EAImageCacheFormatDevices)devices { | |
if (self = [super init]) { | |
CGFloat roundedAspectRatio = roundedTrucatedAspectRatio(entityAspectRatio); | |
self.name = [EAImageCacheFormat formatNameWithFormatFamily:family | |
aspectRatio:roundedAspectRatio]; | |
self.family = family; | |
self.entityAspectRatio = [NSString stringWithFormat:@"%.2f", roundedAspectRatio]; | |
self.imageSize = imageSize; | |
self.style = [EAImageCacheFormat FICImageFormatStyleFromEAImageCacheFormatStyle:style]; | |
self.maximumCount = maximumCount; | |
self.devices = [EAImageCacheFormat FICImageFormatDevicesFromEAImageCacheFormatDevices:devices]; | |
self.protectionMode = FICImageFormatProtectionModeNone; | |
_cacheInMemory = cacheInMemory; | |
_cacheInFastDisk = cacheInFastDisk; | |
_cacheOnDisk = cacheOnDisk; | |
} | |
return self; | |
} | |
+ (NSString *)formatNameWithFormatFamily:(NSString *)formatFamily | |
aspectRatio:(CGFloat)aspectRatio { | |
NSString *name = [NSString stringWithFormat:@"%@_%.2f", formatFamily, aspectRatio]; | |
return name; | |
} | |
+ (instancetype)formatWithFamily:(NSString *)family | |
entityAspectRatio:(CGFloat)entityAspectRatio | |
imageSize:(CGSize)imageSize | |
style:(EAImageCacheFormatStyle)style | |
cacheInMemory:(BOOL)cacheInMemory | |
cacheInFastDisk:(BOOL)cacheInFastDisk | |
cacheOnDisk:(BOOL)cacheOnDisk | |
maximumCount:(NSInteger)maximumCount | |
devices:(EAImageCacheFormatDevices)devices { | |
// See if we have an existing format that matches the same aspect ratio | |
NSString *name = [self formatNameWithFormatFamily:family aspectRatio:entityAspectRatio]; | |
EAImageCacheFormat *existingFormat = [[EAFastDiskImageCache sharedImageCache] formatWithName:name]; | |
if (existingFormat) { | |
return existingFormat; | |
} | |
EAImageCacheFormat *format = | |
[[EAImageCacheFormat alloc] initWithFamily:family | |
entityAspectRatio:entityAspectRatio | |
imageSize:imageSize | |
style:style | |
cacheInMemory:cacheInMemory | |
cacheInFastDisk:cacheInFastDisk | |
cacheOnDisk:cacheOnDisk | |
maximumCount:maximumCount | |
devices:devices]; | |
return format; | |
} | |
+ (FICImageFormatStyle)FICImageFormatStyleFromEAImageCacheFormatStyle:(EAImageCacheFormatStyle)format { | |
switch (format) { | |
case EAImageCacheFormatStyle32BitBGRA: return FICImageFormatStyle32BitBGRA; | |
case EAImageCacheFormatStyle32BitBGR: return FICImageFormatStyle32BitBGR; | |
case EAImageCacheFormatStyle16BitBGR: return FICImageFormatStyle16BitBGR; | |
case EAImageCacheFormatStyle8BitGrayscale: return FICImageFormatStyle8BitGrayscale; | |
default: return FICImageFormatStyle16BitBGR; | |
} | |
} | |
+ (FICImageFormatDevices)FICImageFormatDevicesFromEAImageCacheFormatDevices:(EAImageCacheFormatDevices)devices { | |
FICImageFormatDevices ficDevices = 0; | |
if (devices & EAImageCacheFormatDevicePad) { | |
ficDevices |= FICImageFormatDevicePad; | |
} | |
if (devices & EAImageCacheFormatDevicePhone) { | |
ficDevices |= FICImageFormatDevicePhone; | |
} | |
return ficDevices; | |
} | |
#pragma mark - Working with Dictionary Representations | |
- (NSDictionary *)dictionaryRepresentation { | |
NSMutableDictionary *dictionaryRepresentation = [[super dictionaryRepresentation] mutableCopy]; | |
dictionaryRepresentation[@"entityAspectRatio"] = self.entityAspectRatio; | |
dictionaryRepresentation[@"cacheInMemory"] = @(self.cacheInMemory); | |
dictionaryRepresentation[@"cacheInFastDisk"] = @(self.cacheInFastDisk); | |
dictionaryRepresentation[@"cacheOnDisk"] = @(self.cacheOnDisk); | |
return dictionaryRepresentation; | |
} | |
+ (EAImageCacheFormat *)formatWithDictionaryRepresentation:(NSDictionary *)dictionaryRepresentation { | |
CGSize imageSize = CGSizeMake([dictionaryRepresentation[@"width"] unsignedIntegerValue], | |
[dictionaryRepresentation[@"height"] unsignedIntegerValue]); | |
EAImageCacheFormat *format = | |
[EAImageCacheFormat formatWithFamily:dictionaryRepresentation[@"family"] | |
entityAspectRatio:[dictionaryRepresentation[@"entityAspectRatio"] floatValue] | |
imageSize:imageSize | |
style:[dictionaryRepresentation[@"style"] intValue] | |
cacheInMemory:[dictionaryRepresentation[@"cacheInMemory"] boolValue] | |
cacheInFastDisk:[dictionaryRepresentation[@"cacheInFastDisk"] boolValue] | |
cacheOnDisk:[dictionaryRepresentation[@"cacheOnDisk"] boolValue] | |
maximumCount:[dictionaryRepresentation[@"maximumCount"] unsignedIntegerValue] | |
devices:[dictionaryRepresentation[@"devices"] intValue]]; | |
return format; | |
} | |
#pragma mark - Protocol Implementations | |
#pragma mark - NSObject (NSCopying) | |
- (id)copyWithZone:(NSZone *)zone { | |
EAImageCacheFormat *imageFormatCopy = [[EAImageCacheFormat alloc] init]; | |
[imageFormatCopy setName:[self name]]; | |
[imageFormatCopy setFamily:[self family]]; | |
[imageFormatCopy setImageSize:[self imageSize]]; | |
[imageFormatCopy setStyle:[self style]]; | |
[imageFormatCopy setMaximumCount:[self maximumCount]]; | |
[imageFormatCopy setDevices:[self devices]]; | |
[imageFormatCopy setProtectionMode:[self protectionMode]]; | |
[imageFormatCopy setCacheInMemory:self.cacheInMemory]; | |
[imageFormatCopy setCacheInFastDisk:self.cacheInFastDisk]; | |
[imageFormatCopy setCacheOnDisk:self.cacheOnDisk]; | |
return imageFormatCopy; | |
} | |
#pragma mark - Internal Getters / Setters - | |
- (void)setEntityAspectRatio:(NSString *)entityAspectRatio { | |
_entityAspectRatio = [entityAspectRatio copy]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment