diff options
Diffstat (limited to 'platform')
11 files changed, 152 insertions, 1 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapChangeReceiver.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapChangeReceiver.java index 3eaa381239..ac83e37a1f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapChangeReceiver.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapChangeReceiver.java @@ -27,6 +27,8 @@ class MapChangeReceiver implements NativeMapView.StateCallback { = new CopyOnWriteArrayList<>(); private final List<MapView.OnDidFinishRenderingMapListener> onDidFinishRenderingMapListenerList = new CopyOnWriteArrayList<>(); + private final List<MapView.OnDidEnterIdleListener> onDidEnterIdleListenerList + = new CopyOnWriteArrayList<>(); private final List<MapView.OnDidFinishLoadingStyleListener> onDidFinishLoadingStyleListenerList = new CopyOnWriteArrayList<>(); private final List<MapView.OnSourceChangedListener> onSourceChangedListenerList = new CopyOnWriteArrayList<>(); @@ -172,6 +174,20 @@ class MapChangeReceiver implements NativeMapView.StateCallback { } @Override + public void onDidEnterIdle() { + try { + if (!onDidEnterIdleListenerList.isEmpty()) { + for (MapView.OnDidEnterIdleListener listener : onDidEnterIdleListenerList) { + listener.onDidEnterIdle(); + } + } + } catch (Throwable err) { + Logger.e(TAG, "Exception in onDidEnterIdle", err); + throw err; + } + } + + @Override public void onDidFinishLoadingStyle() { try { if (!onDidFinishLoadingStyleListenerList.isEmpty()) { @@ -279,6 +295,14 @@ class MapChangeReceiver implements NativeMapView.StateCallback { onDidFinishRenderingMapListenerList.remove(listener); } + void addOnDidEnterIdleListener(MapView.OnDidEnterIdleListener listener) { + onDidEnterIdleListenerList.add(listener); + } + + void removeOnDidEnterIdleListener(MapView.OnDidEnterIdleListener listener) { + onDidEnterIdleListenerList.remove(listener); + } + void addOnDidFinishLoadingStyleListener(MapView.OnDidFinishLoadingStyleListener listener) { onDidFinishLoadingStyleListenerList.add(listener); } @@ -306,6 +330,7 @@ class MapChangeReceiver implements NativeMapView.StateCallback { onDidFinishRenderingFrameList.clear(); onWillStartRenderingMapListenerList.clear(); onDidFinishRenderingMapListenerList.clear(); + onDidEnterIdleListenerList.clear(); onDidFinishLoadingStyleListenerList.clear(); onSourceChangedListenerList.clear(); } 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 0a2ece7378..9ca1c595b1 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 @@ -858,13 +858,33 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { /** * 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 + * @param listener The callback that's invoked when the map has has finished rendering. */ public void removeOnDidFinishRenderingMapListener(OnDidFinishRenderingMapListener listener) { mapChangeReceiver.removeOnDidFinishRenderingMapListener(listener); } /** + * Set a callback that's invoked when the map has entered the idle state. + * + * @param listener The callback that's invoked when the map has entered the idle state. + */ + public void addOnDidEnterIdleListener(OnDidEnterIdleListener listener) { + mapChangeReceiver.addOnDidEnterIdleListener(listener); + } + + /** + * Remove a callback that's invoked when the map has entered the idle state. + * + * @param listener The callback that's invoked when the map has entered the idle state. + */ + public void removeOnDidEnterIdleListener(OnDidEnterIdleListener listener) { + mapChangeReceiver.removeOnDidEnterIdleListener(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 @@ -1038,6 +1058,19 @@ public class MapView extends FrameLayout implements NativeMapView.ViewCallback { } /** + * Interface definition for a callback to be invoked when the map has entered the idle state. + * <p> + * {@link MapView#addOnDidEnterIdleListener(OnDidEnterIdleListener)} + * </p> + */ + public interface OnDidEnterIdleListener { + /** + * Called when the map has entered the idle state. + */ + void onDidEnterIdle(); + } + + /** * Interface definition for a callback to be invoked when the map has loaded the style. * <p> * {@link MapView#addOnDidFailLoadingMapListener(OnDidFailLoadingMapListener)} 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 48c571ee98..2a1cd29b94 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 @@ -993,6 +993,11 @@ final class NativeMapView { } @Keep + private void onDidEnterIdle() { + stateCallback.onDidEnterIdle(); + } + + @Keep private void onDidFinishLoadingStyle() { stateCallback.onDidFinishLoadingStyle(); // deprecated API @@ -1445,6 +1450,8 @@ final class NativeMapView { void onDidFinishLoadingStyle(); + void onDidEnterIdle(); + void onSourceChanged(String sourceId); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapChangeReceiverTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapChangeReceiverTest.java index 688b4badec..816bbaee1c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapChangeReceiverTest.java +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/MapChangeReceiverTest.java @@ -53,6 +53,9 @@ public class MapChangeReceiverTest { private MapView.OnDidFinishRenderingMapListener onDidFinishRenderingMapListener; @Mock + private MapView.OnDidEnterIdleListener onDidEnterIdleListener; + + @Mock private MapView.OnDidFinishLoadingStyleListener onDidFinishLoadingStyleListener; @Mock @@ -307,6 +310,36 @@ public class MapChangeReceiverTest { } @Test + public void testOnDidEnterIdleListener() { + mapChangeEventManager.addOnDidEnterIdleListener(onDidEnterIdleListener); + mapChangeEventManager.onDidEnterIdle(); + verify(onDidEnterIdleListener).onDidEnterIdle(); + mapChangeEventManager.removeOnDidEnterIdleListener(onDidEnterIdleListener); + mapChangeEventManager.onDidEnterIdle(); + verify(onDidEnterIdleListener).onDidEnterIdle(); + + mapChangeEventManager.addOnDidEnterIdleListener(onDidEnterIdleListener); + Logger.setLoggerDefinition(loggerDefinition); + Exception exc = new RuntimeException(); + doThrow(exc).when(onDidEnterIdleListener).onDidEnterIdle(); + try { + mapChangeEventManager.onDidEnterIdle(); + Assert.fail("The exception should've been re-thrown."); + } catch (RuntimeException throwable) { + verify(loggerDefinition).e(anyString(), anyString(), eq(exc)); + } + + Error err = new ExecutionError("", new Error()); + doThrow(err).when(onDidEnterIdleListener).onDidEnterIdle(); + try { + mapChangeEventManager.onDidEnterIdle(); + Assert.fail("The exception should've been re-thrown."); + } catch (ExecutionError throwable) { + verify(loggerDefinition).e(anyString(), anyString(), eq(err)); + } + } + + @Test public void testOnDidFinishLoadingStyleListener() { mapChangeEventManager.addOnDidFinishLoadingStyleListener(onDidFinishLoadingStyleListener); mapChangeEventManager.onDidFinishLoadingStyle(); 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 e3af101a8d..ba669d8260 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 @@ -33,6 +33,7 @@ public class MapChangeActivity extends AppCompatActivity { mapView.addOnDidFinishLoadingStyleListener(() -> Timber.v("OnDidFinishLoadingStyle")); mapView.addOnDidFinishRenderingFrameListener(fully -> Timber.v("OnDidFinishRenderingFrame: fully: %s", fully)); mapView.addOnDidFinishRenderingMapListener(fully -> Timber.v("OnDidFinishRenderingMap: fully: %s", fully)); + mapView.addOnDidEnterIdleListener(() -> Timber.v("OnDidEnterIdle")); mapView.addOnSourceChangedListener(sourceId -> Timber.v("OnSourceChangedListener: source with id: %s", sourceId)); mapView.addOnWillStartLoadingMapListener(() -> Timber.v("OnWillStartLoadingMap")); mapView.addOnWillStartRenderingFrameListener(() -> Timber.v("OnWillStartRenderingFrame")); diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index f12c48f938..4874f5ea34 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -186,6 +186,15 @@ void NativeMapView::onDidFinishRenderingMap(MapObserver::RenderMode mode) { javaPeer.get(*_env).Call(*_env, onDidFinishRenderingMap, (jboolean) (mode != MapObserver::RenderMode::Partial)); } +void NativeMapView::onDidEnterIdle() { + assert(vm != nullptr); + + android::UniqueEnv _env = android::AttachEnv(); + static auto& javaClass = jni::Class<NativeMapView>::Singleton(*_env); + static auto onDidEnterIdle = javaClass.GetMethod<void ()>(*_env, "onDidEnterIdle"); + javaPeer.get(*_env).Call(*_env, onDidEnterIdle); +} + void NativeMapView::onDidFinishLoadingStyle() { assert(vm != nullptr); diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp index 08f1efa46d..94f8acdada 100755 --- a/platform/android/src/native_map_view.hpp +++ b/platform/android/src/native_map_view.hpp @@ -67,6 +67,7 @@ public: void onDidFinishRenderingFrame(MapObserver::RenderMode) override; void onWillStartRenderingMap() override; void onDidFinishRenderingMap(MapObserver::RenderMode) override; + void onDidEnterIdle() override; void onDidFinishLoadingStyle() override; void onSourceChanged(mbgl::style::Source&) override; diff --git a/platform/ios/src/MGLMapViewDelegate.h b/platform/ios/src/MGLMapViewDelegate.h index 77dd2e4ef4..60f3cc7370 100644 --- a/platform/ios/src/MGLMapViewDelegate.h +++ b/platform/ios/src/MGLMapViewDelegate.h @@ -230,6 +230,19 @@ NS_ASSUME_NONNULL_BEGIN - (void)mapViewDidFinishRenderingFrame:(MGLMapView *)mapView fullyRendered:(BOOL)fullyRendered; /** + Tells the delegate that the map view is entering an idle state, and no more + drawing will be necessary until new data is loaded or there is some interaction + with the map. + + - No camera transitions are in progress + - All currently requested tiles have loaded + - All fade/transition animations have completed + + @param mapView The map view that has just entered the idle state. + */ +- (void)mapViewDidEnterIdle:(MGLMapView *)mapView; + +/** Tells the delegate that the map has just finished loading a style. This method is called during the initialization of the map view and after any diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index 9f9bb855d2..67bf94ca11 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -928,6 +928,16 @@ public: } } +- (void)mapViewDidEnterIdle { + if (!_mbglMap) { + return; + } + + if ([self.delegate respondsToSelector:@selector(mapViewDidEnterIdle)]) { + [self.delegate mapViewDidEnterIdle:self]; + } +} + - (void)mapViewDidFinishLoadingStyle { if (!_mbglMap) { return; @@ -3012,6 +3022,10 @@ public: bool fullyRendered = mode == mbgl::MapObserver::RenderMode::Full; [nativeView mapViewDidFinishRenderingMapFullyRendered:fullyRendered]; } + + void onDidEnterIdle() override { + [nativeView mapViewDidEnterIdle]; + } void onDidFinishLoadingStyle() override { [nativeView mapViewDidFinishLoadingStyle]; diff --git a/platform/macos/src/MGLMapViewDelegate.h b/platform/macos/src/MGLMapViewDelegate.h index 2a8b28c1b4..ad59f5bd39 100644 --- a/platform/macos/src/MGLMapViewDelegate.h +++ b/platform/macos/src/MGLMapViewDelegate.h @@ -152,6 +152,19 @@ NS_ASSUME_NONNULL_BEGIN - (void)mapViewDidFinishRenderingFrame:(MGLMapView *)mapView fullyRendered:(BOOL)fullyRendered; /** + Tells the delegate that the map view is entering an idle state, and no more + drawing will be necessary until new data is loaded or there is some interaction + with the map. + + - No camera transitions are in progress + - All currently requested tiles have loaded + - All fade/transition animations have completed + + @param mapView The map view that has just entered the idle state. + */ +- (void)mapViewDidEnterIdle:(MGLMapView *)mapView; + +/** Tells the delegate that the map has just finished loading a style. This method is called during the initialization of the map view and after any diff --git a/platform/macos/test/MGLMapViewDelegateIntegrationTests.swift b/platform/macos/test/MGLMapViewDelegateIntegrationTests.swift index 00635d97eb..109c279a09 100644 --- a/platform/macos/test/MGLMapViewDelegateIntegrationTests.swift +++ b/platform/macos/test/MGLMapViewDelegateIntegrationTests.swift @@ -24,6 +24,8 @@ extension MGLMapViewDelegateIntegrationTests: MGLMapViewDelegate { func mapViewDidFinishRenderingFrame(_ mapView: MGLMapView, fullyRendered: Bool) {} func mapViewDidFinishRenderingMap(_ mapView: MGLMapView, fullyRendered: Bool) {} + + func mapViewDidEnterIdle(_ mapView: MGLMapView) {} func mapViewDidFailLoadingMap(_ mapView: MGLMapView, withError error: Error) {} |