[android] Move conversion code to .cpp files

This commit is contained in:
John Firebaugh
2018-08-17 16:25:12 -07:00
parent 7ce6af3f55
commit 2ff1ac3097
19 changed files with 496 additions and 390 deletions

View File

@@ -48,12 +48,27 @@ platform/default/mbgl/map/map_snapshotter.hpp
platform/linux/src/headless_backend_egl.cpp
# Conversion C++ -> Java
platform/android/src/conversion/collection.cpp
platform/android/src/conversion/collection.hpp
platform/android/src/conversion/color.cpp
platform/android/src/conversion/color.hpp
platform/android/src/conversion/constant.cpp
platform/android/src/conversion/constant.hpp
platform/android/src/conversion/conversion.hpp
platform/android/src/geojson/conversion/feature.cpp
platform/android/src/geojson/conversion/feature.hpp
platform/android/src/style/conversion/filter.cpp
platform/android/src/style/conversion/filter.hpp
platform/android/src/style/conversion/position.cpp
platform/android/src/style/conversion/position.hpp
platform/android/src/style/conversion/property_expression.hpp
platform/android/src/style/conversion/property_value.hpp
platform/android/src/style/conversion/transition_options.cpp
platform/android/src/style/conversion/transition_options.hpp
platform/android/src/style/conversion/types.hpp
platform/android/src/style/conversion/types_string_values.hpp
platform/android/src/style/conversion/url_or_tileset.cpp
platform/android/src/style/conversion/url_or_tileset.hpp
platform/android/src/map/camera_position.cpp
platform/android/src/map/camera_position.hpp
platform/android/src/map/image.cpp

View File

@@ -0,0 +1,38 @@
#include "collection.hpp"
#include "constant.hpp"
namespace mbgl {
namespace android {
namespace conversion {
std::vector<std::string> toVector(JNIEnv& env, jni::jarray<jni::jobject>& array) {
std::vector<std::string> vector;
std::size_t len = jni::GetArrayLength(env, array);
vector.reserve(len);
for (std::size_t i = 0; i < len; i++) {
jni::jstring* jstr = reinterpret_cast<jni::jstring*>(jni::GetObjectArrayElement(env, array, i));
vector.push_back(*convert<std::string, jni::String>(env, jni::String(jstr)));
jni::DeleteLocalRef(env, jstr);
}
return vector;
}
std::vector<std::string> toVector(JNIEnv& env, jni::Array<jni::String> array) {
std::size_t len = array.Length(env);
std::vector<std::string> vector;
vector.reserve(len);
for (std::size_t i = 0; i < len; i++) {
jni::String jstr = array.Get(env, i);
vector.push_back(*convert<std::string, jni::String>(env, jstr));
jni::DeleteLocalRef(env, jstr);
}
return vector;
}
}
}
}

View File

@@ -1,9 +1,7 @@
#pragma once
#include "conversion.hpp"
#include "constant.hpp"
#include <mbgl/util/optional.hpp>
#include <jni/jni.hpp>
#include <vector>
@@ -16,7 +14,7 @@ namespace conversion {
* Convert jarray -> ArrayList
*/
template <class T>
inline jni::jobject* toArrayList(JNIEnv& env, jni::jarray<T>& array) {
jni::jobject* toArrayList(JNIEnv& env, jni::jarray<T>& array) {
static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/util/Arrays")).release();
static jni::jmethodID* asList = &jni::GetStaticMethodID(env, *javaClass, "asList", "([Ljava/lang/Object;)Ljava/util/List;");
return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *asList, array));
@@ -24,34 +22,8 @@ inline jni::jobject* toArrayList(JNIEnv& env, jni::jarray<T>& array) {
// Java -> C++
inline std::vector<std::string> toVector(JNIEnv& env, jni::jarray<jni::jobject>& array) {
std::vector<std::string> vector;
std::size_t len = jni::GetArrayLength(env, array);
vector.reserve(len);
for (std::size_t i = 0; i < len; i++) {
jni::jstring* jstr = reinterpret_cast<jni::jstring*>(jni::GetObjectArrayElement(env, array, i));
vector.push_back(*convert<std::string, jni::String>(env, jni::String(jstr)));
jni::DeleteLocalRef(env, jstr);
}
return vector;
}
inline std::vector<std::string> toVector(JNIEnv& env, jni::Array<jni::String> array) {
std::size_t len = array.Length(env);
std::vector<std::string> vector;
vector.reserve(len);
for (std::size_t i = 0; i < len; i++) {
jni::String jstr = array.Get(env, i);
vector.push_back(*convert<std::string, jni::String>(env, jstr));
jni::DeleteLocalRef(env, jstr);
}
return vector;
}
std::vector<std::string> toVector(JNIEnv& env, jni::jarray<jni::jobject>& array);
std::vector<std::string> toVector(JNIEnv& env, jni::Array<jni::String> array);
}
}

