Skip to content

Commit

Permalink
Replace BroadcastChannel with MutableSharedFlow
Browse files Browse the repository at this point in the history
Replace all usages of `ConflatedBroadcastChannel` and `BroadcastChannel` with `MutableSharedFlow`.
  • Loading branch information
ianhanniballake committed Oct 27, 2020
1 parent bbe075d commit 973b929
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 19 deletions.
Expand Up @@ -24,11 +24,11 @@ import android.util.Size
import com.google.android.apps.muzei.api.MuzeiContract
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.channels.ConflatedBroadcastChannel
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.sendBlocking
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
Expand All @@ -41,11 +41,13 @@ import java.io.FileNotFoundException
@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class)
class ArtworkImageLoader(private val context: Context) {

private val requestedSizeChannel = ConflatedBroadcastChannel<Size?>(null)
private val requestSizeSharedFlow = MutableSharedFlow<Size?>(
replay = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST)
var requestedSize: Size?
get() = requestedSizeChannel.value
get() = requestSizeSharedFlow.replayCache.firstOrNull()
set(value) {
requestedSizeChannel.offer(value)
requestSizeSharedFlow.tryEmit(value)
}

private val unsizedArtworkFlow: Flow<Bitmap> = callbackFlow {
Expand Down Expand Up @@ -77,7 +79,7 @@ class ArtworkImageLoader(private val context: Context) {
}

val artworkFlow = unsizedArtworkFlow.combine(
requestedSizeChannel.asFlow().distinctUntilChanged()
requestSizeSharedFlow.distinctUntilChanged()
) { image, size ->
// Resize the image to the specified size
when {
Expand Down
Expand Up @@ -19,23 +19,24 @@ package com.google.android.apps.muzei
import android.graphics.RectF
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.channels.BroadcastChannel
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.MutableSharedFlow

// Singleton that can be observed
@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class)
object ArtDetailViewport {
private val viewport0 = RectF()
private val viewport1 = RectF()
private val broadcastChannel = BroadcastChannel<Boolean>(Channel.BUFFERED)
private val changes = MutableSharedFlow<Boolean>(
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST)

/**
* Get a [Flow] for listening for viewport change events.
* The boolean indicates whether the change was triggered directly by a user interaction.
*/
fun getChanges(): Flow<Boolean> = broadcastChannel.asFlow()
fun getChanges(): Flow<Boolean> = changes

fun getViewport(id: Int): RectF {
return if (id == 0) viewport0 else viewport1
Expand All @@ -55,7 +56,7 @@ object ArtDetailViewport {
isFromUser: Boolean = false
) {
getViewport(id).set(left, top, right, bottom)
broadcastChannel.offer(isFromUser)
changes.tryEmit(isFromUser)
}

fun setDefaultViewport(
Expand All @@ -76,7 +77,7 @@ object ArtDetailViewport {
1f,
0.5f + bitmapAspectRatio / screenAspectRatio / 2f)
}
broadcastChannel.offer(false)
changes.tryEmit(false)
return this
}
}
Expand Up @@ -28,9 +28,9 @@ import com.google.android.apps.muzei.util.ContentProviderClientCompat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.ConflatedBroadcastChannel
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
Expand All @@ -43,11 +43,13 @@ class BrowseProviderViewModel(
application: Application
): AndroidViewModel(application) {

private val contentUriChannel = ConflatedBroadcastChannel<Uri>()
private val contentUriSharedFlow = MutableSharedFlow<Uri>(
replay = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST)
var contentUri: Uri
get() = contentUriChannel.value
get() = contentUriSharedFlow.replayCache.first()
set(value) {
contentUriChannel.offer(value)
contentUriSharedFlow.tryEmit(value)
}

private fun getProviderArtwork(contentUri: Uri) = callbackFlow {
Expand Down Expand Up @@ -94,7 +96,7 @@ class BrowseProviderViewModel(
}
}

val artLiveData = contentUriChannel.asFlow().distinctUntilChanged()
val artLiveData = contentUriSharedFlow.distinctUntilChanged()
.flatMapLatest { contentUri ->
getProviderArtwork(contentUri)
}.asLiveData(viewModelScope.coroutineContext + EmptyCoroutineContext)
Expand Down

0 comments on commit 973b929

Please sign in to comment.