Skip to content

Commit

Permalink
Make QSResourceManager thread safe
Browse files Browse the repository at this point in the history
Fixes #1861
  • Loading branch information
pjrobertson committed Jun 8, 2014
1 parent 7457748 commit b7e1d05
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 94 deletions.
2 changes: 1 addition & 1 deletion Quicksilver/Code-App/QSMainMenuPrefPane.m
Expand Up @@ -69,7 +69,7 @@ - (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier willSendRequ
[(NSMutableURLRequest *)request setURL:[NSURL fileURLWithPath:path]];
}
} else if ([[[request URL] scheme] isEqualToString:@"qsimage"]) {
NSString *path = [QSRez pathForImageNamed:[[request URL] host]];
NSString *path = [[QSResourceManager sharedInstance] pathForImageNamed:[[request URL] host]];
if (path) {
request = [request mutableCopy];
[(NSMutableURLRequest *)request setURL:[NSURL fileURLWithPath:path]];
Expand Down
2 changes: 1 addition & 1 deletion Quicksilver/Code-QuickStepCore/QSAction.m
Expand Up @@ -406,7 +406,7 @@ - (void)setQuickIconForObject:(QSObject *)object { [object setIcon:[NSImage imag
- (BOOL)drawIconForObject:(QSObject *)object inRect:(NSRect)rect flipped:(BOOL)flipped { return NO; }

- (BOOL)loadIconForObject:(QSObject *)object {
NSImage *icon = [QSRez imageWithExactName:[object identifier]];
NSImage *icon = [[QSResourceManager sharedInstance] imageWithExactName:[object identifier]];
NSString *name = [[object objectForType:QSActionType] objectForKey:kActionIcon];
if (!icon && name)
icon = [QSResourceManager imageNamed:name inBundle:[object bundle]];
Expand Down
4 changes: 2 additions & 2 deletions Quicksilver/Code-QuickStepCore/QSCommand.m
Expand Up @@ -359,7 +359,7 @@ - (QSObject *)dObject {
}

if (!object) {
object = [QSObject fileObjectWithPath:[QSRez pathWithLocatorInformation:[cmdDict objectForKey:@"directResource"]]];
object = [QSObject fileObjectWithPath:[[QSResourceManager sharedInstance] pathWithLocatorInformation:[cmdDict objectForKey:@"directResource"]]];
}

// For cases where the command has a directID/directArchive, but its corresponding object hasn't already been created (i.e. *not* in the catalog)
Expand Down Expand Up @@ -399,7 +399,7 @@ - (QSObject *)iObject {
}

if (!object) {
object = [QSObject fileObjectWithPath:[QSRez pathWithLocatorInformation:[cmdDict objectForKey:@"indirectResource"]]];
object = [QSObject fileObjectWithPath:[[QSResourceManager sharedInstance] pathWithLocatorInformation:[cmdDict objectForKey:@"indirectResource"]]];
}

// For cases where the object doesn't exist (not in the catalog)
Expand Down
5 changes: 3 additions & 2 deletions Quicksilver/Code-QuickStepCore/QSResourceManager.h
Expand Up @@ -11,16 +11,17 @@ extern id QSRez;
NSString *resourceOverrideFolder;
NSDictionary *resourceOverrideList;
}
+ (void)initialize;

+ (id)sharedInstance;
+ (NSImage *)imageNamed:(NSString *)name;
+ (NSImage *)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle;
- (NSImage *)imageNamed:(NSString *)name;

- (NSImage *)imageWithLocatorInformation:(id)locator;
- (void)addResourcesFromDictionary:(NSDictionary *)dict;
- (NSString *)pathWithLocatorInformation:(id)locator;
- (NSImage *)imageWithExactName:(NSString *)name;
//- (NSImage *)daedalusImage;

- (NSString *)pathForImageNamed:(NSString *)name;
@end

170 changes: 83 additions & 87 deletions Quicksilver/Code-QuickStepCore/QSResourceManager.m
Expand Up @@ -2,32 +2,28 @@
#import "QSRegistry.h"
#import "QSLocalization.h"

NSString *gSysIconBundle = nil;
id QSRez;
#define gSysIconBundle @"/System/Library/CoreServices/CoreTypes.bundle"

@implementation QSResourceManager
QSResourceManager * QSRez;

+ (void)initialize {
//SInt32 version;
//Gestalt (gestaltSystemVersion, &version);
//if (version < 0x1040)
// gSysIconBundle = @"/System/Library/CoreServices/SystemIcons.bundle";
//else
gSysIconBundle = @"/System/Library/CoreServices/CoreTypes.bundle";
// NSLog(@"Using %@", gSysIconBundle);
}
@implementation QSResourceManager

+ (id)sharedInstance {
if (!QSRez) QSRez = [[[self class] allocWithZone:nil] init];
return QSRez;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
QSRez = [[self alloc] init];
});
return QSRez;
}

+ (NSImage *)imageNamed:(NSString *)name {
return [[self sharedInstance] imageNamed:name];
}

+ (NSImage *)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle {
return [[self sharedInstance] imageNamed:name inBundle:bundle];
}

- (id)init {
if (self = [super init]) {
resourceDict = [NSMutableDictionary dictionaryWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"ResourceLocations" ofType:@"plist"]];
Expand All @@ -52,91 +48,91 @@ - (NSImage *)sysIconNamed:(NSString *)name {
if (!path) return nil;
return [[NSImage alloc] initByReferencingFile:path];
}
- (NSString *)resourceNamed:(NSString *)name inBundle:(NSBundle *)bundle {
return nil;
}

- (NSString *)pathForImageNamed:(NSString *)name {
id locator = [resourceDict objectForKey:name];
return [self pathWithLocatorInformation:locator];
}

- (NSImage *)imageWithExactName:(NSString *)name {
NSImage *image = [NSImage imageNamed:name];
if (!image && resourceOverrideList) {
NSString *file = [resourceOverrideList objectForKey:name];
if (file)
image = [[NSImage alloc] initByReferencingFile:[resourceOverrideFolder stringByAppendingPathComponent:file]];
[image setName:name];

}

id locator = [resourceDict objectForKey:name];
if ([locator isKindOfClass:[NSNull class]]) return nil;
if (locator)
image = [self imageWithLocatorInformation:locator];
return image;
}

- (NSImage *)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle {
if (!name) { return nil; }

NSImage *image = [NSImage imageNamed:name];
if (!image && resourceOverrideList) {
NSString *file = [resourceOverrideList objectForKey:name];
if (file) {
image = [[NSImage alloc] initByReferencingFile:[resourceOverrideFolder stringByAppendingPathComponent:file]];
}
[image setName:name];
}

if (!image && bundle) { image = [bundle imageNamed:name]; }

if (image) { return image; }

id locator = [resourceDict objectForKey:name];
if ([locator isKindOfClass:[NSNull class]]) { return nil; }
if (locator) {
image = [self imageWithLocatorInformation:locator];
} else if (!image && ([name hasPrefix:@"/"] || [name hasPrefix:@"~"])) { // !!! Andre Berg 20091007: Try iconForFile first if name looks like ordinary path
NSString *path = [name stringByStandardizingPath];
if ([[NSImage imageUnfilteredFileTypes] containsObject:[path pathExtension]]) {
image = [[NSImage alloc] initByReferencingFile:path];
} else {
image = [[NSWorkspace sharedWorkspace] iconForFile:path];
}
} else {// Try the systemicons bundle
image = [self sysIconNamed:name];
if (!image) { // Try by bundle id
image = [self imageWithLocatorInformation:[NSDictionary dictionaryWithObjectsAndKeys:name, @"bundle", nil]];
}
}
if (!image && [locator isKindOfClass:[NSString class]]) {
image = [self imageNamed:locator];
}

if(!image) {
SEL selector = NSSelectorFromString([NSString stringWithFormat:@"%@Image", name]);
if ([self respondsToSelector:selector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
image = [self performSelector:selector];
#pragma clang diagnostic pop
}
}

if (!image) {
[resourceDict setObject:[NSNull null] forKey:name];
} else {
[image setName:name];
}
return image;
@synchronized(self) {
NSImage *image = [NSImage imageNamed:name];
if (!image && resourceOverrideList) {
NSString *file = [resourceOverrideList objectForKey:name];
if (file)
image = [[NSImage alloc] initByReferencingFile:[resourceOverrideFolder stringByAppendingPathComponent:file]];
[image setName:name];

}

id locator = [resourceDict objectForKey:name];
if ([locator isKindOfClass:[NSNull class]]) return nil;
if (locator)
image = [self imageWithLocatorInformation:locator];
return image;
}
}

- (NSImage *)imageNamed:(NSString *)name {
return [self imageNamed:name inBundle:nil];
}

- (NSImage *)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle {
@synchronized(self) {
if (!name) { return nil; }

NSImage *image = [NSImage imageNamed:name];
if (!image && resourceOverrideList) {
NSString *file = [resourceOverrideList objectForKey:name];
if (file) {
image = [[NSImage alloc] initByReferencingFile:[resourceOverrideFolder stringByAppendingPathComponent:file]];
}
[image setName:name];
}

if (!image && bundle) { image = [bundle imageNamed:name]; }

if (image) { return image; }

id locator = [resourceDict objectForKey:name];
if ([locator isKindOfClass:[NSNull class]]) { return nil; }
if (locator) {
image = [self imageWithLocatorInformation:locator];
} else if (!image && ([name hasPrefix:@"/"] || [name hasPrefix:@"~"])) { // !!! Andre Berg 20091007: Try iconForFile first if name looks like ordinary path
NSString *path = [name stringByStandardizingPath];
if ([[NSImage imageUnfilteredFileTypes] containsObject:[path pathExtension]]) {
image = [[NSImage alloc] initByReferencingFile:path];
} else {
image = [[NSWorkspace sharedWorkspace] iconForFile:path];
}
} else {// Try the systemicons bundle
image = [self sysIconNamed:name];
if (!image) { // Try by bundle id
image = [self imageWithLocatorInformation:[NSDictionary dictionaryWithObjectsAndKeys:name, @"bundle", nil]];
}
}
if (!image && [locator isKindOfClass:[NSString class]]) {
image = [self imageNamed:locator];
}

if(!image) {
SEL selector = NSSelectorFromString([NSString stringWithFormat:@"%@Image", name]);
if ([self respondsToSelector:selector]) {
image = ((NSImage* (*)(id, SEL))[self methodForSelector:selector])(self, selector);
}
}

if (!image) {
[resourceDict setObject:[NSNull null] forKey:name];
} else {
[image setName:name];
}
return image;
}
}

- (NSString *)pathWithLocatorInformation:(id)locator {
@synchronized(self) {
NSString *path = nil;
if ([locator isKindOfClass:[NSString class]]) {
if (![locator length]) return nil;
Expand Down Expand Up @@ -180,7 +176,7 @@ - (NSString *)pathWithLocatorInformation:(id)locator {

}
return path;

}
}

- (NSImage *)imageWithLocatorInformation:(id)locator {
Expand Down
2 changes: 1 addition & 1 deletion Quicksilver/Code-QuickStepInterface/BLTRResizeView.m
Expand Up @@ -26,7 +26,7 @@ - (void)drawRect:(NSRect)rect {
[transform translateXBy:-16 yBy:0];
}
[transform concat];
[[NSImage imageNamed:@"ResizeWidget"] drawInRect:rect fromRect:rect operation:NSCompositeSourceOver fraction:1.0];
[[QSResourceManager imageNamed:@"ResizeWidget"] drawInRect:rect fromRect:rect operation:NSCompositeSourceOver fraction:1.0];
}

- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { return YES; }
Expand Down

0 comments on commit b7e1d05

Please sign in to comment.