View File

@@ -0,0 +1,17 @@
#include "color.hpp"
namespace mbgl {
namespace android {
namespace conversion {
Result<mbgl::Color> Converter<mbgl::Color, int>::operator()(jni::JNIEnv&, const int& color) const {
float r = (color >> 16) & 0xFF;
float g = (color >> 8) & 0xFF;
float b = (color) & 0xFF;
float a = (color >> 24) & 0xFF;
return { mbgl::Color( r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f ) };
}
} // namespace conversion
} // namespace style
} // namespace mbgl

View File

@@ -10,13 +10,7 @@ namespace conversion {
template <>
struct Converter<mbgl::Color, int> {
Result<mbgl::Color> operator()(jni::JNIEnv&, const int& color) const {
float r = (color >> 16) & 0xFF;
float g = (color >> 8) & 0xFF;
float b = (color) & 0xFF;
float a = (color >> 24) & 0xFF;
return { mbgl::Color( r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f ) };
}
Result<mbgl::Color> operator()(jni::JNIEnv&, const int& color) const;
};
} // namespace conversion

View File

@@ -0,0 +1,86 @@
#include "constant.hpp"
#include <sstream>
namespace mbgl {
namespace android {
namespace conversion {
Result<jni::jobject*> Converter<jni::jobject*, bool>::operator()(jni::JNIEnv& env, const bool& value) const {
static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/Boolean")).release();
static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "(Z)V");
return {&jni::NewObject(env, *javaClass, *constructor, (jboolean) value)};
}
Result<jni::jboolean> Converter<jni::jboolean, bool>::operator()(jni::JNIEnv&, const bool& value) const {
return {(jni::jboolean) value};
}
Result<jni::jobject*> Converter<jni::jobject*, float>::operator()(jni::JNIEnv& env, const float& value) const {
static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/Float")).release();
static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "(F)V");
return {&jni::NewObject(env, *javaClass, *constructor, (jfloat) value)};
}
Result<jni::jfloat> Converter<jni::jfloat, float>::operator()(jni::JNIEnv&, const float& value) const {
return {(jni::jfloat) value};
}
Result<jni::jobject*> Converter<jni::jobject*, double>::operator()(jni::JNIEnv& env, const double& value) const {
static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/Double")).release();
static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "(D)V");
return {&jni::NewObject(env, *javaClass, *constructor, (jfloat) value)};
}
Result<jni::jdouble> Converter<jni::jdouble, float>::operator()(jni::JNIEnv&, const double& value) const {
return {(jni::jdouble) value};
}
Result<jni::jobject*> Converter<jni::jobject*, std::string>::operator()(jni::JNIEnv& env, const std::string& value) const {
return {jni::Make<jni::String>(env, value).Get()};
}
Result<jni::jstring*> Converter<jni::jstring*, std::string>::operator()(jni::JNIEnv& env, const std::string& value) const {
return {jni::Make<jni::String>(env, value).Get()};
}
Result<jni::jobject*> Converter<jni::jobject*, Color>::operator()(jni::JNIEnv& env, const Color& value) const {
std::stringstream sstream;
sstream << "rgba(" << value.r << ", " << value.g << ", " << value.b << ", " << value.a << ")";
std::string result = sstream.str();
return convert<jni::jobject*, std::string>(env, result);
}
Result<jni::jobject*> Converter<jni::jobject*, std::vector<std::string>>::operator()(jni::JNIEnv& env, const std::vector<std::string>& value) const {
static jni::jclass* stringCass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/String")).release();
jni::jarray<jni::jobject>& jarray = jni::NewObjectArray(env, value.size(), *stringCass);
for(size_t i = 0; i < value.size(); i = i + 1) {
Result<jni::jobject*> converted = convert<jni::jobject*, std::string>(env, value.at(i));
jni::SetObjectArrayElement(env, jarray, i, *converted);
}
return &jarray;
}
Result<jni::jobject*> Converter<jni::jobject*, std::vector<float>>::operator()(jni::JNIEnv& env, const std::vector<float>& value) const {
static jni::jclass* floatClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/Float")).release();
jni::jarray<jni::jobject>& jarray = jni::NewObjectArray(env, value.size(), *floatClass);
for(size_t i = 0; i < value.size(); i = i + 1) {
Result<jni::jobject*> converted = convert<jni::jobject*, float>(env, value.at(i));
jni::SetObjectArrayElement(env, jarray, i, *converted);
}
return &jarray;
}
// Java -> C++
Result<std::string> Converter<std::string, jni::String>::operator()(jni::JNIEnv& env, const jni::String& value) const {
return { jni::Make<std::string>(env, value) };
}
} // namespace conversion
} // namespace style
} // namespace mbgl

