From 89cc64f91b799487cd5b51e0c7e086642a4d451b Mon Sep 17 00:00:00 2001 From: Varun Talwar Date: Tue, 13 Dec 2016 18:18:50 -0500 Subject: [PATCH] Add Android API for scene loading with scene updates - MapView provides an overloaded `getMapAsync` which accepts an ArrayList of SceneUpdates (new Class). - MapController::loadSceneFile provides an overloaded method to accept an ArrayList of SceneUpdates - MapController::queueSceneUpdates provides an overloaded method to accept an ArrayList of SceneUpdates --- android/tangram/jni/jniExports.cpp | 19 +++++++++++ .../src/com/mapzen/tangram/MapController.java | 34 +++++++++++++++++++ .../src/com/mapzen/tangram/MapView.java | 22 +++++++++++- .../src/com/mapzen/tangram/SceneUpdate.java | 24 +++++++++++++ core/src/tangram.h | 1 + 5 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 android/tangram/src/com/mapzen/tangram/SceneUpdate.java diff --git a/android/tangram/jni/jniExports.cpp b/android/tangram/jni/jniExports.cpp index 8997dc8b36..1bbc732ef8 100644 --- a/android/tangram/jni/jniExports.cpp +++ b/android/tangram/jni/jniExports.cpp @@ -118,6 +118,25 @@ extern "C" { jniEnv->ReleaseStringUTFChars(path, cPath); } + JNIEXPORT void JNICALL Java_com_mapzen_tangram_MapController_nativeLoadSceneWithUpdates(JNIEnv* jniEnv, jobject obj, jlong mapPtr, jstring path, jobjectArray jsceneUpdatePaths, jobjectArray jsceneUpdateValues) { + assert(mapPtr > 0); + size_t n_sceneUpdates = (jsceneUpdatePaths == NULL)? 0 : jniEnv->GetArrayLength(jsceneUpdatePaths); + + std::vector sceneUpdates; + for (size_t i = 0; i < n_sceneUpdates; i++) { + jstring path = (jstring) (jniEnv->GetObjectArrayElement(jsceneUpdatePaths, i)); + jstring value = (jstring) (jniEnv->GetObjectArrayElement(jsceneUpdateValues, i)); + sceneUpdates.emplace_back(stringFromJString(jniEnv, path), stringFromJString(jniEnv, value)); + jniEnv->DeleteLocalRef(path); + jniEnv->DeleteLocalRef(value); + } + + auto map = reinterpret_cast(mapPtr); + const char* cPath = jniEnv->GetStringUTFChars(path, NULL); + map->loadScene(resolveScenePath(cPath).c_str(), false, sceneUpdates); + jniEnv->ReleaseStringUTFChars(path, cPath); + } + JNIEXPORT void JNICALL Java_com_mapzen_tangram_MapController_nativeResize(JNIEnv* jniEnv, jobject obj, jlong mapPtr, jint width, jint height) { assert(mapPtr > 0); auto map = reinterpret_cast(mapPtr); diff --git a/android/tangram/src/com/mapzen/tangram/MapController.java b/android/tangram/src/com/mapzen/tangram/MapController.java index c3adcb4fae..5b44702c69 100644 --- a/android/tangram/src/com/mapzen/tangram/MapController.java +++ b/android/tangram/src/com/mapzen/tangram/MapController.java @@ -13,6 +13,7 @@ import com.squareup.okhttp.Response; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -228,6 +229,26 @@ public void loadSceneFile(String path) { requestRender(); } + /** + * Load a new scene file + * @param path Location of the YAML scene file within the application assets + * @param sceneUpdates List of path:value pairs to be applied when loading this scene + */ + public void loadSceneFile(String path, ArrayList sceneUpdates) { + String[] paths = new String[sceneUpdates.size()]; + String[] values = new String[sceneUpdates.size()]; + int index = 0; + for (SceneUpdate sceneUpdate : sceneUpdates) { + paths[index] = sceneUpdate.path; + values[index] = sceneUpdate.value; + index++; + } + scenePath = path; + checkPointer(mapPointer); + nativeLoadSceneWithUpdates(mapPointer, path, paths, values); + requestRender(); + } + /** * Set the {@link HttpHandler} for retrieving remote map resources; a default-constructed * HttpHandler is suitable for most cases, but methods can be extended to modify resource URLs @@ -746,6 +767,18 @@ public void queueSceneUpdate(String componentPath, String value) { nativeQueueSceneUpdate(mapPointer, componentPath, value); } + /** + * Enqueue a scene component update with its corresponding YAML node value + * @param componentPath The YAML component path delimited by a '.' (example "scene.animated") + * @param value A YAML valid string (example "{ property: true }" or "true") + */ + public void queueSceneUpdate(ArrayList sceneUpdates) { + checkPointer(mapPointer); + for(SceneUpdate sceneUpdate : sceneUpdates) { + nativeQueueSceneUpdate(mapPointer, sceneUpdate.path, sceneUpdate.value); + } + } + /** * Apply updates queued by queueSceneUpdate; this empties the current queue of updates */ @@ -862,6 +895,7 @@ boolean setMarkerDrawOrder(long markerId, int drawOrder) { private synchronized native long nativeInit(MapController instance, AssetManager assetManager); private synchronized native void nativeDispose(long mapPtr); private synchronized native void nativeLoadScene(long mapPtr, String path); + private synchronized native void nativeLoadSceneWithUpdates(long mapPtr, String path, String[] sceneUpdatePaths, String[] sceneUpdateValues); private synchronized native void nativeSetupGL(long mapPtr); private synchronized native void nativeResize(long mapPtr, int width, int height); private synchronized native boolean nativeUpdate(long mapPtr, float dt); diff --git a/android/tangram/src/com/mapzen/tangram/MapView.java b/android/tangram/src/com/mapzen/tangram/MapView.java index 656870cf7f..8cbbb27f48 100644 --- a/android/tangram/src/com/mapzen/tangram/MapView.java +++ b/android/tangram/src/com/mapzen/tangram/MapView.java @@ -8,6 +8,8 @@ import android.util.AttributeSet; import android.widget.FrameLayout; +import java.util.ArrayList; + /** * {@code MapView} is a View for displaying a Tangram map. */ @@ -55,6 +57,20 @@ public interface OnMapReadyCallback { public void getMapAsync(@NonNull final OnMapReadyCallback callback, @NonNull final String sceneFilePath) { + getMapAsync(callback, sceneFilePath, new ArrayList()); + } + + /** + * Construct a {@code MapController} asynchronously; may only be called from the UI thread + * @param callback The object to receive the resulting MapController in a callback; + * the callback will be made on the UI thread + * @param sceneFilePath Location of the YAML scene file within the asset bundle + * @param sceneUpdates List of SceneUpdate to be applied when loading this scene + */ + public void getMapAsync(@NonNull final OnMapReadyCallback callback, + @NonNull final String sceneFilePath, + final ArrayList sceneUpdates) { + disposeTask(); final MapController mapInstance = getMapInstance(); @@ -65,7 +81,11 @@ public void getMapAsync(@NonNull final OnMapReadyCallback callback, @SuppressWarnings("WrongThread") protected Boolean doInBackground(Void... params) { mapInstance.init(); - mapInstance.loadSceneFile(sceneFilePath); + if (sceneUpdates.size() > 0) { + mapInstance.loadSceneFile(sceneFilePath, sceneUpdates); + } else { + mapInstance.loadSceneFile(sceneFilePath); + } return true; } diff --git a/android/tangram/src/com/mapzen/tangram/SceneUpdate.java b/android/tangram/src/com/mapzen/tangram/SceneUpdate.java new file mode 100644 index 0000000000..e17db28032 --- /dev/null +++ b/android/tangram/src/com/mapzen/tangram/SceneUpdate.java @@ -0,0 +1,24 @@ +package com.mapzen.tangram; + +/** + * {@code SceneUpdate} Represents a DataStructure to specify a yaml path and the corresponding value for a Scene Update. + */ + +public class SceneUpdate { + + public String path; + public String value; + + public SceneUpdate() { this("", ""); } + + public SceneUpdate(String path, String value) { + set(path, value); + } + + public SceneUpdate set(String p, String v) { + path = p; + value = v; + return this; + } + +} diff --git a/core/src/tangram.h b/core/src/tangram.h index 4228ec16d3..3a7686fa52 100644 --- a/core/src/tangram.h +++ b/core/src/tangram.h @@ -46,6 +46,7 @@ using LabelPickCallback = std::function; struct SceneUpdate { std::string path; std::string value; + SceneUpdate(std::string p, std::string v) : path(p), value(v) {} }; enum class EaseType : char {