Skip to content

Commit

Permalink
Merge branch 'standalone-main'
Browse files Browse the repository at this point in the history
  • Loading branch information
alexzhirkevich committed Nov 13, 2024
2 parents 7f62af5 + b491aec commit b267a7d
Show file tree
Hide file tree
Showing 14 changed files with 103 additions and 92 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ xcuserdata
*.pgp
*.psd
kotlins-js-store
.kotlin
.kotlin
**.log
5 changes: 1 addition & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
@file:Suppress("DSL_SCOPE_VIOLATION")

import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi

plugins {

id("root.publication")
alias(libs.plugins.kotlin.multiplatform) apply false
alias(libs.plugins.android.application).apply(false)
alias(libs.plugins.android.library) apply false
alias(libs.plugins.compose).apply(false)
alias(libs.plugins.composeCompiler).apply(false)
alias(libs.plugins.serialization).apply(false)
alias(libs.plugins.atomicfu).apply(false)
}

buildscript {
dependencies {
classpath(libs.gp.atomicfu)
classpath(libs.nexus.publish)
}
}
Expand Down
2 changes: 1 addition & 1 deletion compottie-network-core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id("kotlinx-atomicfu")
alias(libs.plugins.atomicfu)
}

kotlin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import kotlinx.atomicfu.locks.SynchronizedObject
import kotlinx.atomicfu.locks.synchronized
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -124,9 +123,7 @@ internal class DiskLruCache(
private val journalFileTmp = directory / JOURNAL_FILE_TMP
private val journalFileBackup = directory / JOURNAL_FILE_BACKUP
private val lruEntries = LinkedHashMap<String, Entry>()
private val cleanupScope =
@OptIn(ExperimentalCoroutinesApi::class)
CoroutineScope(SupervisorJob() + cleanupDispatcher.limitedParallelism(1))
private val cleanupScope = CoroutineScope(SupervisorJob() + cleanupDispatcher.limitedParallelism(1))
private val lock = SynchronizedObject()
private var size = 0L
private var operationsSinceRewrite = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,36 @@ package io.github.alexzhirkevich.compottie
import kotlinx.coroutines.withContext
import okio.Path

@OptIn(InternalCompottieApi::class)
private val NetworkLock = MapMutex()

@OptIn(InternalCompottieApi::class)
internal suspend fun networkLoad(
request : suspend (url: String) -> ByteArray,
cacheStrategy: LottieCacheStrategy,
url: String
): Pair<Path?, ByteArray?> {
return withContext(Compottie.ioDispatcher()) {
NetworkLock.withLock(url) {
try {
try {
try {
cacheStrategy.load(url)?.let {
return@withLock cacheStrategy.path(url) to it
}
} catch (_: Throwable) {
cacheStrategy.load(url)?.let {
return@withContext cacheStrategy.path(url) to it
}
} catch (_: Throwable) {
}

val bytes = request(url)
val bytes = request(url)

try {
cacheStrategy.save(url, bytes)?.let {
return@withLock it to bytes
}
} catch (e: Throwable) {
Compottie.logger?.error(
"${this::class.simpleName} failed to cache downloaded asset",
e
)
try {
cacheStrategy.save(url, bytes)?.let {
return@withContext it to bytes
}
null to bytes
} catch (t: Throwable) {
null to null
} catch (e: Throwable) {
Compottie.logger?.error(
"${this::class.simpleName} failed to cache downloaded asset",
e
)
}
null to bytes
} catch (t: Throwable) {
null to null
}
}
}
2 changes: 1 addition & 1 deletion compottie-network/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id("kotlinx-atomicfu")
alias(libs.plugins.atomicfu)
}

kotlin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ package io.github.alexzhirkevich.compottie

import io.ktor.client.HttpClient
import io.ktor.client.plugins.HttpRequestRetry
import io.ktor.client.plugins.HttpTimeout
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsBytes
import io.ktor.client.statement.bodyAsChannel
import io.ktor.utils.io.InternalAPI
import io.ktor.utils.io.toByteArray

internal val DefaultHttpClient by lazy {
HttpClient {
followRedirects = true
expectSuccess = true
install(HttpTimeout){
requestTimeoutMillis = 15_000
connectTimeoutMillis = 15_000
}
install(HttpRequestRetry) {
maxRetries = 2
constantDelay(1000, 500)
Expand Down
2 changes: 1 addition & 1 deletion compottie/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.jetbrains.compose.ExperimentalComposeLibrary

plugins {
alias(libs.plugins.serialization)
id("kotlinx-atomicfu")
alias(libs.plugins.atomicfu)
}

kotlin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import kotlin.time.Duration
import kotlin.time.Duration.Companion.microseconds
import kotlin.time.measureTime


/**
Expand Down Expand Up @@ -104,10 +103,9 @@ public fun rememberLottieComposition(
}

LaunchedEffect(result) {

try {
val composition = withContext(Compottie.ioDispatcher()) {
spec.load()
}
val composition = withContext(Compottie.ioDispatcher()) { spec.load() }
result.complete(composition)
} catch (c: CancellationException) {
result.completeExceptionally(c)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.Matrix
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.scale
Expand Down Expand Up @@ -87,22 +89,22 @@ public fun rememberLottiePainter(
null -> null
}

val painter by produceState<Painter>(
EmptyPainter,
composition,
dp != null
val copy = dp != null

val painter by produceState<LottiePainter?>(
null, composition, copy
) {
if (composition != null) {
val assets = async(Compottie.ioDispatcher()) {
composition.loadAssets(assetsManager ?: EmptyAssetsManager, true)
composition.loadAssets(assetsManager ?: EmptyAssetsManager, copy)
}
val fonts = async(Compottie.ioDispatcher()) {
composition.loadFonts(fontManager ?: EmptyFontManager)
}

value = LottiePainter(
composition = composition.deepCopy(),
progress = { updatedProgress() },
composition = if (copy) composition.deepCopy() else composition,
progress = updatedProgress::invoke,
dynamicProperties = dp,
clipTextToBoundingBoxes = clipTextToBoundingBoxes,
fontFamilyResolver = fontFamilyResolver,
Expand All @@ -126,7 +128,7 @@ public fun rememberLottiePainter(
enableMergePaths,
enableExpressions
) {
(painter as? LottiePainter)?.let {
painter?.let {
it.enableMergePaths = enableMergePaths
it.enableExpressions = enableExpressions
it.applyOpacityToLayers = applyOpacityToLayers
Expand All @@ -136,14 +138,13 @@ public fun rememberLottiePainter(
}
}

LaunchedEffect(
painter,
dp
) {
(painter as? LottiePainter)?.setDynamicProperties(dp)
LaunchedEffect(painter, dp) {
painter?.setDynamicProperties(dp)
}

return painter
return remember {
LateInitPainter { painter }
}
}

/**
Expand Down Expand Up @@ -186,7 +187,7 @@ public fun rememberLottiePainter(

return rememberLottiePainter(
composition = composition,
progress = { progress.value },
progress = progress::value,
assetsManager = assetsManager,
fontManager = fontManager,
dynamicProperties = dynamicProperties,
Expand Down Expand Up @@ -222,9 +223,17 @@ public suspend fun LottiePainter(
enableMergePaths: Boolean = false,
enableExpressions: Boolean = true,
) : Painter = coroutineScope {

val dp = when (dynamicProperties) {
is DynamicCompositionProvider -> dynamicProperties
null -> null
}

val copy = dp != null

val assets = async(Compottie.ioDispatcher()) {
assetsManager?.let {
composition.loadAssets(it, true)
composition.loadAssets(it, copy)
}
}
val fonts = async(Compottie.ioDispatcher()) {
Expand All @@ -234,12 +243,9 @@ public suspend fun LottiePainter(
}

LottiePainter(
composition = composition.deepCopy(),
composition = if (copy) composition.deepCopy() else composition,
progress = progress,
dynamicProperties = when (dynamicProperties) {
is DynamicCompositionProvider -> dynamicProperties
null -> null
},
dynamicProperties = dp,
clipTextToBoundingBoxes = clipTextToBoundingBoxes,
enableTextGrouping = enableTextGrouping,
fontFamilyResolver = makeFontFamilyResolver(),
Expand All @@ -255,12 +261,31 @@ public suspend fun LottiePainter(
internal expect fun makeFontFamilyResolver() : FontFamily.Resolver
internal expect fun mockFontFamilyResolver() : FontFamily.Resolver

private object EmptyPainter : Painter() {
private class LateInitPainter(
val painter : () -> LottiePainter?
) : Painter() {

private var alpha by mutableStateOf(1f)
private var colorFilter by mutableStateOf<ColorFilter?>(null)

override val intrinsicSize: Size by derivedStateOf {
painter()?.intrinsicSize ?: Size(1f,1f)
}

override fun applyAlpha(alpha: Float): Boolean {
this.alpha = alpha
return true
}

override val intrinsicSize: Size = Size(1f,1f)
override fun applyColorFilter(colorFilter: ColorFilter?): Boolean {
this.colorFilter = colorFilter
return true
}

override fun DrawScope.onDraw() {
painter()?.run {
draw(size, alpha, colorFilter)
}
}
}

Expand Down Expand Up @@ -332,7 +357,7 @@ private class LottiePainter(
var enableMergePaths: Boolean by animationState::enableMergePaths
var enableExpressions: Boolean by animationState::enableExpressions

override fun applyAlpha(alpha: Float): Boolean {
public override fun applyAlpha(alpha: Float): Boolean {
if (alpha !in 0f..1f)
return false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,36 @@ package io.github.alexzhirkevich.compottie

import kotlinx.atomicfu.locks.SynchronizedObject
import kotlinx.atomicfu.locks.synchronized
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

internal class LruMap<T : Any>(
private val delegate : LinkedHashMap<Any,T> = LinkedHashMap(),
private val limit : () -> Int,
) : MutableMap<Any, T> by delegate {
) : SynchronizedObject(), MutableMap<Any, T> by delegate {

@OptIn(InternalCompottieApi::class)
private val suspendGetOrPutMutex = MapMutex()
private val lock = SynchronizedObject()
private val suspendGetOrPutMutex = MultiOwnerMutex()

override fun put(key: Any, value: T): T? = synchronized(lock) {
override fun put(key: Any, value: T): T? = synchronized(this) {
putRaw(key, value)
}

override fun clear() = synchronized(lock) {
override fun clear() = synchronized(this) {
clearRaw()
}

override fun putAll(from: Map<out Any, T>) = synchronized(lock) {
override fun putAll(from: Map<out Any, T>) = synchronized(this) {
putAllRaw(from)
}

override fun remove(key: Any): T? = synchronized(lock) {
override fun remove(key: Any): T? = synchronized(this) {
removeRaw(key)
}

override fun get(key: Any): T? = synchronized(lock) {
override fun get(key: Any): T? = synchronized(this) {
getRaw(key)
}

fun getOrPut(key: Any?, put: () -> T): T = synchronized(lock) {
fun getOrPut(key: Any?, put: () -> T): T = synchronized(this) {
if (key == null)
return put()

Expand All @@ -55,7 +52,7 @@ internal class LruMap<T : Any>(
private fun putRaw(key: Any, value: T): T? {
val cacheLimit = limit()

if (cacheLimit < 1){
if (cacheLimit < 1) {
clearRaw()
} else {
while (cacheLimit < size) {
Expand All @@ -79,5 +76,6 @@ internal class LruMap<T : Any>(
}

private fun removeRaw(key: Any): T? = delegate.remove(key)

private fun clearRaw() = delegate.clear()
}
Loading

0 comments on commit b267a7d

Please sign in to comment.