-
Notifications
You must be signed in to change notification settings - Fork 240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Android API for scene loading with scene updates #1173
Conversation
public void queueSceneUpdate(ArrayList<SceneUpdate> sceneUpdates) { | ||
checkPointer(mapPointer); | ||
for(SceneUpdate sceneUpdate : sceneUpdates) { | ||
nativeQueueSceneUpdate(mapPointer, sceneUpdate.path, sceneUpdate.value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we want to make it a single call here nativeQueueSceneUpdates(long mapPtr, String[] sceneUpdatePaths, String[] sceneUpdateValues)
? It would reduce jumping between platform code and core library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, will update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recommend using the SceneUpdate
type in the older queueSceneUpdate
method as well.
set(path, value); | ||
} | ||
|
||
public SceneUpdate set(String p, String v) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we make this public we should be more explicit on the variable names p
and v
.
I'm not sure we need the default constructor SceneUpdate()
and this setter since the variable are public.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was just being more formal here. Will remove the constructor and directly assign.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recommend removing the setter and only setting members in the constructor.
public SceneUpdate set(String p, String v) { | ||
path = p; | ||
value = v; | ||
return this; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the return?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying something else before. Will update this.
@@ -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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like we could merge this with the method above and just pass a null array when no updates are given.
* @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<SceneUpdate> sceneUpdates) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These methods should take a List<SceneUpdate>
, the List
interface should be preferred to concrete types when we don't need the specific type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also check this for null
.
public String path; | ||
public String value; | ||
|
||
public SceneUpdate() { this("", ""); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recommend removing this constructor.
public class SceneUpdate { | ||
|
||
public String path; | ||
public String value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recommend making these members private and adding getters.
set(path, value); | ||
} | ||
|
||
public SceneUpdate set(String p, String v) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recommend removing the setter and only setting members in the constructor.
public void queueSceneUpdate(ArrayList<SceneUpdate> sceneUpdates) { | ||
checkPointer(mapPointer); | ||
for(SceneUpdate sceneUpdate : sceneUpdates) { | ||
nativeQueueSceneUpdate(mapPointer, sceneUpdate.path, sceneUpdate.value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recommend using the SceneUpdate
type in the older queueSceneUpdate
method as well.
|
||
public SceneUpdate() { this("", ""); } | ||
|
||
public SceneUpdate(String path, String value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recommend adding documentation explaining the meaning of these arguments.
@@ -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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This branch should be unnecessary if we allow empty or null
lists as the second argument to loadSceneFile
.
Addressed all comments here: 7353bbe |
7353bbe
to
a710b43
Compare
Comments got removed of the pull request: 7353bbe#commitcomment-20205669. Merging once updated. |
Ohh, thanks @karimnaaji . Updated. |
I have changes to suggest for this - don't merge quite yet please. |
e77febb
to
4b54361
Compare
@ecgreb this one needs your approval! It's good to merge otherwise. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Public API looks good to me. Two suggestions inline regarding input validation and duplicate code.
* @param sceneUpdates List of {@code SceneUpdate} | ||
*/ | ||
public void queueSceneUpdate(List<SceneUpdate> sceneUpdates) { | ||
checkPointer(mapPointer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to provide some input validation on sceneUpdates
param. Perhaps throw an IllegalArgumentException
if it is empty or null
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, tangram will be handling a null
or empty
sceneUpdates
gracefully, through the jni code here:
tangram-es/android/tangram/jni/jniExports.cpp
Lines 470 to 483 in 4b54361
JNIEXPORT void JNICALL Java_com_mapzen_tangram_MapController_nativeQueueSceneUpdates(JNIEnv* jniEnv, jobject obj, jlong mapPtr, jobjectArray updateStrings) { | |
assert(mapPtr > 0); | |
size_t nUpdateStrings = (updateStrings == NULL)? 0 : jniEnv->GetArrayLength(updateStrings); | |
std::vector<Tangram::SceneUpdate> sceneUpdates; | |
for (size_t i = 0; i < nUpdateStrings;) { | |
jstring path = (jstring) (jniEnv->GetObjectArrayElement(updateStrings, i++)); | |
jstring value = (jstring) (jniEnv->GetObjectArrayElement(updateStrings, i++)); | |
sceneUpdates.emplace_back(stringFromJString(jniEnv, path), stringFromJString(jniEnv, value)); | |
jniEnv->DeleteLocalRef(path); | |
jniEnv->DeleteLocalRef(value); | |
} | |
if (sceneUpdates.empty()) { return; } |
Am I missing java thingy, which will help here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No the code won't break but it could be helpful to the developer if we provided some explicit feedback rather than failing silently in the case of invalid input.
Also passing data across the JNI is expensive. If we can avoid that by checking the input in Java first that would be preferable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok Both are valid points. Updated here: 8c1ff13
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
String[] updateStrings = null; | ||
|
||
if (sceneUpdates != null) { | ||
updateStrings = new String[sceneUpdates.size() * 2]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic to build updateStrings
is repeated again below in queueSceneUpdate(...)
. Could be extracted into a private method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed here: c362285
With an update to arguments for Will rebase this with master and merge. |
- 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
path -> getPath value -> getValue
- BundleSceneUpdate private method bundles list of scene updates as an array of strings alternating scene yaml path and corresponding value
8c1ff13
to
67eb847
Compare
getMapAsync
which accepts an ArrayList of SceneUpdates (newClass).
SceneUpdates