Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Rework expression conversion #11490

Merged
merged 3 commits into from
Apr 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public CircleLayer withFilter(Expression filter) {
@Nullable
public Expression getFilter() {
Expression expression = null;
JsonArray array = nativeGetFilter();
JsonArray array = (JsonArray) nativeGetFilter();
if (array != null) {
expression = Expression.Converter.convert(array);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public FillExtrusionLayer withFilter(Expression filter) {
@Nullable
public Expression getFilter() {
Expression expression = null;
JsonArray array = nativeGetFilter();
JsonArray array = (JsonArray) nativeGetFilter();
if (array != null) {
expression = Expression.Converter.convert(array);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public FillLayer withFilter(Expression filter) {
@Nullable
public Expression getFilter() {
Expression expression = null;
JsonArray array = nativeGetFilter();
JsonArray array = (JsonArray) nativeGetFilter();
if (array != null) {
expression = Expression.Converter.convert(array);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public HeatmapLayer withFilter(Expression filter) {
@Nullable
public Expression getFilter() {
Expression expression = null;
JsonArray array = nativeGetFilter();
JsonArray array = (JsonArray) nativeGetFilter();
if (array != null) {
expression = Expression.Converter.convert(array);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.support.annotation.NonNull;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.mapbox.mapboxsdk.style.expressions.Expression;

/**
Expand Down Expand Up @@ -72,7 +73,7 @@ public void setMaxZoom(float zoom) {

protected native void nativeSetFilter(Object[] filter);

protected native JsonArray nativeGetFilter();
protected native JsonElement nativeGetFilter();

protected native void nativeSetSourceLayer(String sourceLayer);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public LineLayer withFilter(Expression filter) {
@Nullable
public Expression getFilter() {
Expression expression = null;
JsonArray array = nativeGetFilter();
JsonArray array = (JsonArray) nativeGetFilter();
if (array != null) {
expression = Expression.Converter.convert(array);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public SymbolLayer withFilter(Expression filter) {
@Nullable
public Expression getFilter() {
Expression expression = null;
JsonArray array = nativeGetFilter();
JsonArray array = (JsonArray) nativeGetFilter();
if (array != null) {
expression = Expression.Converter.convert(array);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,13 @@ public void onDataLoaded(@NonNull FeatureCollection featureCollection) {
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),
Expand Down
3 changes: 2 additions & 1 deletion platform/android/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
19 changes: 17 additions & 2 deletions platform/android/src/gson/json_array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a loop like this, it's important to clean up the temporary local references (jni:DeleteLocalRef(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) {
Expand All @@ -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();
}
Expand Down
2 changes: 2 additions & 0 deletions platform/android/src/gson/json_array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
28 changes: 28 additions & 0 deletions platform/android/src/gson/json_element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const ref?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not seeing where I can add an additional const here

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;

Expand Down
2 changes: 2 additions & 0 deletions platform/android/src/gson/json_element.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>);
Expand Down
17 changes: 17 additions & 0 deletions platform/android/src/gson/json_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete local references (jsonElement and key)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const ref

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>>
Expand Down
2 changes: 2 additions & 0 deletions platform/android/src/gson/json_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
80 changes: 80 additions & 0 deletions platform/android/src/gson/json_primitive.cpp
Original file line number Diff line number Diff line change
@@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete local references

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete local reference

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) {
Expand Down
2 changes: 2 additions & 0 deletions platform/android/src/gson/json_primitive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class JsonPrimitive : private mbgl::util::noncopyable {

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>);
Expand Down
Loading