Skip to content

Commit

Permalink
Replace most GoogleMap() rememberUpdatedState() usages with single St…
Browse files Browse the repository at this point in the history
…ate object and encapsulate Subcomposition functionality

Fixes #492
  • Loading branch information
bubenheimer committed Jan 1, 2024
1 parent e09d848 commit 8795698
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCompositionContext
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalInspectionMode
Expand Down Expand Up @@ -114,39 +116,74 @@ public fun GoogleMap(
it.onMyLocationClick = onMyLocationClick
it.onPOIClick = onPOIClick
}
val currentLocationSource by rememberUpdatedState(locationSource)
val currentCameraPositionState by rememberUpdatedState(cameraPositionState)
val currentContentPadding by rememberUpdatedState(contentPadding)
val currentUiSettings by rememberUpdatedState(uiSettings)
val currentMapProperties by rememberUpdatedState(properties)

val mapUpdaterState = remember {
MapUpdaterState(
mergeDescendants,
contentDescription,
cameraPositionState,
contentPadding,
locationSource,
properties,
uiSettings
)
}.also {
it.mergeDescendants = mergeDescendants
it.contentDescription = contentDescription
it.cameraPositionState = cameraPositionState
it.contentPadding = contentPadding
it.locationSource = locationSource
it.mapProperties = properties
it.mapUiSettings = uiSettings
}

val parentComposition = rememberCompositionContext()
val currentContent by rememberUpdatedState(content)
LaunchedEffect(Unit) {
disposingComposition {
mapView.newComposition(parentComposition, mapClickListeners) {
MapUpdater(
mergeDescendants = mergeDescendants,
contentDescription = contentDescription,
cameraPositionState = currentCameraPositionState,
contentPadding = currentContentPadding,
locationSource = currentLocationSource,
mapProperties = currentMapProperties,
mapUiSettings = currentUiSettings,
)

MapClickListenerUpdater()

CompositionLocalProvider(
LocalCameraPositionState provides cameraPositionState,
) {
currentContent?.invoke()
Subcomposition(mapUpdaterState) {
// todo change parameter default to {} from "null", which is less meaningful
currentContent ?: {}
}
}
}
}
}

@Composable
private inline fun Subcomposition(
mapUpdaterState: MapUpdaterState,
crossinline content: @GoogleMapComposable () -> Unit
) {
MapUpdater(mapUpdaterState)

MapClickListenerUpdater()

CompositionLocalProvider(
LocalCameraPositionState provides mapUpdaterState.cameraPositionState
) { content() }
}

@Stable
internal class MapUpdaterState(
mergeDescendants: Boolean,
contentDescription: String?,
cameraPositionState: CameraPositionState,
contentPadding: PaddingValues,
locationSource: LocationSource?,
mapProperties: MapProperties,
mapUiSettings: MapUiSettings
) {
var mergeDescendants by mutableStateOf(mergeDescendants)
var contentDescription by mutableStateOf(contentDescription)
var cameraPositionState by mutableStateOf(cameraPositionState)
var contentPadding by mutableStateOf(contentPadding)
var locationSource by mutableStateOf(locationSource)
var mapProperties by mutableStateOf(mapProperties)
var mapUiSettings by mutableStateOf(mapUiSettings)
}

internal suspend inline fun disposingComposition(factory: () -> Composition) {
val composition = factory()
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.LocationSource

internal class MapPropertiesNode(
val map: GoogleMap,
Expand Down Expand Up @@ -93,15 +92,7 @@ internal val NoPadding = PaddingValues()
@SuppressLint("MissingPermission")
@Suppress("NOTHING_TO_INLINE")
@Composable
internal inline fun MapUpdater(
mergeDescendants: Boolean = false,
contentDescription: String?,
cameraPositionState: CameraPositionState,
contentPadding: PaddingValues = NoPadding,
locationSource: LocationSource?,
mapProperties: MapProperties,
mapUiSettings: MapUiSettings,
) {
internal inline fun MapUpdater(mapUpdaterState: MapUpdaterState) = with(mapUpdaterState) {
val map = (currentComposer.applier as MapApplier).map
val mapView = (currentComposer.applier as MapApplier).mapView
if (mergeDescendants) {
Expand Down

0 comments on commit 8795698

Please sign in to comment.