diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a364cda349..8f1be5240b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ # Changelog +## 0.32.0 + +* `Versions`: + * `crypto-js`: `4.1.1` -> `4.2.0` + * `AndroidX Fragment`: `1.9.0` -> `1.9.1` + * `AndroidX Core KTX`: `1.19.0` -> `1.19.1` + * `NMCP`: `1.6.1` -> `1.6.2` + * `Gradle Versions`: `0.61.0` -> `0.65.0` + * `KotlinPoet`: `2.3.0` -> `2.4.0` + * `Okio`: `3.18.1` -> `3.18.2` + * `Ktor`: `3.5.2` -> `3.6.0` + * `Exposed`: `1.5.0` -> `1.5.1` + * `Compose Material3`: `1.11.0-alpha07` -> `1.9.0` + * `KSLog`: `1.7.0` -> `2.1.0` + * `Kotlin`: `2.4.10` -> `2.4.21` + * `Compose`: `1.12.0` -> `1.12.1` + * `Gradle wrapper`: `9.3.1` -> `9.7.0` +* `Coroutines`: + * `SmartSemaphore`: + * Rewrite docs for `freePermits` property. + * Add constructor arguments requirements to fail on invalid `permits` and `acquiredPermits` values. + * `SmartRWLocker`: + * Add constructor arguments requirements to fail on invalid `readPermits` values. + * `SmartKeyRWLocker`: + * Add constructor arguments requirements to fail on invalid `globalLockerReadPermits` and `perKeyReadPermits` values. + + ## 0.31.1 * `Coroutines`: diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartKeyRWLocker.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartKeyRWLocker.kt index 1f92ed2651b..fbaf157e5cd 100644 --- a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartKeyRWLocker.kt +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartKeyRWLocker.kt @@ -28,6 +28,11 @@ class SmartKeyRWLocker( globalLockerWriteIsLocked: Boolean = false, private val perKeyReadPermits: Int = Int.MAX_VALUE ) { + init { + require(globalLockerReadPermits > 0) { "The maximal number 'globalLockerReadPermits' of global permits on reading ($globalLockerReadPermits) must be positive." } + require(perKeyReadPermits > 0) { "The maximal number 'perKeyReadPermits' of permits on reading per key ($perKeyReadPermits) must be positive." } + } + private val globalRWLocker: SmartRWLocker = SmartRWLocker( readPermits = globalLockerReadPermits, writeIsLocked = globalLockerWriteIsLocked diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartRWLocker.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartRWLocker.kt index f1f74e7b59f..08bf9a487ef 100644 --- a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartRWLocker.kt +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartRWLocker.kt @@ -17,6 +17,10 @@ import kotlin.contracts.contract * * [unlockWrite] will just unlock [writeMutex] */ class SmartRWLocker(private val readPermits: Int = Int.MAX_VALUE, writeIsLocked: Boolean = false) { + init { + require(readPermits > 0) { "The maximal number 'readPermits' of permits on reading ($readPermits) must be positive." } + } + private val _readSemaphore = SmartSemaphore.Mutable(permits = readPermits, acquiredPermits = if (writeIsLocked) readPermits else 0) private val _writeMutex = SmartMutex.Mutable(locked = writeIsLocked) diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartSemaphore.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartSemaphore.kt index 43f0550e4fc..4d45a437245 100644 --- a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartSemaphore.kt +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartSemaphore.kt @@ -29,8 +29,10 @@ sealed interface SmartSemaphore { val permitsStateFlow: StateFlow /** - * * True - locked - * * False - unlocked + * The number of the available permits. + * + * If returns `0`, it is fully acquired (locked). + * If it returns the same value as `maxPermits`, it is fully released (unlocked). */ val freePermits: Int get() = permitsStateFlow.value @@ -47,6 +49,12 @@ sealed interface SmartSemaphore { * @param locked Preset state of [freePermits] and its internal [_freePermitsStateFlow] */ class Mutable(permits: Int, acquiredPermits: Int = 0) : SmartSemaphore { + init { + require(permits > 0) { "The maximal number 'permits' of permits ($permits) must be positive." } + require(acquiredPermits >= 0) { "The number 'acquiredPermits' of initially acquired permits ($acquiredPermits) must be non-negative." } + require(permits >= acquiredPermits) { "The number 'acquiredPermits' of acquired initially permits ($acquiredPermits) must not exceed the maximal number 'permits' of permits ($permits)." } + } + override val maxPermits: Int = permits private val _freePermitsStateFlow = MutableRedeliverStateFlow(permits - acquiredPermits) override val permitsStateFlow: StateFlow = _freePermitsStateFlow.asStateFlow() diff --git a/gradle.properties b/gradle.properties index 3a9445c08a0..625b9fd4882 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,10 +11,10 @@ org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=2g # JS NPM -crypto_js_version=4.1.1 +crypto_js_version=4.2.0 # Project data group=dev.inmo -version=0.31.1 -android_code_version=318 +version=0.32.0 +android_code_version=319 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2000c3b62fd..e06b3767319 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,17 +1,17 @@ [versions] -kt = "2.4.10" +kt = "2.4.21" kt-serialization = "1.11.0" kt-coroutines = "1.11.0" kotlinx-browser = "0.5.0" -kslog = "1.7.0" +kslog = "2.1.0" -jb-compose = "1.12.0" -jb-compose-material3 = "1.11.0-alpha07" +jb-compose = "1.12.1" +jb-compose-material3 = "1.9.0" jb-compose-icons = "1.7.8" -jb-exposed = "1.5.0" +jb-exposed = "1.5.1" jb-dokka = "2.2.0" sqlite = "3.53.4.0" @@ -19,27 +19,27 @@ sqlite = "3.53.4.0" korlibs = "5.4.0" uuid = "0.8.4" -ktor = "3.5.2" +ktor = "3.6.0" gh-release = "2.5.2" koin = "4.2.2" -okio = "3.18.1" +okio = "3.18.2" ksp = "2.3.11" -kotlin-poet = "2.3.0" +kotlin-poet = "2.4.0" -versions = "0.61.0" -nmcp = "1.6.1" +versions = "0.65.0" +nmcp = "1.6.2" android-gradle = "9.1.1" dexcount = "4.0.0" -android-coreKtx = "1.19.0" +android-coreKtx = "1.19.1" android-recyclerView = "1.4.0" android-appCompat = "1.8.0" -android-fragment = "1.9.0" +android-fragment = "1.9.1" android-espresso = "3.7.0" android-test = "1.3.0" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 62d4c053550..eddabd2eef8 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2f2958b923a..8bf5ce2600a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists