diff --git a/coil-core/src/commonMain/kotlin/coil3/ComponentRegistry.kt b/coil-core/src/commonMain/kotlin/coil3/ComponentRegistry.kt index 868185c6a6..ae31260e7d 100644 --- a/coil-core/src/commonMain/kotlin/coil3/ComponentRegistry.kt +++ b/coil-core/src/commonMain/kotlin/coil3/ComponentRegistry.kt @@ -8,6 +8,7 @@ import coil3.intercept.Interceptor import coil3.key.Keyer import coil3.map.Mapper import coil3.request.Options +import coil3.util.flatMapIndices import coil3.util.forEachIndices import coil3.util.toImmutableList import kotlin.jvm.JvmOverloads @@ -30,11 +31,11 @@ class ComponentRegistry private constructor( constructor() : this(emptyList(), emptyList(), emptyList(), emptyList(), emptyList()) val fetcherFactories: List, KClass>> by lazy { - lazyFetcherFactories.flatMap { it() }.also { lazyFetcherFactories = emptyList() } + lazyFetcherFactories.flatMapIndices { it() }.also { lazyFetcherFactories = emptyList() } } val decoderFactories: List by lazy { - lazyDecoderFactories.flatMap { it() }.also { lazyDecoderFactories = emptyList() } + lazyDecoderFactories.flatMapIndices { it() }.also { lazyDecoderFactories = emptyList() } } /** diff --git a/coil-core/src/commonMain/kotlin/coil3/RealImageLoader.common.kt b/coil-core/src/commonMain/kotlin/coil3/RealImageLoader.common.kt index 7dfaf3e36e..79ee22067d 100644 --- a/coil-core/src/commonMain/kotlin/coil3/RealImageLoader.common.kt +++ b/coil-core/src/commonMain/kotlin/coil3/RealImageLoader.common.kt @@ -27,6 +27,7 @@ import coil3.util.SystemCallbacks import coil3.util.emoji import coil3.util.get import coil3.util.log +import coil3.util.mapNotNullIndices import kotlin.coroutines.coroutineContext import kotlinx.atomicfu.atomic import kotlinx.coroutines.CancellationException @@ -254,15 +255,15 @@ internal fun ComponentRegistry.Builder.addServiceLoaderComponents( if (options.serviceLoaderEnabled) { // Delay reading the fetchers and decoders until the fetching/decoding stage. addFetcherFactories { - ServiceLoaderComponentRegistry.fetchers.mapNotNull { target -> + ServiceLoaderComponentRegistry.fetchers.mapNotNullIndices { target -> target as FetcherServiceLoaderTarget - val factory = target.factory() ?: return@mapNotNull null - val type = target.type() ?: return@mapNotNull null + val factory = target.factory() ?: return@mapNotNullIndices null + val type = target.type() ?: return@mapNotNullIndices null factory to type } } addDecoderFactories { - ServiceLoaderComponentRegistry.decoders.mapNotNull { target -> + ServiceLoaderComponentRegistry.decoders.mapNotNullIndices { target -> target.factory() } } diff --git a/coil-core/src/commonMain/kotlin/coil3/util/collections.common.kt b/coil-core/src/commonMain/kotlin/coil3/util/collections.common.kt index dfaa35105e..f4ecf5e9e7 100644 --- a/coil-core/src/commonMain/kotlin/coil3/util/collections.common.kt +++ b/coil-core/src/commonMain/kotlin/coil3/util/collections.common.kt @@ -14,10 +14,7 @@ internal expect fun Map.toImmutableMap(): Map internal expect fun List.toImmutableList(): List -/** - * Functionally the same as [Iterable.forEach] except it generates - * an index-based loop that doesn't use an [Iterator]. - */ +/** @see forEach */ @PublishedApi // Used by extension modules. internal inline fun List.forEachIndices(action: (T) -> Unit) { for (i in indices) { @@ -25,20 +22,35 @@ internal inline fun List.forEachIndices(action: (T) -> Unit) { } } -/** - * Functionally the same as [Iterable.forEachIndexed] except it generates - * an index-based loop that doesn't use an [Iterator]. - */ +/** @see forEachIndices */ internal inline fun List.forEachIndexedIndices(action: (Int, T) -> Unit) { for (i in indices) { action(i, get(i)) } } -/** - * Functionally the same as [Iterable.fold] except it generates - * an index-based loop that doesn't use an [Iterator]. - */ +/** @see mapNotNull */ +internal inline fun List.mapNotNullIndices(transform: (T) -> R?): List { + val destination = mutableListOf() + for (i in indices) { + val value = transform(get(i)) + if (value != null) { + destination += value + } + } + return destination +} + +/** @see flatMap */ +internal inline fun List.flatMapIndices(transform: (T) -> List): List { + val destination = mutableListOf() + for (i in indices) { + destination += transform(get(i)) + } + return destination +} + +/** @see fold */ internal inline fun List.foldIndices(initial: R, operation: (R, T) -> R): R { var accumulator = initial for (i in indices) {