diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java index 8304d0e6edc..60defe54576 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java @@ -15,7 +15,6 @@ import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.constants.MapboxConstants; -import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.utils.AnimatorUtils; @@ -34,7 +33,7 @@ * SDK views to be used as a symbol see https://github.com/mapbox/mapbox-gl-native/blob/68f32bc104422207c64da8d90e8411b138d87f04/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolGeneratorActivity.java */ @Deprecated -public class MarkerViewManager implements MapView.OnMapChangedListener { +public class MarkerViewManager { private final ViewGroup markerViewContainer; private final ViewTreeObserver.OnPreDrawListener markerViewPreDrawObserver = @@ -75,9 +74,8 @@ public void bind(MapboxMap mapboxMap) { this.mapboxMap = mapboxMap; } - @Override - public void onMapChanged(@MapView.MapChange int change) { - if (isWaitingForRenderInvoke && change == MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED) { + public void onDidFinishRenderingFrameFully() { + if (isWaitingForRenderInvoke) { isWaitingForRenderInvoke = false; invalidateViewMarkersInVisibleRegion(); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java index c09c926eb5b..9a381147104 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java @@ -62,7 +62,7 @@ class AnnotationManager { private Polygons polygons; private Polylines polylines; - AnnotationManager(NativeMapView view, MapView mapView, LongSparseArray annotationsArray, + AnnotationManager(MapView mapView, LongSparseArray annotationsArray, MarkerViewManager markerViewManager, IconManager iconManager, Annotations annotations, Markers markers, Polygons polygons, Polylines polylines) { this.mapView = mapView; @@ -73,10 +73,6 @@ class AnnotationManager { this.markers = markers; this.polygons = polygons; this.polylines = polylines; - if (view != null) { - // null checking needed for unit tests - view.addOnMapChangedListener(markerViewManager); - } } // TODO refactor MapboxMap out for Projection and Transform diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapChangeEventManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapChangeEventManager.java new file mode 100644 index 00000000000..40cdecdd6e0 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapChangeEventManager.java @@ -0,0 +1,356 @@ +package com.mapbox.mapboxsdk.maps; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import timber.log.Timber; + +/* + * Class responsible for forwarding map change events emitted by core. + *

+ * Events are dispatched to end-user defined callbacks and MapView.MapChangeResultHandler. + *

+ *

+ * This class is responsible for managing the deprecated MapView.OnMapChangeListener API. + *

