diff options
26 files changed, 318 insertions, 157 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java index 8f1c00f1b5..94929398d5 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java @@ -99,7 +99,7 @@ public class CircleLayer extends Layer { @Nullable public Expression getFilter() { Expression expression = null; - JsonArray array = nativeGetFilter(); + JsonArray array = (JsonArray) nativeGetFilter(); if (array != null) { expression = Expression.Converter.convert(array); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillExtrusionLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillExtrusionLayer.java index 34f062b4d6..29e2b49d76 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillExtrusionLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillExtrusionLayer.java @@ -99,7 +99,7 @@ public class FillExtrusionLayer extends Layer { @Nullable public Expression getFilter() { Expression expression = null; - JsonArray array = nativeGetFilter(); + JsonArray array = (JsonArray) nativeGetFilter(); if (array != null) { expression = Expression.Converter.convert(array); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java index 1865349c42..ed780811c0 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java @@ -99,7 +99,7 @@ public class FillLayer extends Layer { @Nullable public Expression getFilter() { Expression expression = null; - JsonArray array = nativeGetFilter(); + JsonArray array = (JsonArray) nativeGetFilter(); if (array != null) { expression = Expression.Converter.convert(array); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/HeatmapLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/HeatmapLayer.java index a8d07bdbb4..42b4210710 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/HeatmapLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/HeatmapLayer.java @@ -99,7 +99,7 @@ public class HeatmapLayer extends Layer { @Nullable public Expression getFilter() { Expression expression = null; - JsonArray array = nativeGetFilter(); + JsonArray array = (JsonArray) nativeGetFilter(); if (array != null) { expression = Expression.Converter.convert(array); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java index 26fc9d32e1..411fbe4435 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java @@ -3,6 +3,7 @@ package com.mapbox.mapboxsdk.style.layers; import android.support.annotation.NonNull; import com.google.gson.JsonArray; +import com.google.gson.JsonElement; import com.mapbox.mapboxsdk.style.expressions.Expression; /** @@ -72,7 +73,7 @@ public abstract class Layer { protected native void nativeSetFilter(Object[] filter); - protected native JsonArray nativeGetFilter(); + protected native JsonElement nativeGetFilter(); protected native void nativeSetSourceLayer(String sourceLayer); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java index 9dbd3aeb19..5e6e6d38e7 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java @@ -99,7 +99,7 @@ public class LineLayer extends Layer { @Nullable public Expression getFilter() { Expression expression = null; - JsonArray array = nativeGetFilter(); + JsonArray array = (JsonArray) nativeGetFilter(); if (array != null) { expression = Expression.Converter.convert(array); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java index bc1e02a89f..6a2e131d7d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java @@ -99,7 +99,7 @@ public class SymbolLayer extends Layer { @Nullable public Expression getFilter() { Expression expression = null; - JsonArray array = nativeGetFilter(); + JsonArray array = (JsonArray) nativeGetFilter(); if (array != null) { expression = Expression.Converter.convert(array); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs index f3941aacf6..851a85f3d6 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs @@ -119,7 +119,7 @@ public class <%- camelize(type) %>Layer extends Layer { @Nullable public Expression getFilter() { Expression expression = null; - JsonArray array = nativeGetFilter(); + JsonArray array = (JsonArray) nativeGetFilter(); if (array != null) { expression = Expression.Converter.convert(array); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolGeneratorActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolGeneratorActivity.java index c42f264478..f32aa5faf8 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolGeneratorActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolGeneratorActivity.java @@ -294,6 +294,13 @@ public class SymbolGeneratorActivity extends AppCompatActivity implements OnMapR Expression textFieldExpressionResult = symbolLayer.getTextField().getExpression(); Expression textColorExpressionResult = symbolLayer.getTextColor().getExpression(); + // log expressions + Timber.e(iconImageExpressionResult.toString()); + Timber.e(iconSizeExpressionResult.toString()); + Timber.e(textSizeExpressionResult.toString()); + Timber.e(textFieldExpressionResult.toString()); + Timber.e(textColorExpressionResult.toString()); + // reset expressions symbolLayer.setProperties( iconImage(iconImageExpressionResult), diff --git a/platform/android/config.cmake b/platform/android/config.cmake index 80d0810564..77074dc82c 100644 --- a/platform/android/config.cmake +++ b/platform/android/config.cmake @@ -131,7 +131,6 @@ add_library(mbgl-android STATIC platform/android/src/conversion/constant.hpp platform/android/src/conversion/conversion.hpp platform/android/src/style/conversion/function.hpp - platform/android/src/style/conversion/gson.hpp platform/android/src/style/conversion/property_value.hpp platform/android/src/style/conversion/types.hpp platform/android/src/style/conversion/types_string_values.hpp @@ -213,6 +212,8 @@ add_library(mbgl-android STATIC platform/android/src/map_renderer_runnable.hpp # Java core classes + platform/android/src/java/lang.cpp + platform/android/src/java/lang.hpp platform/android/src/java/util.cpp platform/android/src/java/util.hpp diff --git a/platform/android/src/gson/json_array.cpp b/platform/android/src/gson/json_array.cpp index d91e323ac9..e8852d77e9 100644 --- a/platform/android/src/gson/json_array.cpp +++ b/platform/android/src/gson/json_array.cpp @@ -6,7 +6,22 @@ namespace mbgl { namespace android { namespace gson { -std::vector<mapbox::geometry::value> JsonArray::convert(jni::JNIEnv &env, jni::Object<JsonArray> jsonArray) { +jni::Object<JsonArray> JsonArray::New(jni::JNIEnv& env, const std::vector<mapbox::geometry::value>& values){ + static auto constructor = JsonArray::javaClass.GetConstructor(env); + static auto addMethod = JsonArray::javaClass.GetMethod<void (jni::Object<JsonElement>)>(env, "add"); + + auto jsonArray = JsonArray::javaClass.New(env, constructor); + + for (const auto &v : values) { + auto jsonElement = JsonElement::New(env, v); + jsonArray.Call(env, addMethod, jsonElement); + jni::DeleteLocalRef(env, jsonElement); + } + + return jsonArray; +} + +std::vector<mapbox::geometry::value> JsonArray::convert(jni::JNIEnv& env, const jni::Object<JsonArray> jsonArray) { std::vector<mapbox::geometry::value> values; if (jsonArray) { @@ -28,7 +43,7 @@ std::vector<mapbox::geometry::value> JsonArray::convert(jni::JNIEnv &env, jni::O return values; } -void JsonArray::registerNative(jni::JNIEnv &env) { +void JsonArray::registerNative(jni::JNIEnv& env) { // Lookup the class javaClass = *jni::Class<JsonArray>::Find(env).NewGlobalRef(env).release(); } diff --git a/platform/android/src/gson/json_array.hpp b/platform/android/src/gson/json_array.hpp index 8571ad5dba..c9ae98692f 100644 --- a/platform/android/src/gson/json_array.hpp +++ b/platform/android/src/gson/json_array.hpp @@ -13,6 +13,8 @@ class JsonArray : private mbgl::util::noncopyable { public: static constexpr auto Name() { return "com/google/gson/JsonArray"; }; + static jni::Object<JsonArray> New(jni::JNIEnv&, const std::vector<mapbox::geometry::value>&); + static std::vector<mapbox::geometry::value> convert(JNIEnv&, jni::Object<JsonArray>); static jni::Class<JsonArray> javaClass; diff --git a/platform/android/src/gson/json_element.cpp b/platform/android/src/gson/json_element.cpp index 060b1e0fe2..5eaaf531f4 100644 --- a/platform/android/src/gson/json_element.cpp +++ b/platform/android/src/gson/json_element.cpp @@ -11,6 +11,34 @@ namespace mbgl { namespace android { namespace gson { +/** + * Turn mapbox::geometry::value into Java Gson JsonElement + */ +class JsonElementEvaluator { +public: + + jni::JNIEnv& env; + + jni::Object<JsonElement> operator()(const JsonPrimitive::value value) const { + return jni::Cast(env, JsonPrimitive::New(env, value), JsonElement::javaClass); + } + + jni::Object<JsonElement> operator()(const std::vector<mapbox::geometry::value> &values) const { + return jni::Cast(env, JsonArray::New(env, values), JsonElement::javaClass); + } + + jni::Object<JsonElement> operator()(const std::unordered_map<std::string, mapbox::geometry::value> &values) const { + return jni::Cast(env, JsonObject::New(env, values), JsonElement::javaClass); + } + +}; + + +jni::Object<JsonElement> JsonElement::New(jni::JNIEnv& env, const mapbox::geometry::value& value) { + JsonElementEvaluator evaluator { env } ; + return mapbox::geometry::value::visit(value, evaluator); +} + mapbox::geometry::value JsonElement::convert(jni::JNIEnv &env, jni::Object<JsonElement> jsonElement) { mapbox::geometry::value value; diff --git a/platform/android/src/gson/json_element.hpp b/platform/android/src/gson/json_element.hpp index 7619350617..d850caa526 100644 --- a/platform/android/src/gson/json_element.hpp +++ b/platform/android/src/gson/json_element.hpp @@ -13,6 +13,8 @@ class JsonElement : private mbgl::util::noncopyable { public: static constexpr auto Name() { return "com/google/gson/JsonElement"; }; + static jni::Object<JsonElement> New(jni::JNIEnv&, const mapbox::geometry::value&); + static mapbox::geometry::value convert(JNIEnv&, jni::Object<JsonElement>); static bool isJsonObject(JNIEnv&, jni::Object<JsonElement>); diff --git a/platform/android/src/gson/json_object.cpp b/platform/android/src/gson/json_object.cpp index a704dae9dd..61b55f8b9e 100644 --- a/platform/android/src/gson/json_object.cpp +++ b/platform/android/src/gson/json_object.cpp @@ -9,6 +9,23 @@ namespace android { namespace gson { +jni::Object<JsonObject> JsonObject::New(jni::JNIEnv& env, const std::unordered_map<std::string, mapbox::geometry::value>& values) { + static auto constructor = JsonObject::javaClass.GetConstructor(env); + static auto addMethod = JsonObject::javaClass.GetMethod<void (jni::String, jni::Object<JsonElement>)>(env, "add"); + + jni::Object<JsonObject> jsonObject = JsonObject::javaClass.New(env, constructor); + + for (auto &item : values) { + jni::Object<JsonElement> jsonElement = JsonElement::New(env, item.second); + jni::String key = jni::Make<jni::String>(env, item.first); + jsonObject.Call(env, addMethod, key, jsonElement); + jni::DeleteLocalRef(env, jsonElement); + jni::DeleteLocalRef(env, key); + } + + return jsonObject; +} + template <typename F> // void (jni::String, jni::Object<gson::JsonElement>) static void iterateEntrySet(jni::JNIEnv& env, jni::Object<JsonObject> jsonObject, F callback) { // Get Set<Map.Entry<String, JsonElement>> diff --git a/platform/android/src/gson/json_object.hpp b/platform/android/src/gson/json_object.hpp index aba8e40415..4bc61e51a2 100644 --- a/platform/android/src/gson/json_object.hpp +++ b/platform/android/src/gson/json_object.hpp @@ -13,6 +13,8 @@ class JsonObject : private mbgl::util::noncopyable { public: static constexpr auto Name() { return "com/google/gson/JsonObject"; }; + static jni::Object<JsonObject> New(jni::JNIEnv&, const std::unordered_map<std::string, mapbox::geometry::value>&); + static mapbox::geometry::property_map convert(JNIEnv&, jni::Object<JsonObject>); static jni::Class<JsonObject> javaClass; diff --git a/platform/android/src/gson/json_primitive.cpp b/platform/android/src/gson/json_primitive.cpp index 58d0b45fe7..4e171c4845 100644 --- a/platform/android/src/gson/json_primitive.cpp +++ b/platform/android/src/gson/json_primitive.cpp @@ -1,9 +1,89 @@ #include "json_primitive.hpp" +#include "../java/lang.hpp" namespace mbgl { namespace android { namespace gson { +/** + * Turn mapbox::geometry::value into Java Gson JsonPrimitives + */ +class JsonPrimitiveEvaluator { +public: + + jni::JNIEnv& env; + + /** + * Create a null primitive + */ + jni::Object<JsonPrimitive> operator()(const mapbox::geometry::null_value_t) const { + return jni::Object<JsonPrimitive>(); + } + + /** + * Create a primitive containing a string value + */ + jni::Object<JsonPrimitive> operator()(const std::string value) const { + static auto constructor = JsonPrimitive::javaClass.GetConstructor<jni::String>(env); + auto jvalue = jni::Make<jni::String>(env, value); + auto jsonPrimitive = JsonPrimitive::javaClass.New(env, constructor, jvalue); + jni::DeleteLocalRef(env, jvalue); + return jsonPrimitive; + } + + /** + * Create a primitive containing a number value with type double + */ + jni::Object<JsonPrimitive> operator()(const double value) const { + static auto constructor = JsonPrimitive::javaClass.GetConstructor<jni::Object<java::lang::Number>>(env); + auto boxedValue = java::lang::Double::valueOf(env, value); + auto number = jni::Cast(env, boxedValue, java::lang::Number::javaClass); + auto jsonPrimitive = JsonPrimitive::javaClass.New(env, constructor, number); + jni::DeleteLocalRef(env, boxedValue); + return jsonPrimitive; + } + + /** + * Create a primitive containing a number value with type long + */ + jni::Object<JsonPrimitive> operator()(const int64_t value) const { + static auto constructor = JsonPrimitive::javaClass.GetConstructor<jni::Object<java::lang::Number>>(env); + auto boxedValue = java::lang::Long::valueOf(env, value); + auto number = jni::Cast(env, boxedValue, java::lang::Number::javaClass); + auto jsonPrimitive = JsonPrimitive::javaClass.New(env, constructor, number); + jni::DeleteLocalRef(env, boxedValue); + return jsonPrimitive; + } + + /** + * Create a primitive containing a number value with type long + */ + jni::Object<JsonPrimitive> operator()(const uint64_t value) const { + static auto constructor = JsonPrimitive::javaClass.GetConstructor<jni::Object<java::lang::Number>>(env); + auto boxedValue = java::lang::Long::valueOf(env, value); + auto number = jni::Cast(env, boxedValue, java::lang::Number::javaClass); + auto jsonPrimitive = JsonPrimitive::javaClass.New(env, constructor, number); + jni::DeleteLocalRef(env, boxedValue); + return jsonPrimitive; + } + + /** + * Create a primitive containing a boolean value + */ + jni::Object<JsonPrimitive> operator()(const bool value) const { + static auto constructor = JsonPrimitive::javaClass.GetConstructor<jni::Object<java::lang::Boolean>>(env); + auto boxedValue = java::lang::Boolean::valueOf(env, value); + auto jsonPrimitive = JsonPrimitive::javaClass.New(env, constructor, boxedValue); + jni::DeleteLocalRef(env, boxedValue); + return jsonPrimitive; + } +}; + +jni::Object<JsonPrimitive> JsonPrimitive::New(jni::JNIEnv &env, const value& value) { + JsonPrimitiveEvaluator evaluator { env }; + return value::visit(value, evaluator); +} + JsonPrimitive::value JsonPrimitive::convert(jni::JNIEnv &env, jni::Object<JsonPrimitive> jsonPrimitive) { value value; if (jsonPrimitive) { diff --git a/platform/android/src/gson/json_primitive.hpp b/platform/android/src/gson/json_primitive.hpp index 5fc8a2b485..c418e0ebe8 100644 --- a/platform/android/src/gson/json_primitive.hpp +++ b/platform/android/src/gson/json_primitive.hpp @@ -15,6 +15,8 @@ public: static constexpr auto Name() { return "com/google/gson/JsonPrimitive"; }; + static jni::Object<JsonPrimitive> New(jni::JNIEnv&, const value&); + static value convert(JNIEnv&, jni::Object<JsonPrimitive>); static bool isBoolean(JNIEnv&, jni::Object<JsonPrimitive>); diff --git a/platform/android/src/java/lang.cpp b/platform/android/src/java/lang.cpp new file mode 100644 index 0000000000..3c95737169 --- /dev/null +++ b/platform/android/src/java/lang.cpp @@ -0,0 +1,76 @@ +#include "lang.hpp" + +namespace mbgl { +namespace android { +namespace java { +namespace lang { + +// Float + +jni::Object<Float> Float::valueOf(JNIEnv &env, jfloat value) { + static auto method = javaClass.GetStaticMethod<jni::Object<Float> (jni::jfloat)>(env, "valueOf"); + return javaClass.Call(env, method, value); +} + +void Float::registerNative(jni::JNIEnv &env) { + // Lookup the class + javaClass = *jni::Class<Float>::Find(env).NewGlobalRef(env).release(); +} + +jni::Class<Float> Float::javaClass; + +// Long + +jni::Object<Long> Long::valueOf(JNIEnv &env, jlong value) { + static auto method = javaClass.GetStaticMethod<jni::Object<Long> (jni::jlong)>(env, "valueOf"); + return javaClass.Call(env, method, value); +} + +void Long::registerNative(jni::JNIEnv &env) { + // Lookup the class + javaClass = *jni::Class<Long>::Find(env).NewGlobalRef(env).release(); +} + +jni::Class<Long> Long::javaClass; + +// Double + +jni::Object<Double> Double::valueOf(JNIEnv &env, jdouble value) { + static auto method = javaClass.GetStaticMethod<jni::Object<Double> (jni::jdouble)>(env, "valueOf"); + return javaClass.Call(env, method, value); +} + +void Double::registerNative(jni::JNIEnv &env) { + // Lookup the class + javaClass = *jni::Class<Double>::Find(env).NewGlobalRef(env).release(); +} + +jni::Class<Double> Double::javaClass; + +// Boolean + +jni::Object<Boolean> Boolean::valueOf(JNIEnv &env, jboolean value) { + static auto method = javaClass.GetStaticMethod<jni::Object<Boolean> (jni::jboolean)>(env, "valueOf"); + return javaClass.Call(env, method, value); +} + +void Boolean::registerNative(jni::JNIEnv &env) { + // Lookup the class + javaClass = *jni::Class<Boolean>::Find(env).NewGlobalRef(env).release(); +} + +jni::Class<Boolean> Boolean::javaClass; + +// Number + +void Number::registerNative(jni::JNIEnv &env) { + // Lookup the class + javaClass = *jni::Class<Number>::Find(env).NewGlobalRef(env).release(); +} + +jni::Class<Number> Number::javaClass; + +} // namespace lang +} // namespace java +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/java/lang.hpp b/platform/android/src/java/lang.hpp index dcf81a9d0c..981e3b14b7 100644 --- a/platform/android/src/java/lang.hpp +++ b/platform/android/src/java/lang.hpp @@ -1,18 +1,64 @@ #pragma once +#include <jni/jni.hpp> +#include <mbgl/util/noncopyable.hpp> + namespace mbgl { namespace android { namespace java { namespace lang { -class Float { +class Float : private mbgl::util::noncopyable { public: static constexpr auto Name() { return "java/lang/Float"; }; + + static jni::Object<Float> valueOf(JNIEnv&, jfloat); + + static jni::Class<Float> javaClass; + + static void registerNative(jni::JNIEnv&); +}; + +class Double : private mbgl::util::noncopyable { +public: + static constexpr auto Name() { return "java/lang/Double"; }; + + static jni::Object<Double> valueOf(JNIEnv&, jdouble); + + static jni::Class<Double> javaClass; + + static void registerNative(jni::JNIEnv&); +}; + +class Long : private mbgl::util::noncopyable { +public: + static constexpr auto Name() { return "java/lang/Long"; }; + + static jni::Object<Long> valueOf(JNIEnv&, jlong); + + static jni::Class<Long> javaClass; + + static void registerNative(jni::JNIEnv&); +}; + +class Boolean : private mbgl::util::noncopyable { +public: + static constexpr auto Name() { return "java/lang/Boolean"; }; + + static jni::Object<Boolean> valueOf(JNIEnv&, jboolean); + + static jni::Class<Boolean> javaClass; + + static void registerNative(jni::JNIEnv&); }; -class Number { +class Number : private mbgl::util::noncopyable { public: static constexpr auto Name() { return "java/lang/Number"; }; + + static jni::Class<Number> javaClass; + + static void registerNative(jni::JNIEnv&); }; } // namespace lang diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp index c8c20e939a..2f6ed96ab0 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -47,6 +47,7 @@ #include "snapshotter/map_snapshotter.hpp" #include "snapshotter/map_snapshot.hpp" #include "text/local_glyph_rasterizer_jni.hpp" +#include "java/lang.hpp" namespace mbgl { namespace android { @@ -112,6 +113,11 @@ void registerNatives(JavaVM *vm) { java::util::registerNative(env); PointF::registerNative(env); RectF::registerNative(env); + java::lang::Number::registerNative(env); + java::lang::Float::registerNative(env); + java::lang::Boolean::registerNative(env); + java::lang::Double::registerNative(env); + java::lang::Long::registerNative(env); // GeoJSON geojson::Feature::registerNative(env); diff --git a/platform/android/src/style/conversion/function.hpp b/platform/android/src/style/conversion/function.hpp index 510efd3c94..d6669b4508 100644 --- a/platform/android/src/style/conversion/function.hpp +++ b/platform/android/src/style/conversion/function.hpp @@ -7,7 +7,8 @@ #include "../../java/lang.hpp" #include <jni/jni.hpp> -#include "gson.hpp" +#include "../../gson/json_element.hpp" + #include <tuple> #include <map> @@ -16,41 +17,32 @@ namespace android { namespace conversion { template <class T> -struct Converter<jni::jobject*, mbgl::style::CameraFunction<T>> { +struct Converter<jni::Object<android::gson::JsonElement>, mbgl::style::CameraFunction<T>> { - Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::CameraFunction<T>& value) const { + Result<jni::Object<android::gson::JsonElement>> operator()(jni::JNIEnv& env, const mbgl::style::CameraFunction<T>& value) const { // Convert expressions mbgl::Value expressionValue = value.getExpression().serialize(); - JsonEvaluator jsonEvaluator{env}; - jni::jobject* converted = apply_visitor(jsonEvaluator, expressionValue); - - return converted; + return gson::JsonElement::New(env, expressionValue); } }; template <class T> -struct Converter<jni::jobject*, mbgl::style::SourceFunction<T>> { +struct Converter<jni::Object<android::gson::JsonElement>, mbgl::style::SourceFunction<T>> { - Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::SourceFunction<T>& value) const { + Result<jni::Object<android::gson::JsonElement>> operator()(jni::JNIEnv& env, const mbgl::style::SourceFunction<T>& value) const { // Convert expressions mbgl::Value expressionValue = value.getExpression().serialize(); - JsonEvaluator jsonEvaluator{env}; - jni::jobject* converted = apply_visitor(jsonEvaluator, expressionValue); - - return converted; + return gson::JsonElement::New(env, expressionValue); } }; template <class T> -struct Converter<jni::jobject*, mbgl::style::CompositeFunction<T>> { +struct Converter<jni::Object<android::gson::JsonElement>, mbgl::style::CompositeFunction<T>> { - Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::CompositeFunction<T>& value) const { + Result<jni::Object<android::gson::JsonElement>> operator()(jni::JNIEnv& env, const mbgl::style::CompositeFunction<T>& value) const { // Convert expressions mbgl::Value expressionValue = value.getExpression().serialize(); - JsonEvaluator jsonEvaluator{env}; - jni::jobject* converted = apply_visitor(jsonEvaluator, expressionValue); - - return converted; + return gson::JsonElement::New(env, expressionValue); } }; diff --git a/platform/android/src/style/conversion/gson.hpp b/platform/android/src/style/conversion/gson.hpp deleted file mode 100644 index 02c3fdd30d..0000000000 --- a/platform/android/src/style/conversion/gson.hpp +++ /dev/null @@ -1,114 +0,0 @@ -#pragma once - -#include "../../conversion/constant.hpp" -#include "../../conversion/collection.hpp" - -#include <mapbox/geometry.hpp> -#include <jni/jni.hpp> -#include "../../jni/local_object.hpp" -#include "mapbox/geometry/feature.hpp" - -namespace mbgl { -namespace android { -namespace conversion { - -/** - * Turn mapbox::geometry::value type into Java Json - */ -class JsonEvaluator { -public: - - jni::JNIEnv& env; - - jni::jobject* operator()(const mapbox::geometry::null_value_t) const { - return (jni::jobject*) nullptr;; - } - - jni::jobject* operator()(const bool& value) const { - static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/google/gson/JsonPrimitive")).release(); - static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "(Ljava/lang/Boolean;)V"); - - // Create JsonPrimitive - jni::LocalObject<jni::jobject> converted = jni::NewLocalObject(env, *convert<jni::jobject*, bool>(env, value)); - jni::jobject* object = &jni::NewObject(env, *javaClass, *constructor, *converted); - - return object; - } - - template <class Number> - jni::jobject* operator()(const Number& value) const { - static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/google/gson/JsonPrimitive")).release(); - static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "(Ljava/lang/Number;)V"); - - // Create JsonPrimitive - jni::LocalObject<jni::jobject> converted = jni::NewLocalObject(env, *convert<jni::jobject*, Number>(env, value)); - jni::jobject* object = &jni::NewObject(env, *javaClass, *constructor, converted.get()); - - return object; - } - - jni::jobject* operator()(const std::string value) const { - static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/google/gson/JsonPrimitive")).release(); - static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "(Ljava/lang/String;)V"); - - // Create JsonPrimitive - jni::LocalObject<jni::jobject> converted = jni::NewLocalObject(env, *convert<jni::jobject*, std::string>(env, value)); - jni::jobject* object = &jni::NewObject(env, *javaClass, *constructor, converted.get()); - - return object; - } - - jni::jobject* operator()(const std::vector<mapbox::geometry::value> values) const { - static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/google/gson/JsonArray")).release(); - static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "()V");; - static jni::jmethodID* add = &jni::GetMethodID(env, *javaClass, "add", "(Lcom/google/gson/JsonElement;)V"); - - // Create json array - jni::jobject* jarray = &jni::NewObject(env, *javaClass, *constructor); - - // Add values - for (const auto &v : values) { - jni::LocalObject<jni::jobject> converted = jni::NewLocalObject(env, mapbox::geometry::value::visit(v, *this)); - jni::CallMethod<void>(env, jarray, *add, converted.get()); - } - - return jarray; - } - - jni::jobject* operator()(const std::unordered_map<std::string, mapbox::geometry::value> value) const { - static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/google/gson/JsonObject")).release(); - static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "()V");; - static jni::jmethodID* add = &jni::GetMethodID(env, *javaClass, "add", "(Ljava/lang/String;Lcom/google/gson/JsonElement;)V"); - - // Create json object - jni::jobject* jsonObject = &jni::NewObject(env, *javaClass, *constructor); - - // Add items - for (auto &item : value) { - jni::LocalObject<jni::jobject> converted = jni::NewLocalObject(env, mbgl::Value::visit(item.second, *this)); - jni::LocalObject<jni::jobject> key = jni::NewLocalObject(env, *convert<jni::jobject*, std::string>(env, item.first)); - jni::CallMethod<void>(env, jsonObject, *add, key.get(), converted.get()); - } - - return jsonObject; - } - -private: - -}; - -/** - * mapbox::geometry::value -> Java Json - */ -template <> -struct Converter<jni::jobject*, mapbox::geometry::value> { - Result<jni::jobject*> operator()(jni::JNIEnv& env, const mapbox::geometry::value& value) const { - JsonEvaluator evaluator { env } ; - jni::jobject* converted = mapbox::geometry::value::visit(value, evaluator); - return { converted }; - } -}; - -} -} -} diff --git a/platform/android/src/style/conversion/property_value.hpp b/platform/android/src/style/conversion/property_value.hpp index 4ed25eac25..902d1e80b2 100644 --- a/platform/android/src/style/conversion/property_value.hpp +++ b/platform/android/src/style/conversion/property_value.hpp @@ -7,7 +7,6 @@ #include "../../conversion/constant.hpp" #include "types.hpp" #include "function.hpp" -#include "gson.hpp" namespace mbgl { namespace android { @@ -32,15 +31,15 @@ public: } jni::jobject* operator()(const mbgl::style::CameraFunction<T> &value) const { - return *convert<jni::jobject*, mbgl::style::CameraFunction<T>>(env, value); + return *convert<jni::Object<android::gson::JsonElement>, mbgl::style::CameraFunction<T>>(env, value); } jni::jobject* operator()(const mbgl::style::SourceFunction<T> &value) const { - return *convert<jni::jobject*, mbgl::style::SourceFunction<T>>(env, value); + return *convert<jni::Object<android::gson::JsonElement>, mbgl::style::SourceFunction<T>>(env, value); } jni::jobject* operator()(const mbgl::style::CompositeFunction<T> &value) const { - return *convert<jni::jobject*, mbgl::style::CompositeFunction<T>>(env, value); + return *convert<jni::Object<android::gson::JsonElement>, mbgl::style::CompositeFunction<T>>(env, value); } private: diff --git a/platform/android/src/style/layers/layer.cpp b/platform/android/src/style/layers/layer.cpp index a2f4087fce..6fe6e3cb29 100644 --- a/platform/android/src/style/layers/layer.cpp +++ b/platform/android/src/style/layers/layer.cpp @@ -26,7 +26,6 @@ // C++ -> Java conversion #include "../conversion/property_value.hpp" #include <mbgl/style/filter.hpp> -#include "../conversion/gson.hpp" #include <string> @@ -153,20 +152,19 @@ namespace android { } }; - jni::Object<gson::JsonArray> Layer::getFilter(jni::JNIEnv& env) { + jni::Object<gson::JsonElement> Layer::getFilter(jni::JNIEnv& env) { using namespace mbgl::style; using namespace mbgl::style::conversion; Filter filter = layer.accept(GetFilterEvaluator()); - jni::jobject* converted = nullptr; + jni::Object<gson::JsonElement> converted; if (filter.is<ExpressionFilter>()) { ExpressionFilter filterExpression = filter.get<ExpressionFilter>(); mbgl::Value expressionValue = filterExpression.expression.get()->serialize(); - conversion::JsonEvaluator jsonEvaluator{env}; - converted = apply_visitor(jsonEvaluator, expressionValue); + converted = gson::JsonElement::New(env, expressionValue); } - return jni::Object<gson::JsonArray>(converted); + return converted; } struct SetSourceLayerEvaluator { diff --git a/platform/android/src/style/layers/layer.hpp b/platform/android/src/style/layers/layer.hpp index 19713a1baa..2486b0dfa6 100644 --- a/platform/android/src/style/layers/layer.hpp +++ b/platform/android/src/style/layers/layer.hpp @@ -5,6 +5,7 @@ #include <mbgl/style/layer.hpp> #include "../../gson/json_array.hpp" #include "../value.hpp" +#include "../../gson/json_element.hpp" #include <jni/jni.hpp> @@ -68,7 +69,7 @@ public: void setFilter(jni::JNIEnv&, jni::Array<jni::Object<>>); - jni::Object<gson::JsonArray> getFilter(jni::JNIEnv&); + jni::Object<gson::JsonElement> getFilter(jni::JNIEnv&); void setSourceLayer(jni::JNIEnv&, jni::String); |