View File

@@ -2,14 +2,12 @@
#include "conversion.hpp"
#include <mbgl/util/optional.hpp>
#include <mbgl/util/color.hpp>
#include <jni/jni.hpp>
#include <string>
#include <array>
#include <vector>
#include <sstream>
namespace mbgl {
namespace android {
@@ -17,51 +15,33 @@ namespace conversion {
template <>
struct Converter<jni::jobject*, bool> {
Result<jni::jobject*> operator()(jni::JNIEnv& env, const bool& value) const {
static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/Boolean")).release();
static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "(Z)V");
return {&jni::NewObject(env, *javaClass, *constructor, (jboolean) value)};
}
Result<jni::jobject*> operator()(jni::JNIEnv& env, const bool& value) const;
};
template <>
struct Converter<jni::jboolean, bool> {
Result<jni::jboolean> operator()(jni::JNIEnv&, const bool& value) const {
return {(jni::jboolean) value};
}
Result<jni::jboolean> operator()(jni::JNIEnv&, const bool& value) const;
};
template <>
struct Converter<jni::jobject*, float> {
Result<jni::jobject*> operator()(jni::JNIEnv& env, const float& value) const {
static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/Float")).release();
static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "(F)V");
return {&jni::NewObject(env, *javaClass, *constructor, (jfloat) value)};
}
Result<jni::jobject*> operator()(jni::JNIEnv& env, const float& value) const;
};
template <>
struct Converter<jni::jfloat, float> {
Result<jni::jfloat> operator()(jni::JNIEnv&, const float& value) const {
return {(jni::jfloat) value};
}
Result<jni::jfloat> operator()(jni::JNIEnv&, const float& value) const;
};
template <>
struct Converter<jni::jobject*, double> {
Result<jni::jobject*> operator()(jni::JNIEnv& env, const double& value) const {
static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/Double")).release();
static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "(D)V");
return {&jni::NewObject(env, *javaClass, *constructor, (jfloat) value)};
}
Result<jni::jobject*> operator()(jni::JNIEnv& env, const double& value) const;
};
template <>
struct Converter<jni::jdouble, float> {
Result<jni::jdouble> operator()(jni::JNIEnv&, const double& value) const {
return {(jni::jdouble) value};
}
Result<jni::jdouble> operator()(jni::JNIEnv&, const double& value) const;
};
/**
@@ -81,26 +61,17 @@ struct Converter<jni::jobject*, T, typename std::enable_if<std::is_integral<T>::
template <>
struct Converter<jni::jobject*, std::string> {
Result<jni::jobject*> operator()(jni::JNIEnv& env, const std::string& value) const {
return {jni::Make<jni::String>(env, value).Get()};
}
Result<jni::jobject*> operator()(jni::JNIEnv& env, const std::string& value) const;
};
template <>
struct Converter<jni::jstring*, std::string> {
Result<jni::jstring*> operator()(jni::JNIEnv& env, const std::string& value) const {
return {jni::Make<jni::String>(env, value).Get()};
}
Result<jni::jstring*> operator()(jni::JNIEnv& env, const std::string& value) const;
};
template <>
struct Converter<jni::jobject*, Color> {
Result<jni::jobject*> operator()(jni::JNIEnv& env, const Color& value) const {
std::stringstream sstream;
sstream << "rgba(" << value.r << ", " << value.g << ", " << value.b << ", " << value.a << ")";
std::string result = sstream.str();
return convert<jni::jobject*, std::string>(env, result);
}
Result<jni::jobject*> operator()(jni::JNIEnv& env, const Color& value) const;
};
template <std::size_t N>
@@ -116,41 +87,19 @@ struct Converter<jni::jobject*, std::array<float, N>> {
template <>
struct Converter<jni::jobject*, std::vector<std::string>> {
Result<jni::jobject*> operator()(jni::JNIEnv& env, const std::vector<std::string>& value) const {
static jni::jclass* stringCass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/String")).release();
jni::jarray<jni::jobject>& jarray = jni::NewObjectArray(env, value.size(), *stringCass);
for(size_t i = 0; i < value.size(); i = i + 1) {
Result<jni::jobject*> converted = convert<jni::jobject*, std::string>(env, value.at(i));
jni::SetObjectArrayElement(env, jarray, i, *converted);
}
return &jarray;
}
Result<jni::jobject*> operator()(jni::JNIEnv& env, const std::vector<std::string>& value) const;
};
template <>
struct Converter<jni::jobject*, std::vector<float>> {
Result<jni::jobject*> operator()(jni::JNIEnv& env, const std::vector<float>& value) const {
static jni::jclass* floatClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/Float")).release();
jni::jarray<jni::jobject>& jarray = jni::NewObjectArray(env, value.size(), *floatClass);
for(size_t i = 0; i < value.size(); i = i + 1) {
Result<jni::jobject*> converted = convert<jni::jobject*, float>(env, value.at(i));
jni::SetObjectArrayElement(env, jarray, i, *converted);
}
return &jarray;
}
Result<jni::jobject*> operator()(jni::JNIEnv& env, const std::vector<float>& value) const;
};
// Java -> C++
template <>
struct Converter<std::string, jni::String> {
Result<std::string> operator()(jni::JNIEnv& env, const jni::String& value) const {
return { jni::Make<std::string>(env, value) };
}
Result<std::string> operator()(jni::JNIEnv& env, const jni::String& value) const;
};
} // namespace conversion

View File

@@ -0,0 +1,192 @@
#include "feature.hpp"
#include "geometry.hpp"
#include "../../conversion/constant.hpp"
#include "../../conversion/conversion.hpp"
#include "../../jni/local_object.hpp"
namespace mbgl {
namespace android {
namespace conversion {
/**
* Turn feature identifier into std::string
*/
class FeatureIdVisitor {
public:
template<class T>
std::string operator()(const T& i) const {
return std::to_string(i);
}
std::string operator()(const std::string& i) const {
return i;
}
std::string operator()(const std::nullptr_t&) const {
return "";
}
};
/**
* Turn properties into Java GSON JsonObject's
*/
class PropertyValueEvaluator {
public:
jni::JNIEnv& env;
/**
* null
*/
jni::jobject* operator()(const mapbox::geometry::null_value_t &) const {
return (jni::jobject*) nullptr;
}
/**
* Boolean primitive
*/
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;
}
/**
* String primitive
*/
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;
}
/**
* Number primitives
*/
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;
}
/**
* Json Array
*/
jni::jobject* operator()(const std::vector<mbgl::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, mbgl::Value::visit(v, *this));
jni::CallMethod<void>(env, jarray, *add, converted.get());
}
return jarray;
}
/**
* Json Object
*/
jni::jobject* operator()(const std::unordered_map<std::string, mbgl::Value> &value) const {
// TODO: clean up duplication here
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;
}
};
Result<jni::jobject*> Converter<jni::jobject*, std::unordered_map<std::string, mbgl::Value>>::operator()(jni::JNIEnv& env, const std::unordered_map<std::string, mbgl::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
PropertyValueEvaluator evaluator {env};
for (auto &item : value) {
jni::LocalObject<jni::jobject> converted = jni::NewLocalObject(env, mbgl::Value::visit(item.second, evaluator));
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};
}
Result<jni::Object<android::geojson::Feature>> Converter<jni::Object<android::geojson::Feature>, mbgl::Feature>::operator()(jni::JNIEnv& env, const mbgl::Feature& value) const {
// Convert Id
FeatureIdVisitor idEvaluator;
std::string id = (value.id) ? mapbox::geometry::identifier::visit(value.id.value(), idEvaluator) : "";
auto jid = jni::Make<jni::String>(env, id);
// Convert properties
auto properties = jni::Object<gson::JsonObject>(*convert<jni::jobject*>(env, value.properties));
// Convert geometry
auto geometry = *convert<jni::Object<android::geojson::Geometry>>(env, value.geometry);
// Create feature
auto feature = android::geojson::Feature::fromGeometry(env, geometry, properties, jid);
//Cleanup
jni::DeleteLocalRef(env, jid);
jni::DeleteLocalRef(env, geometry);
jni::DeleteLocalRef(env, properties);
return feature;
}
Result<jni::Array<jni::Object<android::geojson::Feature>>> Converter<jni::Array<jni::Object<android::geojson::Feature>>, std::vector<mbgl::Feature>>::operator()(jni::JNIEnv& env, const std::vector<mbgl::Feature>& value) const {
using namespace mbgl::android::geojson;
auto features = jni::Array<jni::Object<Feature>>::New(env, value.size(), Feature::javaClass);
for(size_t i = 0; i < value.size(); i = i + 1) {
auto converted = *convert<jni::Object<android::geojson::Feature>, mbgl::Feature>(env, value.at(i));
features.Set(env, i, converted);
jni::DeleteLocalRef(env, converted);
}
return {features};
}
} // namespace conversion
} // namespace android
} // namespace mbgl

