[android] Reuse Java Source objects by holding on to a strong reference in the C++ peer.
This commit is contained in:
@@ -733,7 +733,7 @@ final class NativeMapView {
|
||||
if (isDestroyedOn("addSource")) {
|
||||
return;
|
||||
}
|
||||
nativeAddSource(source.getNativePtr());
|
||||
nativeAddSource(source, source.getNativePtr());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -741,14 +741,15 @@ final class NativeMapView {
|
||||
if (isDestroyedOn("removeSource")) {
|
||||
return null;
|
||||
}
|
||||
return nativeRemoveSourceById(sourceId);
|
||||
Source source = getSource(sourceId);
|
||||
return removeSource(source);
|
||||
}
|
||||
|
||||
public Source removeSource(@NonNull Source source) {
|
||||
if (isDestroyedOn("removeSource")) {
|
||||
return null;
|
||||
}
|
||||
nativeRemoveSource(source.getNativePtr());
|
||||
nativeRemoveSource(source, source.getNativePtr());
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -1027,11 +1028,9 @@ final class NativeMapView {
|
||||
|
||||
private native Source nativeGetSource(String sourceId);
|
||||
|
||||
private native void nativeAddSource(long nativeSourcePtr) throws CannotAddSourceException;
|
||||
private native void nativeAddSource(Source source, long sourcePtr) throws CannotAddSourceException;
|
||||
|
||||
private native Source nativeRemoveSourceById(String sourceId);
|
||||
|
||||
private native void nativeRemoveSource(long sourcePtr);
|
||||
private native void nativeRemoveSource(Source source, long sourcePtr);
|
||||
|
||||
private native void nativeAddImage(String name, int width, int height, float pixelRatio,
|
||||
byte[] array);
|
||||
|
||||
@@ -181,8 +181,6 @@ add_library(mbgl-android STATIC
|
||||
platform/android/src/style/sources/custom_geometry_source.hpp
|
||||
platform/android/src/style/sources/source.cpp
|
||||
platform/android/src/style/sources/source.hpp
|
||||
platform/android/src/style/sources/sources.cpp
|
||||
platform/android/src/style/sources/sources.hpp
|
||||
platform/android/src/style/sources/raster_source.cpp
|
||||
platform/android/src/style/sources/raster_source.hpp
|
||||
platform/android/src/style/sources/unknown_source.cpp
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
#include "style/functions/interval_stops.hpp"
|
||||
#include "style/functions/stop.hpp"
|
||||
#include "style/layers/layers.hpp"
|
||||
#include "style/sources/sources.hpp"
|
||||
#include "style/sources/source.hpp"
|
||||
#include "style/light.hpp"
|
||||
#include "snapshotter/map_snapshotter.hpp"
|
||||
#include "snapshotter/map_snapshot.hpp"
|
||||
@@ -161,7 +161,7 @@ void registerNatives(JavaVM *vm) {
|
||||
// Style
|
||||
TransitionOptions::registerNative(env);
|
||||
registerNativeLayers(env);
|
||||
registerNativeSources(env);
|
||||
Source::registerNative(env);
|
||||
Light::registerNative(env);
|
||||
Position::registerNative(env);
|
||||
Stop::registerNative(env);
|
||||
|
||||
@@ -856,9 +856,7 @@ jni::Array<jni::Object<Source>> NativeMapView::getSources(JNIEnv& env) {
|
||||
jni::Array<jni::Object<Source>> jSources = jni::Array<jni::Object<Source>>::New(env, sources.size(), Source::javaClass);
|
||||
int index = 0;
|
||||
for (auto source : sources) {
|
||||
auto jSource = jni::Object<Source>(createJavaSourcePeer(env, *rendererFrontend, *source));
|
||||
jSources.Set(env, index, jSource);
|
||||
jni::DeleteLocalRef(env, jSource);
|
||||
jSources.Set(env, index, Source::peerForCoreSource(env, *source, *rendererFrontend));
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -874,38 +872,25 @@ jni::Object<Source> NativeMapView::getSource(JNIEnv& env, jni::String sourceId)
|
||||
}
|
||||
|
||||
// Create and return the source's native peer
|
||||
return jni::Object<Source>(createJavaSourcePeer(env, *rendererFrontend, *coreSource));
|
||||
return Source::peerForCoreSource(env, *coreSource, *rendererFrontend);
|
||||
}
|
||||
|
||||
void NativeMapView::addSource(JNIEnv& env, jni::jlong sourcePtr) {
|
||||
void NativeMapView::addSource(JNIEnv& env, jni::Object<Source> obj, jlong sourcePtr) {
|
||||
assert(sourcePtr != 0);
|
||||
|
||||
Source *source = reinterpret_cast<Source *>(sourcePtr);
|
||||
try {
|
||||
source->addToMap(*map);
|
||||
source->setRendererFrontend(*rendererFrontend);
|
||||
source->addToMap(env, obj, *map, *rendererFrontend);
|
||||
} catch (const std::runtime_error& error) {
|
||||
jni::ThrowNew(env, jni::FindClass(env, "com/mapbox/mapboxsdk/style/sources/CannotAddSourceException"), error.what());
|
||||
}
|
||||
}
|
||||
|
||||
jni::Object<Source> NativeMapView::removeSourceById(JNIEnv& env, jni::String id) {
|
||||
std::unique_ptr<mbgl::style::Source> coreSource = map->getStyle().removeSource(jni::Make<std::string>(env, id));
|
||||
if (coreSource) {
|
||||
return jni::Object<Source>(createJavaSourcePeer(env, *rendererFrontend, *coreSource));
|
||||
} else {
|
||||
return jni::Object<Source>();
|
||||
}
|
||||
}
|
||||
|
||||
void NativeMapView::removeSource(JNIEnv&, jlong sourcePtr) {
|
||||
void NativeMapView::removeSource(JNIEnv& env, jni::Object<Source> obj, jlong sourcePtr) {
|
||||
assert(sourcePtr != 0);
|
||||
|
||||
mbgl::android::Source *source = reinterpret_cast<mbgl::android::Source *>(sourcePtr);
|
||||
std::unique_ptr<mbgl::style::Source> coreSource = map->getStyle().removeSource(source->get().getID());
|
||||
if (coreSource) {
|
||||
source->setSource(std::move(coreSource));
|
||||
}
|
||||
source->removeFromMap(env, obj, *map);
|
||||
}
|
||||
|
||||
void NativeMapView::addImage(JNIEnv& env, jni::String name, jni::jint w, jni::jint h, jni::jfloat scale, jni::Array<jbyte> pixels) {
|
||||
@@ -1048,7 +1033,6 @@ void NativeMapView::registerNative(jni::JNIEnv& env) {
|
||||
METHOD(&NativeMapView::getSources, "nativeGetSources"),
|
||||
METHOD(&NativeMapView::getSource, "nativeGetSource"),
|
||||
METHOD(&NativeMapView::addSource, "nativeAddSource"),
|
||||
METHOD(&NativeMapView::removeSourceById, "nativeRemoveSourceById"),
|
||||
METHOD(&NativeMapView::removeSource, "nativeRemoveSource"),
|
||||
METHOD(&NativeMapView::addImage, "nativeAddImage"),
|
||||
METHOD(&NativeMapView::addImages, "nativeAddImages"),
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "geometry/lat_lng.hpp"
|
||||
#include "geometry/projected_meters.hpp"
|
||||
#include "style/layers/layers.hpp"
|
||||
#include "style/sources/sources.hpp"
|
||||
#include "style/sources/source.hpp"
|
||||
#include "geometry/lat_lng_bounds.hpp"
|
||||
#include "map/camera_position.hpp"
|
||||
#include "map/image.hpp"
|
||||
@@ -230,11 +230,11 @@ public:
|
||||
|
||||
jni::Object<Source> getSource(JNIEnv&, jni::String);
|
||||
|
||||
void addSource(JNIEnv&, jni::jlong);
|
||||
void addSource(JNIEnv&, jni::Object<Source>, jlong nativePtr);
|
||||
|
||||
jni::Object<Source> removeSourceById(JNIEnv&, jni::String);
|
||||
|
||||
void removeSource(JNIEnv&, jlong);
|
||||
void removeSource(JNIEnv&, jni::Object<Source>, jlong nativePtr);
|
||||
|
||||
void addImage(JNIEnv&, jni::String, jni::jint, jni::jint, jni::jfloat, jni::Array<jbyte>);
|
||||
|
||||
|
||||
@@ -46,6 +46,12 @@ namespace android {
|
||||
javaPeer(_obj.NewGlobalRef(env)) {
|
||||
}
|
||||
|
||||
CustomGeometrySource::CustomGeometrySource(jni::JNIEnv& env,
|
||||
mbgl::style::Source& coreSource,
|
||||
AndroidRendererFrontend& frontend)
|
||||
: Source(env, coreSource, createJavaPeer(env), frontend) {
|
||||
}
|
||||
|
||||
CustomGeometrySource::~CustomGeometrySource() = default;
|
||||
|
||||
void CustomGeometrySource::fetchTile (const mbgl::CanonicalTileID& tileID) {
|
||||
@@ -94,9 +100,9 @@ namespace android {
|
||||
|
||||
jni::Class<CustomGeometrySource> CustomGeometrySource::javaClass;
|
||||
|
||||
jni::jobject* CustomGeometrySource::createJavaPeer(jni::JNIEnv& env) {
|
||||
jni::Object<Source> CustomGeometrySource::createJavaPeer(jni::JNIEnv& env) {
|
||||
static auto constructor = CustomGeometrySource::javaClass.template GetConstructor<jni::jlong>(env);
|
||||
return CustomGeometrySource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this));
|
||||
return jni::Object<Source>(CustomGeometrySource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)).Get());
|
||||
}
|
||||
|
||||
void CustomGeometrySource::registerNative(jni::JNIEnv& env) {
|
||||
|
||||
@@ -27,6 +27,8 @@ public:
|
||||
jni::String,
|
||||
jni::Object<>);
|
||||
|
||||
CustomGeometrySource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
|
||||
|
||||
~CustomGeometrySource();
|
||||
|
||||
void fetchTile(const mbgl::CanonicalTileID& tileID);
|
||||
@@ -39,7 +41,8 @@ public:
|
||||
jni::Array<jni::Object<geojson::Feature>> querySourceFeatures(jni::JNIEnv&,
|
||||
jni::Array<jni::Object<>> );
|
||||
|
||||
jni::jobject* createJavaPeer(jni::JNIEnv&);
|
||||
private:
|
||||
jni::Object<Source> createJavaPeer(jni::JNIEnv&);
|
||||
|
||||
jni::UniqueObject<CustomGeometrySource> javaPeer;
|
||||
}; // class CustomGeometrySource
|
||||
|
||||
@@ -43,8 +43,10 @@ namespace android {
|
||||
) {
|
||||
}
|
||||
|
||||
GeoJSONSource::GeoJSONSource(mbgl::style::GeoJSONSource& coreSource)
|
||||
: Source(coreSource) {
|
||||
GeoJSONSource::GeoJSONSource(jni::JNIEnv& env,
|
||||
mbgl::style::Source& coreSource,
|
||||
AndroidRendererFrontend& frontend)
|
||||
: Source(env, coreSource, createJavaPeer(env), frontend) {
|
||||
}
|
||||
|
||||
GeoJSONSource::~GeoJSONSource() = default;
|
||||
@@ -118,9 +120,9 @@ namespace android {
|
||||
|
||||
jni::Class<GeoJSONSource> GeoJSONSource::javaClass;
|
||||
|
||||
jni::jobject* GeoJSONSource::createJavaPeer(jni::JNIEnv& env) {
|
||||
jni::Object<Source> GeoJSONSource::createJavaPeer(jni::JNIEnv& env) {
|
||||
static auto constructor = GeoJSONSource::javaClass.template GetConstructor<jni::jlong>(env);
|
||||
return GeoJSONSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this));
|
||||
return jni::Object<Source>(GeoJSONSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)).Get());
|
||||
}
|
||||
|
||||
void GeoJSONSource::registerNative(jni::JNIEnv& env) {
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
|
||||
GeoJSONSource(jni::JNIEnv&, jni::String, jni::Object<>);
|
||||
|
||||
GeoJSONSource(mbgl::style::GeoJSONSource&);
|
||||
GeoJSONSource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
|
||||
|
||||
~GeoJSONSource();
|
||||
|
||||
@@ -40,7 +40,8 @@ public:
|
||||
|
||||
jni::String getURL(jni::JNIEnv&);
|
||||
|
||||
jni::jobject* createJavaPeer(jni::JNIEnv&);
|
||||
private:
|
||||
jni::Object<Source> createJavaPeer(jni::JNIEnv&);
|
||||
|
||||
}; // class GeoJSONSource
|
||||
|
||||
|
||||
@@ -23,8 +23,10 @@ namespace android {
|
||||
) {
|
||||
}
|
||||
|
||||
ImageSource::ImageSource(mbgl::style::ImageSource& coreSource)
|
||||
: Source(coreSource) {
|
||||
ImageSource::ImageSource(jni::JNIEnv& env,
|
||||
mbgl::style::Source& coreSource,
|
||||
AndroidRendererFrontend& frontend)
|
||||
: Source(env, coreSource, createJavaPeer(env), frontend) {
|
||||
}
|
||||
|
||||
ImageSource::~ImageSource() = default;
|
||||
@@ -45,9 +47,9 @@ namespace android {
|
||||
|
||||
jni::Class<ImageSource> ImageSource::javaClass;
|
||||
|
||||
jni::jobject* ImageSource::createJavaPeer(jni::JNIEnv& env) {
|
||||
jni::Object<Source> ImageSource::createJavaPeer(jni::JNIEnv& env) {
|
||||
static auto constructor = ImageSource::javaClass.template GetConstructor<jni::jlong>(env);
|
||||
return ImageSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this));
|
||||
return jni::Object<Source>(ImageSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)).Get());
|
||||
}
|
||||
|
||||
void ImageSource::registerNative(jni::JNIEnv& env) {
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
|
||||
ImageSource(jni::JNIEnv&, jni::String, jni::Object<LatLngQuad>);
|
||||
|
||||
ImageSource(mbgl::style::ImageSource&);
|
||||
ImageSource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
|
||||
|
||||
~ImageSource();
|
||||
|
||||
@@ -30,7 +30,8 @@ public:
|
||||
|
||||
void setImage(jni::JNIEnv&, jni::Object<Bitmap>);
|
||||
|
||||
jni::jobject* createJavaPeer(jni::JNIEnv&);
|
||||
private:
|
||||
jni::Object<Source> createJavaPeer(jni::JNIEnv&);
|
||||
|
||||
}; // class ImageSource
|
||||
|
||||
|
||||
@@ -22,8 +22,10 @@ namespace android {
|
||||
) {
|
||||
}
|
||||
|
||||
RasterSource::RasterSource(mbgl::style::RasterSource& coreSource)
|
||||
: Source(coreSource) {
|
||||
RasterSource::RasterSource(jni::JNIEnv& env,
|
||||
mbgl::style::Source& coreSource,
|
||||
AndroidRendererFrontend& frontend)
|
||||
: Source(env, coreSource, createJavaPeer(env), frontend) {
|
||||
}
|
||||
|
||||
RasterSource::~RasterSource() = default;
|
||||
@@ -35,9 +37,9 @@ namespace android {
|
||||
|
||||
jni::Class<RasterSource> RasterSource::javaClass;
|
||||
|
||||
jni::jobject* RasterSource::createJavaPeer(jni::JNIEnv& env) {
|
||||
jni::Object<Source> RasterSource::createJavaPeer(jni::JNIEnv& env) {
|
||||
static auto constructor = RasterSource::javaClass.template GetConstructor<jni::jlong>(env);
|
||||
return RasterSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this));
|
||||
return jni::Object<Source>(RasterSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)).Get());
|
||||
}
|
||||
|
||||
void RasterSource::registerNative(jni::JNIEnv& env) {
|
||||
|
||||
@@ -18,13 +18,14 @@ public:
|
||||
|
||||
RasterSource(jni::JNIEnv&, jni::String, jni::Object<>, jni::jint);
|
||||
|
||||
RasterSource(mbgl::style::RasterSource&);
|
||||
RasterSource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
|
||||
|
||||
~RasterSource();
|
||||
|
||||
jni::String getURL(jni::JNIEnv&);
|
||||
|
||||
jni::jobject* createJavaPeer(jni::JNIEnv&);
|
||||
private:
|
||||
jni::Object<Source> createJavaPeer(jni::JNIEnv&);
|
||||
|
||||
}; // class RasterSource
|
||||
|
||||
|
||||
@@ -15,29 +15,70 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
// Core Sources
|
||||
#include <mbgl/style/sources/geojson_source.hpp>
|
||||
#include <mbgl/style/sources/image_source.hpp>
|
||||
#include <mbgl/style/sources/raster_source.hpp>
|
||||
#include <mbgl/style/sources/vector_source.hpp>
|
||||
|
||||
// Android Source peers
|
||||
#include "geojson_source.hpp"
|
||||
#include "image_source.hpp"
|
||||
#include "raster_source.hpp"
|
||||
#include "unknown_source.hpp"
|
||||
#include "vector_source.hpp"
|
||||
#include "custom_geometry_source.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
/**
|
||||
* Invoked when the construction is initiated from the jvm through a subclass
|
||||
*/
|
||||
static std::unique_ptr<Source> createSourcePeer(jni::JNIEnv& env, mbgl::style::Source& coreSource, AndroidRendererFrontend& frontend) {
|
||||
if (coreSource.is<mbgl::style::VectorSource>()) {
|
||||
return std::make_unique<VectorSource>(env, *coreSource.as<mbgl::style::VectorSource>(), frontend);
|
||||
} else if (coreSource.is<mbgl::style::RasterSource>()) {
|
||||
return std::make_unique<RasterSource>(env, *coreSource.as<mbgl::style::RasterSource>(), frontend);
|
||||
} else if (coreSource.is<mbgl::style::GeoJSONSource>()) {
|
||||
return std::make_unique<GeoJSONSource>(env, *coreSource.as<mbgl::style::GeoJSONSource>(), frontend);
|
||||
} else if (coreSource.is<mbgl::style::ImageSource>()) {
|
||||
return std::make_unique<ImageSource>(env, *coreSource.as<mbgl::style::ImageSource>(), frontend);
|
||||
} else {
|
||||
return std::make_unique<UnknownSource>(env, coreSource, frontend);
|
||||
}
|
||||
}
|
||||
|
||||
jni::Object<Source> Source::peerForCoreSource(jni::JNIEnv& env, mbgl::style::Source& coreSource, AndroidRendererFrontend& frontend) {
|
||||
if (!coreSource.peer.has_value()) {
|
||||
coreSource.peer = createSourcePeer(env, coreSource, frontend);
|
||||
}
|
||||
return *mbgl::util::any_cast<std::unique_ptr<Source>>(&coreSource.peer)->get()->javaPeer;
|
||||
}
|
||||
|
||||
Source::Source(jni::JNIEnv& env, mbgl::style::Source& coreSource, jni::Object<Source> obj, AndroidRendererFrontend& frontend)
|
||||
: source(coreSource)
|
||||
, javaPeer(obj.NewGlobalRef(env))
|
||||
, rendererFrontend(&frontend) {
|
||||
}
|
||||
|
||||
Source::Source(jni::JNIEnv&, std::unique_ptr<mbgl::style::Source> coreSource)
|
||||
: ownedSource(std::move(coreSource))
|
||||
, source(*ownedSource) {
|
||||
}
|
||||
|
||||
Source::Source(mbgl::style::Source& coreSource)
|
||||
: source(coreSource) {
|
||||
}
|
||||
|
||||
Source::~Source() = default;
|
||||
|
||||
style::Source& Source::get() {
|
||||
return source;
|
||||
}
|
||||
|
||||
void Source::setSource(std::unique_ptr<style::Source> coreSource) {
|
||||
this->ownedSource = std::move(coreSource);
|
||||
Source::~Source() {
|
||||
// Before being added to a map, the Java peer owns this C++ peer and cleans
|
||||
// up after itself correctly through the jni native peer bindings.
|
||||
// After being added to the map, the ownership is flipped and the C++ peer has a strong reference
|
||||
// to it's Java peer, preventing the Java peer from being GC'ed.
|
||||
// In this case, the core source initiates the destruction, which requires releasing the Java peer,
|
||||
// while also resetting it's nativePtr to 0 to prevent the subsequent GC of the Java peer from
|
||||
// re-entering this dtor.
|
||||
if (ownedSource.get() == nullptr && javaPeer.get() != nullptr) {
|
||||
// Manually clear the java peer
|
||||
android::UniqueEnv env = android::AttachEnv();
|
||||
static auto nativePtrField = javaClass.GetField<jlong>(*env, "nativePtr");
|
||||
javaPeer->Set(*env, nativePtrField, (jlong) 0);
|
||||
javaPeer.reset();
|
||||
}
|
||||
}
|
||||
|
||||
jni::String Source::getId(jni::JNIEnv& env) {
|
||||
@@ -49,23 +90,48 @@ namespace android {
|
||||
return attribution ? jni::Make<jni::String>(env, attribution.value()) : jni::Make<jni::String>(env,"");
|
||||
}
|
||||
|
||||
void Source::addToMap(mbgl::Map& _map) {
|
||||
void Source::addToMap(JNIEnv& env, jni::Object<Source> obj, mbgl::Map& map, AndroidRendererFrontend& frontend) {
|
||||
// Check to see if we own the source first
|
||||
if (!ownedSource) {
|
||||
throw std::runtime_error("Cannot add source twice");
|
||||
}
|
||||
|
||||
// Add source to map
|
||||
_map.getStyle().addSource(releaseCoreSource());
|
||||
// Add source to map and release ownership
|
||||
map.getStyle().addSource(std::move(ownedSource));
|
||||
|
||||
// Add peer to core source
|
||||
source.peer = std::unique_ptr<Source>(this);
|
||||
|
||||
// Add strong reference to java source
|
||||
javaPeer = obj.NewGlobalRef(env);
|
||||
|
||||
rendererFrontend = &frontend;
|
||||
}
|
||||
|
||||
void Source::setRendererFrontend(AndroidRendererFrontend& frontend_) {
|
||||
rendererFrontend = &frontend_;
|
||||
}
|
||||
void Source::removeFromMap(JNIEnv&, jni::Object<Source>, mbgl::Map& map) {
|
||||
// Cannot remove if not attached yet
|
||||
if (ownedSource) {
|
||||
throw std::runtime_error("Cannot remove detached source");
|
||||
}
|
||||
|
||||
std::unique_ptr<mbgl::style::Source> Source::releaseCoreSource() {
|
||||
assert(ownedSource != nullptr);
|
||||
return std::move(ownedSource);
|
||||
// Remove the source from the map and take ownership
|
||||
ownedSource = map.getStyle().removeSource(source.getID());
|
||||
|
||||
// The source may not be removed if any layers still reference it
|
||||
if (!ownedSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Release the peer relationships. These will be re-established when the source is added to a map
|
||||
assert(ownedSource->peer.has_value());
|
||||
util::any_cast<std::unique_ptr<Source>>(&(ownedSource->peer))->release();
|
||||
ownedSource->peer.reset();
|
||||
|
||||
// Release the strong reference to the java peer
|
||||
assert(javaPeer);
|
||||
javaPeer.release();
|
||||
|
||||
rendererFrontend = nullptr;
|
||||
}
|
||||
|
||||
jni::Class<Source> Source::javaClass;
|
||||
@@ -82,6 +148,13 @@ namespace android {
|
||||
METHOD(&Source::getAttribution, "nativeGetAttribution")
|
||||
);
|
||||
|
||||
// Register subclasses
|
||||
GeoJSONSource::registerNative(env);
|
||||
ImageSource::registerNative(env);
|
||||
RasterSource::registerNative(env);
|
||||
UnknownSource::registerNative(env);
|
||||
VectorSource::registerNative(env);
|
||||
CustomGeometrySource::registerNative(env);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -21,48 +21,40 @@ public:
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
/*
|
||||
* Called when a Java object is created on the c++ side
|
||||
*/
|
||||
Source(mbgl::style::Source&);
|
||||
static jni::Object<Source> peerForCoreSource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
|
||||
|
||||
/*
|
||||
* Called when a Java object was created from the jvm side
|
||||
* Called when a Java object is created for a core source that belongs to a map.
|
||||
*/
|
||||
Source(jni::JNIEnv&, mbgl::style::Source&, jni::Object<Source>, AndroidRendererFrontend&);
|
||||
|
||||
/*
|
||||
* Called when a Java object is created for a new core source that does not belong to a map.
|
||||
*/
|
||||
Source(jni::JNIEnv&, std::unique_ptr<mbgl::style::Source>);
|
||||
|
||||
virtual ~Source();
|
||||
|
||||
/**
|
||||
* Set core source (ie return ownership after remove)
|
||||
*/
|
||||
void setSource(std::unique_ptr<style::Source>);
|
||||
void addToMap(JNIEnv&, jni::Object<Source>, mbgl::Map&, AndroidRendererFrontend&);
|
||||
|
||||
style::Source& get();
|
||||
|
||||
void addToMap(mbgl::Map&);
|
||||
|
||||
void setRendererFrontend(AndroidRendererFrontend&);
|
||||
|
||||
virtual jni::jobject* createJavaPeer(jni::JNIEnv&) = 0;
|
||||
void removeFromMap(JNIEnv&, jni::Object<Source>, mbgl::Map&);
|
||||
|
||||
jni::String getId(jni::JNIEnv&);
|
||||
|
||||
jni::String getAttribution(jni::JNIEnv&);
|
||||
|
||||
protected:
|
||||
// Release the owned view and return it
|
||||
std::unique_ptr<mbgl::style::Source> releaseCoreSource();
|
||||
|
||||
// Set on newly created sources until added to the map
|
||||
// Set on newly created sources until added to the map.
|
||||
std::unique_ptr<mbgl::style::Source> ownedSource;
|
||||
|
||||
// Raw pointer that is valid until the source is removed from the map
|
||||
// Raw pointer that is valid at all times.
|
||||
mbgl::style::Source& source;
|
||||
|
||||
// RendererFrontend pointer is valid only when
|
||||
// added to the map
|
||||
AndroidRendererFrontend* rendererFrontend;
|
||||
// Set when the source is added to a map.
|
||||
jni::UniqueObject<Source> javaPeer;
|
||||
|
||||
// RendererFrontend pointer is valid only when added to the map.
|
||||
AndroidRendererFrontend* rendererFrontend { nullptr };
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
#include "sources.hpp"
|
||||
|
||||
#include <mbgl/style/source.hpp>
|
||||
#include <mbgl/style/sources/geojson_source.hpp>
|
||||
#include <mbgl/style/sources/image_source.hpp>
|
||||
#include <mbgl/style/sources/raster_source.hpp>
|
||||
#include <mbgl/style/sources/vector_source.hpp>
|
||||
|
||||
#include "source.hpp"
|
||||
#include "geojson_source.hpp"
|
||||
#include "image_source.hpp"
|
||||
#include "raster_source.hpp"
|
||||
#include "unknown_source.hpp"
|
||||
#include "vector_source.hpp"
|
||||
#include "custom_geometry_source.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace mbgl::android;
|
||||
|
||||
Source* initializeSourcePeer(mbgl::style::Source& coreSource) {
|
||||
Source* source;
|
||||
if (coreSource.is<mbgl::style::VectorSource>()) {
|
||||
source = new VectorSource(*coreSource.as<mbgl::style::VectorSource>());
|
||||
} else if (coreSource.is<mbgl::style::RasterSource>()) {
|
||||
source = new RasterSource(*coreSource.as<mbgl::style::RasterSource>());
|
||||
} else if (coreSource.is<mbgl::style::GeoJSONSource>()) {
|
||||
source = new GeoJSONSource(*coreSource.as<mbgl::style::GeoJSONSource>());
|
||||
} else if (coreSource.is<mbgl::style::ImageSource>()) {
|
||||
source = new ImageSource(*coreSource.as<mbgl::style::ImageSource>());
|
||||
} else {
|
||||
source = new UnknownSource(coreSource);
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
|
||||
jni::jobject* createJavaSourcePeer(jni::JNIEnv& env, AndroidRendererFrontend& frontend, mbgl::style::Source& coreSource) {
|
||||
std::unique_ptr<Source> peerSource = std::unique_ptr<Source>(initializeSourcePeer(coreSource));
|
||||
peerSource->setRendererFrontend(frontend);
|
||||
jni::jobject* result = peerSource->createJavaPeer(env);
|
||||
peerSource.release();
|
||||
return result;
|
||||
}
|
||||
|
||||
void registerNativeSources(jni::JNIEnv& env) {
|
||||
Source::registerNative(env);
|
||||
GeoJSONSource::registerNative(env);
|
||||
ImageSource::registerNative(env);
|
||||
RasterSource::registerNative(env);
|
||||
UnknownSource::registerNative(env);
|
||||
VectorSource::registerNative(env);
|
||||
CustomGeometrySource::registerNative(env);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/source.hpp>
|
||||
|
||||
#include "source.hpp"
|
||||
#include "../../android_renderer_frontend.hpp"
|
||||
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
jni::jobject* createJavaSourcePeer(jni::JNIEnv&, AndroidRendererFrontend&, mbgl::style::Source&);
|
||||
|
||||
void registerNativeSources(jni::JNIEnv&);
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
@@ -12,15 +12,17 @@ namespace {
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
UnknownSource::UnknownSource(mbgl::style::Source& coreSource)
|
||||
: Source(coreSource) {
|
||||
UnknownSource::UnknownSource(jni::JNIEnv& env,
|
||||
mbgl::style::Source& coreSource,
|
||||
AndroidRendererFrontend& frontend)
|
||||
: Source(env, coreSource, createJavaPeer(env), frontend) {
|
||||
}
|
||||
|
||||
jni::Class<UnknownSource> UnknownSource::javaClass;
|
||||
|
||||
jni::jobject* UnknownSource::createJavaPeer(jni::JNIEnv& env) {
|
||||
jni::Object<Source> UnknownSource::createJavaPeer(jni::JNIEnv& env) {
|
||||
static auto constructor = UnknownSource::javaClass.template GetConstructor<jni::jlong>(env);
|
||||
return UnknownSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this));
|
||||
return jni::Object<Source>(UnknownSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)).Get());
|
||||
}
|
||||
|
||||
void UnknownSource::registerNative(jni::JNIEnv& env) {
|
||||
|
||||
@@ -16,11 +16,12 @@ public:
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
UnknownSource(mbgl::style::Source&);
|
||||
UnknownSource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
|
||||
|
||||
~UnknownSource() = default;
|
||||
|
||||
jni::jobject* createJavaPeer(jni::JNIEnv&);
|
||||
private:
|
||||
jni::Object<Source> createJavaPeer(jni::JNIEnv&);
|
||||
|
||||
}; // class UnknownSource
|
||||
|
||||
|
||||
@@ -30,8 +30,10 @@ namespace android {
|
||||
) {
|
||||
}
|
||||
|
||||
VectorSource::VectorSource(mbgl::style::VectorSource& coreSource)
|
||||
: Source(coreSource) {
|
||||
VectorSource::VectorSource(jni::JNIEnv& env,
|
||||
mbgl::style::Source& coreSource,
|
||||
AndroidRendererFrontend& frontend)
|
||||
: Source(env, coreSource, createJavaPeer(env), frontend) {
|
||||
}
|
||||
|
||||
VectorSource::~VectorSource() = default;
|
||||
@@ -56,9 +58,9 @@ namespace android {
|
||||
|
||||
jni::Class<VectorSource> VectorSource::javaClass;
|
||||
|
||||
jni::jobject* VectorSource::createJavaPeer(jni::JNIEnv& env) {
|
||||
jni::Object<Source> VectorSource::createJavaPeer(jni::JNIEnv& env) {
|
||||
static auto constructor = VectorSource::javaClass.template GetConstructor<jni::jlong>(env);
|
||||
return VectorSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this));
|
||||
return jni::Object<Source>(VectorSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)).Get());
|
||||
}
|
||||
|
||||
void VectorSource::registerNative(jni::JNIEnv& env) {
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
|
||||
VectorSource(jni::JNIEnv&, jni::String, jni::Object<>);
|
||||
|
||||
VectorSource(mbgl::style::VectorSource&);
|
||||
VectorSource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
|
||||
|
||||
~VectorSource();
|
||||
|
||||
@@ -28,7 +28,8 @@ public:
|
||||
|
||||
jni::String getURL(jni::JNIEnv&);
|
||||
|
||||
jni::jobject* createJavaPeer(jni::JNIEnv&);
|
||||
private:
|
||||
jni::Object<Source> createJavaPeer(jni::JNIEnv&);
|
||||
|
||||
}; // class VectorSource
|
||||
|
||||
|
||||
Reference in New Issue
Block a user