diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CannotAddSourceException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CannotAddSourceException.java new file mode 100644 index 000000000..9d5a837b5 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CannotAddSourceException.java @@ -0,0 +1,12 @@ +package com.mapbox.mapboxsdk.style.sources; + +/** + * Thrown when adding a source to a map twice + */ +public class CannotAddSourceException extends RuntimeException { + + public CannotAddSourceException(String message) { + super(message); + } + +} diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp index 832fa436c..1d4849dcf 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -1142,9 +1142,13 @@ void nativeAddSource(JNIEnv *env, jni::jobject* obj, jni::jlong nativeMapViewPtr assert(nativeSourcePtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - Source *source = reinterpret_cast(nativeSourcePtr); - nativeMapView->getMap().addSource(source->releaseCoreSource()); + Source *source = reinterpret_cast(nativeSourcePtr); + try { + source->addToMap(nativeMapView->getMap()); + } catch (const std::runtime_error& error) { + jni::ThrowNew(*env, jni::FindClass(*env, "com/mapbox/mapboxsdk/style/sources/CannotAddSourceException"), error.what()); + } } void nativeRemoveSource(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* id) { diff --git a/platform/android/src/style/sources/source.cpp b/platform/android/src/style/sources/source.cpp index f3daa777d..24fce79e9 100644 --- a/platform/android/src/style/sources/source.cpp +++ b/platform/android/src/style/sources/source.cpp @@ -35,6 +35,19 @@ namespace android { return jni::Make(env, source.getID()); } + void Source::addToMap(mbgl::Map& _map) { + //Check to see if we own the source first + if (!ownedSource) { + throw std::runtime_error("Cannot add source twice"); + } + + //Add source to map + _map.addSource(releaseCoreSource()); + + //Save pointer to the map + this->map = &_map; + } + std::unique_ptr Source::releaseCoreSource() { assert(ownedSource != nullptr); return std::move(ownedSource); diff --git a/platform/android/src/style/sources/source.hpp b/platform/android/src/style/sources/source.hpp index 0785e4d4e..b24dc891b 100644 --- a/platform/android/src/style/sources/source.hpp +++ b/platform/android/src/style/sources/source.hpp @@ -32,16 +32,23 @@ public: virtual ~Source(); + void addToMap(mbgl::Map&); + virtual jni::jobject* createJavaPeer(jni::JNIEnv&) = 0; jni::String getId(jni::JNIEnv&); +protected: //Release the owned view and return it std::unique_ptr releaseCoreSource(); -protected: + //Set on newly created sources until added to the map std::unique_ptr ownedSource; + + //Raw pointer that is valid until the source is removed from the map mbgl::style::Source& source; + + //Map pointer is valid for newly created sources only after adding to the map mbgl::Map* map; };