View File

@@ -1,215 +1,31 @@
#pragma once
#include "../../conversion/constant.hpp"
#include "../../conversion/conversion.hpp"
#include "geometry.hpp"
#include "../../gson/json_object.hpp"
#include <mbgl/util/feature.hpp>
#include <mapbox/variant.hpp>
#include <mapbox/geometry.hpp>
#include <jni/jni.hpp>
#include "../../jni/local_object.hpp"
#include "../feature.hpp"
#include <string>
#include <array>
#include <vector>
#include <sstream>
#include <mbgl/util/feature.hpp>
#include <jni/jni.hpp>
#include <mbgl/util/logging.hpp>
#include <vector>
#include <unordered_map>
namespace mbgl {
namespace android {
namespace conversion {
/**
* Turn feature identifier into std::string
*/
class FeatureIdVisitor {
public:
template<class T>
std::string operator()(const T& i) const {
return std::to_string(i);
}
std::string operator()(const std::string& i) const {
return i;
}
std::string operator()(const std::nullptr_t&) const {
return "";
}
};
/**
* Turn properties into Java GSON JsonObject's
*/
class PropertyValueEvaluator {
public:
jni::JNIEnv& env;
/**
* null
*/
jni::jobject* operator()(const mapbox::geometry::null_value_t &) const {
return (jni::jobject*) nullptr;
}
/**
* Boolean primitive
*/
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;
}
/**
* String primitive
*/
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;
}
/**
* Number primitives
*/
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;
}
/**
* Json Array
*/
jni::jobject* operator()(const std::vector<mbgl::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, mbgl::Value::visit(v, *this));
jni::CallMethod<void>(env, jarray, *add, converted.get());
}
return jarray;
}
/**
* Json Object
*/
jni::jobject* operator()(const std::unordered_map<std::string, mbgl::Value> &value) const {
// TODO: clean up duplication here
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;
}
};
template <>
struct Converter<jni::jobject*, std::unordered_map<std::string, mbgl::Value>> {
Result<jni::jobject*> operator()(jni::JNIEnv& env, const std::unordered_map<std::string, mbgl::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
PropertyValueEvaluator evaluator {env};
for (auto &item : value) {
jni::LocalObject<jni::jobject> converted = jni::NewLocalObject(env, mbgl::Value::visit(item.second, evaluator));
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};
}
Result<jni::jobject*> operator()(jni::JNIEnv& env, const std::unordered_map<std::string, mbgl::Value>& value) const;
};
template <>
struct Converter<jni::Object<android::geojson::Feature>, mbgl::Feature> {
Result<jni::Object<android::geojson::Feature>> operator()(jni::JNIEnv& env, const mbgl::Feature& value) const {
// Convert Id
FeatureIdVisitor idEvaluator;
std::string id = (value.id) ? mapbox::geometry::identifier::visit(value.id.value(), idEvaluator) : "";
auto jid = jni::Make<jni::String>(env, id);
// Convert properties
auto properties = jni::Object<gson::JsonObject>(*convert<jni::jobject*>(env, value.properties));
// Convert geometry
auto geometry = *convert<jni::Object<android::geojson::Geometry>>(env, value.geometry);
// Create feature
auto feature = android::geojson::Feature::fromGeometry(env, geometry, properties, jid);
//Cleanup
jni::DeleteLocalRef(env, jid);
jni::DeleteLocalRef(env, geometry);
jni::DeleteLocalRef(env, properties);
return feature;
}
Result<jni::Object<android::geojson::Feature>> operator()(jni::JNIEnv& env, const mbgl::Feature& value) const;
};
template <>
struct Converter<jni::Array<jni::Object<android::geojson::Feature>>, std::vector<mbgl::Feature>> {
Result<jni::Array<jni::Object<android::geojson::Feature>>> operator()(jni::JNIEnv& env, const std::vector<mbgl::Feature>& value) const {
using namespace mbgl::android::geojson;
auto features = jni::Array<jni::Object<Feature>>::New(env, value.size(), Feature::javaClass);
for(size_t i = 0; i < value.size(); i = i + 1) {
auto converted = *convert<jni::Object<android::geojson::Feature>, mbgl::Feature>(env, value.at(i));
features.Set(env, i, converted);
jni::DeleteLocalRef(env, converted);
}
return {features};
}
Result<jni::Array<jni::Object<android::geojson::Feature>>> operator()(jni::JNIEnv& env, const std::vector<mbgl::Feature>& value) const;
};
} // namespace conversion

