All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.seiko.imageloader.ImageLoader.kt Maven / Gradle / Ivy

There is a newer version: 1.9.0
Show newest version
package com.seiko.imageloader

import androidx.compose.runtime.Immutable
import com.seiko.imageloader.cache.disk.DiskCache
import com.seiko.imageloader.cache.memory.MemoryCache
import com.seiko.imageloader.component.ComponentRegistry
import com.seiko.imageloader.intercept.DecodeInterceptor
import com.seiko.imageloader.intercept.DiskCacheInterceptor
import com.seiko.imageloader.intercept.EngineInterceptor
import com.seiko.imageloader.intercept.Interceptor
import com.seiko.imageloader.intercept.MappedInterceptor
import com.seiko.imageloader.intercept.MemoryCacheInterceptor
import com.seiko.imageloader.intercept.RealInterceptorChain
import com.seiko.imageloader.request.ErrorResult
import com.seiko.imageloader.request.ImageRequest
import com.seiko.imageloader.request.ImageResult
import com.seiko.imageloader.request.Options
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.withContext

@Immutable
interface ImageLoader {
    val imageScope: CoroutineScope
    suspend fun execute(request: ImageRequest): ImageResult
}

@Immutable
class RealImageLoader(
    private val components: ComponentRegistry,
    private val options: Options,
    private val requestDispatcher: CoroutineDispatcher,
    override val imageScope: CoroutineScope,
    interceptors: List,
    memoryCache: Lazy,
    diskCache: Lazy?,
) : ImageLoader {

    private val interceptors = interceptors + listOfNotNull(
        MappedInterceptor(),
        if (supportImageMemoryCache) MemoryCacheInterceptor(memoryCache) else null,
        DecodeInterceptor(),
        diskCache?.let { DiskCacheInterceptor(it) },
        EngineInterceptor(),
    )

    override suspend fun execute(request: ImageRequest): ImageResult {
        return withContext(requestDispatcher) {
            executeMain(request)
        }
    }

    private suspend fun executeMain(initialRequest: ImageRequest): ImageResult {
        val request = initialRequest.newBuilder().build()
        return try {
            RealInterceptorChain(
                initialRequest = initialRequest,
                interceptors = interceptors,
                index = 0,
                components = components,
                options = options,
                request = request,
            ).proceed(request)
        } catch (throwable: Throwable) {
            if (throwable is CancellationException) {
                throw throwable
            } else {
                ErrorResult(
                    request = initialRequest,
                    error = throwable,
                )
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy