summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin R. Miller <incanus@codesorcery.net>2015-03-27 09:00:07 -0700
committerJustin R. Miller <incanus@codesorcery.net>2015-03-27 09:00:07 -0700
commit2066e201ea5b90cc804c68c4e1cc8fb7eb5bea35 (patch)
tree0f5aa56590fee5fbea85eabbb39452dff6410e8d
parent1a8d6445d18741b399f381e3835c2362286582f6 (diff)
parent64b60faced2cc3b90aa69813cda369e34eb88f03 (diff)
downloadqtlocation-mapboxgl-2066e201ea5b90cc804c68c4e1cc8fb7eb5bea35.tar.gz
Merge remote-tracking branch 'origin/master' into 1128-convert-booleans
-rw-r--r--include/mbgl/ios/MGLMapboxEvents.h30
-rw-r--r--include/mbgl/map/map.hpp15
-rw-r--r--platform/ios/MGLMapView.mm44
-rw-r--r--platform/ios/MGLMapboxEvents.m40
-rw-r--r--platform/ios/MGLMetricsLocationManager.m6
-rw-r--r--src/mbgl/map/map.cpp87
6 files changed, 148 insertions, 74 deletions
diff --git a/include/mbgl/ios/MGLMapboxEvents.h b/include/mbgl/ios/MGLMapboxEvents.h
index 6f994fea26..0567eb6764 100644
--- a/include/mbgl/ios/MGLMapboxEvents.h
+++ b/include/mbgl/ios/MGLMapboxEvents.h
@@ -1,16 +1,24 @@
#import <Foundation/Foundation.h>
-extern NSString *const MGLEventMapLoad;
-extern NSString *const MGLEventMapTap;
-extern NSString *const MGLEventMapSingleTap;
-extern NSString *const MGLEventMapDoubleTap;
-extern NSString *const MGLEventMapTwoFingerSingleTap;
-extern NSString *const MGLEventMapQuickZoom;
-extern NSString *const MGLEventMapPanStart;
-extern NSString *const MGLEventMapPanEnd;
-extern NSString *const MGLEventMapPinchStart;
-extern NSString *const MGLEventMapRotateStart;
-extern NSString *const MGLEventMapLocation;
+extern NSString *const MGLEventTypeMapLoad;
+extern NSString *const MGLEventTypeMapTap;
+extern NSString *const MGLEventTypeMapDragEnd;
+extern NSString *const MGLEventTypeLocation;
+
+extern NSString *const MGLEventKeyLatitude;
+extern NSString *const MGLEventKeyLongitude;
+extern NSString *const MGLEventKeyZoomLevel;
+extern NSString *const MGLEventKeyPushEnabled;
+extern NSString *const MGLEventKeyEmailEnabled;
+extern NSString *const MGLEventKeyGestureID;
+
+extern NSString *const MGLEventGestureSingleTap;
+extern NSString *const MGLEventGestureDoubleTap;
+extern NSString *const MGLEventGestureTwoFingerSingleTap;
+extern NSString *const MGLEventGestureQuickZoom;
+extern NSString *const MGLEventGesturePanStart;
+extern NSString *const MGLEventGesturePinchStart;
+extern NSString *const MGLEventGestureRotateStart;
@interface MGLMapboxEvents : NSObject
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index cb93916284..4ce7014307 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -15,6 +15,7 @@
#include <iosfwd>
#include <set>
#include <vector>
+#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>
@@ -159,8 +160,8 @@ public:
const std::vector<std::string>& symbols);
void removeAnnotation(uint32_t);
void removeAnnotations(const std::vector<uint32_t>&);
- std::vector<uint32_t> getAnnotationsInBounds(const LatLngBounds&) const;
- LatLngBounds getBoundsForAnnotations(const std::vector<uint32_t>&) const;
+ std::vector<uint32_t> getAnnotationsInBounds(const LatLngBounds&);
+ LatLngBounds getBoundsForAnnotations(const std::vector<uint32_t>&);
// Debug
void setDebug(bool value);
@@ -200,6 +201,12 @@ private:
// the stylesheet.
void prepare();
+ // Runs the function in the map thread.
+ void invokeTask(std::function<void()>&&);
+ template <typename Fn> auto invokeSyncTask(const Fn& fn) -> decltype(fn());
+
+ void processTasks();
+
void updateAnnotationTiles(const std::vector<Tile::ID>&);
enum class Mode : uint8_t {
@@ -219,6 +226,7 @@ private:
std::thread thread;
std::unique_ptr<uv::async> asyncTerminate;
std::unique_ptr<uv::async> asyncUpdate;
+ std::unique_ptr<uv::async> asyncInvoke;
std::unique_ptr<uv::async> asyncRender;
bool terminating = false;
@@ -257,6 +265,9 @@ private:
std::set<util::ptr<StyleSource>> activeSources;
std::atomic<UpdateType> updated;
+
+ std::mutex mutexTask;
+ std::queue<std::function<void()>> tasks;
};
}
diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm
index 31d84000ac..6f3aec8038 100644
--- a/platform/ios/MGLMapView.mm
+++ b/platform/ios/MGLMapView.mm
@@ -355,12 +355,12 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
const mbgl::LatLng latLng = mbglMap->getLatLng();
const double zoom = mbglMap->getZoom();
- [MGLMapboxEvents pushEvent:MGLEventMapLoad withAttributes:@{
- @"lat": @(latLng.latitude),
- @"lng": @(latLng.longitude),
- @"zoom": @(zoom),
- @"enabled.push": @([MGLMapboxEvents checkPushEnabled]),
- @"enabled.email": @([MGLMapboxEvents checkEmailEnabled])
+ [MGLMapboxEvents pushEvent:MGLEventTypeMapLoad withAttributes:@{
+ MGLEventKeyLatitude: @(latLng.latitude),
+ MGLEventKeyLongitude: @(latLng.longitude),
+ MGLEventKeyZoomLevel: @(zoom),
+ MGLEventKeyPushEnabled: @([MGLMapboxEvents checkPushEnabled]),
+ MGLEventKeyEmailEnabled: @([MGLMapboxEvents checkEmailEnabled])
}];
return YES;
@@ -586,7 +586,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
- (void)handlePanGesture:(UIPanGestureRecognizer *)pan
{
- [self trackGestureEvent:MGLEventMapPanStart forRecognizer:pan];
+ [self trackGestureEvent:MGLEventGesturePanStart forRecognizer:pan];
if ( ! self.isScrollEnabled) return;
@@ -653,17 +653,17 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
CLLocationCoordinate2D panCoordinate = [self convertPoint:pointInView toCoordinateFromView:pan.view];
double zoom = [self zoomLevel];
- [MGLMapboxEvents pushEvent:MGLEventMapPanEnd withAttributes:@{
- @"lat": @(panCoordinate.latitude),
- @"lng": @(panCoordinate.longitude),
- @"zoom": @(zoom)
+ [MGLMapboxEvents pushEvent:MGLEventTypeMapDragEnd withAttributes:@{
+ MGLEventKeyLatitude: @(panCoordinate.latitude),
+ MGLEventKeyLongitude: @(panCoordinate.longitude),
+ MGLEventKeyZoomLevel: @(zoom)
}];
}
}
- (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch
{
- [self trackGestureEvent:MGLEventMapPinchStart forRecognizer:pinch];
+ [self trackGestureEvent:MGLEventGesturePinchStart forRecognizer:pinch];
if ( ! self.isZoomEnabled) return;
@@ -701,7 +701,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
- (void)handleRotateGesture:(UIRotationGestureRecognizer *)rotate
{
- [self trackGestureEvent:MGLEventMapRotateStart forRecognizer:rotate];
+ [self trackGestureEvent:MGLEventGestureRotateStart forRecognizer:rotate];
if ( ! self.isRotateEnabled) return;
@@ -743,7 +743,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
- (void)handleSingleTapGesture:(UITapGestureRecognizer *)singleTap
{
- [self trackGestureEvent:MGLEventMapSingleTap forRecognizer:singleTap];
+ [self trackGestureEvent:MGLEventGestureSingleTap forRecognizer:singleTap];
CGPoint tapPoint = [singleTap locationInView:self];
@@ -866,7 +866,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
- (void)handleDoubleTapGesture:(UITapGestureRecognizer *)doubleTap
{
- [self trackGestureEvent:MGLEventMapDoubleTap forRecognizer:doubleTap];
+ [self trackGestureEvent:MGLEventGestureDoubleTap forRecognizer:doubleTap];
if ( ! self.isZoomEnabled) return;
@@ -897,7 +897,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
- (void)handleTwoFingerTapGesture:(UITapGestureRecognizer *)twoFingerTap
{
- [self trackGestureEvent:MGLEventMapTwoFingerSingleTap forRecognizer:twoFingerTap];
+ [self trackGestureEvent:MGLEventGestureTwoFingerSingleTap forRecognizer:twoFingerTap];
if ( ! self.isZoomEnabled) return;
@@ -930,7 +930,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
- (void)handleQuickZoomGesture:(UILongPressGestureRecognizer *)quickZoom
{
- [self trackGestureEvent:MGLEventMapQuickZoom forRecognizer:quickZoom];
+ [self trackGestureEvent:MGLEventGestureQuickZoom forRecognizer:quickZoom];
if ( ! self.isZoomEnabled) return;
@@ -984,11 +984,11 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr;
CLLocationCoordinate2D gestureCoordinate = [self convertPoint:pointInView toCoordinateFromView:recognizer.view];
double zoom = [self zoomLevel];
- [MGLMapboxEvents pushEvent:MGLEventMapTap withAttributes:@{
- @"lat": @(gestureCoordinate.latitude),
- @"lng": @(gestureCoordinate.longitude),
- @"zoom": @(zoom),
- @"gesture": gestureID
+ [MGLMapboxEvents pushEvent:MGLEventTypeMapTap withAttributes:@{
+ MGLEventKeyLatitude: @(gestureCoordinate.latitude),
+ MGLEventKeyLongitude: @(gestureCoordinate.longitude),
+ MGLEventKeyZoomLevel: @(zoom),
+ MGLEventKeyGestureID: gestureID
}];
}
diff --git a/platform/ios/MGLMapboxEvents.m b/platform/ios/MGLMapboxEvents.m
index 1ce8288f5d..94374b9da9 100644
--- a/platform/ios/MGLMapboxEvents.m
+++ b/platform/ios/MGLMapboxEvents.m
@@ -12,17 +12,25 @@
static NSString *const MGLMapboxEventsUserAgent = @"MapboxEventsiOS/1.0";
static NSString *const MGLMapboxEventsAPIBase = @"https://api.tiles.mapbox.com";
-NSString *const MGLEventMapLoad = @"map.load";
-NSString *const MGLEventMapTap = @"map.click";
-NSString *const MGLEventMapSingleTap = @"SingleTap";
-NSString *const MGLEventMapDoubleTap = @"DoubleTap";
-NSString *const MGLEventMapTwoFingerSingleTap = @"TwoFingerTap";
-NSString *const MGLEventMapQuickZoom = @"QuickZoom";
-NSString *const MGLEventMapPanStart = @"Pan";
-NSString *const MGLEventMapPanEnd = @"map.dragend";
-NSString *const MGLEventMapPinchStart = @"Pinch";
-NSString *const MGLEventMapRotateStart = @"Rotation";
-NSString *const MGLEventMapLocation = @"Location";
+NSString *const MGLEventTypeMapLoad = @"map.load";
+NSString *const MGLEventTypeMapTap = @"map.click";
+NSString *const MGLEventTypeMapDragEnd = @"map.dragend";
+NSString *const MGLEventTypeLocation = @"Location";
+
+NSString *const MGLEventKeyLatitude = @"lat";
+NSString *const MGLEventKeyLongitude = @"lng";
+NSString *const MGLEventKeyZoomLevel = @"zoom";
+NSString *const MGLEventKeyPushEnabled = @"enabled.push";
+NSString *const MGLEventKeyEmailEnabled = @"enabled.email";
+NSString *const MGLEventKeyGestureID = @"gesture";
+
+NSString *const MGLEventGestureSingleTap = @"SingleTap";
+NSString *const MGLEventGestureDoubleTap = @"DoubleTap";
+NSString *const MGLEventGestureTwoFingerSingleTap = @"TwoFingerTap";
+NSString *const MGLEventGestureQuickZoom = @"QuickZoom";
+NSString *const MGLEventGesturePanStart = @"Pan";
+NSString *const MGLEventGesturePinchStart = @"Pinch";
+NSString *const MGLEventGestureRotateStart = @"Rotation";
//
// Threadsafety conventions:
@@ -216,7 +224,7 @@ NSString *const MGLEventMapLocation = @"Location";
// use of +pushEvent:withAttributes:.
//
- (void) pushEvent:(NSString *)event withAttributes:(NSDictionary *)attributeDictionary {
- // convert any BOOL types to string values written out like JS
+ // conve+rt any BOOL types to string values written out like JS
NSMutableDictionary *newAttributeDictionary = [NSMutableDictionary dictionaryWithCapacity:[attributeDictionary count]];
NSString *key;
NSObject *value;
@@ -249,7 +257,7 @@ NSString *const MGLEventMapLocation = @"Location";
if (!event) return;
- NSMutableDictionary *evt = [[NSMutableDictionary alloc] init];
+ NSMutableDictionary *evt = [[NSMutableDictionary alloc] initWithDictionary:attributeDictionary];
// mapbox-events stock attributes
[evt setObject:event forKey:@"event"];
[evt setObject:@(1) forKey:@"version"];
@@ -268,11 +276,7 @@ NSString *const MGLEventMapLocation = @"Location";
[evt setValue:[weakSelf getCurrentCellularNetworkConnectionType] forKey:@"cellularNetworkType"];
[evt setValue:[weakSelf getWifiNetworkName] forKey:@"wifi"];
[evt setValue:@([weakSelf getContentSizeScale]) forKey:@"accessibilityFontScale"];
-
- for (NSString *key in [attributeDictionary allKeys]) {
- [evt setObject:[attributeDictionary valueForKey:key] forKey:key];
- }
-
+
// Make Immutable Version
NSDictionary *finalEvent = [NSDictionary dictionaryWithDictionary:evt];
diff --git a/platform/ios/MGLMetricsLocationManager.m b/platform/ios/MGLMetricsLocationManager.m
index bdf6e14ae9..c0ff740b3a 100644
--- a/platform/ios/MGLMetricsLocationManager.m
+++ b/platform/ios/MGLMetricsLocationManager.m
@@ -43,9 +43,9 @@
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
// Iterate through locations to pass all data
for (CLLocation *loc in locations) {
- [MGLMapboxEvents pushEvent:MGLEventMapLocation withAttributes:@{
- @"lat": @(loc.coordinate.latitude),
- @"lng": @(loc.coordinate.longitude)
+ [MGLMapboxEvents pushEvent:MGLEventTypeLocation withAttributes:@{
+ MGLEventKeyLatitude: @(loc.coordinate.latitude),
+ MGLEventKeyLongitude: @(loc.coordinate.longitude)
}];
}
}
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index a49df01191..47d6ed71d1 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -144,6 +144,11 @@ void Map::start(bool startPaused) {
update();
});
+ asyncInvoke = util::make_unique<uv::async>(env->loop, [this] {
+ processTasks();
+ });
+
+
asyncRender = util::make_unique<uv::async>(env->loop, [this] {
// Must be called in Map thread.
assert(Environment::currentlyOn(ThreadType::Map));
@@ -315,6 +320,42 @@ void Map::triggerRender() {
asyncRender->send();
}
+// Runs the function in the map thread.
+void Map::invokeTask(std::function<void()>&& fn) {
+ {
+ std::lock_guard<std::mutex> lock(mutexTask);
+ tasks.emplace(::std::forward<std::function<void()>>(fn));
+ }
+
+ // TODO: Once we have aligned static and continuous rendering, this should always dispatch
+ // to the async queue.
+ if (asyncInvoke) {
+ asyncInvoke->send();
+ } else {
+ processTasks();
+ }
+}
+
+template <typename Fn> auto Map::invokeSyncTask(const Fn& fn) -> decltype(fn()) {
+ std::promise<decltype(fn())> promise;
+ invokeTask([&fn, &promise] { promise.set_value(fn()); });
+ return promise.get_future().get();
+}
+
+// Processes the functions that should be run in the map thread.
+void Map::processTasks() {
+ std::queue<std::function<void()>> queue;
+ {
+ std::lock_guard<std::mutex> lock(mutexTask);
+ queue.swap(tasks);
+ }
+
+ while (!queue.empty()) {
+ queue.front()();
+ queue.pop();
+ }
+}
+
void Map::checkForPause() {
std::unique_lock<std::mutex> lockRun (mutexRun);
while (pausing) {
@@ -542,27 +583,31 @@ std::string Map::getAccessToken() const {
void Map::setDefaultPointAnnotationSymbol(const std::string& symbol) {
assert(Environment::currentlyOn(ThreadType::Main));
- annotationManager->setDefaultPointAnnotationSymbol(symbol);
+ invokeTask([=] {
+ annotationManager->setDefaultPointAnnotationSymbol(symbol);
+ });
}
double Map::getTopOffsetPixelsForAnnotationSymbol(const std::string& symbol) {
- SpritePosition pos = sprite->getSpritePosition(symbol);
-
- return -pos.height / pos.pixelRatio / 2;
+ assert(Environment::currentlyOn(ThreadType::Main));
+ return invokeSyncTask([&] {
+ assert(sprite);
+ const SpritePosition pos = sprite->getSpritePosition(symbol);
+ return -pos.height / pos.pixelRatio / 2;
+ });
}
uint32_t Map::addPointAnnotation(const LatLng& point, const std::string& symbol) {
- assert(Environment::currentlyOn(ThreadType::Main));
- std::vector<LatLng> points({ point });
- std::vector<std::string> symbols({ symbol });
- return addPointAnnotations(points, symbols)[0];
+ return addPointAnnotations({ point }, { symbol }).front();
}
std::vector<uint32_t> Map::addPointAnnotations(const std::vector<LatLng>& points, const std::vector<std::string>& symbols) {
assert(Environment::currentlyOn(ThreadType::Main));
- auto result = annotationManager->addPointAnnotations(points, symbols, *this);
- updateAnnotationTiles(result.first);
- return result.second;
+ return invokeSyncTask([&] {
+ auto result = annotationManager->addPointAnnotations(points, symbols, *this);
+ updateAnnotationTiles(result.first);
+ return result.second;
+ });
}
void Map::removeAnnotation(uint32_t annotation) {
@@ -572,22 +617,28 @@ void Map::removeAnnotation(uint32_t annotation) {
void Map::removeAnnotations(const std::vector<uint32_t>& annotations) {
assert(Environment::currentlyOn(ThreadType::Main));
- auto result = annotationManager->removeAnnotations(annotations, *this);
- updateAnnotationTiles(result);
+ invokeTask([=] {
+ auto result = annotationManager->removeAnnotations(annotations, *this);
+ updateAnnotationTiles(result);
+ });
}
-std::vector<uint32_t> Map::getAnnotationsInBounds(const LatLngBounds& bounds) const {
+std::vector<uint32_t> Map::getAnnotationsInBounds(const LatLngBounds& bounds) {
assert(Environment::currentlyOn(ThreadType::Main));
- return annotationManager->getAnnotationsInBounds(bounds, *this);
+ return invokeSyncTask([&] {
+ return annotationManager->getAnnotationsInBounds(bounds, *this);
+ });
}
-LatLngBounds Map::getBoundsForAnnotations(const std::vector<uint32_t>& annotations) const {
+LatLngBounds Map::getBoundsForAnnotations(const std::vector<uint32_t>& annotations) {
assert(Environment::currentlyOn(ThreadType::Main));
- return annotationManager->getBoundsForAnnotations(annotations);
+ return invokeSyncTask([&] {
+ return annotationManager->getBoundsForAnnotations(annotations);
+ });
}
void Map::updateAnnotationTiles(const std::vector<Tile::ID>& ids) {
- assert(Environment::currentlyOn(ThreadType::Main));
+ assert(Environment::currentlyOn(ThreadType::Map));
for (const auto &source : activeSources) {
if (source->info.type == SourceType::Annotations) {
source->source->invalidateTiles(*this, ids);