feat: add Resource Cache for loading the same resource
This commit is contained in:
parent
5b80e4e0e1
commit
3bedd8034c
@ -18,6 +18,7 @@ package pub.doric.resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -32,16 +33,16 @@ public class DoricResourceManager {
|
||||
private final Map<String, DoricResourceLoader> mResourceLoaders = new HashMap<>();
|
||||
private final Map<String, DoricResource> cachedResources = new WeakHashMap<>();
|
||||
|
||||
public void registerLoader(DoricResourceLoader loader) {
|
||||
public synchronized void registerLoader(DoricResourceLoader loader) {
|
||||
mResourceLoaders.put(loader.resourceType(), loader);
|
||||
}
|
||||
|
||||
public void unRegisterLoader(DoricResourceLoader loader) {
|
||||
public synchronized void unRegisterLoader(DoricResourceLoader loader) {
|
||||
mResourceLoaders.remove(loader.resourceType());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DoricResource load(@NonNull DoricContext doricContext,
|
||||
public synchronized DoricResource load(@NonNull DoricContext doricContext,
|
||||
@NonNull String resId,
|
||||
@NonNull String type,
|
||||
@NonNull String identifier) {
|
||||
|
@ -25,7 +25,8 @@
|
||||
|
||||
- (void)unRegisterLoader:(id <DoricResourceLoader>)loader;
|
||||
|
||||
- (__kindof DoricResource *)load:(NSString *)identifier
|
||||
- (__kindof DoricResource *)load:(NSString *)resId
|
||||
withIdentifier:(NSString *)identifier
|
||||
withResourceType:(NSString *)resourceType
|
||||
withContext:(DoricContext *)context;
|
||||
@end
|
||||
|
@ -21,29 +21,48 @@
|
||||
|
||||
@interface DoricResourceManager ()
|
||||
@property(nonatomic, strong) NSMutableDictionary <NSString *, id <DoricResourceLoader>> *loaders;
|
||||
@property(nonatomic, strong) NSMapTable <NSString *, __kindof DoricResource *> *cachedResources;
|
||||
@property(nonatomic, strong) dispatch_queue_t mapQueue;
|
||||
@end
|
||||
|
||||
@implementation DoricResourceManager
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
_loaders = [NSMutableDictionary new];
|
||||
_mapQueue = dispatch_queue_create("doric.resource", DISPATCH_QUEUE_SERIAL);
|
||||
_cachedResources = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsCopyIn
|
||||
valueOptions:NSPointerFunctionsWeakMemory
|
||||
capacity:0];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)registerLoader:(id <DoricResourceLoader>)loader {
|
||||
dispatch_sync(self.mapQueue, ^{
|
||||
self.loaders[loader.resourceType] = loader;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)unRegisterLoader:(id <DoricResourceLoader>)loader {
|
||||
dispatch_sync(self.mapQueue, ^{
|
||||
[self.loaders removeObjectForKey:loader.resourceType];
|
||||
});
|
||||
}
|
||||
|
||||
- (__kindof DoricResource *)load:(NSString *)identifier
|
||||
- (__kindof DoricResource *)load:(NSString *)resId
|
||||
withIdentifier:(NSString *)identifier
|
||||
withResourceType:(NSString *)resourceType
|
||||
withContext:(DoricContext *)context {
|
||||
__block __kindof DoricResource *resource;
|
||||
dispatch_sync(self.mapQueue, ^() {
|
||||
resource = [self.cachedResources objectForKey:resId];
|
||||
if (!resource) {
|
||||
id <DoricResourceLoader> loader = self.loaders[resourceType];
|
||||
return [loader load:identifier withContext:context];
|
||||
resource = [loader load:identifier withContext:context];
|
||||
[self.cachedResources setObject:resource forKey:resId];
|
||||
}
|
||||
});
|
||||
return resource;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -238,8 +238,12 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id
|
||||
if ([@"image" isEqualToString:name]) {
|
||||
NSString *type = prop[@"type"];
|
||||
NSString *identifier = prop[@"identifier"];
|
||||
NSString *resId = prop[@"resId"];
|
||||
DoricAsyncResult <NSData *> *asyncResult = [[self.doricContext.driver.registry.loaderManager
|
||||
load:identifier withResourceType:type withContext:self.doricContext] fetchRaw];
|
||||
load:resId
|
||||
withIdentifier:identifier
|
||||
withResourceType:type
|
||||
withContext:self.doricContext] fetchRaw];
|
||||
[asyncResult setResultCallback:^(NSData *imageData) {
|
||||
[self.doricContext dispatchToMainQueue:^{
|
||||
#if DORIC_USE_YYWEBIMAGE
|
||||
|
Reference in New Issue
Block a user