diff options
Diffstat (limited to 'platform/darwin')
-rw-r--r-- | platform/darwin/src/MGLFoundation.h | 7 | ||||
-rw-r--r-- | platform/darwin/src/MGLFoundation_Private.h | 8 | ||||
-rw-r--r-- | platform/darwin/src/MGLRendererConfiguration.h | 6 | ||||
-rw-r--r-- | platform/darwin/src/MGLRendererConfiguration.mm | 49 | ||||
-rw-r--r-- | platform/darwin/test/MGLRendererConfigurationTests.mm | 96 |
5 files changed, 152 insertions, 14 deletions
diff --git a/platform/darwin/src/MGLFoundation.h b/platform/darwin/src/MGLFoundation.h index be86bb92f9..3400c63979 100644 --- a/platform/darwin/src/MGLFoundation.h +++ b/platform/darwin/src/MGLFoundation.h @@ -3,10 +3,3 @@ #import <Foundation/Foundation.h> #define MGL_EXPORT __attribute__((visibility ("default"))) - -/* Using a compound statement (GNU Extension, supported by clang) */ -#define MGL_OBJC_DYNAMIC_CAST(object, type) \ - ({ \ - __typeof__( object ) temp##__LINE__ = (object); \ - (type *)([temp##__LINE__ isKindOfClass:[type class]] ? temp##__LINE__ : nil); \ - }) diff --git a/platform/darwin/src/MGLFoundation_Private.h b/platform/darwin/src/MGLFoundation_Private.h index f231628756..71737c2cf9 100644 --- a/platform/darwin/src/MGLFoundation_Private.h +++ b/platform/darwin/src/MGLFoundation_Private.h @@ -3,3 +3,11 @@ #include <mbgl/util/run_loop.hpp> void MGLInitializeRunLoop(); + +/* Using a compound statement (GNU Extension, supported by clang) */ +#define MGL_OBJC_DYNAMIC_CAST(object, type) \ + ({ \ + __typeof__( object ) temp##__LINE__ = (object); \ + (type *)([temp##__LINE__ isKindOfClass:[type class]] ? temp##__LINE__ : nil); \ + }) + diff --git a/platform/darwin/src/MGLRendererConfiguration.h b/platform/darwin/src/MGLRendererConfiguration.h index d5b6527d7e..ea13582488 100644 --- a/platform/darwin/src/MGLRendererConfiguration.h +++ b/platform/darwin/src/MGLRendererConfiguration.h @@ -1,3 +1,4 @@ +#import "MGLFoundation.h" #import <Foundation/Foundation.h> #import <mbgl/storage/default_file_source.hpp> #import <mbgl/renderer/mode.hpp> @@ -8,6 +9,7 @@ NS_ASSUME_NONNULL_BEGIN The MGLRendererConfiguration object represents configuration values for the renderer. */ +MGL_EXPORT @interface MGLRendererConfiguration : NSObject /** Returns an instance of the current renderer configuration. */ @@ -39,7 +41,9 @@ NS_ASSUME_NONNULL_BEGIN A Boolean value indicating whether symbol layers may enable per-source symbol collision detection. - Set `MGLCollisionBehaviorPre4_0` in your containing app's Info.plist. + Set `MGLCollisionBehaviorPre4_0` in your containing app's Info.plist or by using + `[[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:@"MGLCollisionBehaviorPre4_0"]`. + If both are set, the value from `NSUserDefaults` takes priority. Setting this property to `YES` in the plist results in symbol layers only running collision detection against other symbol layers that are part of the same source. diff --git a/platform/darwin/src/MGLRendererConfiguration.mm b/platform/darwin/src/MGLRendererConfiguration.mm index b31da674cf..90778ea86d 100644 --- a/platform/darwin/src/MGLRendererConfiguration.mm +++ b/platform/darwin/src/MGLRendererConfiguration.mm @@ -1,5 +1,6 @@ #import "MGLRendererConfiguration.h" #import "MGLOfflineStorage_Private.h" +#import "MGLFoundation_Private.h" #if TARGET_OS_IPHONE #import <UIKit/UIKit.h> @@ -7,6 +8,12 @@ #import <AppKit/AppKit.h> #endif +static NSString * const MGLCollisionBehaviorPre4_0Key = @"MGLCollisionBehaviorPre4_0"; + +@interface MGLRendererConfiguration () +@property (nonatomic, readwrite) BOOL perSourceCollisions; +@end + @implementation MGLRendererConfiguration @@ -14,6 +21,42 @@ return [[self alloc] init]; } +- (instancetype)init { + return [self initWithPropertyDictionary:[[NSBundle mainBundle] infoDictionary]]; +} + +- (instancetype)initWithPropertyDictionary:(nonnull NSDictionary *)properties { + self = [super init]; + + if (self) { + // Set the collision behaviour. A value set in `NSUserDefaults.standardUserDefaults` + // should override anything in the application's info.plist + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + + if ([defaults objectForKey:MGLCollisionBehaviorPre4_0Key]) { + _perSourceCollisions = [defaults boolForKey:MGLCollisionBehaviorPre4_0Key]; + } + else { + id collisionBehaviourValue = properties[MGLCollisionBehaviorPre4_0Key]; + + NSNumber *collisionBehaviourNumber = MGL_OBJC_DYNAMIC_CAST(collisionBehaviourValue, NSNumber); + + if (collisionBehaviourNumber) { + _perSourceCollisions = collisionBehaviourNumber.boolValue; + } else { + // Also support NSString to correspond with the behavior of `-[NSUserDefaults boolForKey:]` + NSString *collisionBehaviourString = MGL_OBJC_DYNAMIC_CAST(collisionBehaviourValue, NSString); + + if (collisionBehaviourString) { + _perSourceCollisions = collisionBehaviourString.boolValue; + } + } + } + } + + return self; +} + - (mbgl::DefaultFileSource *)fileSource { return [MGLOfflineStorage sharedOfflineStorage].mbglFileSource; } @@ -40,10 +83,4 @@ return fontFamilyName ? std::string([fontFamilyName UTF8String]) : mbgl::optional<std::string>(); } -- (BOOL)perSourceCollisions { - NSNumber *boolWrapper = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"MGLCollisionBehaviorPre4_0"]; - - return boolWrapper.boolValue; -} - @end diff --git a/platform/darwin/test/MGLRendererConfigurationTests.mm b/platform/darwin/test/MGLRendererConfigurationTests.mm new file mode 100644 index 0000000000..a0c630ebb5 --- /dev/null +++ b/platform/darwin/test/MGLRendererConfigurationTests.mm @@ -0,0 +1,96 @@ +#import <Mapbox/Mapbox.h> +#import <XCTest/XCTest.h> +#import "MGLRendererConfiguration.h" + +static NSString * const MGLRendererConfigurationTests_collisionBehaviorKey = @"MGLCollisionBehaviorPre4_0"; + +@interface MGLRendererConfiguration (Tests) +- (instancetype)initWithPropertyDictionary:(nonnull NSDictionary*)bundle; +@end + + +@interface MGLRendererConfigurationTests : XCTestCase +@end + +@implementation MGLRendererConfigurationTests +- (void)setUp { + [[NSUserDefaults standardUserDefaults] removeObjectForKey:MGLRendererConfigurationTests_collisionBehaviorKey]; +} + +- (void)tearDown { + [[NSUserDefaults standardUserDefaults] removeObjectForKey:MGLRendererConfigurationTests_collisionBehaviorKey]; +} + +// Emulate what would happen with an Info.plist. +- (void)testSettingMGLCollisionBehaviorPre40WithEmptyDictionary +{ + MGLRendererConfiguration *config = [[MGLRendererConfiguration alloc] initWithPropertyDictionary:@{}]; + XCTAssertFalse(config.perSourceCollisions); +} + +- (void)testSettingMGLCollisionBehaviorPre40WithYESDictionary +{ + MGLRendererConfiguration *config = [[MGLRendererConfiguration alloc] initWithPropertyDictionary:@{MGLRendererConfigurationTests_collisionBehaviorKey:@(NO)}]; + XCTAssertFalse(config.perSourceCollisions); +} + +- (void)testSettingMGLCollisionBehaviorPre40WithNODictionary +{ + MGLRendererConfiguration *config = [[MGLRendererConfiguration alloc] initWithPropertyDictionary:@{MGLRendererConfigurationTests_collisionBehaviorKey:@(YES)}]; + XCTAssert(config.perSourceCollisions); +} + +- (void)testSettingMGLCollisionBehaviorPre40InNSUserDefaults { + { + XCTAssertNil([[NSUserDefaults standardUserDefaults] objectForKey:MGLRendererConfigurationTests_collisionBehaviorKey]); + MGLRendererConfiguration *config = [MGLRendererConfiguration currentConfiguration]; + XCTAssertFalse(config.perSourceCollisions); + } + + [[NSUserDefaults standardUserDefaults] setObject:@(NO) forKey:MGLRendererConfigurationTests_collisionBehaviorKey]; + { + XCTAssertNotNil([[NSUserDefaults standardUserDefaults] objectForKey:MGLRendererConfigurationTests_collisionBehaviorKey]); + MGLRendererConfiguration *config = [MGLRendererConfiguration currentConfiguration]; + XCTAssertFalse(config.perSourceCollisions); + } + + [[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:MGLRendererConfigurationTests_collisionBehaviorKey]; + { + XCTAssertNotNil([[NSUserDefaults standardUserDefaults] objectForKey:MGLRendererConfigurationTests_collisionBehaviorKey]); + MGLRendererConfiguration *config = [MGLRendererConfiguration currentConfiguration]; + XCTAssert(config.perSourceCollisions); + } +} + +- (void)testSettingMGLCollisionBehaviorPre40PListValueUsingString { + // Dictionary = "NO" + { + MGLRendererConfiguration *config = [[MGLRendererConfiguration alloc] initWithPropertyDictionary:@{MGLRendererConfigurationTests_collisionBehaviorKey:@"NO"}]; + XCTAssertFalse(config.perSourceCollisions); + } + + // Dictionary = "YES" + { + MGLRendererConfiguration *config = [[MGLRendererConfiguration alloc] initWithPropertyDictionary:@{MGLRendererConfigurationTests_collisionBehaviorKey:@"YES"}]; + XCTAssert(config.perSourceCollisions); + } +} + +- (void)testOverridingMGLCollisionBehaviorPre40 { + + // Dictionary = NO, NSUserDefaults = YES + { + [[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:MGLRendererConfigurationTests_collisionBehaviorKey]; + MGLRendererConfiguration *config = [[MGLRendererConfiguration alloc] initWithPropertyDictionary:@{MGLRendererConfigurationTests_collisionBehaviorKey:@(NO)}]; + XCTAssert(config.perSourceCollisions); + } + + // Dictionary = YES, NSUserDefaults = NO + { + [[NSUserDefaults standardUserDefaults] setObject:@(NO) forKey:MGLRendererConfigurationTests_collisionBehaviorKey]; + MGLRendererConfiguration *config = [[MGLRendererConfiguration alloc] initWithPropertyDictionary:@{MGLRendererConfigurationTests_collisionBehaviorKey:@(YES)}]; + XCTAssertFalse(config.perSourceCollisions); + } +} + +@end |