From 578d48b303d5d615ac70f9f1f6f3edfef020d8a3 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Wed, 22 Apr 2015 17:19:59 -0500 Subject: [PATCH 01/33] #1225 - Initial setup of MapboxGL as a singleton object with access token --- gyp/platform-ios.gypi | 1 + include/mbgl/ios/MapboxGL.h | 6 ++++++ platform/ios/MapboxGL.m | 39 +++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 platform/ios/MapboxGL.m diff --git a/gyp/platform-ios.gypi b/gyp/platform-ios.gypi index f70743118..142896c4e 100644 --- a/gyp/platform-ios.gypi +++ b/gyp/platform-ios.gypi @@ -17,6 +17,7 @@ '../platform/darwin/image.mm', '../platform/darwin/reachability.m', '../include/mbgl/ios/MapboxGL.h', + '../platform/ios/MapboxGL.m', '../include/mbgl/ios/MGLMapboxEvents.h', '../platform/ios/MGLMapboxEvents.m', '../include/mbgl/ios/MGLMapView.h', diff --git a/include/mbgl/ios/MapboxGL.h b/include/mbgl/ios/MapboxGL.h index c32915bc7..84c3f4542 100644 --- a/include/mbgl/ios/MapboxGL.h +++ b/include/mbgl/ios/MapboxGL.h @@ -2,3 +2,9 @@ #import "MGLMapView.h" #import "MGLTypes.h" #import "MGLUserLocation.h" + +@interface MapboxGL : NSObject + ++ (void) sharedInstanceWithAccessToken:(NSString *)token; + +@end \ No newline at end of file diff --git a/platform/ios/MapboxGL.m b/platform/ios/MapboxGL.m new file mode 100644 index 000000000..b1cb44cbc --- /dev/null +++ b/platform/ios/MapboxGL.m @@ -0,0 +1,39 @@ +#import + +#import "MapboxGL.h" + +@interface MapboxGL() + +@end + +@property (atomic) NSString *accessToken; + +@implementation MapboxGL + + +// Can be called from any thread. Called implicitly from any +// public class convenience methods. +// ++ (instancetype) sharedInstanceWithAccessToken:(NSString *)token { + static dispatch_once_t onceToken; + static MapboxGL *_sharedManager; + dispatch_once(&onceToken, ^{ + if ( ! NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent) { + void (^setupBlock)() = ^{ + _sharedManager = [[self alloc] init]; + _sharedManager.accessToken = token; + }; + if ( ! [[NSThread currentThread] isMainThread]) { + dispatch_sync(dispatch_get_main_queue(), ^{ + setupBlock(); + }); + } + else { + setupBlock(); + } + } + }); + return _sharedManager; +} + +@end \ No newline at end of file From 7e145780ebbd5d35a74f263c51827ae2a37c4eb8 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Thu, 23 Apr 2015 18:15:01 -0500 Subject: [PATCH 02/33] #1225 - Initial conversion of Mapbox GL app to set access token in AppDelegate and exposing MGLMapView.initWithFrame to support it --- include/mbgl/ios/MGLMapView.h | 5 +++++ include/mbgl/ios/MapboxGL.h | 3 ++- ios/app/MBXAppDelegate.m | 16 ++++++++++++++++ ios/app/MBXViewController.mm | 15 +-------------- platform/ios/MGLMapView.mm | 2 ++ platform/ios/MapboxGL.m | 15 ++++++++++++--- 6 files changed, 38 insertions(+), 18 deletions(-) diff --git a/include/mbgl/ios/MGLMapView.h b/include/mbgl/ios/MGLMapView.h index 8717b5e8a..eb9a770dc 100644 --- a/include/mbgl/ios/MGLMapView.h +++ b/include/mbgl/ios/MGLMapView.h @@ -20,6 +20,11 @@ IB_DESIGNABLE /** @name Initializing a Map View */ +/** Initialize a map view with the default style, given frame, and access token set in MapboxGL singleton. +* @param frame The frame with which to initialize the map view. +* @return An initialized map view, or `nil` if the map view was unable to be initialized. */ +- (instancetype)initWithFrame:(CGRect)frame; + /** Initialize a map view with the default style and a given frame and access token. * @param frame The frame with which to initialize the map view. * @param accessToken A Mapbox API access token. diff --git a/include/mbgl/ios/MapboxGL.h b/include/mbgl/ios/MapboxGL.h index 84c3f4542..4e5ff09b2 100644 --- a/include/mbgl/ios/MapboxGL.h +++ b/include/mbgl/ios/MapboxGL.h @@ -5,6 +5,7 @@ @interface MapboxGL : NSObject -+ (void) sharedInstanceWithAccessToken:(NSString *)token; ++ (id) sharedInstanceWithAccessToken:(NSString *)token; ++ (NSString *) getAccessToken; @end \ No newline at end of file diff --git a/ios/app/MBXAppDelegate.m b/ios/app/MBXAppDelegate.m index f2ef69ec6..4d314483a 100644 --- a/ios/app/MBXAppDelegate.m +++ b/ios/app/MBXAppDelegate.m @@ -1,11 +1,27 @@ #import "MBXAppDelegate.h" #import "MBXViewController.h" +#import #import @implementation MBXAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Set Access Token + NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"]; + if (accessToken) { + // Store to preferences so that we can launch the app later on without having to specify + // token. + [[NSUserDefaults standardUserDefaults] setObject:accessToken forKey:@"access_token"]; + } else { + // Try to retrieve from preferences, maybe we've stored them there previously and can reuse + // the token. + accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"access_token"]; + } + if ( ! accessToken) NSLog(@"No access token set. Mapbox vector tiles won't work."); + + [MapboxGL sharedInstanceWithAccessToken:accessToken]; + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[MBXViewController new]]; [self.window makeKeyAndVisible]; diff --git a/ios/app/MBXViewController.mm b/ios/app/MBXViewController.mm index 13235beb0..394536b98 100644 --- a/ios/app/MBXViewController.mm +++ b/ios/app/MBXViewController.mm @@ -52,20 +52,7 @@ mbgl::Settings_NSUserDefaults *settings = nullptr; { [super viewDidLoad]; - NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"]; - if (accessToken) { - // Store to preferences so that we can launch the app later on without having to specify - // token. - [[NSUserDefaults standardUserDefaults] setObject:accessToken forKey:@"access_token"]; - } else { - // Try to retrieve from preferences, maybe we've stored them there previously and can reuse - // the token. - accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"access_token"]; - } - - if ( ! accessToken) NSLog(@"No access token set. Mapbox vector tiles won't work."); - - self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:accessToken]; + self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds]; self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.mapView.viewControllerForLayoutGuides = self; self.mapView.showsUserLocation = YES; diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 5f5e99b0e..e48b3d82d 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -25,6 +25,7 @@ #import "SMCalloutView.h" #import "MGLMapboxEvents.h" +#import "MapboxGL.h" #import @@ -122,6 +123,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; if (self && [self commonInit]) { self.styleURL = nil; + self.accessToken = [MapboxGL getAccessToken]; return self; } diff --git a/platform/ios/MapboxGL.m b/platform/ios/MapboxGL.m index b1cb44cbc..97ac8f1d5 100644 --- a/platform/ios/MapboxGL.m +++ b/platform/ios/MapboxGL.m @@ -1,22 +1,24 @@ #import #import "MapboxGL.h" +#import "NSProcessInfo+MGLAdditions.h" @interface MapboxGL() +@property (atomic) NSString *accessToken; + @end -@property (atomic) NSString *accessToken; @implementation MapboxGL +static MapboxGL *_sharedManager; // Can be called from any thread. Called implicitly from any // public class convenience methods. // -+ (instancetype) sharedInstanceWithAccessToken:(NSString *)token { ++ (id) sharedInstanceWithAccessToken:(NSString *)token { static dispatch_once_t onceToken; - static MapboxGL *_sharedManager; dispatch_once(&onceToken, ^{ if ( ! NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent) { void (^setupBlock)() = ^{ @@ -36,4 +38,11 @@ return _sharedManager; } ++ (NSString *) getAccessToken { + if (_sharedManager) { + return _sharedManager.accessToken; + } + return nil; +} + @end \ No newline at end of file From 317be3470827ab278e930240b71fefee3fe87c02 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Fri, 24 Apr 2015 15:29:34 -0500 Subject: [PATCH 03/33] #1225 - Removing unavailable block on MGLMapView.initWithFrame --- include/mbgl/ios/MGLMapView.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/mbgl/ios/MGLMapView.h b/include/mbgl/ios/MGLMapView.h index eb9a770dc..e6aaee9a0 100644 --- a/include/mbgl/ios/MGLMapView.h +++ b/include/mbgl/ios/MGLMapView.h @@ -38,8 +38,6 @@ IB_DESIGNABLE * @return An initialized map view, or `nil` if the map view was unable to be initialized. */ - (instancetype)initWithFrame:(CGRect)frame accessToken:(NSString *)accessToken styleURL:(NSURL *)styleURL; -- (instancetype)initWithFrame:(CGRect)frame __attribute__((unavailable("Instantiating an MGLMapView requires setting a style and/or an access token."))); - #pragma mark - Authorizing Access /** @name Authorizing Access */ From 591c63286b6471a6c769eb17d8e1b16c698a4e11 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Fri, 24 Apr 2015 15:41:21 -0500 Subject: [PATCH 04/33] #1225 - Converting id to instancetype --- include/mbgl/ios/MapboxGL.h | 2 +- platform/ios/MapboxGL.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbgl/ios/MapboxGL.h b/include/mbgl/ios/MapboxGL.h index 4e5ff09b2..8470591d5 100644 --- a/include/mbgl/ios/MapboxGL.h +++ b/include/mbgl/ios/MapboxGL.h @@ -5,7 +5,7 @@ @interface MapboxGL : NSObject -+ (id) sharedInstanceWithAccessToken:(NSString *)token; ++ (instancetype) sharedInstanceWithAccessToken:(NSString *)token; + (NSString *) getAccessToken; @end \ No newline at end of file diff --git a/platform/ios/MapboxGL.m b/platform/ios/MapboxGL.m index 97ac8f1d5..0c8812821 100644 --- a/platform/ios/MapboxGL.m +++ b/platform/ios/MapboxGL.m @@ -17,7 +17,7 @@ static MapboxGL *_sharedManager; // Can be called from any thread. Called implicitly from any // public class convenience methods. // -+ (id) sharedInstanceWithAccessToken:(NSString *)token { ++ (instancetype) sharedInstanceWithAccessToken:(NSString *)token { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ if ( ! NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent) { From f96046103f3800b95e80753f4b63435d4946fcd0 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Fri, 24 Apr 2015 16:09:50 -0500 Subject: [PATCH 05/33] #1225 - Starting Mapbox Events at shared instance setup time --- platform/ios/MapboxGL.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/ios/MapboxGL.m b/platform/ios/MapboxGL.m index 0c8812821..7c542cb36 100644 --- a/platform/ios/MapboxGL.m +++ b/platform/ios/MapboxGL.m @@ -2,6 +2,7 @@ #import "MapboxGL.h" #import "NSProcessInfo+MGLAdditions.h" +#import "MGLMapboxEvents.h" @interface MapboxGL() @@ -24,6 +25,7 @@ static MapboxGL *_sharedManager; void (^setupBlock)() = ^{ _sharedManager = [[self alloc] init]; _sharedManager.accessToken = token; + [MGLMapboxEvents setToken:token]; }; if ( ! [[NSThread currentThread] isMainThread]) { dispatch_sync(dispatch_get_main_queue(), ^{ From 0e36bf1c8d620b55db1171a1575350e7e4ac699f Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Mon, 4 May 2015 16:13:18 -0500 Subject: [PATCH 06/33] #1225 - Restoring MapboxGL.h as an Umbrella header file by splitting the singleton code into MGLAccountManager.h and .m --- gyp/platform-ios.gypi | 3 ++- include/mbgl/ios/MGLAccountManager.h | 6 ++++++ include/mbgl/ios/MapboxGL.h | 8 +------- ios/app/MBXAppDelegate.m | 3 ++- platform/ios/{MapboxGL.m => MGLAccountManager.m} | 8 ++++---- platform/ios/MGLMapView.mm | 2 +- test/ios/KIF | 2 +- 7 files changed, 17 insertions(+), 15 deletions(-) create mode 100644 include/mbgl/ios/MGLAccountManager.h rename platform/ios/{MapboxGL.m => MGLAccountManager.m} (89%) diff --git a/gyp/platform-ios.gypi b/gyp/platform-ios.gypi index 142896c4e..305fd5284 100644 --- a/gyp/platform-ios.gypi +++ b/gyp/platform-ios.gypi @@ -17,12 +17,13 @@ '../platform/darwin/image.mm', '../platform/darwin/reachability.m', '../include/mbgl/ios/MapboxGL.h', - '../platform/ios/MapboxGL.m', '../include/mbgl/ios/MGLMapboxEvents.h', '../platform/ios/MGLMapboxEvents.m', '../include/mbgl/ios/MGLMapView.h', '../include/mbgl/ios/MGLMapView+IBAdditions.h', '../platform/ios/MGLMapView.mm', + '../include/mbgl/ios/MGLAccountManager.h', + '../platform/ios/MGLAccountManager.m', '../include/mbgl/ios/MGLAnnotation.h', '../include/mbgl/ios/MGLUserLocation.h', '../platform/ios/MGLUserLocation_Private.h', diff --git a/include/mbgl/ios/MGLAccountManager.h b/include/mbgl/ios/MGLAccountManager.h new file mode 100644 index 000000000..aed2536a3 --- /dev/null +++ b/include/mbgl/ios/MGLAccountManager.h @@ -0,0 +1,6 @@ +@interface MGLAccountManager : NSObject + ++ (instancetype) sharedInstanceWithAccessToken:(NSString *)token; ++ (NSString *) getAccessToken; + +@end \ No newline at end of file diff --git a/include/mbgl/ios/MapboxGL.h b/include/mbgl/ios/MapboxGL.h index 8470591d5..34e080a51 100644 --- a/include/mbgl/ios/MapboxGL.h +++ b/include/mbgl/ios/MapboxGL.h @@ -2,10 +2,4 @@ #import "MGLMapView.h" #import "MGLTypes.h" #import "MGLUserLocation.h" - -@interface MapboxGL : NSObject - -+ (instancetype) sharedInstanceWithAccessToken:(NSString *)token; -+ (NSString *) getAccessToken; - -@end \ No newline at end of file +#import "MGLAccountManager.h" \ No newline at end of file diff --git a/ios/app/MBXAppDelegate.m b/ios/app/MBXAppDelegate.m index 4d314483a..0a81e83fb 100644 --- a/ios/app/MBXAppDelegate.m +++ b/ios/app/MBXAppDelegate.m @@ -1,6 +1,7 @@ #import "MBXAppDelegate.h" #import "MBXViewController.h" #import +#import #import @implementation MBXAppDelegate @@ -20,7 +21,7 @@ } if ( ! accessToken) NSLog(@"No access token set. Mapbox vector tiles won't work."); - [MapboxGL sharedInstanceWithAccessToken:accessToken]; + [MGLAccountManager sharedInstanceWithAccessToken:accessToken]; self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[MBXViewController new]]; diff --git a/platform/ios/MapboxGL.m b/platform/ios/MGLAccountManager.m similarity index 89% rename from platform/ios/MapboxGL.m rename to platform/ios/MGLAccountManager.m index 7c542cb36..d408ba8d4 100644 --- a/platform/ios/MapboxGL.m +++ b/platform/ios/MGLAccountManager.m @@ -1,19 +1,19 @@ #import -#import "MapboxGL.h" +#import "MGLAccountManager.h" #import "NSProcessInfo+MGLAdditions.h" #import "MGLMapboxEvents.h" -@interface MapboxGL() +@interface MGLAccountManager() @property (atomic) NSString *accessToken; @end -@implementation MapboxGL +@implementation MGLAccountManager -static MapboxGL *_sharedManager; +static MGLAccountManager *_sharedManager; // Can be called from any thread. Called implicitly from any // public class convenience methods. diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index e48b3d82d..b915fa01f 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -123,7 +123,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; if (self && [self commonInit]) { self.styleURL = nil; - self.accessToken = [MapboxGL getAccessToken]; + self.accessToken = [MGLAccountManager getAccessToken]; return self; } diff --git a/test/ios/KIF b/test/ios/KIF index ab5a46ff7..976aafa2e 160000 --- a/test/ios/KIF +++ b/test/ios/KIF @@ -1 +1 @@ -Subproject commit ab5a46ff7e970de5578df48a1e1f013bd5e1bd4e +Subproject commit 976aafa2e211dd095411bfef09da6c0919d70476 From 7f6cc6cc6d462952c02fbc50bd90f4f765a55809 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Mon, 4 May 2015 16:52:41 -0500 Subject: [PATCH 07/33] #1225 - Renaming getAccessToken method to sharedAccessToken to avoid any iOS get naming conventions --- include/mbgl/ios/MGLAccountManager.h | 2 +- platform/ios/MGLAccountManager.m | 2 +- platform/ios/MGLMapView.mm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/mbgl/ios/MGLAccountManager.h b/include/mbgl/ios/MGLAccountManager.h index aed2536a3..569a01cc5 100644 --- a/include/mbgl/ios/MGLAccountManager.h +++ b/include/mbgl/ios/MGLAccountManager.h @@ -1,6 +1,6 @@ @interface MGLAccountManager : NSObject + (instancetype) sharedInstanceWithAccessToken:(NSString *)token; -+ (NSString *) getAccessToken; ++ (NSString *) sharedAccessToken; @end \ No newline at end of file diff --git a/platform/ios/MGLAccountManager.m b/platform/ios/MGLAccountManager.m index d408ba8d4..22608f94c 100644 --- a/platform/ios/MGLAccountManager.m +++ b/platform/ios/MGLAccountManager.m @@ -40,7 +40,7 @@ static MGLAccountManager *_sharedManager; return _sharedManager; } -+ (NSString *) getAccessToken { ++ (NSString *) sharedAccessToken { if (_sharedManager) { return _sharedManager.accessToken; } diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index b915fa01f..36970c8aa 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -123,7 +123,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; if (self && [self commonInit]) { self.styleURL = nil; - self.accessToken = [MGLAccountManager getAccessToken]; + self.accessToken = [MGLAccountManager sharedAccessToken]; return self; } From 4956da61b9112618cd0ae7e247ca532582648cb7 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Tue, 21 Apr 2015 12:05:37 +0200 Subject: [PATCH 08/33] Introduce the ResourceLoader ResourceLoader will handle all the tile changes and notifications through the Source object owned by the Style. This object lives entirely on the Map thread and should be only accessed by it. The observer will receive notifications every time the tile data changes and this will probably trigger a new rendering operation. This first patch will delegate Source loading to the ResourceLoader. --- src/mbgl/map/map_context.cpp | 17 +++++++---- src/mbgl/map/map_context.hpp | 7 ++++- src/mbgl/map/resource_loader.cpp | 48 ++++++++++++++++++++++++++++++++ src/mbgl/map/resource_loader.hpp | 47 +++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 7 deletions(-) create mode 100644 src/mbgl/map/resource_loader.cpp create mode 100644 src/mbgl/map/resource_loader.hpp diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp index 4e0a04472..c14cedb03 100644 --- a/src/mbgl/map/map_context.cpp +++ b/src/mbgl/map/map_context.cpp @@ -62,6 +62,7 @@ MapContext::~MapContext() { // Explicit resets currently necessary because these abandon resources that need to be // cleaned up by env.performCleanup(); + resourceLoader.reset(); style.reset(); sprite.reset(); painter.reset(); @@ -141,6 +142,7 @@ util::ptr MapContext::getSprite() { void MapContext::loadStyleJSON(const std::string& json, const std::string& base) { assert(Environment::currentlyOn(ThreadType::Map)); + resourceLoader.reset(); sprite.reset(); style.reset(); @@ -153,12 +155,10 @@ void MapContext::loadStyleJSON(const std::string& json, const std::string& base) const std::string glyphURL = util::mapbox::normalizeGlyphsURL(style->glyph_url, data.getAccessToken()); glyphStore->setURL(glyphURL); - for (const auto& source : style->sources) { - source->load(data.getAccessToken(), env, [this]() { - assert(Environment::currentlyOn(ThreadType::Map)); - triggerUpdate(); - }); - } + resourceLoader = util::make_unique(); + resourceLoader->setAccessToken(data.getAccessToken()); + resourceLoader->setObserver(this); + resourceLoader->setStyle(style.get()); triggerUpdate(Update::Zoom); } @@ -299,4 +299,9 @@ void MapContext::onLowMemory() { view.invalidate([this] { render(); }); } +void MapContext::onTileDataChanged() { + assert(Environment::currentlyOn(ThreadType::Map)); + triggerUpdate(); +} + } diff --git a/src/mbgl/map/map_context.hpp b/src/mbgl/map/map_context.hpp index 93670fd1f..6941c3040 100644 --- a/src/mbgl/map/map_context.hpp +++ b/src/mbgl/map/map_context.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -32,7 +33,7 @@ class StillImage; struct LatLng; struct LatLngBounds; -class MapContext { +class MapContext : public ResourceLoader::Observer { public: MapContext(uv_loop_t*, View&, FileSource&, MapData&, bool startPaused); ~MapContext(); @@ -58,6 +59,9 @@ public: void setSourceTileCacheSize(size_t size); void onLowMemory(); + // ResourceLoader::Observer implementation. + void onTileDataChanged() override; + private: util::ptr getSprite(); void updateTiles(); @@ -84,6 +88,7 @@ private: std::unique_ptr texturePool; std::unique_ptr painter; std::unique_ptr