+ */ +class MapChangeEventManager { + + // Support deprecated API + private final CopyOnWriteArrayList onMapChangedListeners = new CopyOnWriteArrayList<>(); + + // End-user callbacks + private final List onCameraWillChangeListenerList = new ArrayList<>(); + private final List onCameraIsChangingListenerList = new ArrayList<>(); + private final List onCameraDidChangeListenerList = new ArrayList<>(); + private final List onWillStartLoadingMapListenerList = new ArrayList<>(); + private final List onDidFinishLoadingMapListenerList = new ArrayList<>(); + private final List onDidFailLoadingMapListenerList = new ArrayList<>(); + private final List onWillStartRenderingFrameList = new ArrayList<>(); + private final List onDidFinishRenderingFrameList = new ArrayList<>(); + private final List onWillStartRenderingMapListenerList = new ArrayList<>(); + private final List onDidFinishRenderingMapListenerList = new ArrayList<>(); + private final List onDidFinishLoadingStyleListenerList = new ArrayList<>(); + private final List onSourceChangedListenerList = new ArrayList<>(); + + // Internal components callbacks + private final List onMapReadyCallbackList = new ArrayList<>(); + private MapboxMap mapboxMap; + private boolean initialLoad = true; + + void addOnCameraWillChangeListener(MapView.OnCameraWillChangeListener listener) { + onCameraWillChangeListenerList.add(listener); + } + + void removeOnCameraWillChangeListener(MapView.OnCameraWillChangeListener listener) { + if (onCameraWillChangeListenerList.contains(listener)) { + onCameraWillChangeListenerList.remove(listener); + } + } + + void addOnCameraIsChangingListener(MapView.OnCameraIsChangingListener listener) { + onCameraIsChangingListenerList.add(listener); + } + + void removeOnCameraIsChangingListener(MapView.OnCameraIsChangingListener listener) { + if (onCameraIsChangingListenerList.contains(listener)) { + onCameraIsChangingListenerList.remove(listener); + } + } + + void addOnCameraDidChangeListener(MapView.OnCameraDidChangeListener listener) { + onCameraDidChangeListenerList.add(listener); + } + + void removeOnCameraDidChangeListener(MapView.OnCameraDidChangeListener listener) { + if (onCameraDidChangeListenerList.contains(listener)) { + onCameraDidChangeListenerList.remove(listener); + } + } + + void addOnWillStartLoadingMapListener(MapView.OnWillStartLoadingMapListener listener) { + onWillStartLoadingMapListenerList.add(listener); + } + + void removeOnWillStartLoadingMapListener(MapView.OnWillStartLoadingMapListener listener) { + if (onWillStartLoadingMapListenerList.contains(listener)) { + onWillStartLoadingMapListenerList.remove(listener); + } + } + + void addOnDidFinishLoadingMapListener(MapView.OnDidFinishLoadingMapListener listener) { + onDidFinishLoadingMapListenerList.add(listener); + } + + void removeOnDidFinishLoadingMapListener(MapView.OnDidFinishLoadingMapListener listener) { + if (onDidFinishLoadingMapListenerList.contains(listener)) { + onDidFinishLoadingMapListenerList.remove(listener); + } + } + + void addOnDidFailLoadingMapListener(MapView.OnDidFailLoadingMapListener listener) { + onDidFailLoadingMapListenerList.add(listener); + } + + void removeOnDidFailLoadingMapListener(MapView.OnDidFailLoadingMapListener listener) { + if (onDidFailLoadingMapListenerList.contains(listener)) { + onDidFailLoadingMapListenerList.remove(listener); + } + } + + void addOnWillStartRenderingFrameListener(MapView.OnWillStartRenderingFrameListener listener) { + onWillStartRenderingFrameList.add(listener); + } + + void removeOnWillStartRenderingFrameListener(MapView.OnWillStartRenderingFrameListener listener) { + if (onWillStartRenderingFrameList.contains(listener)) { + onWillStartRenderingFrameList.remove(listener); + } + } + + void addOnDidFinishRenderingFrameListener(MapView.OnDidFinishRenderingFrameListener listener) { + onDidFinishRenderingFrameList.add(listener); + } + + void removeOnDidFinishRenderingFrameListener(MapView.OnDidFinishRenderingFrameListener listener) { + if (onDidFinishRenderingFrameList.contains(listener)) { + onDidFinishRenderingFrameList.remove(listener); + } + } + + void addOnWillStartRenderingMapListener(MapView.OnWillStartRenderingMapListener listener) { + onWillStartRenderingMapListenerList.add(listener); + } + + void removeOnWillStartRenderingMapListener(MapView.OnWillStartRenderingMapListener listener) { + if (onWillStartRenderingMapListenerList.contains(listener)) { + onWillStartRenderingMapListenerList.remove(listener); + } + } + + void addOnDidFinishRenderingMapListener(MapView.OnDidFinishRenderingMapListener listener) { + onDidFinishRenderingMapListenerList.add(listener); + } + + void removeOnDidFinishRenderingMapListener(MapView.OnDidFinishRenderingMapListener listener) { + if (onDidFinishRenderingMapListenerList.contains(listener)) { + onDidFinishRenderingMapListenerList.remove(listener); + } + } + + void addOnDidFinishLoadingStyleListener(MapView.OnDidFinishLoadingStyleListener listener) { + if (!onDidFinishLoadingStyleListenerList.contains(listener)) { + onDidFinishLoadingStyleListenerList.add(listener); + } + } + + void removeOnDidFinishLoadingStyleListener(MapView.OnDidFinishLoadingStyleListener listener) { + if (onDidFinishLoadingStyleListenerList.contains(listener)) { + onDidFinishLoadingStyleListenerList.remove(listener); + } + } + + void addOnSourceChangedListener(MapView.OnSourceChangedListener listener) { + onSourceChangedListenerList.add(listener); + } + + void removeOnSourceChangedListener(MapView.OnSourceChangedListener listener) { + if (onSourceChangedListenerList.contains(listener)) { + onSourceChangedListenerList.remove(listener); + } + } + + void onCameraWillChange(boolean animated) { + if (!onCameraWillChangeListenerList.isEmpty()) { + for (MapView.OnCameraWillChangeListener onCameraWillChangeListener : onCameraWillChangeListenerList) { + onCameraWillChangeListener.onCameraWillChange(animated); + } + } + onMapChange(animated ? MapView.REGION_WILL_CHANGE_ANIMATED : MapView.REGION_WILL_CHANGE); + } + + void onCameraIsChanging() { + if (!onCameraIsChangingListenerList.isEmpty()) { + for (MapView.OnCameraIsChangingListener onCameraIsChangingListener : onCameraIsChangingListenerList) { + if (onCameraIsChangingListener != null) { + onCameraIsChangingListener.onCameraIsChanging(); + } + } + } + if (mapboxMap != null) { + mapboxMap.onCameraChange(); + } + onMapChange(MapView.REGION_IS_CHANGING); + } + + void onCameraDidChange(boolean animated) { + if (!onCameraDidChangeListenerList.isEmpty()) { + for (MapView.OnCameraDidChangeListener onCameraDidChangeListener : onCameraDidChangeListenerList) { + onCameraDidChangeListener.onCameraDidChange(animated); + } + } + if (animated && mapboxMap != null) { + mapboxMap.onCameraDidChangeAnimated(); + } else if (mapboxMap != null) { + mapboxMap.onCameraChange(); + } + onMapChange(animated ? MapView.REGION_DID_CHANGE_ANIMATED : MapView.REGION_DID_CHANGE); + } + + void onWillStartLoadingMap() { + if (!onWillStartLoadingMapListenerList.isEmpty()) { + for (MapView.OnWillStartLoadingMapListener onWillStartLoadingMapListener : onWillStartLoadingMapListenerList) { + onWillStartLoadingMapListener.onWillStartLoadingMap(); + } + } + onMapChange(MapView.WILL_START_LOADING_MAP); + } + + void onDidFinishLoadingMap() { + if (!onDidFinishLoadingMapListenerList.isEmpty()) { + for (MapView.OnDidFinishLoadingMapListener onDidFinishLoadingMapListener : onDidFinishLoadingMapListenerList) { + onDidFinishLoadingMapListener.onDidFinishLoadingMap(); + } + } + + // we require an additional update after the map has finished loading + // in case an end user action hasn't been invoked at that time + mapboxMap.onCameraChange(); + onMapChange(MapView.DID_FINISH_LOADING_MAP); + } + + void onDidFailLoadingMap(String errorMessage) { + if (!onDidFailLoadingMapListenerList.isEmpty()) { + for (MapView.OnDidFailLoadingMapListener onDidFailLoadingMapListener : onDidFailLoadingMapListenerList) { + onDidFailLoadingMapListener.onDidFailLoadingMap(errorMessage); + } + } + onMapChange(MapView.DID_FAIL_LOADING_MAP); + } + + void onWillStartRenderingFrame() { + if (!onWillStartRenderingFrameList.isEmpty()) { + for (MapView.OnWillStartRenderingFrameListener frameListener : onWillStartRenderingFrameList) { + frameListener.onWillStartRenderingFrame(); + } + } + onMapChange(MapView.WILL_START_RENDERING_FRAME); + } + + void onDidFinishRenderingFrame(boolean partial) { + if (!onDidFinishRenderingFrameList.isEmpty()) { + for (MapView.OnDidFinishRenderingFrameListener frameListener : onDidFinishRenderingFrameList) { + frameListener.onDidFinishRenderingFrame(partial); + } + } + + if (partial && mapboxMap != null) { + mapboxMap.onDidFinishRenderingFrame(); + } else if (mapboxMap != null) { + mapboxMap.onDidFinishRenderingFrameFully(); + } + onMapChange(partial ? MapView.DID_FINISH_RENDERING_FRAME : MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED); + } + + void onWillStartRenderingMap() { + if (!onWillStartRenderingMapListenerList.isEmpty()) { + for (MapView.OnWillStartRenderingMapListener frameListener : onWillStartRenderingMapListenerList) { + frameListener.onWillStartRenderingMap(); + } + } + onMapChange(MapView.WILL_START_RENDERING_MAP); + } + + void onDidFinishRenderingMap(boolean partial) { + if (!onDidFinishRenderingMapListenerList.isEmpty()) { + for (MapView.OnDidFinishRenderingMapListener mapListener : onDidFinishRenderingMapListenerList) { + mapListener.onDidFinishRenderingMap(partial); + } + } + onMapChange(partial ? MapView.DID_FINISH_RENDERING_MAP : MapView.DID_FINISH_RENDERING_MAP_FULLY_RENDERED); + } + + void onDidFinishLoadingStyle() { + if (!onDidFinishLoadingStyleListenerList.isEmpty()) { + for (MapView.OnDidFinishLoadingStyleListener styleListener : onDidFinishLoadingStyleListenerList) { + styleListener.onDidFinishLoadingStyle(); + } + } + + if (initialLoad) { + initialLoad = false; + mapboxMap.onPreMapReady(); + onMapReady(); + mapboxMap.onPostMapReady(); + } + + onMapChange(MapView.DID_FINISH_LOADING_STYLE); + } + + void onSourceChanged(String id) { + if (!onSourceChangedListenerList.isEmpty()) { + for (MapView.OnSourceChangedListener onSourceChangedListener : onSourceChangedListenerList) { + onSourceChangedListener.onSourceChangedListener(id); + } + } + onMapChange(MapView.SOURCE_DID_CHANGE); + } + + // + // Deprecated API since 5.2.0 + // + + void onMapChange(int onMapChange) { + if (!onMapChangedListeners.isEmpty()) { + for (MapView.OnMapChangedListener onMapChangedListener : onMapChangedListeners) { + try { + onMapChangedListener.onMapChanged(onMapChange); + } catch (RuntimeException err) { + Timber.e("Exception (%s) in MapView.OnMapChangedListener: %s", err.getClass(), err.getMessage()); + } + } + } + } + + void addOnMapChangedListener(MapView.OnMapChangedListener listener) { + onMapChangedListeners.add(listener); + } + + void removeOnMapChangedListener(MapView.OnMapChangedListener listener) { + onMapChangedListeners.remove(listener); + } + + // + // internal api methods related to mapboxMap#getMapAsync() + // + + private void onMapReady() { + if (onMapReadyCallbackList.size() > 0) { + // Notify listeners, clear when done + Iterator iterator = onMapReadyCallbackList.iterator(); + while (iterator.hasNext()) { + OnMapReadyCallback callback = iterator.next(); + callback.onMapReady(mapboxMap); + iterator.remove(); + } + } + } + + boolean isInitialLoad() { + return initialLoad; + } + + void addOnMapReadyCallback(OnMapReadyCallback callback) { + onMapReadyCallbackList.add(callback); + } + + void clearOnMapReadyCallbacks() { + onMapReadyCallbackList.clear(); + } + + void bind(MapboxMap map) { + mapboxMap = map; + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index f4198cdde7f..a26ac5a9c1f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -39,15 +39,11 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; -import timber.log.Timber; - import static android.opengl.GLSurfaceView.RENDERMODE_WHEN_DIRTY; import static com.mapbox.mapboxsdk.maps.widgets.CompassView.TIME_MAP_NORTH_ANIMATION; import static com.mapbox.mapboxsdk.maps.widgets.CompassView.TIME_WAIT_IDLE; @@ -68,10 +64,10 @@ */ public class MapView extends FrameLayout { - private final MapCallback mapCallback = new MapCallback(); - private MapboxMap mapboxMap; + private final MapChangeEventManager mapChangeEventManager = new MapChangeEventManager(); private NativeMapView nativeMapView; + private MapboxMap mapboxMap; private MapboxMapOptions mapboxMapOptions; private boolean destroyed; @@ -85,7 +81,6 @@ public class MapView extends FrameLayout { private MapKeyListener mapKeyListener; private MapZoomButtonController mapZoomButtonController; private Bundle savedInstanceState; - private final CopyOnWriteArrayList onMapChangedListeners = new CopyOnWriteArrayList<>(); private GLSurfaceView glSurfaceView; @@ -146,7 +141,6 @@ public void onGlobalLayout() { private void initialiseMap() { Context context = getContext(); - addOnMapChangedListener(mapCallback); // callback for focal point invalidation final FocalPointInvalidator focalPointInvalidator = new FocalPointInvalidator(); @@ -175,7 +169,7 @@ private void initialiseMap() { Markers markers = new MarkerContainer(nativeMapView, this, annotationsArray, iconManager, markerViewManager); Polygons polygons = new PolygonContainer(nativeMapView, annotationsArray); Polylines polylines = new PolylineContainer(nativeMapView, annotationsArray); - AnnotationManager annotationManager = new AnnotationManager(nativeMapView, this, annotationsArray, + AnnotationManager annotationManager = new AnnotationManager(this, annotationsArray, markerViewManager, iconManager, annotations, markers, polygons, polylines); Transform transform = new Transform(nativeMapView, annotationManager.getMarkerViewManager(), trackingSettings, cameraChangeDispatcher); @@ -184,7 +178,8 @@ private void initialiseMap() { registerTouchListener, annotationManager, cameraChangeDispatcher); focalPointInvalidator.addListener(mapboxMap.createFocalPointChangeListener()); - mapCallback.attachMapboxMap(mapboxMap); + // map change events + mapChangeEventManager.bind(mapboxMap); // user input mapGestureDetector = new MapGestureDetector(context, transform, proj, uiSettings, trackingSettings, @@ -316,7 +311,7 @@ public void run() { glSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY); glSurfaceView.setVisibility(View.VISIBLE); - nativeMapView = new NativeMapView(this, mapRenderer); + nativeMapView = new NativeMapView(this, mapRenderer, mapChangeEventManager); nativeMapView.resizeView(getMeasuredWidth(), getMeasuredHeight()); } @@ -383,7 +378,7 @@ public void onStop() { @UiThread public void onDestroy() { destroyed = true; - mapCallback.clearOnMapReadyCallbacks(); + mapChangeEventManager.clearOnMapReadyCallbacks(); nativeMapView.destroy(); nativeMapView = null; } @@ -539,16 +534,6 @@ protected void onVisibilityChanged(@NonNull View changedView, int visibility) { // Map events // - void onMapChange(int rawChange) { - for (MapView.OnMapChangedListener onMapChangedListener : onMapChangedListeners) { - try { - onMapChangedListener.onMapChanged(rawChange); - } catch (RuntimeException err) { - Timber.e(err, "Exception in MapView.OnMapChangedListener"); - } - } - } - /** *

* Add a callback that's invoked when the displayed map view changes. @@ -557,10 +542,17 @@ void onMapChange(int rawChange) { * * @param listener The callback that's invoked on every frame rendered to the map view. * @see MapView#removeOnMapChangedListener(OnMapChangedListener) + * @deprecated use dedicated map change event callbacks instead. See {@link OnCameraWillChangeListener}, + * {@link OnSourceChangedListener}, {@link OnCameraDidChangeListener}, {@link OnCameraIsChangingListener}, + * {@link OnDidFailLoadingMapListener}, {@link OnDidFinishLoadingMapListener}, + * {@link OnDidFinishLoadingStyleListener}, {@link OnDidFinishRenderingFrameListener}, + * {@link OnDidFinishRenderingMapListener}, {@link OnWillStartLoadingMapListener}, + * {@link OnWillStartRenderingFrameListener} and {@link OnWillStartRenderingMapListener}. */ + @Deprecated public void addOnMapChangedListener(@Nullable OnMapChangedListener listener) { if (listener != null) { - onMapChangedListeners.add(listener); + mapChangeEventManager.addOnMapChangedListener(listener); } } @@ -569,10 +561,17 @@ public void addOnMapChangedListener(@Nullable OnMapChangedListener listener) { * * @param listener The previously added callback to remove. * @see MapView#addOnMapChangedListener(OnMapChangedListener) + * @deprecated use dedicated map change event callbacks instead. See {@link OnCameraWillChangeListener}, + * {@link OnSourceChangedListener}, {@link OnCameraDidChangeListener}, {@link OnCameraIsChangingListener}, + * {@link OnDidFailLoadingMapListener}, {@link OnDidFinishLoadingMapListener}, + * {@link OnDidFinishLoadingStyleListener}, {@link OnDidFinishRenderingFrameListener}, + * {@link OnDidFinishRenderingMapListener}, {@link OnWillStartLoadingMapListener}, + * {@link OnWillStartRenderingFrameListener} and {@link OnWillStartRenderingMapListener}. */ + @Deprecated public void removeOnMapChangedListener(@Nullable OnMapChangedListener listener) { if (listener != null) { - onMapChangedListeners.remove(listener); + mapChangeEventManager.removeOnMapChangedListener(listener); } } @@ -583,11 +582,11 @@ public void removeOnMapChangedListener(@Nullable OnMapChangedListener listener) */ @UiThread public void getMapAsync(final OnMapReadyCallback callback) { - if (!mapCallback.isInitialLoad() && callback != null) { + if (!mapChangeEventManager.isInitialLoad() && callback != null) { callback.onMapReady(mapboxMap); } else { if (callback != null) { - mapCallback.addOnMapReadyCallback(callback); + mapChangeEventManager.addOnMapReadyCallback(callback); } } } @@ -814,6 +813,381 @@ void setMapboxMap(MapboxMap mapboxMap) { */ public static final int SOURCE_DID_CHANGE = 15; + /** + * Set a callback that's invoked when the camera region will change. + * + * @param listener The callback that's invoked when the camera region will change + */ + public void addOnCameraWillChangeListener(OnCameraWillChangeListener listener) { + mapChangeEventManager.addOnCameraWillChangeListener(listener); + } + + /** + * Remove a callback that's invoked when the camera region will change. + * + * @param listener The callback that's invoked when the camera region will change + */ + public void removeOnCameraWillChangeListener(OnCameraWillChangeListener listener) { + mapChangeEventManager.removeOnCameraWillChangeListener(listener); + } + + /** + * Set a callback that's invoked when the camera is changing. + * + * @param listener The callback that's invoked when the camera is changing + */ + public void addOnCameraIsChangingListener(OnCameraIsChangingListener listener) { + mapChangeEventManager.addOnCameraIsChangingListener(listener); + } + + /** + * Remove a callback that's invoked when the camera is changing. + * + * @param listener The callback that's invoked when the camera is changing + */ + public void removeOnCameraIsChangingListener(OnCameraIsChangingListener listener) { + mapChangeEventManager.removeOnCameraIsChangingListener(listener); + } + + /** + * Set a callback that's invoked when the camera region did change. + * + * @param listener The callback that's invoked when the camera region did change + */ + public void addOnCameraDidChangeListener(OnCameraDidChangeListener listener) { + mapChangeEventManager.addOnCameraDidChangeListener(listener); + } + + /** + * Set a callback that's invoked when the camera region did change. + * + * @param listener The callback that's invoked when the camera region did change + */ + public void removeOnCameraDidChangeListener(OnCameraDidChangeListener listener) { + mapChangeEventManager.removeOnCameraDidChangeListener(listener); + } + + /** + * Set a callback that's invoked when the map will start loading. + * + * @param listener The callback that's invoked when the map will start loading + */ + public void addOnWillStartLoadingMapListener(OnWillStartLoadingMapListener listener) { + mapChangeEventManager.addOnWillStartLoadingMapListener(listener); + } + + /** + * Set a callback that's invoked when the map will start loading. + * + * @param listener The callback that's invoked when the map will start loading + */ + public void removeOnWillStartLoadingMapListener(OnWillStartLoadingMapListener listener) { + mapChangeEventManager.removeOnWillStartLoadingMapListener(listener); + } + + /** + * Set a callback that's invoked when the map has finished loading. + * + * @param listener The callback that's invoked when the map has finished loading + */ + public void addOnDidFinishLoadingMapListener(OnDidFinishLoadingMapListener listener) { + mapChangeEventManager.addOnDidFinishLoadingMapListener(listener); + } + + /** + * Set a callback that's invoked when the map has finished loading. + * + * @param listener The callback that's invoked when the map has finished loading + */ + public void removeOnDidFinishLoadingMapListener(OnDidFinishLoadingMapListener listener) { + mapChangeEventManager.removeOnDidFinishLoadingMapListener(listener); + } + + /** + * Set a callback that's invoked when the map failed to load. + * + * @param listener The callback that's invoked when the map failed to load + */ + public void addOnDidFailLoadingMapListener(OnDidFailLoadingMapListener listener) { + mapChangeEventManager.addOnDidFailLoadingMapListener(listener); + } + + /** + * Set a callback that's invoked when the map failed to load. + * + * @param listener The callback that's invoked when the map failed to load + */ + public void removeOnDidFailLoadingMapListener(OnDidFailLoadingMapListener listener) { + mapChangeEventManager.removeOnDidFailLoadingMapListener(listener); + } + + /** + * Set a callback that's invoked when the map will start rendering a frame. + * + * @param listener The callback that's invoked when the camera will start rendering a frame + */ + public void addOnWillStartRenderingFrameListener(OnWillStartRenderingFrameListener listener) { + mapChangeEventManager.addOnWillStartRenderingFrameListener(listener); + } + + /** + * Set a callback that's invoked when the map will start rendering a frame. + * + * @param listener The callback that's invoked when the camera will start rendering a frame + */ + public void removeOnWillStartRenderingFrameListener(OnWillStartRenderingFrameListener listener) { + mapChangeEventManager.removeOnWillStartRenderingFrameListener(listener); + } + + /** + * Set a callback that's invoked when the map has finished rendering a frame. + * + * @param listener The callback that's invoked when the map has finished rendering a frame + */ + public void addOnDidFinishRenderingFrameListener(OnDidFinishRenderingFrameListener listener) { + mapChangeEventManager.addOnDidFinishRenderingFrameListener(listener); + } + + /** + * Set a callback that's invoked when the map has finished rendering a frame. + * + * @param listener The callback that's invoked when the map has finished rendering a frame + */ + public void removeOnDidFinishRenderingFrameListener(OnDidFinishRenderingFrameListener listener) { + mapChangeEventManager.removeOnDidFinishRenderingFrameListener(listener); + } + + /** + * Set a callback that's invoked when the map will start rendering. + * + * @param listener The callback that's invoked when the map will start rendering + */ + public void addOnWillStartRenderingMapListener(OnWillStartRenderingMapListener listener) { + mapChangeEventManager.addOnWillStartRenderingMapListener(listener); + } + + /** + * Set a callback that's invoked when the map will start rendering. + * + * @param listener The callback that's invoked when the map will start rendering + */ + public void removeOnWillStartRenderingMapListener(OnWillStartRenderingMapListener listener) { + mapChangeEventManager.removeOnWillStartRenderingMapListener(listener); + } + + /** + * Set a callback that's invoked when the map has finished rendering. + * + * @param listener The callback that's invoked when the map has finished rendering + */ + public void addOnDidFinishRenderingMapListener(OnDidFinishRenderingMapListener listener) { + mapChangeEventManager.addOnDidFinishRenderingMapListener(listener); + } + + /** + * Remove a callback that's invoked when the map has finished rendering. + * + * @param listener The callback that's invoked when the map has finished rendering + */ + public void removeOnDidFinishRenderingMapListener(OnDidFinishRenderingMapListener listener) { + mapChangeEventManager.removeOnDidFinishRenderingMapListener(listener); + } + + /** + * Set a callback that's invoked when the style has finished loading. + * + * @param listener The callback that's invoked when the style has finished loading + */ + public void addOnDidFinishLoadingStyleListener(OnDidFinishLoadingStyleListener listener) { + mapChangeEventManager.addOnDidFinishLoadingStyleListener(listener); + } + + /** + * Set a callback that's invoked when the style has finished loading. + * + * @param listener The callback that's invoked when the style has finished loading + */ + public void removeOnDidFinishLoadingStyleListener(OnDidFinishLoadingStyleListener listener) { + mapChangeEventManager.removeOnDidFinishLoadingStyleListener(listener); + } + + /** + * Set a callback that's invoked when a map source has changed. + * + * @param listener The callback that's invoked when the source has changed + */ + public void addOnSourceChangedListener(OnSourceChangedListener listener) { + mapChangeEventManager.addOnSourceChangedListener(listener); + } + + /** + * Set a callback that's invoked when a map source has changed. + * + * @param listener The callback that's invoked when the source has changed + */ + public void removeOnSourceChangedListener(OnSourceChangedListener listener) { + mapChangeEventManager.removeOnSourceChangedListener(listener); + } + + public interface OnCameraWillChangeListener { + + /** + * Called when the camera region will change. + */ + void onCameraWillChange(boolean animated); + } + + /** + * Interface definition for a callback to be invoked when the camera is changing. + *

+ * {@link MapView#addOnCameraIsChangingListener(OnCameraIsChangingListener)} + *

+ */ + public interface OnCameraIsChangingListener { + /** + * Called when the camera is changing. + */ + void onCameraIsChanging(); + } + + /** + * Interface definition for a callback to be invoked when the map region did change. + *

+ * {@link MapView#addOnCameraDidChangeListener(OnCameraDidChangeListener)} + *

+ */ + public interface OnCameraDidChangeListener { + /** + * Called when the camera did change. + */ + void onCameraDidChange(boolean animated); + } + + /** + * Interface definition for a callback to be invoked when the map will start loading. + *

+ * {@link MapView#addOnWillStartLoadingMapListener(OnWillStartLoadingMapListener)} + *

+ */ + public interface OnWillStartLoadingMapListener { + /** + * Called when the map will start loading. + */ + void onWillStartLoadingMap(); + } + + /** + * Interface definition for a callback to be invoked when the map finished loading. + *

+ * {@link MapView#addOnDidFinishLoadingMapListener(OnDidFinishLoadingMapListener)} + *

+ */ + public interface OnDidFinishLoadingMapListener { + /** + * Called when the map has finished loading. + */ + void onDidFinishLoadingMap(); + } + + /** + * Interface definition for a callback to be invoked when the map is changing. + *

+ * {@link MapView#addOnDidFailLoadingMapListener(OnDidFailLoadingMapListener)} + *

+ */ + public interface OnDidFailLoadingMapListener { + /** + * Called when the map failed to load. + * + * @param errorMessage The reason why the map failed to load + */ + void onDidFailLoadingMap(String errorMessage); + } + + /** + * Interface definition for a callback to be invoked when the map will start rendering a frame. + *

+ * {@link MapView#addOnWillStartRenderingFrameListener(OnWillStartRenderingFrameListener)} + *

+ */ + public interface OnWillStartRenderingFrameListener { + /** + * Called when the map will start rendering a frame. + */ + void onWillStartRenderingFrame(); + } + + /** + * Interface definition for a callback to be invoked when the map finished rendering a frame. + *

+ * {@link MapView#addOnDidFinishRenderingFrameListener(OnDidFinishRenderingFrameListener)} + *

+ */ + public interface OnDidFinishRenderingFrameListener { + /** + * Called when the map has finished rendering a frame + * + * @param partial true if map is still rendering frames, false if all frames have been rendered + */ + void onDidFinishRenderingFrame(boolean partial); + } + + /** + * Interface definition for a callback to be invoked when the map will start rendering the map. + *

+ * {@link MapView#addOnDidFailLoadingMapListener(OnDidFailLoadingMapListener)} + *

+ */ + public interface OnWillStartRenderingMapListener { + /** + * Called when the map will start rendering. + */ + void onWillStartRenderingMap(); + } + + /** + * Interface definition for a callback to be invoked when the map is changing. + *

+ * {@link MapView#addOnDidFinishRenderingMapListener(OnDidFinishRenderingMapListener)} + *

+ */ + public interface OnDidFinishRenderingMapListener { + /** + * Called when the map has finished rendering. + * + * @param partial true if map is partially rendered, false if fully rendered + */ + void onDidFinishRenderingMap(boolean partial); + } + + /** + * Interface definition for a callback to be invoked when the map has loaded the style. + *

+ * {@link MapView#addOnDidFailLoadingMapListener(OnDidFailLoadingMapListener)} + *

+ */ + public interface OnDidFinishLoadingStyleListener { + /** + * Called when a style has finished loading. + */ + void onDidFinishLoadingStyle(); + } + + /** + * Interface definition for a callback to be invoked when a map source has changed. + *

+ * {@link MapView#addOnDidFailLoadingMapListener(OnDidFailLoadingMapListener)} + *

+ */ + public interface OnSourceChangedListener { + /** + * Called when a map source has changed. + * + * @param id the id of the source that has changed + */ + void onSourceChangedListener(String id); + } + /** * Interface definition for a callback to be invoked when the displayed map view changes. *

@@ -822,7 +1196,14 @@ void setMapboxMap(MapboxMap mapboxMap) { * * @see MapView#addOnMapChangedListener(OnMapChangedListener) * @see MapView.MapChange + * @deprecated Use dedicated callbacks instead. See {@link OnCameraWillChangeListener}, + * {@link OnSourceChangedListener}, {@link OnCameraDidChangeListener}, {@link OnCameraIsChangingListener}, + * {@link OnDidFailLoadingMapListener}, {@link OnDidFinishLoadingMapListener}, + * {@link OnDidFinishLoadingStyleListener}, {@link OnDidFinishRenderingFrameListener}, + * {@link OnDidFinishRenderingMapListener}, {@link OnWillStartLoadingMapListener}, + * {@link OnWillStartRenderingFrameListener} and {@link OnWillStartRenderingMapListener}. */ + @Deprecated public interface OnMapChangedListener { /** * Called when the displayed map view changes. @@ -949,53 +1330,4 @@ private void setZoom(double zoomLevel, @Nullable PointF focalPoint, @NonNull Tra } } } - - private static class MapCallback implements OnMapChangedListener { - - private MapboxMap mapboxMap; - private final List onMapReadyCallbackList = new ArrayList<>(); - private boolean initialLoad = true; - - void attachMapboxMap(MapboxMap mapboxMap) { - this.mapboxMap = mapboxMap; - } - - @Override - public void onMapChanged(@MapChange int change) { - if (change == DID_FINISH_LOADING_STYLE && initialLoad) { - initialLoad = false; - mapboxMap.onPreMapReady(); - onMapReady(); - mapboxMap.onPostMapReady(); - } else if (change == DID_FINISH_RENDERING_FRAME || change == DID_FINISH_RENDERING_FRAME_FULLY_RENDERED) { - mapboxMap.onUpdateFullyRendered(); - } else if (change == REGION_IS_CHANGING || change == REGION_DID_CHANGE || change == DID_FINISH_LOADING_MAP) { - mapboxMap.onUpdateRegionChange(); - } - } - - private void onMapReady() { - if (onMapReadyCallbackList.size() > 0) { - // Notify listeners, clear when done - Iterator iterator = onMapReadyCallbackList.iterator(); - while (iterator.hasNext()) { - OnMapReadyCallback callback = iterator.next(); - callback.onMapReady(mapboxMap); - iterator.remove(); - } - } - } - - boolean isInitialLoad() { - return initialLoad; - } - - void addOnMapReadyCallback(OnMapReadyCallback callback) { - onMapReadyCallbackList.add(callback); - } - - void clearOnMapReadyCallbacks() { - onMapReadyCallbackList.clear(); - } - } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index 6a88470ee76..aae00acefd1 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -188,21 +188,32 @@ void onPostMapReady() { /** * Called when the region is changing or has changed. */ - void onUpdateRegionChange() { + void onCameraChange() { trackingSettings.update(); annotationManager.update(); } + /** + * Called when the region did change animated. + */ + void onCameraDidChangeAnimated() { + transform.onCameraDidChangeAnimated(); + } + /** * Called when the map frame is fully rendered. */ - void onUpdateFullyRendered() { + void onDidFinishRenderingFrame() { CameraPosition cameraPosition = transform.invalidateCameraPosition(); if (cameraPosition != null) { uiSettings.update(cameraPosition); } } + void onDidFinishRenderingFrameFully() { + annotationManager.getMarkerViewManager().onDidFinishRenderingFrameFully(); + } + // Style /** @@ -1082,6 +1093,7 @@ public void setStyleUrl(@NonNull String url) { */ public void setStyleUrl(@NonNull final String url, @Nullable final OnStyleLoadedListener callback) { if (callback != null) { + // TODO refactor out nativeMapView.addOnMapChangedListener(new MapView.OnMapChangedListener() { @Override public void onMapChanged(@MapView.MapChange int change) { @@ -1670,9 +1682,9 @@ public CameraPosition getCameraForLatLngBounds(@Nullable LatLngBounds latLngBoun /** * Get a camera position that fits a provided shape with a given bearing and padding. * - * @param geometry the geometry to constrain the map with - * @param bearing the bearing at which to compute the geometry's bounds - * @param padding the padding to apply to the bounds + * @param geometry the geometry to constrain the map with + * @param bearing the bearing at which to compute the geometry's bounds + * @param padding the padding to apply to the bounds * @return the camera position that fits the bounds and padding */ public CameraPosition getCameraForGeometry(Geometry geometry, double bearing, int[] padding) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java index bd8a54783ef..7b532bcb00e 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java @@ -62,6 +62,8 @@ final class NativeMapView { // Listener invoked to return a bitmap of the map private MapboxMap.SnapshotReadyCallback snapshotReadyCallback; + private MapChangeEventManager mapChangeEventManager; + static { LibraryLoader.load(); } @@ -70,9 +72,10 @@ final class NativeMapView { // Constructors // - public NativeMapView(final MapView mapView, MapRenderer mapRenderer) { + public NativeMapView(final MapView mapView, MapRenderer mapRenderer, MapChangeEventManager mapChangeEventManager) { this.mapRenderer = mapRenderer; this.mapView = mapView; + this.mapChangeEventManager = mapChangeEventManager; Context context = mapView.getContext(); fileSource = FileSource.getInstance(context); @@ -829,10 +832,52 @@ public float getPixelRatio() { // Callbacks // - protected void onMapChanged(int rawChange) { - if (mapView != null) { - mapView.onMapChange(rawChange); - } + protected void onCameraWillChange(boolean animated) { + mapChangeEventManager.onCameraWillChange(animated); + } + + protected void onCameraIsChanging() { + mapChangeEventManager.onCameraIsChanging(); + } + + protected void onCameraDidChange(boolean animated) { + mapChangeEventManager.onCameraDidChange(animated); + } + + protected void onWillStartLoadingMap() { + mapChangeEventManager.onWillStartLoadingMap(); + } + + protected void onDidFinishLoadingMap() { + mapChangeEventManager.onDidFinishLoadingMap(); + } + + protected void onDidFailLoadingMap(String erorMessage) { + mapChangeEventManager.onDidFailLoadingMap(erorMessage); + } + + protected void onWillStartRenderingFrame() { + mapChangeEventManager.onWillStartRenderingFrame(); + } + + protected void onDidFinishRenderingFrame(boolean partial) { + mapChangeEventManager.onDidFinishRenderingFrame(partial); + } + + protected void onWillStartRenderingMap() { + mapChangeEventManager.onWillStartRenderingMap(); + } + + protected void onDidFinishRenderingMap(boolean partial) { + mapChangeEventManager.onDidFinishRenderingMap(partial); + } + + protected void onDidFinishLoadingStyle() { + mapChangeEventManager.onDidFinishLoadingStyle(); + } + + protected void onSourceChanged(String id) { + mapChangeEventManager.onSourceChanged(id); } protected void onSnapshotReady(Bitmap mapContent) { @@ -1050,11 +1095,11 @@ int getHeight() { // void addOnMapChangedListener(@NonNull MapView.OnMapChangedListener listener) { - mapView.addOnMapChangedListener(listener); + mapChangeEventManager.addOnMapChangedListener(listener); } void removeOnMapChangedListener(@NonNull MapView.OnMapChangedListener listener) { - mapView.removeOnMapChangedListener(listener); + mapChangeEventManager.removeOnMapChangedListener(listener); } // diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java index 6f63c2eba8f..61c594a6649 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java @@ -15,7 +15,6 @@ import timber.log.Timber; -import static com.mapbox.mapboxsdk.maps.MapView.REGION_DID_CHANGE_ANIMATED; import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener; /** @@ -25,7 +24,7 @@ * {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraChangeListener}. *

*/ -final class Transform implements MapView.OnMapChangedListener { +final class Transform { private final NativeMapView mapView; private final MarkerViewManager markerViewManager; @@ -38,6 +37,7 @@ final class Transform implements MapView.OnMapChangedListener { private MapboxMap.OnCameraChangeListener onCameraChangeListener; private CameraChangeDispatcher cameraChangeDispatcher; + private boolean observeAnimatedCameraChange; Transform(NativeMapView mapView, MarkerViewManager markerViewManager, TrackingSettings trackingSettings, CameraChangeDispatcher cameraChangeDispatcher) { @@ -77,16 +77,15 @@ void updateCameraPosition(@NonNull CameraPosition position) { markerViewManager.setTilt((float) position.tilt); } - @Override - public void onMapChanged(@MapView.MapChange int change) { - if (change == REGION_DID_CHANGE_ANIMATED) { + public void onCameraDidChangeAnimated() { + if (observeAnimatedCameraChange) { + observeAnimatedCameraChange = false; updateCameraPosition(invalidateCameraPosition()); if (cameraCancelableCallback != null) { cameraCancelableCallback.onFinish(); cameraCancelableCallback = null; } cameraChangeDispatcher.onCameraIdle(); - mapView.removeOnMapChangedListener(this); } } @@ -117,7 +116,7 @@ final void easeCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, if (callback != null) { cameraCancelableCallback = callback; } - mapView.addOnMapChangedListener(this); + observeAnimatedCameraChange = true; mapView.easeTo(cameraPosition.bearing, cameraPosition.target, durationMs, cameraPosition.tilt, cameraPosition.zoom, easingInterpolator); } @@ -135,7 +134,7 @@ final void animateCamera(MapboxMap mapboxMap, CameraUpdate update, int durationM if (callback != null) { cameraCancelableCallback = callback; } - mapView.addOnMapChangedListener(this); + observeAnimatedCameraChange = true; mapView.flyTo(cameraPosition.bearing, cameraPosition.target, durationMs, cameraPosition.tilt, cameraPosition.zoom); } @@ -227,6 +226,7 @@ void setZoom(double zoom, @NonNull PointF focalPoint) { void setZoom(double zoom, @NonNull PointF focalPoint, long duration) { mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() { + // TODO refactor out @Override public void onMapChanged(int change) { if (change == MapView.REGION_DID_CHANGE_ANIMATED) { @@ -327,6 +327,7 @@ void zoomBy(double z, float x, float y) { void moveBy(double offsetX, double offsetY, long duration) { if (duration > 0) { + // TODO refactor out mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() { @Override public void onMapChanged(int change) { diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/AnnotationManagerTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/AnnotationManagerTest.java index 0d592f9bb37..6e74e85ad0b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/AnnotationManagerTest.java +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/AnnotationManagerTest.java @@ -32,7 +32,7 @@ public void checksAddAMarker() throws Exception { Markers markers = new MarkerContainer(aNativeMapView, aMapView, annotationsArray, aIconManager, aMarkerViewManager); Polygons polygons = new PolygonContainer(aNativeMapView, annotationsArray); Polylines polylines = new PolylineContainer(aNativeMapView, annotationsArray); - AnnotationManager annotationManager = new AnnotationManager(aNativeMapView, aMapView, annotationsArray, + AnnotationManager annotationManager = new AnnotationManager(aMapView, annotationsArray, aMarkerViewManager, aIconManager, annotations, markers, polygons, polylines); Marker aMarker = mock(Marker.class); long aId = 5L; @@ -58,7 +58,7 @@ public void checksAddMarkers() throws Exception { Markers markers = new MarkerContainer(aNativeMapView, aMapView, annotationsArray, aIconManager, aMarkerViewManager); Polygons polygons = new PolygonContainer(aNativeMapView, annotationsArray); Polylines polylines = new PolylineContainer(aNativeMapView, annotationsArray); - AnnotationManager annotationManager = new AnnotationManager(aNativeMapView, aMapView, annotationsArray, + AnnotationManager annotationManager = new AnnotationManager(aMapView, annotationsArray, aMarkerViewManager, aIconManager, annotations, markers, polygons, polylines); long firstId = 1L; long secondId = 2L; diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapChangeEventManagerTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapChangeEventManagerTest.java new file mode 100644 index 00000000000..f03e5e977f0 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapChangeEventManagerTest.java @@ -0,0 +1,273 @@ +package com.mapbox.mapboxsdk.maps; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +/** + * Tests integration of MapChangeDispatcher and see if events are correctly forwarded. + */ +public class MapChangeEventManagerTest { + + private static final String TEST_STRING = "mapChangeRandom"; + + private MapChangeEventManager mapChangeEventManager; + + @Mock + private MapView.OnCameraWillChangeListener onCameraWillChangeListener; + + @Mock + private MapView.OnCameraDidChangeListener onCameraDidChangeListener; + + @Mock + private MapView.OnCameraIsChangingListener onCameraIsChangingListener; + + @Mock + private MapView.OnWillStartLoadingMapListener onWillStartLoadingMapListener; + + @Mock + private MapView.OnDidFinishLoadingMapListener onDidFinishLoadingMapListener; + + @Mock + private MapView.OnDidFailLoadingMapListener onDidFailLoadingMapListener; + + @Mock + private MapView.OnWillStartRenderingFrameListener onWillStartRenderingFrameListener; + + @Mock + private MapView.OnDidFinishRenderingFrameListener onDidFinishRenderingFrameListener; + + @Mock + private MapView.OnWillStartRenderingMapListener onWillStartRenderingMapListener; + + @Mock + private MapView.OnDidFinishRenderingMapListener onDidFinishRenderingMapListener; + + @Mock + private MapView.OnDidFinishLoadingStyleListener onDidFinishLoadingStyleListener; + + @Mock + private MapView.OnSourceChangedListener onSourceChangedListener; + + @Mock + private MapView.OnMapChangedListener onMapChangedListener; + + @Mock + private MapView.MapChangeInternalHandler mapCallback; + + @Before + public void beforeTest() { + MockitoAnnotations.initMocks(this); + mapChangeEventManager = new MapChangeEventManager(); + mapChangeEventManager.addOnMapChangedListener(onMapChangedListener); + mapChangeEventManager.bind(mapCallback); + } + + @Test + public void testOnCameraRegionWillChangeListener() throws Exception { + mapChangeEventManager.addOnCameraWillChangeListener(onCameraWillChangeListener); + mapChangeEventManager.onCameraWillChange(false); + verify(onCameraWillChangeListener).onCameraWillChange(false); + verify(onMapChangedListener).onMapChanged(MapView.REGION_WILL_CHANGE); + mapChangeEventManager.removeOnCameraWillChangeListener(onCameraWillChangeListener); + mapChangeEventManager.onCameraWillChange(false); + verify(onCameraWillChangeListener).onCameraWillChange(false); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.REGION_WILL_CHANGE); + } + + @Test + public void testOnCameraRegionWillChangeAnimatedListener() throws Exception { + mapChangeEventManager.addOnCameraWillChangeListener(onCameraWillChangeListener); + mapChangeEventManager.onCameraWillChange(true); + verify(onCameraWillChangeListener).onCameraWillChange(true); + verify(onMapChangedListener).onMapChanged(MapView.REGION_WILL_CHANGE_ANIMATED); + mapChangeEventManager.removeOnCameraWillChangeListener(onCameraWillChangeListener); + mapChangeEventManager.onCameraWillChange(true); + verify(onCameraWillChangeListener).onCameraWillChange(true); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.REGION_WILL_CHANGE_ANIMATED); + } + + @Test + public void testOnCameraIsChangingListener() throws Exception { + mapChangeEventManager.addOnCameraIsChangingListener(onCameraIsChangingListener); + mapChangeEventManager.onCameraIsChanging(); + verify(onCameraIsChangingListener).onCameraIsChanging(); + verify(onMapChangedListener).onMapChanged(MapView.REGION_IS_CHANGING); + verify(mapCallback).onCameraIsChanging(); + mapChangeEventManager.removeOnCameraIsChangingListener(onCameraIsChangingListener); + mapChangeEventManager.onCameraIsChanging(); + verify(onCameraIsChangingListener).onCameraIsChanging(); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.REGION_IS_CHANGING); + } + + @Test + public void testOnCameraRegionDidChangeListener() throws Exception { + mapChangeEventManager.addOnCameraDidChangeListener(onCameraDidChangeListener); + mapChangeEventManager.onCameraDidChange(false); + verify(onCameraDidChangeListener).onCameraDidChange(false); + verify(onMapChangedListener).onMapChanged(MapView.REGION_DID_CHANGE); + verify(mapCallback).onCameraDidChange(false); + mapChangeEventManager.removeOnCameraDidChangeListener(onCameraDidChangeListener); + mapChangeEventManager.onCameraDidChange(false); + verify(onCameraDidChangeListener).onCameraDidChange(false); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.REGION_DID_CHANGE); + } + + @Test + public void testOnCameraRegionDidChangeAnimatedListener() throws Exception { + mapChangeEventManager.addOnCameraDidChangeListener(onCameraDidChangeListener); + mapChangeEventManager.onCameraDidChange(true); + verify(onCameraDidChangeListener).onCameraDidChange(true); + verify(onMapChangedListener).onMapChanged(MapView.REGION_DID_CHANGE_ANIMATED); + verify(mapCallback).onCameraDidChange(true); + mapChangeEventManager.removeOnCameraDidChangeListener(onCameraDidChangeListener); + mapChangeEventManager.onCameraDidChange(true); + verify(onCameraDidChangeListener).onCameraDidChange(true); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.REGION_DID_CHANGE_ANIMATED); + verify(mapCallback, times(2)).onCameraDidChange(true); + } + + @Test + public void testOnWillStartLoadingMapListener() throws Exception { + mapChangeEventManager.addOnWillStartLoadingMapListener(onWillStartLoadingMapListener); + mapChangeEventManager.onWillStartLoadingMap(); + verify(onWillStartLoadingMapListener).onWillStartLoadingMap(); + verify(onMapChangedListener).onMapChanged(MapView.WILL_START_LOADING_MAP); + mapChangeEventManager.removeOnWillStartLoadingMapListener(onWillStartLoadingMapListener); + mapChangeEventManager.onWillStartLoadingMap(); + verify(onWillStartLoadingMapListener).onWillStartLoadingMap(); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.WILL_START_LOADING_MAP); + } + + @Test + public void testOnDidFinishLoadingMapListener() throws Exception { + mapChangeEventManager.addOnDidFinishLoadingMapListener(onDidFinishLoadingMapListener); + mapChangeEventManager.onDidFinishLoadingMap(); + verify(onDidFinishLoadingMapListener).onDidFinishLoadingMap(); + verify(onMapChangedListener).onMapChanged(MapView.DID_FINISH_LOADING_MAP); + verify(mapCallback).onDidFinishLoadingMap(); + mapChangeEventManager.removeOnDidFinishLoadingMapListener(onDidFinishLoadingMapListener); + mapChangeEventManager.onDidFinishLoadingMap(); + verify(onDidFinishLoadingMapListener).onDidFinishLoadingMap(); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.DID_FINISH_LOADING_MAP); + verify(mapCallback, times(2)).onDidFinishLoadingMap(); + } + + @Test + public void testOnDidFailLoadingMapListener() throws Exception { + mapChangeEventManager.addOnDidFailLoadingMapListener(onDidFailLoadingMapListener); + mapChangeEventManager.onDidFailLoadingMap(TEST_STRING); + verify(onDidFailLoadingMapListener).onDidFailLoadingMap(TEST_STRING); + verify(onMapChangedListener).onMapChanged(MapView.DID_FAIL_LOADING_MAP); + mapChangeEventManager.removeOnDidFailLoadingMapListener(onDidFailLoadingMapListener); + mapChangeEventManager.onDidFailLoadingMap(TEST_STRING); + verify(onDidFailLoadingMapListener).onDidFailLoadingMap(TEST_STRING); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.DID_FAIL_LOADING_MAP); + } + + @Test + public void testOnWillStartRenderingFrameListener() throws Exception { + mapChangeEventManager.addOnWillStartRenderingFrameListener(onWillStartRenderingFrameListener); + mapChangeEventManager.onWillStartRenderingFrame(); + verify(onWillStartRenderingFrameListener).onWillStartRenderingFrame(); + verify(onMapChangedListener).onMapChanged(MapView.WILL_START_RENDERING_FRAME); + mapChangeEventManager.removeOnWillStartRenderingFrameListener(onWillStartRenderingFrameListener); + mapChangeEventManager.onWillStartRenderingFrame(); + verify(onWillStartRenderingFrameListener).onWillStartRenderingFrame(); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.WILL_START_RENDERING_FRAME); + } + + @Test + public void testOnDidFinishRenderingFrameListener() throws Exception { + mapChangeEventManager.addOnDidFinishRenderingFrameListener(onDidFinishRenderingFrameListener); + mapChangeEventManager.onDidFinishRenderingFrame(true); + verify(onDidFinishRenderingFrameListener).onDidFinishRenderingFrame(true); + verify(onMapChangedListener).onMapChanged(MapView.DID_FINISH_RENDERING_FRAME); + verify(mapCallback).onDidFinishRenderingFrame(true); + mapChangeEventManager.removeOnDidFinishRenderingFrameListener(onDidFinishRenderingFrameListener); + mapChangeEventManager.onDidFinishRenderingFrame(true); + verify(onDidFinishRenderingFrameListener).onDidFinishRenderingFrame(true); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.DID_FINISH_RENDERING_FRAME); + verify(mapCallback, times(2)).onDidFinishRenderingFrame(true); + } + + @Test + public void testOnDidFinishRenderingFrameFullyRenderedListener() throws Exception { + mapChangeEventManager.addOnDidFinishRenderingFrameListener(onDidFinishRenderingFrameListener); + mapChangeEventManager.onDidFinishRenderingFrame(false); + verify(onDidFinishRenderingFrameListener).onDidFinishRenderingFrame(false); + verify(onMapChangedListener).onMapChanged(MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED); + verify(mapCallback).onDidFinishRenderingFrame(false); + mapChangeEventManager.removeOnDidFinishRenderingFrameListener(onDidFinishRenderingFrameListener); + mapChangeEventManager.onDidFinishRenderingFrame(false); + verify(onDidFinishRenderingFrameListener).onDidFinishRenderingFrame(false); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED); + verify(mapCallback, times(2)).onDidFinishRenderingFrame(false); + } + + @Test + public void testOnWillStartRenderingMapListener() throws Exception { + mapChangeEventManager.addOnWillStartRenderingMapListener(onWillStartRenderingMapListener); + mapChangeEventManager.onWillStartRenderingMap(); + verify(onWillStartRenderingMapListener).onWillStartRenderingMap(); + verify(onMapChangedListener).onMapChanged(MapView.WILL_START_RENDERING_MAP); + mapChangeEventManager.removeOnWillStartRenderingMapListener(onWillStartRenderingMapListener); + mapChangeEventManager.onWillStartRenderingMap(); + verify(onWillStartRenderingMapListener).onWillStartRenderingMap(); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.WILL_START_RENDERING_MAP); + } + + @Test + public void testOnDidFinishRenderingMapListener() throws Exception { + mapChangeEventManager.addOnDidFinishRenderingMapListener(onDidFinishRenderingMapListener); + mapChangeEventManager.onDidFinishRenderingMap(true); + verify(onDidFinishRenderingMapListener).onDidFinishRenderingMap(true); + verify(onMapChangedListener).onMapChanged(MapView.DID_FINISH_RENDERING_MAP); + mapChangeEventManager.removeOnDidFinishRenderingMapListener(onDidFinishRenderingMapListener); + mapChangeEventManager.onDidFinishRenderingMap(true); + verify(onDidFinishRenderingMapListener).onDidFinishRenderingMap(true); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.DID_FINISH_RENDERING_MAP); + } + + @Test + public void testOnDidFinishRenderingMapFullyRenderedListener() throws Exception { + mapChangeEventManager.addOnDidFinishRenderingMapListener(onDidFinishRenderingMapListener); + mapChangeEventManager.onDidFinishRenderingMap(false); + verify(onDidFinishRenderingMapListener).onDidFinishRenderingMap(false); + verify(onMapChangedListener).onMapChanged(MapView.DID_FINISH_RENDERING_MAP_FULLY_RENDERED); + mapChangeEventManager.removeOnDidFinishRenderingMapListener(onDidFinishRenderingMapListener); + mapChangeEventManager.onDidFinishRenderingMap(false); + verify(onDidFinishRenderingMapListener).onDidFinishRenderingMap(false); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.DID_FINISH_RENDERING_MAP_FULLY_RENDERED); + } + + @Test + public void testOnDidFinishLoadingStyleListener() throws Exception { + mapChangeEventManager.addOnDidFinishLoadingStyleListener(onDidFinishLoadingStyleListener); + mapChangeEventManager.onDidFinishLoadingStyle(); + verify(onDidFinishLoadingStyleListener).onDidFinishLoadingStyle(); + verify(onMapChangedListener).onMapChanged(MapView.DID_FINISH_LOADING_STYLE); + verify(mapCallback).onDidFinishLoadingStyle(); + mapChangeEventManager.removeOnDidFinishLoadingStyleListener(onDidFinishLoadingStyleListener); + mapChangeEventManager.onDidFinishLoadingStyle(); + verify(onDidFinishLoadingStyleListener).onDidFinishLoadingStyle(); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.DID_FINISH_LOADING_STYLE); + verify(mapCallback, times(2)).onDidFinishLoadingStyle(); + } + + @Test + public void testOnSourceChangedListener() throws Exception { + mapChangeEventManager.addOnSourceChangedListener(onSourceChangedListener); + mapChangeEventManager.onSourceChanged(TEST_STRING); + verify(onSourceChangedListener).onSourceChangedListener(TEST_STRING); + verify(onMapChangedListener).onMapChanged(MapView.SOURCE_DID_CHANGE); + mapChangeEventManager.removeOnSourceChangedListener(onSourceChangedListener); + mapChangeEventManager.onSourceChanged(TEST_STRING); + verify(onSourceChangedListener).onSourceChangedListener(TEST_STRING); + verify(onMapChangedListener, times(2)).onMapChanged(MapView.SOURCE_DID_CHANGE); + } +} \ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapChangeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapChangeActivity.java index 32344248bc7..df11cfb7c38 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapChangeActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapChangeActivity.java @@ -1,7 +1,6 @@ package com.mapbox.mapboxsdk.testapp.activity.maplayout; import android.os.Bundle; -import android.support.v4.util.LongSparseArray; import android.support.v7.app.AppCompatActivity; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; @@ -26,12 +25,88 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_map_simple); - final LongSparseArray mapChangeMap = buildMapChangeStringValueSparseArray(); mapView = (MapView) findViewById(R.id.mapView); - mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() { + mapView.addOnCameraIsChangingListener(new MapView.OnCameraIsChangingListener() { @Override - public void onMapChanged(int change) { - Timber.e("OnMapChange: %s, %s", change, mapChangeMap.get(change)); + public void onCameraIsChanging() { + Timber.v("OnCameraIsChanging"); + } + }); + + mapView.addOnCameraDidChangeListener(new MapView.OnCameraDidChangeListener() { + @Override + public void onCameraDidChange(boolean animated) { + Timber.v("OnCamaraDidChange: animated: %s", animated); + } + }); + + mapView.addOnCameraWillChangeListener(new MapView.OnCameraWillChangeListener() { + @Override + public void onCameraWillChange(boolean animated) { + Timber.v("OnCameraWilChange: animated: %s", animated); + } + }); + + mapView.addOnDidFailLoadingMapListener(new MapView.OnDidFailLoadingMapListener() { + @Override + public void onDidFailLoadingMap(String errorMessage) { + Timber.v("OnDidFailLoadingMap: %s", errorMessage); + } + }); + + mapView.addOnDidFinishLoadingMapListener(new MapView.OnDidFinishLoadingMapListener() { + @Override + public void onDidFinishLoadingMap() { + Timber.v("OnDidFinishLoadingMap"); + } + }); + + mapView.addOnDidFinishLoadingStyleListener(new MapView.OnDidFinishLoadingStyleListener() { + @Override + public void onDidFinishLoadingStyle() { + Timber.v("OnDidFinishLoadingStyle"); + } + }); + + mapView.addOnDidFinishRenderingFrameListener(new MapView.OnDidFinishRenderingFrameListener() { + @Override + public void onDidFinishRenderingFrame(boolean partial) { + Timber.v("OnDidFinishRenderingFrame: partial: %s", partial); + } + }); + + mapView.addOnDidFinishRenderingMapListener(new MapView.OnDidFinishRenderingMapListener() { + @Override + public void onDidFinishRenderingMap(boolean partial) { + Timber.v("OnDidFinishRenderingMap: partial: %s", partial); + } + }); + + mapView.addOnSourceChangedListener(new MapView.OnSourceChangedListener() { + @Override + public void onSourceChangedListener(String sourceId) { + Timber.v("OnSourceChangedListener: source with id: %s", sourceId); + } + }); + + mapView.addOnWillStartLoadingMapListener(new MapView.OnWillStartLoadingMapListener() { + @Override + public void onWillStartLoadingMap() { + Timber.v("OnWillStartLoadingMap"); + } + }); + + mapView.addOnWillStartRenderingFrameListener(new MapView.OnWillStartRenderingFrameListener() { + @Override + public void onWillStartRenderingFrame() { + Timber.v("OnWillStartRenderingFrame"); + } + }); + + mapView.addOnWillStartRenderingMapListener(new MapView.OnWillStartRenderingMapListener() { + @Override + public void onWillStartRenderingMap() { + Timber.v("OnWillStartRenderingMap"); } }); @@ -46,27 +121,6 @@ public void onMapReady(MapboxMap map) { }); } - private LongSparseArray buildMapChangeStringValueSparseArray() { - LongSparseArray mapChangeArray = new LongSparseArray<>(); - mapChangeArray.put(MapView.REGION_WILL_CHANGE, "Region will change"); - mapChangeArray.put(MapView.REGION_WILL_CHANGE_ANIMATED, "Region will change animated"); - mapChangeArray.put(MapView.REGION_IS_CHANGING, "Region is changing"); - mapChangeArray.put(MapView.REGION_DID_CHANGE, "Region did change"); - mapChangeArray.put(MapView.REGION_DID_CHANGE_ANIMATED, "Region did change animated"); - mapChangeArray.put(MapView.WILL_START_LOADING_MAP, "Will start loading map"); - mapChangeArray.put(MapView.DID_FINISH_LOADING_MAP, "Did finish loading map"); - mapChangeArray.put(MapView.DID_FAIL_LOADING_MAP, "Did fail loading map"); - mapChangeArray.put(MapView.WILL_START_RENDERING_FRAME, "Will start rendering frame"); - mapChangeArray.put(MapView.DID_FINISH_RENDERING_FRAME, "Did finish rendering frame"); - mapChangeArray.put(MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED, "Did finish rendering frame fully rendered"); - mapChangeArray.put(MapView.WILL_START_RENDERING_MAP, "Will start rendering map"); - mapChangeArray.put(MapView.DID_FINISH_RENDERING_MAP, "Did finish rendering map"); - mapChangeArray.put(MapView.DID_FINISH_RENDERING_MAP_FULLY_RENDERED, "Did finish rendering map fully rendered"); - mapChangeArray.put(MapView.DID_FINISH_LOADING_STYLE, "Did finish loading style"); - mapChangeArray.put(MapView.SOURCE_DID_CHANGE, "Source did change"); - return mapChangeArray; - } - @Override protected void onStart() { super.onStart(); @@ -108,4 +162,4 @@ protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } -} +} \ No newline at end of file diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 24a35a70685..dab22dda399 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -32,6 +32,7 @@ #include "style/android_conversion.hpp" #include #include +#include // C++ -> Java conversion #include "conversion/conversion.hpp" @@ -94,80 +95,135 @@ NativeMapView::~NativeMapView() { } /** - * From mbgl::RendererBackend. Callback to java NativeMapView#onMapChanged(int). + * From mbgl::MapObserver. Callback to java NativeMapView#onCameraWillChange(). * - * May be called from any thread + * Called from the main thread */ -void NativeMapView::notifyMapChange(mbgl::MapChange change) { - assert(vm != nullptr); - - android::UniqueEnv _env = android::AttachEnv(); - static auto onMapChanged = javaClass.GetMethod(*_env, "onMapChanged"); - javaPeer->Call(*_env, onMapChanged, (int) change); -} - void NativeMapView::onCameraWillChange(MapObserver::CameraChangeMode mode) { - if (mode == MapObserver::CameraChangeMode::Immediate) { - notifyMapChange(MapChange::MapChangeRegionWillChange); - } else { - notifyMapChange(MapChange::MapChangeRegionWillChangeAnimated); - } + android::UniqueEnv env = android::AttachEnv(); + static auto onCameraWillChange = javaClass.GetMethod(*env, "onCameraWillChange"); + javaPeer->Call(*env, onCameraWillChange, (jboolean) (mode == MapObserver::CameraChangeMode::Animated)); } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onCameraIsChanging(). + * + * Called from the main thread + */ void NativeMapView::onCameraIsChanging() { - notifyMapChange(MapChange::MapChangeRegionIsChanging); + android::UniqueEnv env = android::AttachEnv(); + static auto onCameraIsChanging = javaClass.GetMethod(*env, "onCameraIsChanging"); + javaPeer->Call(*env, onCameraIsChanging); } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onCameraDidChange(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onCameraDidChange(MapObserver::CameraChangeMode mode) { - if (mode == MapObserver::CameraChangeMode::Immediate) { - notifyMapChange(MapChange::MapChangeRegionDidChange); - } else { - notifyMapChange(MapChange::MapChangeRegionDidChangeAnimated); - } + android::UniqueEnv env = android::AttachEnv(); + static auto onCameraDidChange = javaClass.GetMethod(*env, "onCameraDidChange"); + javaPeer->Call(*env, onCameraDidChange, (jboolean) (mode == MapObserver::CameraChangeMode::Animated)); } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onWillStartLoadingMap(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onWillStartLoadingMap() { - notifyMapChange(MapChange::MapChangeWillStartLoadingMap); + android::UniqueEnv env = android::AttachEnv(); + static auto onWillStartLoadingMap = javaClass.GetMethod(*env, "onWillStartLoadingMap"); + javaPeer->Call(*env, onWillStartLoadingMap); } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onDidFinishLoadingMap(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onDidFinishLoadingMap() { - notifyMapChange(MapChange::MapChangeDidFinishLoadingMap); + android::UniqueEnv env = android::AttachEnv(); + static auto onDidFinishLoadingMap = javaClass.GetMethod(*env, "onDidFinishLoadingMap"); + javaPeer->Call(*env, onDidFinishLoadingMap); } -void NativeMapView::onDidFailLoadingMap(std::exception_ptr) { - notifyMapChange(MapChange::MapChangeDidFailLoadingMap); +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onDidFailLoadingMap(). + * + * Called from the map thread (main thread) + */ +void NativeMapView::onDidFailLoadingMap(std::exception_ptr eptr) { + android::UniqueEnv _env = android::AttachEnv(); + static auto onDidFailLoadingMap = javaClass.GetMethod(*_env, "onDidFailLoadingMap"); + javaPeer->Call(*_env, onDidFailLoadingMap, jni::Make(*_env, mbgl::util::toString(eptr))); } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onWillStartRenderingFrame(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onWillStartRenderingFrame() { - notifyMapChange(MapChange::MapChangeWillStartRenderingFrame); + android::UniqueEnv env = android::AttachEnv(); + static auto onWillStartRenderingFrame = javaClass.GetMethod(*env, "onWillStartRenderingFrame"); + javaPeer->Call(*env, onWillStartRenderingFrame); } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onDidFinishRenderingFrame(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onDidFinishRenderingFrame(MapObserver::RenderMode mode) { - if (mode == MapObserver::RenderMode::Partial) { - notifyMapChange(MapChange::MapChangeDidFinishRenderingFrame); - } else { - notifyMapChange(MapChange::MapChangeDidFinishRenderingFrameFullyRendered); - } + android::UniqueEnv env = android::AttachEnv(); + static auto onDidFinishRenderingFrame = javaClass.GetMethod(*env, "onDidFinishRenderingFrame"); + javaPeer->Call(*env, onDidFinishRenderingFrame, (jboolean) (mode == MapObserver::RenderMode::Partial)); } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onWillStartRenderingMap(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onWillStartRenderingMap() { - notifyMapChange(MapChange::MapChangeWillStartRenderingMap); + android::UniqueEnv env = android::AttachEnv(); + static auto onWillStartRenderingMap = javaClass.GetMethod(*env, "onWillStartRenderingMap"); + javaPeer->Call(*env, onWillStartRenderingMap); } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onDidFinishRenderingMap(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onDidFinishRenderingMap(MapObserver::RenderMode mode) { - if (mode == MapObserver::RenderMode::Partial) { - notifyMapChange(MapChange::MapChangeDidFinishRenderingMap); - } else { - notifyMapChange(MapChange::MapChangeDidFinishRenderingMapFullyRendered); - } + android::UniqueEnv env = android::AttachEnv(); + static auto onDidFinishRenderingMap = javaClass.GetMethod(*env, "onDidFinishRenderingMap"); + javaPeer->Call(*env, onDidFinishRenderingMap, (jboolean) (mode == MapObserver::RenderMode::Partial)); } +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onDidFinishLoadingStyle(). + * + * Called from the map thread (main thread) + */ void NativeMapView::onDidFinishLoadingStyle() { - notifyMapChange(MapChange::MapChangeDidFinishLoadingStyle); + android::UniqueEnv env = android::AttachEnv(); + static auto onDidFinishLoadingStyle = javaClass.GetMethod(*env, "onDidFinishLoadingStyle"); + javaPeer->Call(*env, onDidFinishLoadingStyle); } -void NativeMapView::onSourceChanged(mbgl::style::Source&) { - notifyMapChange(MapChange::MapChangeSourceDidChange); +/** + * From mbgl::MapObserver. Callback to java NativeMapView#onSourceChanged(). + * + * Called from the map thread (main thread) + */ +void NativeMapView::onSourceChanged(mbgl::style::Source& source) { + android::UniqueEnv env = android::AttachEnv(); + static auto onSourceChanged = javaClass.GetMethod(*env, "onSourceChanged"); + javaPeer->Call(*env, onSourceChanged, jni::Make(*env, source.getID())); } // JNI Methods // diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp index 4d226d0fa9b..05d3976a764 100755 --- a/platform/android/src/native_map_view.hpp +++ b/platform/android/src/native_map_view.hpp @@ -56,9 +56,6 @@ class NativeMapView : public MapObserver { virtual ~NativeMapView(); - // Deprecated // - void notifyMapChange(mbgl::MapChange); - // mbgl::RendererBackend (mbgl::MapObserver) // void onCameraWillChange(MapObserver::CameraChangeMode) override; void onCameraIsChanging() override;