diff --git a/CHANGELOG.md b/CHANGELOG.md index e9e2f479a6..f6bd94e3c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ Mapbox welcomes participation and contributions from everyone. # main +# 10.10.0-rc.1 +## Bug fixes 🐞 +* Trigger repaint after `BitmapWidget` is updated. ([1797](https://github.com/mapbox/mapbox-maps-android/pull/1797)) + # 10.10.0-beta.1 November 03, 2022 ## Features ✨ and improvements 🏁 * Introduce view annotation `ViewAnnotationManager.annotations` API to access list of added view annotations. ([1751](https://github.com/mapbox/mapbox-maps-android/pull/1751)) diff --git a/sdk/src/main/java/com/mapbox/maps/MapController.kt b/sdk/src/main/java/com/mapbox/maps/MapController.kt index 41d3c85100..680991a5e5 100644 --- a/sdk/src/main/java/com/mapbox/maps/MapController.kt +++ b/sdk/src/main/java/com/mapbox/maps/MapController.kt @@ -217,6 +217,9 @@ internal class MapController : MapPluginProviderDelegate, MapControllable { } override fun addWidget(widget: Widget) { + widget.setTriggerRepaintAction { + renderer.scheduleRepaint() + } renderer.renderThread.addWidget(widget) renderer.scheduleRepaint() } diff --git a/sdk/src/main/java/com/mapbox/maps/renderer/MapboxRenderer.kt b/sdk/src/main/java/com/mapbox/maps/renderer/MapboxRenderer.kt index 27d4520495..973eb9502d 100644 --- a/sdk/src/main/java/com/mapbox/maps/renderer/MapboxRenderer.kt +++ b/sdk/src/main/java/com/mapbox/maps/renderer/MapboxRenderer.kt @@ -47,6 +47,7 @@ internal abstract class MapboxRenderer : MapClient { @UiThread fun onDestroy() { logI(TAG, "onDestroy") + widgetRenderer.cleanUpAllWidgets() renderThread.destroy() renderThread.fpsChangedListener = null } diff --git a/sdk/src/main/java/com/mapbox/maps/renderer/MapboxWidgetRenderer.kt b/sdk/src/main/java/com/mapbox/maps/renderer/MapboxWidgetRenderer.kt index e3408d2933..c5a645cfaf 100644 --- a/sdk/src/main/java/com/mapbox/maps/renderer/MapboxWidgetRenderer.kt +++ b/sdk/src/main/java/com/mapbox/maps/renderer/MapboxWidgetRenderer.kt @@ -195,7 +195,18 @@ internal class MapboxWidgetRenderer( widgets.add(widget) } - fun removeWidget(widget: Widget) = widgets.remove(widget) + fun removeWidget(widget: Widget): Boolean { + val removed = widgets.remove(widget) + if (removed) { + widget.setTriggerRepaintAction(null) + } + return removed + } + + fun cleanUpAllWidgets() { + widgets.forEach { it.setTriggerRepaintAction(null) } + widgets.clear() + } private companion object { private const val TAG: String = "MapboxWidgetRenderer" diff --git a/sdk/src/main/java/com/mapbox/maps/renderer/widget/BitmapWidget.kt b/sdk/src/main/java/com/mapbox/maps/renderer/widget/BitmapWidget.kt index 2e7c2dae23..58c39600a5 100644 --- a/sdk/src/main/java/com/mapbox/maps/renderer/widget/BitmapWidget.kt +++ b/sdk/src/main/java/com/mapbox/maps/renderer/widget/BitmapWidget.kt @@ -95,6 +95,7 @@ open class BitmapWidget @JvmOverloads constructor( */ fun updateBitmap(bitmap: Bitmap) { renderer.updateBitmap(bitmap) + triggerRepaint() } /** @@ -102,6 +103,7 @@ open class BitmapWidget @JvmOverloads constructor( */ override fun setPosition(widgetPosition: WidgetPosition) { renderer.setPosition(widgetPosition) + triggerRepaint() } /** @@ -136,6 +138,7 @@ open class BitmapWidget @JvmOverloads constructor( */ override fun setRotation(angleDegrees: Float) { renderer.setRotation(angleDegrees = angleDegrees) + triggerRepaint() } /** diff --git a/sdk/src/main/java/com/mapbox/maps/renderer/widget/Widget.kt b/sdk/src/main/java/com/mapbox/maps/renderer/widget/Widget.kt index b9a806654c..6e79549e94 100644 --- a/sdk/src/main/java/com/mapbox/maps/renderer/widget/Widget.kt +++ b/sdk/src/main/java/com/mapbox/maps/renderer/widget/Widget.kt @@ -8,6 +8,16 @@ import com.mapbox.maps.MapboxExperimental @MapboxExperimental abstract class Widget internal constructor() { internal abstract val renderer: WidgetRenderer + private var triggerRepaintAction: (() -> Unit)? = null + + /** + * Triggers a repaint of the widget, as well as the map. + * It will do nothing if the widget has not been added to the map. + */ + @JvmSynthetic + internal fun triggerRepaint() { + triggerRepaintAction?.invoke() + } /** * Update the widget to the new position. @@ -40,4 +50,9 @@ abstract class Widget internal constructor() { * Get absolute rotation of widget in degrees. */ abstract fun getRotation(): Float + + @JvmSynthetic + internal fun setTriggerRepaintAction(action: (() -> Unit)?) { + triggerRepaintAction = action + } } \ No newline at end of file diff --git a/sdk/src/test/java/com/mapbox/maps/MapControllerTest.kt b/sdk/src/test/java/com/mapbox/maps/MapControllerTest.kt index 1e3726aeb7..b247e9f7b6 100644 --- a/sdk/src/test/java/com/mapbox/maps/MapControllerTest.kt +++ b/sdk/src/test/java/com/mapbox/maps/MapControllerTest.kt @@ -411,12 +411,14 @@ class MapControllerTest { @OptIn(MapboxExperimental::class) @Test fun addWidgetTest() { - val widget = createTestWidget() + val mockWidget = mockk() + every { mockWidget.setTriggerRepaintAction(any()) } just runs val mockRenderThread = mockk(relaxed = true) every { mockRenderer.renderThread } returns mockRenderThread every { mockRenderer.scheduleRepaint() } just runs - testMapController.addWidget(widget) - verifyOnce { mockRenderThread.addWidget(widget) } + testMapController.addWidget(mockWidget) + verifyOnce { mockRenderThread.addWidget(mockWidget) } + verifyOnce { mockWidget.setTriggerRepaintAction(any()) } verifyOnce { mockRenderer.scheduleRepaint() } } diff --git a/sdk/src/test/java/com/mapbox/maps/renderer/MapboxRendererTest.kt b/sdk/src/test/java/com/mapbox/maps/renderer/MapboxRendererTest.kt index 3eee09afc3..6a656c48b4 100644 --- a/sdk/src/test/java/com/mapbox/maps/renderer/MapboxRendererTest.kt +++ b/sdk/src/test/java/com/mapbox/maps/renderer/MapboxRendererTest.kt @@ -5,9 +5,14 @@ import android.os.HandlerThread import android.os.Looper import com.mapbox.maps.* import com.mapbox.maps.renderer.gl.PixelReader +import com.mapbox.maps.renderer.widget.BitmapWidget +import com.mapbox.maps.renderer.widget.BitmapWidgetRenderer +import com.mapbox.maps.renderer.widget.WidgetPosition import io.mockk.* import org.junit.After import org.junit.Assert +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -291,10 +296,18 @@ internal abstract class MapboxRendererTest { @Test fun onDestroyTest() { + val mockWidget = mockk() + val bitmapWidgetRenderer = BitmapWidgetRenderer(null, WidgetPosition { }) + every { mockWidget.renderer } returns bitmapWidgetRenderer + every { mockWidget.setTriggerRepaintAction(any()) } just runs val listener = OnFpsChangedListener { } every { renderThread.fpsChangedListener } returns listener + mapboxRenderer.widgetRenderer.addWidget(mockWidget) + assertTrue(mapboxRenderer.widgetRenderer.hasWidgets()) mapboxRenderer.setOnFpsChangedListener(listener) mapboxRenderer.onDestroy() + assertFalse(mapboxRenderer.widgetRenderer.hasWidgets()) + verify { mockWidget.setTriggerRepaintAction(null) } verify { renderThread.destroy() } verify { renderThread.fpsChangedListener = null } }