Repository navigation
Conversation
Coverage (unit tests)Compared against
Line and branch coverage from unit test reports. History is recorded on the |
Coverage (instrumentation tests)
Files
|
| val viewInfo = keysToViews[ViewKey.Item(item)] ?: createAndAddView(ViewKey.Item(item)) | ||
| applyClusterItemMarkerProperties( | ||
| marker = marker, | ||
| icon = renderViewToBitmapDescriptor(viewInfo.view), |
There was a problem hiding this comment.
DefaultClusterRenderer calls onClusterItemUpdated for every cached marker on each re-cluster, so this redraws every visible item's Compose view to a bitmap on the main thread after each zoom. The base implementation never touches the icon (only title, snippet, position and zIndex), so re-applying anchor, zIndex and rotation should be enough here, rendering only when createAndAddView had to create the view.
There was a problem hiding this comment.
I think this one is still pending: onClusterItemUpdated still calls renderViewToBitmapDescriptor on every update, even when the view already exists in keysToViews. The PR description says the bitmap is only rendered when creating the view, so maybe a change got lost in the squash?
| } | ||
| } | ||
| DisposableEffect(itemsState) { | ||
| DisposableEffect(clusterManager) { |
There was a problem hiding this comment.
Keying this on clusterManager makes sense, but LaunchedEffect(itemsState) and LaunchedEffect(cameraPositionState) above still capture the first clusterManager, so after a change the items keep going to the old one. Now that rememberClusterManager recreates the manager when the contexts change this is easier to hit, could we add clusterManager to both keys?
There was a problem hiding this comment.
The items effect is keyed on clusterManager now, thanks! LaunchedEffect(cameraPositionState) still captures the first manager though, so onCameraIdle() would keep going to the old one. Could we add clusterManager to that key too?
| clusterManager ?: return null | ||
| MapEffect(context) { map -> | ||
| val renderer = ReportingDefaultClusterRenderer(context, map, clusterManager) | ||
| MapEffect(context, executor) { map -> |
There was a problem hiding this comment.
Being executor now an effect key, an unremembered Executor { it.run() } would recreate the renderer on every recomposition. Should we mention in the KDoc that it has to be remembered?
There was a problem hiding this comment.
Still worth a line in the KDoc, I think. The same applies now to mainContext and backgroundContext in rememberClusterManager, since something like Dispatchers.Default + job created inline would recreate the manager on every recomposition.
| context = context, | ||
| map = map, | ||
| clusterManager = clusterManager, | ||
| executor = executor ?: Executors.newSingleThreadExecutor(), |
There was a problem hiding this comment.
nit: this repeats the default from DefaultClusterRenderer, we could pass executor only when it is not null and keep the default in one place.
| clusterManager = clusterManager, | ||
| executor = customExecutor, | ||
| ) | ||
| assertNotNull(renderer) |
There was a problem hiding this comment.
This passes as long as the constructors don't throw, so it doesn't really verify the injection. A test for the actual fix would be more useful, i.e. that a custom zIndex survives onClusterItemUpdated.
There was a problem hiding this comment.
The new tests for applyClusterMarkerProperties are nice, but they cover the helper on its own. What I had in mind is a test that goes through onClusterItemUpdated and checks that a custom zIndex survives, which is the actual bug this fixes. Is that hard to set up with the mocks here?
| } | ||
|
|
||
| testOptions { | ||
| unitTests.isReturnDefaultValues = true |
There was a problem hiding this comment.
I wonder if we need this for the whole module, since it makes any unmocked Android call return a default value and can hide errors in other tests. I would rather mock what ClusterRendererTest needs.
There was a problem hiding this comment.
Is this still needed? With the mockkStatic/mockkConstructor setup in ClusterRendererTest I would expect we can drop it and keep the rest of the module tests strict.
b1271aa to
46396fa
Compare
kikoso
left a comment
There was a problem hiding this comment.
Thanks for adding the BEGIN_COMMIT_OVERRIDE block, @dkhawk ! I think most threads from the previous round are still open though (e.g. the description mentions rendering only on view creation, but the code still renders on every update). Can you take a look? Thanks!
46396fa to
db03085
Compare
| * invalidated. Works by reporting invalidations from its inner AndroidComposeView. | ||
| */ | ||
| private class InvalidatingComposeView( | ||
| internal class InvalidatingComposeView( |
… executors/contexts - Bump com.google.maps.android:android-maps-utils and android-maps-utils-core to 6.1.0. - Expose mainContext and backgroundContext in rememberClusterManager to match ClusterManager coroutine context injection introduced in android-maps-utils 6.1.0 (PR #1822). - Expose executor: Executor? in rememberClusterRenderer and forward it through ReportingDefaultClusterRenderer and ComposeUiClusterRenderer to DefaultClusterRenderer (PR #1682). - Fix DisposableEffect key in Clustering.kt to key on clusterManager instead of itemsState so cluster items are not cleared and re-clustered on every items update prior to LaunchedEffect. - Override onClusterUpdated and onClusterItemUpdated in ComposeUiClusterRenderer so cached markers retain custom Compose icons, anchors, zIndex, and rotation when updated.
45774c8 to
b70b969
Compare
Stack
feat(utils): update android-maps-utils to 6.1.0 and expose clustering executors/contexts(Base →main)feat(utils): add Compose wrappers for HeatmapTileOverlay, DataLayer, GeoJsonLayer, and KmlLayer(Stacked →feat/maps-utils-6.1.0)Summary
com.google.maps.android:android-maps-utilsandcom.google.maps.android:android-maps-utils-corefrom6.0.0to6.1.0.mainContext: CoroutineContext = Dispatchers.MainandbackgroundContext: CoroutineContext = Dispatchers.DefaultinrememberClusterManagerto match the coroutine context injection introduced inandroid-maps-utils6.1.0 (feat(clustering): allow injecting coroutine contexts into ClusterManager android-maps-utils#1822).executor: Executor? = nullinrememberClusterRendererand forward it throughReportingDefaultClusterRendererandComposeUiClusterRenderertoDefaultClusterRenderer(feat: add constructor parameter for custom Executor in cluster renderers android-maps-utils#1682).DisposableEffectandLaunchedEffects inClustering.ktonclusterManagerso cluster items are not cleared and re-clustered on everyitemsupdate prior toLaunchedEffect, and recreatingclusterManagerupdates active effects.onClusterUpdatedandonClusterItemUpdatedinComposeUiClusterRendererso cached markers retain custom Composeanchor,zIndex, androtationwhen updated (rendering the item bitmap only when creating the view).ClusterRendererTest.kt.BEGIN_COMMIT_OVERRIDE
feat(utils): update android-maps-utils to 6.1.0 and expose clustering executors/contexts
fix(clustering): key DisposableEffect and LaunchedEffects on clusterManager
fix(clustering): preserve custom marker properties across onClusterUpdated and onClusterItemUpdated
END_COMMIT_OVERRIDE