diff options
-rw-r--r-- | gyp/platform-ios.gypi | 2 | ||||
-rw-r--r-- | platform/ios/MGLFileCache.h | 10 | ||||
-rw-r--r-- | platform/ios/MGLFileCache.mm | 83 | ||||
-rw-r--r-- | platform/ios/MGLMapView.mm | 23 |
4 files changed, 99 insertions, 19 deletions
diff --git a/gyp/platform-ios.gypi b/gyp/platform-ios.gypi index 8d42069572..f1f95d908e 100644 --- a/gyp/platform-ios.gypi +++ b/gyp/platform-ios.gypi @@ -22,6 +22,8 @@ '../include/mbgl/ios/MGLMapView.h', '../include/mbgl/ios/MGLMapView+IBAdditions.h', '../platform/ios/MGLMapView.mm', + '../platform/ios/MGLFileCache.h', + '../platform/ios/MGLFileCache.mm', '../include/mbgl/ios/MGLAnnotation.h', '../include/mbgl/ios/MGLUserLocation.h', '../platform/ios/MGLUserLocation_Private.h', diff --git a/platform/ios/MGLFileCache.h b/platform/ios/MGLFileCache.h new file mode 100644 index 0000000000..5e9f37fe2d --- /dev/null +++ b/platform/ios/MGLFileCache.h @@ -0,0 +1,10 @@ +#import <Foundation/Foundation.h> + +#include <mbgl/storage/sqlite_cache.hpp> + +@interface MGLFileCache : NSObject + ++ (mbgl::SQLiteCache *)obtainSharedCacheWithObject:(NSObject *)object; ++ (void)releaseSharedCacheForObject:(NSObject *)object; + +@end diff --git a/platform/ios/MGLFileCache.mm b/platform/ios/MGLFileCache.mm new file mode 100644 index 0000000000..3303b395f9 --- /dev/null +++ b/platform/ios/MGLFileCache.mm @@ -0,0 +1,83 @@ +#import "MGLFileCache.h" + +@interface MGLFileCache () + +@property (nonatomic) MGLFileCache *sharedInstance; +@property (nonatomic) mbgl::SQLiteCache *sharedCache; +@property (nonatomic) NSHashTable *retainers; + +@end + +@implementation MGLFileCache + +const std::string &defaultCacheDatabasePath() { + static const std::string path = []() -> std::string { + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + if ([paths count] == 0) { + // Disable the cache if we don't have a location to write. + return ""; + } + + NSString *libraryDirectory = [paths objectAtIndex:0]; + return [[libraryDirectory stringByAppendingPathComponent:@"cache.db"] UTF8String]; + }(); + return path; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _retainers = [NSHashTable weakObjectsHashTable]; + } + return self; +} + ++ (instancetype)sharedInstance { + static dispatch_once_t onceToken; + static MGLFileCache *_sharedInstance; + dispatch_once(&onceToken, ^{ + _sharedInstance = [[self alloc] init]; + }); + return _sharedInstance; +} + +- (void)teardown { + if (self.sharedCache) { + delete self.sharedCache; + self.sharedCache = nullptr; + } +} + +- (void)dealloc { + [self.retainers removeAllObjects]; + [self teardown]; +} + ++ (mbgl::SQLiteCache *)obtainSharedCacheWithObject:(NSObject *)object { + return [[MGLFileCache sharedInstance] obtainSharedCacheWithObject:object]; +} + +- (mbgl::SQLiteCache *)obtainSharedCacheWithObject:(NSObject *)object { + assert([[NSThread currentThread] isMainThread]); + if (!self.sharedCache) { + self.sharedCache = new mbgl::SQLiteCache(defaultCacheDatabasePath()); + } + [self.retainers addObject:object]; + return self.sharedCache; +} + ++ (void)releaseSharedCacheForObject:(NSObject *)object { + return [[MGLFileCache sharedInstance] releaseSharedCacheForObject:object]; +} + +- (void)releaseSharedCacheForObject:(NSObject *)object { + assert([[NSThread currentThread] isMainThread]); + if ([self.retainers containsObject:object]) { + [self.retainers removeObject:object]; + } + if ([self.retainers count] == 0) { + [self teardown]; + } +} + +@end diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 5693c31705..3541dd9a40 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -11,7 +11,6 @@ #include <mbgl/platform/platform.hpp> #include <mbgl/platform/darwin/reachability.h> #include <mbgl/storage/default_file_source.hpp> -#include <mbgl/storage/sqlite_cache.hpp> #include <mbgl/storage/network_status.hpp> #include <mbgl/util/geo.hpp> #include <mbgl/util/constants.hpp> @@ -24,6 +23,7 @@ #import "MGLAnnotation.h" #import "MGLUserLocationAnnotationView.h" #import "MGLUserLocation_Private.h" +#import "MGLFileCache.h" #import "SMCalloutView.h" @@ -33,21 +33,6 @@ class MBGLView; -// Returns the path to the default cache database on this system. -const std::string &defaultCacheDatabase() { - static const std::string path = []() -> std::string { - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); - if ([paths count] == 0) { - // Disable the cache if we don't have a location to write. - return ""; - } - - NSString *libraryDirectory = [paths objectAtIndex:0]; - return [[libraryDirectory stringByAppendingPathComponent:@"cache.db"] UTF8String]; - }(); - return path; -} - static dispatch_once_t loadGLExtensions; NSString *const MGLDefaultStyleName = @"mapbox-streets"; @@ -101,7 +86,6 @@ static NSURL *MGLURLForBundledStyleNamed(NSString *styleName) { mbgl::Map *_mbglMap; MBGLView *_mbglView; - mbgl::SQLiteCache *_mbglFileCache; mbgl::DefaultFileSource *_mbglFileSource; BOOL _isTargetingInterfaceBuilder; @@ -277,8 +261,7 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration) // setup mbgl map // _mbglView = new MBGLView(self); - _mbglFileCache = new mbgl::SQLiteCache(defaultCacheDatabase()); - _mbglFileSource = new mbgl::DefaultFileSource(_mbglFileCache); + _mbglFileSource = new mbgl::DefaultFileSource([MGLFileCache obtainSharedCacheWithObject:self]); // Start paused on the IB canvas _mbglMap = new mbgl::Map(*_mbglView, *_mbglFileSource, mbgl::MapMode::Continuous, _isTargetingInterfaceBuilder); @@ -424,6 +407,8 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration) _mbglFileSource = nullptr; } + [MGLFileCache releaseSharedCacheForObject:self]; + if (_mbglView) { delete _mbglView; |