View File

@@ -0,0 +1,26 @@
#include "filter.hpp"
#include "../android_conversion.hpp"
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/conversion/filter.hpp>
namespace mbgl {
namespace android {
namespace conversion {
optional<mbgl::style::Filter> toFilter(jni::JNIEnv& env, jni::Array<jni::Object<>> jfilter) {
mbgl::optional<mbgl::style::Filter> filter;
if (jfilter) {
mbgl::style::conversion::Error error;
auto converted = mbgl::style::conversion::convert<mbgl::style::Filter>(Value(env, jfilter), error);
if (!converted) {
mbgl::Log::Error(mbgl::Event::JNI, "Error converting filter: " + error.message);
}
filter = std::move(*converted);
}
return filter;
}
} // namespace conversion
} // namespace android
} // namespace mbgl

View File

@@ -1,30 +1,15 @@
#pragma once
#include "../android_conversion.hpp"
#include <mbgl/style/conversion/filter.hpp>
#include <mbgl/style/conversion_impl.hpp>
#include <mbgl/style/filter.hpp>
#include <mbgl/util/optional.hpp>
#include <jni/jni.hpp>
#include <tuple>
#include <map>
namespace mbgl {
namespace android {
namespace conversion {
inline optional<mbgl::style::Filter> toFilter(jni::JNIEnv& env, jni::Array<jni::Object<>> jfilter) {
mbgl::optional<mbgl::style::Filter> filter;
if (jfilter) {
mbgl::style::conversion::Error error;
auto converted = mbgl::style::conversion::convert<mbgl::style::Filter>(Value(env, jfilter), error);
if (!converted) {
mbgl::Log::Error(mbgl::Event::JNI, "Error converting filter: " + error.message);
}
filter = std::move(*converted);
}
return filter;
}
optional<mbgl::style::Filter> toFilter(jni::JNIEnv&, jni::Array<jni::Object<>>);
} // namespace conversion
} // namespace android

View File

@@ -0,0 +1,24 @@
#include "position.hpp"
namespace mbgl {
namespace android {
namespace conversion {
Result<jni::Object<Position>> Converter<jni::Object<Position>, mbgl::style::Position>::operator()(jni::JNIEnv &env, const mbgl::style::Position &value) const {
std::array<float, 3> cartPosition = value.getSpherical();
return Position::fromPosition(env, cartPosition[0], cartPosition[1], cartPosition[2]);
}
Result<mbgl::style::Position> Converter<mbgl::style::Position, jni::Object<Position>>::operator()(jni::JNIEnv &env, const jni::Object<Position> &value) const {
float radialCoordinate = Position::getRadialCoordinate(env, value);
float azimuthalAngle = Position::getAzimuthalAngle(env, value);
float polarAngle = Position::getPolarAngle(env, value);
std::array<float, 3> cartPosition {{radialCoordinate, azimuthalAngle, polarAngle}};
mbgl::style::Position position{};
position.set(cartPosition);
return position;
}
}
}
}

View File

@@ -1,37 +1,25 @@
#pragma once
#include "../../conversion/conversion.hpp"
#include <jni/jni.hpp>
#include <mbgl/style/position.hpp>
#include "../../jni/local_object.hpp"
#include "../position.hpp"
#include <mbgl/style/position.hpp>
#include <jni/jni.hpp>
namespace mbgl {
namespace android {
namespace conversion {
template<>
template <>
struct Converter<jni::Object<Position>, mbgl::style::Position> {
Result<jni::Object<Position>> operator()(jni::JNIEnv &env, const mbgl::style::Position &value) const {
std::array<float, 3> cartPosition = value.getSpherical();
return Position::fromPosition(env, cartPosition[0], cartPosition[1], cartPosition[2]);
}
Result<jni::Object<Position>> operator()(jni::JNIEnv &env, const mbgl::style::Position &value) const;
};
template<>
template <>
struct Converter<mbgl::style::Position, jni::Object<Position>> {
Result<mbgl::style::Position> operator()(jni::JNIEnv &env, const jni::Object<Position> &value) const {
float radialCoordinate = Position::getRadialCoordinate(env, value);
float azimuthalAngle = Position::getAzimuthalAngle(env, value);
float polarAngle = Position::getPolarAngle(env, value);
std::array<float, 3> cartPosition {{radialCoordinate, azimuthalAngle, polarAngle}};
mbgl::style::Position position{};
position.set(cartPosition);
return position;
}
Result<mbgl::style::Position> operator()(jni::JNIEnv &env, const jni::Object<Position> &value) const;
};
}
}
}
}

