Move cpp files into dir
This commit is contained in:
853
android/cpp/JNI.cpp
Normal file
853
android/cpp/JNI.cpp
Normal file
@@ -0,0 +1,853 @@
|
||||
#include <cstdint>
|
||||
#include <cinttypes>
|
||||
|
||||
#include <string>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <android/native_window_jni.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#include "NativeMapView.hpp"
|
||||
|
||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
jmethodID on_map_changed_id = nullptr;
|
||||
|
||||
jclass lon_lat_class = nullptr;
|
||||
jmethodID lon_lat_constructor_id = nullptr;
|
||||
jfieldID lon_lat_lon_id = nullptr;
|
||||
jfieldID lon_lat_lat_id = nullptr;
|
||||
|
||||
jclass lon_lat_zoom_class = nullptr;
|
||||
jmethodID lon_lat_zoom_constructor_id = nullptr;
|
||||
jfieldID lon_lat_zoom_lon_id = nullptr;
|
||||
jfieldID lon_lat_zoom_lat_id = nullptr;
|
||||
jfieldID lon_lat_zoom_zoom_id = nullptr;
|
||||
|
||||
jclass runtime_exception_class = nullptr;
|
||||
|
||||
jmethodID set_to_array_id = nullptr;
|
||||
|
||||
jclass tree_set_class = nullptr;
|
||||
jmethodID tree_set_constructor_id = nullptr;
|
||||
jmethodID tree_set_add_id = nullptr;
|
||||
|
||||
bool throw_error(JNIEnv* env, const char* msg) {
|
||||
if (env->ThrowNew(runtime_exception_class, msg) < 0) {
|
||||
env->ExceptionDescribe();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string std_string_from_jstring(JNIEnv* env, jstring jstr) {
|
||||
std::string str;
|
||||
jsize len = env->GetStringLength(jstr);
|
||||
if (len < 0) {
|
||||
env->ExceptionDescribe();
|
||||
return str;
|
||||
}
|
||||
const jchar* chars = env->GetStringChars(jstr, nullptr);
|
||||
if (chars == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return str;
|
||||
}
|
||||
std::u16string ustr(reinterpret_cast<const char16_t*>(chars), len);
|
||||
env->ReleaseStringChars(jstr, chars);
|
||||
chars = nullptr;
|
||||
str = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t>().to_bytes(ustr);
|
||||
return str;
|
||||
}
|
||||
|
||||
jstring std_string_to_jstring(JNIEnv* env, std::string str) {
|
||||
std::u16string ustr = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t>().from_bytes(str);
|
||||
|
||||
jstring jstr = env->NewString(reinterpret_cast<const jchar*>(ustr.c_str()), ustr.size());
|
||||
if (jstr == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return jstr;
|
||||
}
|
||||
|
||||
|
||||
// TODO: change from Java TreeSet to ArrayList
|
||||
std::vector<std::string> std_vector_string_from_jobject(JNIEnv* env, jobject jset) {
|
||||
std::vector<std::string> vector;
|
||||
|
||||
jobjectArray array = reinterpret_cast<jobjectArray>(env->CallObjectMethod(jset, set_to_array_id));
|
||||
if (env->ExceptionCheck() || (array == nullptr)) {
|
||||
env->ExceptionDescribe();
|
||||
return vector;
|
||||
}
|
||||
|
||||
jsize len = env->GetArrayLength(array);
|
||||
if (len < 0) {
|
||||
env->ExceptionDescribe();
|
||||
return vector;
|
||||
}
|
||||
|
||||
for (jsize i = 0; i < len; i++) {
|
||||
jstring jstr = reinterpret_cast<jstring>(env->GetObjectArrayElement(array, i));
|
||||
if (jstr == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return vector;
|
||||
}
|
||||
|
||||
vector.push_back(std_string_from_jstring(env, jstr));
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
// TODO: change from Java TreeSet to ArrayList
|
||||
jobject std_vector_string_to_jobject(JNIEnv* env, std::vector<std::string> vector) {
|
||||
jobject jset = env->NewObject(tree_set_class, tree_set_constructor_id);
|
||||
if (jset == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (std::string str : vector) {
|
||||
env->CallBooleanMethod(jset, tree_set_add_id, std_string_to_jstring(env, str));
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionDescribe();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return jset;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace mbgl::android;
|
||||
|
||||
// TODO: wrap C++ exceptions?
|
||||
// TODO: wrap other sorts of exceptions? eg coffee catch
|
||||
|
||||
jlong JNICALL nativeCreate(JNIEnv* env, jobject obj, jstring default_style_json) {
|
||||
VERBOSE("nativeCreate");
|
||||
NativeMapView* native_map_view = new NativeMapView(env, obj, std_string_from_jstring(env, default_style_json));
|
||||
if (native_map_view == nullptr) {
|
||||
throw_error(env, "Unable to create NativeMapView.");
|
||||
return 0;
|
||||
}
|
||||
jlong map_view_ptr = reinterpret_cast<jlong>(native_map_view);
|
||||
return map_view_ptr;
|
||||
}
|
||||
|
||||
void JNICALL nativeDestroy(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeDestroy");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
delete native_map_view;
|
||||
native_map_view = nullptr;
|
||||
}
|
||||
|
||||
void JNICALL nativeInitializeDisplay(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeInitializeDisplay");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
if (!native_map_view->initializeDisplay()) {
|
||||
throw_error(env, "Unable to initialize GL display.");
|
||||
}
|
||||
}
|
||||
|
||||
void JNICALL nativeTerminateDisplay(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeTerminateDisplay");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->terminateDisplay();
|
||||
}
|
||||
|
||||
void JNICALL nativeInitializeContext(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeInitializeContext");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
if (!native_map_view->initializeContext()) {
|
||||
throw_error(env, "Unable to initialize GL context.");
|
||||
}
|
||||
}
|
||||
|
||||
void JNICALL nativeTerminateContext(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeTerminateContext");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->terminateContext();
|
||||
}
|
||||
|
||||
void JNICALL nativeCreateSurface(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jobject surface) {
|
||||
VERBOSE("nativeCreateSurface");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
if (!native_map_view->createSurface(ANativeWindow_fromSurface(env, surface))) {
|
||||
throw_error(env, "Unable to create GL surface.");
|
||||
}
|
||||
}
|
||||
|
||||
void JNICALL nativeDestroySurface(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeDestroySurface");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->destroySurface();
|
||||
}
|
||||
|
||||
void JNICALL nativeStart(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeStart");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->start();
|
||||
}
|
||||
|
||||
void JNICALL nativeStop(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeStop");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->stop();
|
||||
}
|
||||
|
||||
void JNICALL nativeRerender(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeRerender");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->rerender();
|
||||
}
|
||||
|
||||
void JNICALL nativeUpdate(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeUpdate");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->update();
|
||||
}
|
||||
|
||||
void JNICALL nativeCleanup(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeCleanup");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->cleanup();
|
||||
}
|
||||
|
||||
// TODO remove these?
|
||||
void JNICALL nativeAddDefaultSource(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeAddDefaultSource");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
// NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
// native_map_view->getMap()->addDefaultSource();
|
||||
}
|
||||
|
||||
void JNICALL nativeRemoveDefaultSource(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeRemoveDefaultSource");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
// NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
// native_map_view->getMap()->removeDefaultSource();
|
||||
}
|
||||
|
||||
void JNICALL nativeAddSource(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jstring name, jstring url) {
|
||||
VERBOSE("nativeAddSource");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
// NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
// native_map_view->getMap()->addSource(std_string_from_jstring(env, name), std_string_from_jstring(env, url));
|
||||
}
|
||||
|
||||
void JNICALL nativeRemoveSource(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jstring name) {
|
||||
VERBOSE("nativeRemoveSource");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
// NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
// native_map_view->getMap()->removeSource(std_string_from_jstring(env, name));
|
||||
}
|
||||
|
||||
void JNICALL nativeResize(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jint width, jint height, jfloat ratio) {
|
||||
VERBOSE("nativeResize");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
ASSERT(width >= 0);
|
||||
ASSERT(height >= 0);
|
||||
ASSERT(width <= UINT16_MAX);
|
||||
ASSERT(height <= UINT16_MAX);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->resize(width, height, ratio);
|
||||
}
|
||||
|
||||
void JNICALL nativeResize(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jint width, jint height, jfloat ratio, jint fb_width, jint fb_height) {
|
||||
VERBOSE("nativeResize");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
ASSERT(width >= 0);
|
||||
ASSERT(height >= 0);
|
||||
ASSERT(width <= UINT16_MAX);
|
||||
ASSERT(height <= UINT16_MAX);
|
||||
ASSERT(fb_width >= 0);
|
||||
ASSERT(fb_height >= 0);
|
||||
ASSERT(fb_width <= UINT16_MAX);
|
||||
ASSERT(fb_height <= UINT16_MAX);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->resize(width, height, ratio, fb_width, fb_height);
|
||||
}
|
||||
|
||||
void JNICALL nativeSetAppliedClasses(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jobject applied_classes) {
|
||||
VERBOSE("nativeSetAppliedClasses");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->setAppliedClasses(std_vector_string_from_jobject(env, applied_classes));
|
||||
}
|
||||
|
||||
jobject JNICALL nativeGetAppliedClasses(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeGetAppliedClasses");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
return std_vector_string_to_jobject(env, native_map_view->getMap()->getAppliedClasses());
|
||||
}
|
||||
|
||||
void JNICALL nativeSetDefaultTransitionDuration(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jlong duration_milliseconds) {
|
||||
VERBOSE("nativeSetDefaultTransitionDuration");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
ASSERT(duration_milliseconds >= 0);
|
||||
//ASSERT(duration_milliseconds <= UINT64_MAX);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->setDefaultTransitionDuration(duration_milliseconds);
|
||||
}
|
||||
|
||||
void JNICALL nativeSetStyleJSON(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jstring new_style_json) {
|
||||
VERBOSE("nativeSetStyleJSON");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->setStyleJSON(std_string_from_jstring(env, new_style_json));
|
||||
}
|
||||
|
||||
jstring JNICALL nativeGetStyleJSON(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeGetStyleJSON");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
return std_string_to_jstring(env, native_map_view->getMap()->getStyleJSON());
|
||||
}
|
||||
|
||||
void JNICALL nativeCancelTransitions(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeCancelTransitions");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->cancelTransitions();
|
||||
}
|
||||
|
||||
void JNICALL nativeMoveBy(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble dx, jdouble dy, jdouble duration) {
|
||||
VERBOSE("nativeMoveBy");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->moveBy(dx, dy, duration);
|
||||
}
|
||||
|
||||
void JNICALL nativeSetLonLat(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jobject lon_lat, jdouble duration) {
|
||||
VERBOSE("nativeSetLonLat");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
|
||||
double lon = env->GetDoubleField(lon_lat, lon_lat_lon_id);
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionDescribe();
|
||||
return;
|
||||
}
|
||||
|
||||
double lat = env->GetDoubleField(lon_lat, lon_lat_lat_id);
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionDescribe();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO remove when fixed
|
||||
DEBUG("lon lat %f %f", lon, lat);
|
||||
native_map_view->getMap()->setLonLat(lon, lat, duration);
|
||||
}
|
||||
|
||||
jobject JNICALL nativeGetLonLat(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeGetLonLat");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
double lon, lat;
|
||||
native_map_view->getMap()->getLonLat(lon, lat);
|
||||
|
||||
jobject ret = env->NewObject(lon_lat_class, lon_lat_constructor_id, lon, lat);
|
||||
if (ret == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void JNICALL nativeStartPanning(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeStartPanning");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->startPanning();
|
||||
}
|
||||
|
||||
void JNICALL nativeStopPanning(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeStopPanning");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->stopPanning();
|
||||
}
|
||||
|
||||
void JNICALL nativeResetPosition(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeResetPosition");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->resetPosition();
|
||||
}
|
||||
|
||||
void JNICALL nativeScaleBy(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble ds, jdouble cx, jdouble cy, jdouble duration) {
|
||||
VERBOSE("nativeScaleBy");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->scaleBy(ds, cx, cy, duration);
|
||||
}
|
||||
|
||||
void JNICALL nativeSetScale(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble scale, jdouble cx, jdouble cy, jdouble duration) {
|
||||
VERBOSE("nativeSetScale");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->setScale(scale, cx, cy, duration);
|
||||
}
|
||||
|
||||
jdouble JNICALL nativeGetScale(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeGetScale");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
return native_map_view->getMap()->getScale();
|
||||
}
|
||||
|
||||
void JNICALL nativeSetZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble zoom, jdouble duration) {
|
||||
VERBOSE("nativeSetZoom");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->setZoom(zoom, duration);
|
||||
}
|
||||
|
||||
jdouble JNICALL nativeGetZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeGetZoom");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
return native_map_view->getMap()->getZoom();
|
||||
}
|
||||
|
||||
void JNICALL nativeSetLonLatZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jobject lon_lat_zoom, jdouble duration) {
|
||||
VERBOSE("nativeSetLonLatZoom");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
|
||||
double lon = env->GetDoubleField(lon_lat_zoom, lon_lat_zoom_lon_id);
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionDescribe();
|
||||
return;
|
||||
}
|
||||
|
||||
double lat = env->GetDoubleField(lon_lat_zoom, lon_lat_zoom_lat_id);
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionDescribe();
|
||||
return;
|
||||
}
|
||||
|
||||
double zoom = env->GetDoubleField(lon_lat_zoom, lon_lat_zoom_zoom_id);
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionDescribe();
|
||||
return;
|
||||
}
|
||||
|
||||
native_map_view->getMap()->setLonLatZoom(lon, lat, zoom, duration);
|
||||
}
|
||||
|
||||
jobject JNICALL nativeGetLonLatZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeGetLonLatZoom");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
double lon, lat, zoom;
|
||||
native_map_view->getMap()->getLonLatZoom(lon, lat, zoom);
|
||||
|
||||
jobject ret = env->NewObject(lon_lat_zoom_class, lon_lat_zoom_constructor_id, lon, lat, zoom);
|
||||
if (ret == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void JNICALL nativeResetZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeResetZoom");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->resetZoom();
|
||||
}
|
||||
|
||||
void JNICALL nativeStartScaling(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeStartScaling");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->startScaling();
|
||||
}
|
||||
|
||||
void JNICALL nativeStopScaling(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeStopScaling");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->stopScaling();
|
||||
}
|
||||
|
||||
jdouble JNICALL nativeGetMinZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeGetMinZoom");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
return native_map_view->getMap()->getMinZoom();
|
||||
}
|
||||
|
||||
jdouble JNICALL nativeGetMaxZoom(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeGetMaxZoom");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
return native_map_view->getMap()->getMaxZoom();
|
||||
}
|
||||
|
||||
void JNICALL nativeRotateBy(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble sx, jdouble sy, jdouble ex, jdouble ey, jdouble duration) {
|
||||
VERBOSE("nativeRotateBy");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->rotateBy(sx, sy, ex, ey, duration);
|
||||
}
|
||||
|
||||
void JNICALL nativeSetAngle(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble angle, jdouble duration) {
|
||||
VERBOSE("nativeSetAngle");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
// TODO update java class
|
||||
//native_map_view->getMap()->setAngle(angle, duration);
|
||||
double degrees = -angle / M_PI * 180;
|
||||
native_map_view->getMap()->setBearing(degrees, duration);
|
||||
}
|
||||
|
||||
void JNICALL nativeSetAngle(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jdouble angle, jdouble cx, jdouble cy) {
|
||||
VERBOSE("nativeSetAngle");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
// TODO update java class
|
||||
//native_map_view->getMap()->setAngle(angle, cx, cy);
|
||||
double degrees = -angle / M_PI * 180;
|
||||
native_map_view->getMap()->setBearing(degrees, cx, cy);
|
||||
}
|
||||
|
||||
jdouble JNICALL nativeGetAngle(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeGetAngle");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
// TODO update java class
|
||||
//return native_map_view->getMap()->getAngle();
|
||||
double degrees = native_map_view->getMap()->getBearing();
|
||||
return -degrees * M_PI / 180;
|
||||
}
|
||||
|
||||
void JNICALL nativeResetNorth(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeResetNorth");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->resetNorth();
|
||||
}
|
||||
|
||||
void JNICALL nativeStartRotating(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeStartRotating");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->startRotating();
|
||||
}
|
||||
|
||||
void JNICALL nativeStopRotating(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeStopRotating");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->stopRotating();
|
||||
}
|
||||
|
||||
jboolean JNICALL nativeCanRotate(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeCanRotate");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
return native_map_view->getMap()->canRotate();
|
||||
}
|
||||
|
||||
void JNICALL nativeSetDebug(JNIEnv* env, jobject obj, jlong native_map_view_ptr, jboolean debug) {
|
||||
VERBOSE("nativeSetDebug");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->setDebug(debug);
|
||||
}
|
||||
|
||||
void JNICALL nativeToggleDebug(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeToggleDebug");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
native_map_view->getMap()->toggleDebug();
|
||||
}
|
||||
|
||||
jboolean JNICALL nativeGetDebug(JNIEnv* env, jobject obj, jlong native_map_view_ptr) {
|
||||
VERBOSE("nativeGetDebug");
|
||||
ASSERT(native_map_view_ptr != 0);
|
||||
NativeMapView* native_map_view = reinterpret_cast<NativeMapView*>(native_map_view_ptr);
|
||||
return native_map_view->getMap()->getDebug();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||
VERBOSE("JNI_OnLoad");
|
||||
|
||||
JNIEnv* env = nullptr;
|
||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
|
||||
ERROR("GetEnv() failed");
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
lon_lat_class = env->FindClass("com/mapbox/mapboxgl/lib/LonLat");
|
||||
if (lon_lat_class == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
lon_lat_constructor_id = env->GetMethodID(lon_lat_class, "<init>", "(DD)V");
|
||||
if (lon_lat_constructor_id == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
lon_lat_lon_id = env->GetFieldID(lon_lat_class, "lon", "D");
|
||||
if (lon_lat_lon_id == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
lon_lat_lat_id = env->GetFieldID(lon_lat_class, "lat", "D");
|
||||
if (lon_lat_lat_id == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
lon_lat_zoom_class = env->FindClass("com/mapbox/mapboxgl/lib/LonLatZoom");
|
||||
if (lon_lat_class == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
lon_lat_zoom_constructor_id = env->GetMethodID(lon_lat_zoom_class, "<init>", "(DDD)V");
|
||||
if (lon_lat_zoom_constructor_id == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
lon_lat_zoom_lon_id = env->GetFieldID(lon_lat_zoom_class, "lon", "D");
|
||||
if (lon_lat_zoom_lon_id == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
lon_lat_zoom_lat_id = env->GetFieldID(lon_lat_zoom_class, "lat", "D");
|
||||
if (lon_lat_zoom_lat_id == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
lon_lat_zoom_zoom_id = env->GetFieldID(lon_lat_zoom_class, "zoom", "D");
|
||||
if (lon_lat_zoom_zoom_id == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
jclass native_map_view_class = env->FindClass("com/mapbox/mapboxgl/lib/NativeMapView");
|
||||
if (native_map_view_class == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
on_map_changed_id = env->GetMethodID(native_map_view_class, "onMapChanged", "()V");
|
||||
if (on_map_changed_id == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
runtime_exception_class = env->FindClass("java/lang/RuntimeException");
|
||||
if (runtime_exception_class == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
jclass set_class = env->FindClass("java/util/Set");
|
||||
if (set_class == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
set_to_array_id = env->GetMethodID(set_class, "toArray", "()[Ljava/lang/Object;");
|
||||
if (set_to_array_id == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
tree_set_class = env->FindClass("java/util/TreeSet");
|
||||
if (tree_set_class == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
tree_set_constructor_id = env->GetMethodID(tree_set_class, "<init>", "()V");
|
||||
if (tree_set_constructor_id == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
tree_set_add_id = env->GetMethodID(tree_set_class, "add", "(Ljava/lang/Object;)Z");
|
||||
if (tree_set_add_id == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
std::array<JNINativeMethod, 54> methods = {{ // Can remove the extra brace in C++14
|
||||
{ "nativeCreate", "(Ljava/lang/String;)J", reinterpret_cast<void*>(&nativeCreate) },
|
||||
{ "nativeDestroy", "(J)V", reinterpret_cast<void*>(&nativeDestroy) },
|
||||
{ "nativeInitializeDisplay", "(J)V", reinterpret_cast<void*>(&nativeInitializeDisplay) },
|
||||
{ "nativeTerminateDisplay", "(J)V", reinterpret_cast<void*>(&nativeTerminateDisplay) },
|
||||
{ "nativeInitializeContext", "(J)V", reinterpret_cast<void*>(&nativeInitializeContext) },
|
||||
{ "nativeTerminateContext", "(J)V", reinterpret_cast<void*>(&nativeTerminateContext) },
|
||||
{ "nativeCreateSurface", "(JLandroid/view/Surface;)V", reinterpret_cast<void*>(&nativeCreateSurface) },
|
||||
{ "nativeDestroySurface", "(J)V", reinterpret_cast<void*>(&nativeDestroySurface) },
|
||||
{ "nativeStart", "(J)V", reinterpret_cast<void*>(&nativeStart) },
|
||||
{ "nativeStop", "(J)V", reinterpret_cast<void*>(&nativeStop) },
|
||||
{ "nativeRerender", "(J)V", reinterpret_cast<void*>(&nativeRerender) },
|
||||
{ "nativeUpdate", "(J)V", reinterpret_cast<void*>(&nativeUpdate) },
|
||||
{ "nativeCleanup", "(J)V", reinterpret_cast<void*>(&nativeCleanup) },
|
||||
{ "nativeAddDefaultSource", "(J)V", reinterpret_cast<void*>(&nativeAddDefaultSource) },
|
||||
{ "nativeRemoveDefaultSource", "(J)V", reinterpret_cast<void*>(&nativeRemoveDefaultSource) },
|
||||
{ "nativeAddSource", "(JLjava/lang/String;Ljava/lang/String;)V", reinterpret_cast<void*>(&nativeAddSource) },
|
||||
{ "nativeRemoveSource", "(JLjava/lang/String;)V", reinterpret_cast<void*>(&nativeRemoveSource) },
|
||||
{ "nativeResize", "(JIIF)V", reinterpret_cast<void*>(static_cast<void JNICALL(*)(JNIEnv*,jobject,jlong,jint,jint,jfloat)>(&nativeResize)) },
|
||||
{ "nativeResize", "(JIIFII)V", reinterpret_cast<void*>(static_cast<void JNICALL(*)(JNIEnv*,jobject,jlong,jint,jint,jfloat,jint,jint)>(&nativeResize)) },
|
||||
{ "nativeSetAppliedClasses", "(JLjava/util/Set;)V", reinterpret_cast<void*>(&nativeSetAppliedClasses) },
|
||||
{ "nativeGetAppliedClasses", "(J)Ljava/util/Set;", reinterpret_cast<void*>(&nativeGetAppliedClasses) },
|
||||
{ "nativeSetDefaultTransitionDuration", "(JJ)V", reinterpret_cast<void*>(&nativeSetDefaultTransitionDuration) },
|
||||
{ "nativeSetStyleJSON", "(JLjava/lang/String;)V", reinterpret_cast<void*>(&nativeSetStyleJSON) },
|
||||
{ "nativeGetStyleJSON", "(J)Ljava/lang/String;", reinterpret_cast<void*>(&nativeGetStyleJSON) },
|
||||
{ "nativeCancelTransitions", "(J)V", reinterpret_cast<void*>(&nativeCancelTransitions) },
|
||||
{ "nativeMoveBy", "(JDDD)V", reinterpret_cast<void*>(&nativeMoveBy) },
|
||||
{ "nativeSetLonLat", "(JLcom/mapbox/mapboxgl/lib/LonLat;D)V", reinterpret_cast<void*>(&nativeSetLonLat) },
|
||||
{ "nativeGetLonLat", "(J)Lcom/mapbox/mapboxgl/lib/LonLat;", reinterpret_cast<void*>(&nativeGetLonLat) },
|
||||
{ "nativeStartPanning", "(J)V", reinterpret_cast<void*>(&nativeStartPanning) },
|
||||
{ "nativeStopPanning", "(J)V", reinterpret_cast<void*>(&nativeStopPanning) },
|
||||
{ "nativeResetPosition", "(J)V", reinterpret_cast<void*>(&nativeResetPosition) },
|
||||
{ "nativeScaleBy", "(JDDDD)V", reinterpret_cast<void*>(&nativeScaleBy) },
|
||||
{ "nativeSetScale", "(JDDDD)V", reinterpret_cast<void*>(&nativeSetScale) },
|
||||
{ "nativeGetScale", "(J)D", reinterpret_cast<void*>(&nativeGetScale) },
|
||||
{ "nativeSetZoom", "(JDD)V", reinterpret_cast<void*>(&nativeSetZoom) },
|
||||
{ "nativeGetZoom", "(J)D", reinterpret_cast<void*>(&nativeGetZoom) },
|
||||
{ "nativeSetLonLatZoom", "(JLcom/mapbox/mapboxgl/lib/LonLatZoom;D)V", reinterpret_cast<void*>(&nativeSetLonLatZoom) },
|
||||
{ "nativeGetLonLatZoom", "(J)Lcom/mapbox/mapboxgl/lib/LonLatZoom;", reinterpret_cast<void*>(&nativeGetLonLatZoom) },
|
||||
{ "nativeResetZoom", "(J)V", reinterpret_cast<void*>(&nativeResetZoom) },
|
||||
{ "nativeStartPanning", "(J)V", reinterpret_cast<void*>(&nativeStartScaling) },
|
||||
{ "nativeStopPanning", "(J)V", reinterpret_cast<void*>(&nativeStopScaling) },
|
||||
{ "nativeGetMinZoom", "(J)D", reinterpret_cast<void*>(&nativeGetMinZoom) },
|
||||
{ "nativeGetMaxZoom", "(J)D", reinterpret_cast<void*>(&nativeGetMaxZoom) },
|
||||
{ "nativeRotateBy", "(JDDDDD)V", reinterpret_cast<void*>(&nativeRotateBy) },
|
||||
{ "nativeSetAngle", "(JDD)V", reinterpret_cast<void*>(static_cast<void JNICALL(*)(JNIEnv*,jobject,jlong,jdouble,jdouble)>(&nativeSetAngle)) },
|
||||
{ "nativeSetAngle", "(JDDD)V", reinterpret_cast<void*>(static_cast<void JNICALL(*)(JNIEnv*,jobject,jlong,jdouble,jdouble,jdouble)>(&nativeSetAngle)) },
|
||||
{ "nativeGetAngle", "(J)D", reinterpret_cast<void*>(&nativeGetAngle) },
|
||||
{ "nativeResetNorth", "(J)V", reinterpret_cast<void*>(&nativeResetNorth) },
|
||||
{ "nativeStartRotating", "(J)V", reinterpret_cast<void*>(&nativeStartRotating) },
|
||||
{ "nativeStopRotating", "(J)V", reinterpret_cast<void*>(&nativeStopRotating) },
|
||||
{ "nativeCanRotate", "(J)Z", reinterpret_cast<void*>(&nativeCanRotate) },
|
||||
{ "nativeSetDebug", "(JZ)V", reinterpret_cast<void*>(&nativeSetDebug) },
|
||||
{ "nativeToggleDebug", "(J)V", reinterpret_cast<void*>(&nativeToggleDebug) },
|
||||
{ "nativeGetDebug", "(J)Z", reinterpret_cast<void*>(&nativeGetDebug) }
|
||||
}};
|
||||
|
||||
if (env->RegisterNatives(native_map_view_class, methods.data(), methods.size()) < 0) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
lon_lat_class = reinterpret_cast<jclass>(env->NewGlobalRef(lon_lat_class));
|
||||
if (lon_lat_class == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
lon_lat_zoom_class = reinterpret_cast<jclass>(env->NewGlobalRef(lon_lat_zoom_class));
|
||||
if (lon_lat_zoom_class == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
env->DeleteGlobalRef(lon_lat_class);
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
runtime_exception_class = reinterpret_cast<jclass>(env->NewGlobalRef(runtime_exception_class));
|
||||
if (runtime_exception_class == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
env->DeleteGlobalRef(lon_lat_class);
|
||||
env->DeleteGlobalRef(lon_lat_zoom_class);
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
tree_set_class = reinterpret_cast<jclass>(env->NewGlobalRef(tree_set_class));
|
||||
if (tree_set_class == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
env->DeleteGlobalRef(lon_lat_class);
|
||||
env->DeleteGlobalRef(lon_lat_zoom_class);
|
||||
env->DeleteGlobalRef(runtime_exception_class);
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
|
||||
VERBOSE("JNI_OnUnload");
|
||||
|
||||
JNIEnv* env = nullptr;
|
||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
|
||||
ERROR("GetEnv() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
env->DeleteGlobalRef(lon_lat_class);
|
||||
lon_lat_class = nullptr;
|
||||
lon_lat_constructor_id = nullptr;
|
||||
lon_lat_lon_id = nullptr;
|
||||
lon_lat_lat_id = nullptr;
|
||||
|
||||
env->DeleteGlobalRef(lon_lat_zoom_class);
|
||||
lon_lat_zoom_class = nullptr;
|
||||
lon_lat_zoom_constructor_id = nullptr;
|
||||
lon_lat_zoom_lon_id = nullptr;
|
||||
lon_lat_zoom_lat_id = nullptr;
|
||||
lon_lat_zoom_zoom_id = nullptr;
|
||||
|
||||
on_map_changed_id = nullptr;
|
||||
|
||||
env->DeleteGlobalRef(runtime_exception_class);
|
||||
runtime_exception_class = nullptr;
|
||||
|
||||
set_to_array_id = nullptr;
|
||||
|
||||
env->DeleteGlobalRef(tree_set_class);
|
||||
tree_set_class = nullptr;
|
||||
tree_set_constructor_id = nullptr;
|
||||
tree_set_add_id = nullptr;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
528
android/cpp/NativeMapView.cpp
Normal file
528
android/cpp/NativeMapView.cpp
Normal file
@@ -0,0 +1,528 @@
|
||||
//#include <cstdio>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#include "NativeMapView.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
void log_egl_string(EGLDisplay display, EGLint name, const char* label) {
|
||||
const char* str = eglQueryString(display, name);
|
||||
if (str == nullptr) {
|
||||
ERROR("eglQueryString(%d) returned error %d", name, eglGetError());
|
||||
} else {
|
||||
INFO("EGL %s: %s", label, str);
|
||||
}
|
||||
}
|
||||
|
||||
void log_gl_string(GLenum name, const char* label) {
|
||||
const GLubyte* str = glGetString(name);
|
||||
if (str == nullptr) {
|
||||
ERROR("glGetString(%d) returned error %d", name, glGetError());
|
||||
} else {
|
||||
INFO("GL %s: %s", label, str);
|
||||
}
|
||||
}
|
||||
|
||||
NativeMapView::NativeMapView(JNIEnv* env, jobject obj_,
|
||||
std::string default_style_json_) :
|
||||
default_style_json(default_style_json_) {
|
||||
VERBOSE("NativeMapView::NativeMapView");
|
||||
|
||||
ASSERT(env != nullptr);
|
||||
ASSERT(obj_ != nullptr);
|
||||
|
||||
if (env->GetJavaVM(&vm) < 0) {
|
||||
env->ExceptionDescribe();
|
||||
return;
|
||||
}
|
||||
|
||||
obj = env->NewGlobalRef(obj_);
|
||||
if (obj == nullptr) {
|
||||
env->ExceptionDescribe();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO replace all printfs in map code with android logging
|
||||
//freopen("/sdcard/stdout.txt", "w", stdout); // NOTE: can't use <cstdio> till NDK fix the stdout macro bug
|
||||
//freopen("/sdcard/stderr.txt", "w", stderr);
|
||||
|
||||
view = new MBGLView(this);
|
||||
map = new mbgl::Map(*view);
|
||||
|
||||
// FIXME need way to load this from Java
|
||||
map->setAccessToken("pk.eyJ1IjoibGpiYWRlIiwiYSI6IlJSQ0FEZ2MifQ.7mE4aOegldh3595AG9dxpQ");
|
||||
|
||||
// FIXME this asserts because it creates FileSource of different thread from run thread
|
||||
//map->setStyleJSON(default_style_json);
|
||||
map->setStyleURL("https://raw.githubusercontent.com/mapbox/mapbox-gl-styles/mb-pages/styles/bright-v5.json");
|
||||
}
|
||||
|
||||
NativeMapView::~NativeMapView() {
|
||||
VERBOSE("NativeMapView::~NativeMapView");
|
||||
terminateContext();
|
||||
|
||||
delete map;
|
||||
map = nullptr;
|
||||
|
||||
delete view;
|
||||
view = nullptr;
|
||||
|
||||
ASSERT(vm != nullptr);
|
||||
ASSERT(obj != nullptr);
|
||||
|
||||
JNIEnv* env = nullptr;
|
||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) == JNI_OK) {
|
||||
env->DeleteGlobalRef(obj);
|
||||
} else {
|
||||
ERROR("GetEnv() failed");
|
||||
}
|
||||
obj = nullptr;
|
||||
vm = nullptr;
|
||||
}
|
||||
|
||||
bool NativeMapView::initializeDisplay() {
|
||||
VERBOSE("NativeMapView::initializeDisplay");
|
||||
|
||||
ASSERT(display == EGL_NO_DISPLAY);
|
||||
ASSERT(config == nullptr);
|
||||
ASSERT(format < 0);
|
||||
|
||||
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (display == EGL_NO_DISPLAY) {
|
||||
ERROR("eglGetDisplay() returned error %d", eglGetError());
|
||||
terminateDisplay();
|
||||
return false;
|
||||
}
|
||||
|
||||
EGLint major, minor;
|
||||
if (!eglInitialize(display, &major, &minor)) {
|
||||
ERROR("eglInitialize() returned error %d", eglGetError());
|
||||
terminateDisplay();
|
||||
return false;
|
||||
}
|
||||
if ((major <= 1) && (minor < 3)) {
|
||||
ERROR("EGL version is too low, need 1.3, got %d.%d", major, minor);
|
||||
terminateDisplay();
|
||||
return false;
|
||||
}
|
||||
|
||||
log_egl_string(display, EGL_VENDOR, "Vendor");
|
||||
log_egl_string(display, EGL_VERSION, "Version");
|
||||
log_egl_string(display, EGL_CLIENT_APIS, "Client APIs");
|
||||
log_egl_string(display, EGL_EXTENSIONS, "Client Extensions");
|
||||
|
||||
// TODO should try 565, then 8888?
|
||||
bool use565 = true;
|
||||
|
||||
const EGLint config_attribs[] = {
|
||||
EGL_CONFIG_CAVEAT, EGL_NONE,
|
||||
EGL_CONFORMANT, EGL_OPENGL_ES2_BIT,
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
|
||||
EGL_BUFFER_SIZE, use565 ? 16 : 32, // Ensure we get 32bit color buffer on Tegra, 24 bit will be sorted first without it (slow software mode)
|
||||
EGL_RED_SIZE, use565 ? 5 : 8,
|
||||
EGL_GREEN_SIZE, use565 ? 6 : 8,
|
||||
EGL_BLUE_SIZE, use565 ? 5 : 8,
|
||||
EGL_DEPTH_SIZE, 16,
|
||||
EGL_STENCIL_SIZE, 8,
|
||||
EGL_NONE
|
||||
};
|
||||
EGLint num_configs;
|
||||
if (!eglChooseConfig(display, config_attribs, nullptr, 0, &num_configs)) {
|
||||
ERROR("eglChooseConfig(NULL) returned error %d", eglGetError());
|
||||
terminateDisplay();
|
||||
return false;
|
||||
}
|
||||
if (num_configs < 1) {
|
||||
ERROR("eglChooseConfig() returned no configs");
|
||||
terminateDisplay();
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO make_unique missing in Android NDK?
|
||||
// const std::unique_ptr<EGLConfig[]> configs = std::make_unique(new EGLConfig[num_configs]);
|
||||
const std::unique_ptr<EGLConfig[]> configs(new EGLConfig[num_configs]);
|
||||
if (!eglChooseConfig(display, config_attribs, configs.get(), num_configs,
|
||||
&num_configs)) {
|
||||
ERROR("eglChooseConfig() returned error %d", eglGetError());
|
||||
terminateDisplay();
|
||||
return false;
|
||||
}
|
||||
|
||||
config = chooseConfig(configs.get(), num_configs, use565);
|
||||
if (config == nullptr) {
|
||||
ERROR("No config chosen");
|
||||
terminateDisplay();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format)) {
|
||||
ERROR("eglGetConfigAttrib() returned error %d", eglGetError());
|
||||
terminateDisplay();
|
||||
return false;
|
||||
}
|
||||
DEBUG("Chosen window format is %d", format);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NativeMapView::terminateDisplay() {
|
||||
VERBOSE("NativeMapView::terminateDisplay");
|
||||
|
||||
if (display != EGL_NO_DISPLAY) {
|
||||
if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT)) {
|
||||
ERROR("eglMakeCurrent(EGL_NO_CONTEXT) returned error %d",
|
||||
eglGetError());
|
||||
}
|
||||
|
||||
if (!eglTerminate(display)) {
|
||||
ERROR("eglTerminate() returned error %d", eglGetError());
|
||||
}
|
||||
}
|
||||
|
||||
display = EGL_NO_DISPLAY;
|
||||
config = nullptr;
|
||||
format = -1;
|
||||
}
|
||||
|
||||
bool NativeMapView::initializeContext() {
|
||||
VERBOSE("NativeMapView::initializeContext");
|
||||
|
||||
ASSERT(display != EGL_NO_DISPLAY);
|
||||
ASSERT(context == EGL_NO_CONTEXT);
|
||||
ASSERT(config != nullptr);
|
||||
|
||||
const EGLint context_attribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_NONE
|
||||
};
|
||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
if (context == EGL_NO_CONTEXT) {
|
||||
ERROR("eglCreateContext() returned error %d", eglGetError());
|
||||
terminateContext();
|
||||
return false;
|
||||
}
|
||||
|
||||
INFO("Context initialized");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NativeMapView::terminateContext() {
|
||||
VERBOSE("NativeMapView::terminateContext");
|
||||
|
||||
map->terminate();
|
||||
|
||||
// TODO: there is a bug when you double tap home to go app switcher, as map is black if you immediately switch to the map again
|
||||
// TODO: this is in the onPause/onResume path
|
||||
// TODO: the bug causes an GL_INVALID_VALUE with glDelteProgram (I think due to context being deleted first)
|
||||
// TODO: we need to free resources before we terminate
|
||||
// TODO: but cause terminate and stop is async they try to do stuff with no context and crash!
|
||||
|
||||
if (display != EGL_NO_DISPLAY) {
|
||||
if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT)) {
|
||||
ERROR("eglMakeCurrent(EGL_NO_CONTEXT) returned error %d",
|
||||
eglGetError());
|
||||
}
|
||||
|
||||
if (context != EGL_NO_CONTEXT) {
|
||||
if (!eglDestroyContext(display, context)) {
|
||||
ERROR("eglDestroyContext() returned error %d", eglGetError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
bool NativeMapView::createSurface(ANativeWindow* window_) {
|
||||
VERBOSE("NativeMapView::createSurface");
|
||||
|
||||
ASSERT(window == nullptr);
|
||||
ASSERT(window_ != nullptr);
|
||||
window = window_;
|
||||
|
||||
ASSERT(display != EGL_NO_DISPLAY);
|
||||
ASSERT(surface == EGL_NO_SURFACE);
|
||||
ASSERT(config != nullptr);
|
||||
ASSERT(format >= 0);
|
||||
|
||||
ANativeWindow_setBuffersGeometry(window, 0, 0, format);
|
||||
|
||||
const EGLint surface_attribs[] = {
|
||||
EGL_NONE
|
||||
};
|
||||
surface = eglCreateWindowSurface(display, config, window, surface_attribs);
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
ERROR("eglCreateWindowSurface() returned error %d", eglGetError());
|
||||
destroySurface();
|
||||
return false;
|
||||
}
|
||||
|
||||
start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NativeMapView::destroySurface() {
|
||||
VERBOSE("NativeMapView::destroySurface");
|
||||
|
||||
if (surface != EGL_NO_SURFACE) {
|
||||
if (!eglDestroySurface(display, surface)) {
|
||||
ERROR("eglDestroySurface() returned error %d", eglGetError());
|
||||
}
|
||||
}
|
||||
|
||||
surface = EGL_NO_SURFACE;
|
||||
|
||||
if (window != nullptr) {
|
||||
ANativeWindow_release(window);
|
||||
window = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
EGLConfig NativeMapView::chooseConfig(const EGLConfig configs[],
|
||||
EGLint num_configs, bool use565) const {
|
||||
INFO("Found %d configs", num_configs);
|
||||
|
||||
int chosen_config = -1;
|
||||
for (int i = 0; i < num_configs; i++) {
|
||||
INFO("Config %d:", i);
|
||||
|
||||
EGLint bits, red, green, blue, alpha, alpha_mask, depth, stencil,
|
||||
sample_buffers, samples;
|
||||
|
||||
if (!eglGetConfigAttrib(display, configs[i], EGL_BUFFER_SIZE, &bits)) {
|
||||
ERROR("eglGetConfigAttrib(EGL_BUFFER_SIZE) returned error %d",
|
||||
eglGetError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!eglGetConfigAttrib(display, configs[i], EGL_RED_SIZE, &red)) {
|
||||
ERROR("eglGetConfigAttrib(EGL_RED_SIZE) returned error %d",
|
||||
eglGetError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!eglGetConfigAttrib(display, configs[i], EGL_GREEN_SIZE, &green)) {
|
||||
ERROR("eglGetConfigAttrib(EGL_GREEN_SIZE) returned error %d",
|
||||
eglGetError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!eglGetConfigAttrib(display, configs[i], EGL_BLUE_SIZE, &blue)) {
|
||||
ERROR("eglGetConfigAttrib(EGL_BLUE_SIZE) returned error %d",
|
||||
eglGetError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!eglGetConfigAttrib(display, configs[i], EGL_ALPHA_SIZE, &alpha)) {
|
||||
ERROR("eglGetConfigAttrib(EGL_ALPHA_SIZE) returned error %d",
|
||||
eglGetError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!eglGetConfigAttrib(display, configs[i], EGL_ALPHA_MASK_SIZE,
|
||||
&alpha_mask)) {
|
||||
ERROR("eglGetConfigAttrib(EGL_ALPHA_MASK_SIZE) returned error %d",
|
||||
eglGetError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!eglGetConfigAttrib(display, configs[i], EGL_DEPTH_SIZE, &depth)) {
|
||||
ERROR("eglGetConfigAttrib(EGL_DEPTH_SIZE) returned error %d",
|
||||
eglGetError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!eglGetConfigAttrib(display, configs[i], EGL_STENCIL_SIZE,
|
||||
&stencil)) {
|
||||
ERROR("eglGetConfigAttrib(EGL_STENCIL_SIZE) returned error %d",
|
||||
eglGetError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!eglGetConfigAttrib(display, configs[i], EGL_SAMPLE_BUFFERS,
|
||||
&sample_buffers)) {
|
||||
ERROR("eglGetConfigAttrib(EGL_SAMPLE_BUFFERS) returned error %d",
|
||||
eglGetError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!eglGetConfigAttrib(display, configs[i], EGL_SAMPLES, &samples)) {
|
||||
ERROR("eglGetConfigAttrib(EGL_SAMPLES) returned error %d",
|
||||
eglGetError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
INFO("Color: %d", bits);
|
||||
INFO("Red: %d", red);
|
||||
INFO("Green: %d", green);
|
||||
INFO("Blue: %d", blue);
|
||||
INFO("Alpha: %d", alpha);
|
||||
INFO("Alpha mask: %d", alpha_mask);
|
||||
INFO("Depth: %d", depth);
|
||||
INFO("Stencil: %d", stencil);
|
||||
INFO("Sample buffers: %d", sample_buffers);
|
||||
INFO("Samples: %d", samples);
|
||||
|
||||
bool config_ok = true;
|
||||
config_ok &= bits == (use565 ? 16 : 32);
|
||||
config_ok &= red == (use565 ? 5 : 8);
|
||||
config_ok &= green == (use565 ? 6 : 8);
|
||||
config_ok &= blue == (use565 ? 5 : 8);
|
||||
//config_ok &= (alpha == 0) || (alpha == 8); // Can be either 0 for RGBX or 8 for RGBA but we don't care either way
|
||||
config_ok &= alpha == 0; // TODO should prefer no alpha over alpha, and 565 over 8888?
|
||||
//config_ok &= depth == 16;
|
||||
//config_ok &= stencil == 8;
|
||||
//config_ok &= sample_buffers == 0;
|
||||
config_ok &= samples == 0;
|
||||
|
||||
if (config_ok) { // Choose the last matching config, that way we get RGBX if possible (since it is sorted highest to lowest bits)
|
||||
chosen_config = i;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG("Chosen config is %d", chosen_config);
|
||||
if (chosen_config >= 0) {
|
||||
return configs[chosen_config];
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeMapView::start() {
|
||||
VERBOSE("NativeMapView::start");
|
||||
|
||||
if (display == EGL_NO_DISPLAY) {
|
||||
initializeDisplay();
|
||||
}
|
||||
|
||||
if (context == EGL_NO_CONTEXT) {
|
||||
initializeContext();
|
||||
}
|
||||
|
||||
if ((display != EGL_NO_DISPLAY) && (surface != EGL_NO_SURFACE)
|
||||
&& (context != EGL_NO_CONTEXT)) {
|
||||
|
||||
if (!eglMakeCurrent(display, surface, surface, context)) {
|
||||
ERROR("eglMakeCurrent() returned error %d", eglGetError());
|
||||
}
|
||||
|
||||
log_gl_string(GL_VENDOR, "Vendor");
|
||||
log_gl_string(GL_RENDERER, "Renderer");
|
||||
log_gl_string(GL_VERSION, "Version");
|
||||
log_gl_string(GL_SHADING_LANGUAGE_VERSION, "SL Version");
|
||||
log_gl_string(GL_EXTENSIONS, "Extensions");
|
||||
|
||||
if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT)) {
|
||||
ERROR("eglMakeCurrent(EGL_NO_CONTEXT) returned error %d",
|
||||
eglGetError());
|
||||
}
|
||||
|
||||
map->start();
|
||||
} else {
|
||||
DEBUG("Not starting because we are not ready");
|
||||
}
|
||||
}
|
||||
|
||||
void NativeMapView::stop() {
|
||||
VERBOSE("NativeMapView::stop");
|
||||
if ((display != EGL_NO_DISPLAY) && (surface != EGL_NO_SURFACE)
|
||||
&& (context != EGL_NO_CONTEXT)) {
|
||||
map->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void NativeMapView::notifyMapChange() {
|
||||
DEBUG("NativeMapView::notify_map_change()");
|
||||
|
||||
ASSERT(vm != nullptr);
|
||||
ASSERT(obj != nullptr);
|
||||
|
||||
JNIEnv* env = nullptr;
|
||||
// FIXME this returns failure
|
||||
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
|
||||
ERROR("GetEnv() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
env->CallVoidMethod(obj, on_map_changed_id);
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionDescribe();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MBGLView::make_active() {
|
||||
VERBOSE("MBGLView::make_active");
|
||||
if ((nativeView->display != EGL_NO_DISPLAY)
|
||||
&& (nativeView->surface != EGL_NO_SURFACE)
|
||||
&& (nativeView->context != EGL_NO_CONTEXT)) {
|
||||
if (!eglMakeCurrent(nativeView->display, nativeView->surface,
|
||||
nativeView->surface, nativeView->context)) {
|
||||
ERROR("eglMakeCurrent() returned error %d", eglGetError());
|
||||
}
|
||||
|
||||
// TODO still can't fix the black screen problem :-(
|
||||
EGLint width, height;
|
||||
if (!(eglQuerySurface(nativeView->display, nativeView->surface, EGL_WIDTH, &width)
|
||||
& eglQuerySurface(nativeView->display, nativeView->surface, EGL_HEIGHT, &height))) {
|
||||
ERROR("eglQuerySurface() returned error %d", eglGetError());
|
||||
}
|
||||
map->resize(width, height);
|
||||
|
||||
} else {
|
||||
DEBUG("Not activating as we are not ready");
|
||||
}
|
||||
}
|
||||
|
||||
void MBGLView::make_inactive() {
|
||||
VERBOSE("MBGLView::make_inactive");
|
||||
if (!eglMakeCurrent(nativeView->display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT)) {
|
||||
ERROR("eglMakeCurrent(EGL_NO_CONTEXT) returned error %d",
|
||||
eglGetError());
|
||||
}
|
||||
}
|
||||
|
||||
void MBGLView::swap() {
|
||||
VERBOSE("MBGLView::swap");
|
||||
if (map->needsSwap() && (nativeView->display != EGL_NO_DISPLAY)
|
||||
&& (nativeView->surface != EGL_NO_SURFACE)) {
|
||||
if (!eglSwapBuffers(nativeView->display, nativeView->surface)) {
|
||||
ERROR("eglSwapBuffers() returned error %d", eglGetError());
|
||||
}
|
||||
map->swapped();
|
||||
} else {
|
||||
DEBUG("Not swapping as we are not ready");
|
||||
}
|
||||
}
|
||||
|
||||
void MBGLView::notify() {
|
||||
DEBUG("MBGLView::notify()");
|
||||
// TODO
|
||||
}
|
||||
|
||||
void MBGLView::notify_map_change(mbgl::MapChange change, mbgl::timestamp delay) {
|
||||
DEBUG("MBGLView::notify_map_change()");
|
||||
nativeView->notifyMapChange();
|
||||
// TODO: use new variables
|
||||
(void)change;
|
||||
(void)delay;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
111
android/cpp/NativeMapView.hpp
Normal file
111
android/cpp/NativeMapView.hpp
Normal file
@@ -0,0 +1,111 @@
|
||||
#ifndef MAP_VIEW_HPP
|
||||
#define MAP_VIEW_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <android/native_window.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <mbgl/mbgl.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
extern jmethodID on_map_changed_id;
|
||||
|
||||
extern jclass lon_lat_class;
|
||||
extern jmethodID lon_lat_constructor_id;
|
||||
extern jfieldID lon_lat_lon_id;
|
||||
extern jfieldID lon_lat_lat_id;
|
||||
|
||||
extern jclass lon_lat_zoom_class;
|
||||
extern jmethodID lon_lat_zoom_constructor_id;
|
||||
extern jfieldID lon_lat_zoom_lon_id;
|
||||
extern jfieldID lon_lat_zoom_lat_id;
|
||||
extern jfieldID lon_lat_zoom_zoom_id;
|
||||
|
||||
extern jclass runtime_exception_class;
|
||||
|
||||
extern jmethodID set_to_array_id;
|
||||
|
||||
extern jclass tree_set_class;
|
||||
extern jmethodID tree_set_constructor_id;
|
||||
extern jmethodID tree_set_add_id;
|
||||
|
||||
class MBGLView;
|
||||
|
||||
class NativeMapView {
|
||||
friend class MBGLView;
|
||||
|
||||
public:
|
||||
NativeMapView(JNIEnv* env, jobject obj, std::string default_style_json);
|
||||
~NativeMapView();
|
||||
|
||||
mbgl::Map* getMap() const {
|
||||
return map;
|
||||
}
|
||||
|
||||
bool initializeDisplay();
|
||||
void terminateDisplay();
|
||||
|
||||
bool initializeContext();
|
||||
void terminateContext();
|
||||
|
||||
bool createSurface(ANativeWindow* window);
|
||||
void destroySurface();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
void notifyMapChange();
|
||||
|
||||
private:
|
||||
EGLConfig chooseConfig(const EGLConfig configs[], EGLint num_configs,
|
||||
bool use565) const;
|
||||
|
||||
private:
|
||||
JavaVM* vm = nullptr;
|
||||
jobject obj = nullptr;
|
||||
|
||||
ANativeWindow* window = nullptr;
|
||||
|
||||
mbgl::Map* map = nullptr;
|
||||
MBGLView* view = nullptr;
|
||||
|
||||
EGLDisplay display = EGL_NO_DISPLAY;
|
||||
EGLSurface surface = EGL_NO_SURFACE;
|
||||
EGLContext context = EGL_NO_CONTEXT;
|
||||
|
||||
EGLConfig config = nullptr;
|
||||
EGLint format = -1;
|
||||
|
||||
std::string default_style_json;
|
||||
};
|
||||
|
||||
class MBGLView: public mbgl::View {
|
||||
public:
|
||||
MBGLView(NativeMapView* nativeView_) :
|
||||
nativeView(nativeView_) {
|
||||
}
|
||||
virtual ~MBGLView() {
|
||||
}
|
||||
|
||||
void make_active() override;
|
||||
void make_inactive() override;
|
||||
|
||||
void swap() override;
|
||||
|
||||
void notify() override;
|
||||
void notify_map_change(mbgl::MapChange change, mbgl::timestamp delay = 0) override;
|
||||
|
||||
private:
|
||||
NativeMapView* nativeView = nullptr;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
|
||||
#endif // MAP_VIEW_HPP
|
||||
18
android/cpp/log.h
Normal file
18
android/cpp/log.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef LOG_H
|
||||
#define LOG_H
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#define S(x) #x
|
||||
#define S_(x) S(x)
|
||||
#define S__LINE__ S_(__LINE__)
|
||||
|
||||
#define VERBOSE(fmt, args...) __android_log_print(ANDROID_LOG_VERBOSE, __FILE__ ":" S__LINE__, fmt, ##args)
|
||||
#define DEBUG(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, __FILE__ ":" S__LINE__, fmt, ##args)
|
||||
#define INFO(fmt, args...) __android_log_print(ANDROID_LOG_INFO, __FILE__ ":" S__LINE__, fmt, ##args)
|
||||
#define WARN(fmt, args...) __android_log_print(ANDROID_LOG_WARN, __FILE__ ":" S__LINE__, fmt, ##args)
|
||||
#define ERROR(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, __FILE__ ":" S__LINE__, fmt, ##args)
|
||||
#define ASSERT(cond, ...) ((cond)?(void)0:__android_log_assert(#cond, __FILE__ ":" S__LINE__, NULL))
|
||||
#define ASSERTMSG(cond, fmt, args...) ((cond)?(void)0:__android_log_assert(#cond, __FILE__ ":" S__LINE__, fmt, ##args))
|
||||
|
||||
#endif // LOG_H
|
||||
Reference in New Issue
Block a user