View File

@@ -1,16 +1,11 @@
#pragma once
#include <mbgl/style/property_value.hpp>
#include "../../conversion/conversion.hpp"
#include "../../conversion/constant.hpp"
#include "types.hpp"
#include "../../java/lang.hpp"
#include <jni/jni.hpp>
#include "../../gson/json_element.hpp"
#include <tuple>
#include <map>
#include <mbgl/style/property_expression.hpp>
#include <jni/jni.hpp>
namespace mbgl {
namespace android {
@@ -18,11 +13,8 @@ namespace conversion {
template <class T>
struct Converter<jni::Object<android::gson::JsonElement>, mbgl::style::PropertyExpression<T>> {
Result<jni::Object<android::gson::JsonElement>> operator()(jni::JNIEnv& env, const mbgl::style::PropertyExpression<T>& value) const {
// Convert expressions
mbgl::Value expressionValue = value.getExpression().serialize();
return gson::JsonElement::New(env, expressionValue);
return gson::JsonElement::New(env, value.getExpression().serialize());
}
};

View File

@@ -2,6 +2,7 @@
#include <mbgl/style/color_ramp_property_value.hpp>
#include <mbgl/style/property_value.hpp>
#include "../../conversion/conversion.hpp"
#include "../../conversion/constant.hpp"
#include "property_expression.hpp"
@@ -17,25 +18,22 @@ namespace conversion {
template <typename T>
class PropertyValueEvaluator {
public:
PropertyValueEvaluator(jni::JNIEnv& _env) : env(_env) {}
jni::jobject* operator()(const mbgl::style::Undefined) const {
return nullptr;
}
jni::jobject* operator()(const T &value) const {
Result<jni::jobject*> result = convert<jni::jobject*>(env, value);
return *result;
jni::jobject* operator()(const T& value) const {
return *convert<jni::jobject*>(env, value);
}
jni::jobject* operator()(const mbgl::style::PropertyExpression<T> &value) const {
return *convert<jni::Object<android::gson::JsonElement>, mbgl::style::PropertyExpression<T>>(env, value);
jni::jobject* operator()(const mbgl::style::PropertyExpression<T>& value) const {
return *convert<jni::Object<android::gson::JsonElement>>(env, value);
}
private:
jni::JNIEnv& env;
};
/**
@@ -43,7 +41,6 @@ private:
*/
template <class T>
struct Converter<jni::jobject*, mbgl::style::PropertyValue<T>> {
Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::PropertyValue<T>& value) const {
PropertyValueEvaluator<T> evaluator(env);
return value.evaluate(evaluator);
@@ -55,8 +52,7 @@ struct Converter<jni::jobject*, mbgl::style::PropertyValue<T>> {
*/
template <>
struct Converter<jni::jobject*, mbgl::style::ColorRampPropertyValue> {
Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::ColorRampPropertyValue value) const {
Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::ColorRampPropertyValue& value) const {
PropertyValueEvaluator<mbgl::style::ColorRampPropertyValue> evaluator(env);
return *convert<jni::jobject*>(env, value.evaluate(evaluator));
}

View File

@@ -0,0 +1,16 @@
#include "transition_options.hpp"
namespace mbgl {
namespace android {
namespace conversion {
Result<jni::Object<TransitionOptions>> Converter<jni::Object<TransitionOptions>, mbgl::style::TransitionOptions>::operator()(jni::JNIEnv& env, const mbgl::style::TransitionOptions& value) const {
return TransitionOptions::fromTransitionOptions(env,
std::chrono::duration_cast<std::chrono::milliseconds>(value.duration.value_or(mbgl::Duration::zero())).count(),
std::chrono::duration_cast<std::chrono::milliseconds>(value.delay.value_or(mbgl::Duration::zero())).count()
);
}
}
}
}

View File

@@ -1,11 +1,11 @@
#pragma once
#include "../../conversion/conversion.hpp"
#include "../transition_options.hpp"
#include <mbgl/style/transition_options.hpp>
#include <jni/jni.hpp>
#include <mbgl/style/transition_options.hpp>
#include "../../jni/local_object.hpp"
#include "../transition_options.hpp"
namespace mbgl {
namespace android {
@@ -13,18 +13,9 @@ namespace conversion {
template<>
struct Converter<jni::Object<TransitionOptions>, mbgl::style::TransitionOptions> {
Result<jni::Object<TransitionOptions>> operator()(jni::JNIEnv &env, const mbgl::style::TransitionOptions &value) const {
// Convert duration
jlong duration = std::chrono::duration_cast<std::chrono::milliseconds>(value.duration.value_or(mbgl::Duration::zero())).count();
// Convert delay
jlong delay = std::chrono::duration_cast<std::chrono::milliseconds>(value.delay.value_or(mbgl::Duration::zero())).count();
// Create transition options
return TransitionOptions::fromTransitionOptions(env, duration, delay);
}
Result<jni::Object<TransitionOptions>> operator()(jni::JNIEnv&, const mbgl::style::TransitionOptions&) const;
};
}
}
}
}

View File

@@ -0,0 +1,30 @@
#include "url_or_tileset.hpp"
#include "../android_conversion.hpp"
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/conversion/tileset.hpp>
namespace mbgl {
namespace android {
// This conversion is expected not to fail because it's used only in contexts where
// the value was originally a String or TileSet object on the Java side. If it fails
// to convert, it's a bug in our serialization or Java-side static typing.
variant<std::string, Tileset> convertURLOrTileset(mbgl::android::Value&& value) {
using namespace mbgl::style::conversion;
const Convertible convertible(std::move(value));
if (isObject(convertible)) {
Error error;
optional<Tileset> tileset = convert<Tileset>(convertible, error);
if (!tileset) {
throw std::logic_error(error.message);
}
return { *tileset };
} else {
return { *toString(convertible) };
}
}
}
}

View File

@@ -1,37 +1,16 @@
#pragma once
#include <mbgl/util/optional.hpp>
#include <mbgl/util/variant.hpp>
#include <mbgl/util/tileset.hpp>
#include <mbgl/style/conversion/tileset.hpp>
#include <mbgl/style/conversion_impl.hpp>
#include <jni/jni.hpp>
#include <string>
#include "../value.hpp"
namespace mbgl {
namespace android {
// This conversion is expected not to fail because it's used only in contexts where
// the value was originally a String or TileSet object on the Java side. If it fails
// to convert, it's a bug in our serialization or Java-side static typing.
inline variant<std::string, Tileset> convertURLOrTileset(mbgl::android::Value&& value) {
using namespace mbgl::style::conversion;
const Convertible convertible(std::move(value));
if (isObject(convertible)) {
Error error;
optional<Tileset> tileset = convert<Tileset>(convertible, error);
if (!tileset) {
throw std::logic_error(error.message);
}
return { *tileset };
} else {
return { *toString(convertible) };
}
}
variant<std::string, Tileset> convertURLOrTileset(mbgl::android::Value&& value);
}
}