Skip to content

Commit f1ae9c2

Browse files
authored
Remove co.touchlab:stately-iso-collections dependency (#437)
1 parent efe6ec2 commit f1ae9c2

4 files changed

Lines changed: 16 additions & 39 deletions

File tree

core/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ kotlin {
3838
api(libs.kotlinx.coroutines.core)
3939
api(libs.uuid)
4040
implementation(libs.tuulbox.collections)
41-
implementation(libs.stately.collections)
4241
}
4342
}
4443

core/src/commonMain/kotlin/Observation.kt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ internal class Observation(
1414
private val characteristic: Characteristic,
1515
logging: Logging,
1616
identifier: String,
17-
private val subscribers: MutableList<OnSubscriptionAction> = mutableListOf(),
1817
) {
1918

2019
interface Handler {
@@ -24,6 +23,7 @@ internal class Observation(
2423

2524
private val logger = Logger(logging, tag = "Kable/Observation", identifier)
2625

26+
private val subscribers = mutableListOf<OnSubscriptionAction>()
2727
private val mutex = Mutex()
2828

2929
private val _didStartObservation = atomic(false)
@@ -34,12 +34,9 @@ internal class Observation(
3434
private val isConnected: Boolean
3535
get() = state.value.isAtLeast<Observes>()
3636

37-
private val hasSubscribers: Boolean
38-
get() = subscribers.isNotEmpty()
39-
4037
suspend fun onSubscription(action: OnSubscriptionAction) = mutex.withLock {
4138
subscribers += action
42-
val shouldStartObservation = !didStartObservation && hasSubscribers && isConnected
39+
val shouldStartObservation = !didStartObservation && subscribers.isNotEmpty() && isConnected
4340
if (shouldStartObservation) {
4441
suppressConnectionExceptions {
4542
startObservation()
@@ -50,13 +47,13 @@ internal class Observation(
5047

5148
suspend fun onCompletion(action: OnSubscriptionAction) = mutex.withLock {
5249
subscribers -= action
53-
val shouldStopObservation = didStartObservation && !hasSubscribers && isConnected
50+
val shouldStopObservation = didStartObservation && subscribers.isEmpty() && isConnected
5451
if (shouldStopObservation) stopObservation()
5552
}
5653

5754
suspend fun onConnected() = mutex.withLock {
5855
if (isConnected) {
59-
if (hasSubscribers) {
56+
if (subscribers.isNotEmpty()) {
6057
suppressConnectionExceptions {
6158
startObservation()
6259
subscribers.forEach { it() }

core/src/commonMain/kotlin/Observers.kt

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.juul.kable
22

3-
import co.touchlab.stately.collections.IsoMutableList
4-
import co.touchlab.stately.isolate.IsolateState
53
import com.juul.kable.ObservationEvent.CharacteristicChange
64
import com.juul.kable.ObservationEvent.Error
75
import com.juul.kable.logs.Logging
6+
import kotlinx.atomicfu.locks.SynchronizedObject
7+
import kotlinx.atomicfu.locks.synchronized
88
import kotlinx.coroutines.flow.Flow
99
import kotlinx.coroutines.flow.MutableSharedFlow
1010
import kotlinx.coroutines.flow.filter
@@ -44,7 +44,9 @@ internal class Observers<T>(
4444
) {
4545

4646
val characteristicChanges = MutableSharedFlow<ObservationEvent<T>>(extraBufferCapacity = Int.MAX_VALUE)
47-
private val observations = Observations()
47+
48+
private val observations = mutableMapOf<Characteristic, Observation>()
49+
private val lock = SynchronizedObject()
4850

4951
fun acquire(
5052
characteristic: Characteristic,
@@ -54,12 +56,10 @@ internal class Observers<T>(
5456
val handler = peripheral.observationHandler()
5557
val identifier = peripheral.identifier
5658

57-
// `IsoMutableList` created outside of `getOrPut`, because it would deadlock on Native if created in
58-
// `Observation` constructor.
59-
val subscribers = IsoMutableList<OnSubscriptionAction>()
60-
61-
val observation = observations.getOrPut(characteristic) {
62-
Observation(state, handler, characteristic, logging, identifier.toString(), subscribers)
59+
val observation = synchronized(lock) {
60+
observations.getOrPut(characteristic) {
61+
Observation(state, handler, characteristic, logging, identifier.toString())
62+
}
6363
}
6464

6565
return characteristicChanges
@@ -91,7 +91,9 @@ internal class Observers<T>(
9191
}
9292

9393
suspend fun onConnected() {
94-
observations.entries.forEach { (_, observation) ->
94+
synchronized(lock) {
95+
observations.entries
96+
}.forEach { (_, observation) ->
9597
// Pipe failures to `characteristicChanges` while honoring in-flight connection cancellations.
9698
try {
9799
observation.onConnected()
@@ -103,23 +105,3 @@ internal class Observers<T>(
103105
}
104106
}
105107
}
106-
107-
private class Observations : IsolateState<MutableMap<Characteristic, Observation>>(
108-
producer = { mutableMapOf() },
109-
) {
110-
111-
val entries: List<Pair<Characteristic, Observation>>
112-
get() = access { observations ->
113-
// `map` used as a means to copy entries, to prevent freeze exceptions on Native.
114-
observations.entries.map { (characteristic, observation) ->
115-
characteristic to observation
116-
}
117-
}
118-
119-
fun getOrPut(
120-
characteristic: Characteristic,
121-
defaultValue: () -> Observation,
122-
): Observation = access { observations ->
123-
observations.getOrPut(characteristic, defaultValue)
124-
}
125-
}

gradle/libs.versions.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ atomicfu = { module = "org.jetbrains.kotlinx:atomicfu-jvm", version.ref = "atomi
1313
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" }
1414
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
1515
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" }
16-
stately-collections = { module = "co.touchlab:stately-iso-collections", version = "1.2.3" }
1716
tuulbox-logging = { module = "com.juul.tuulbox:logging", version.ref = "tuulbox" }
1817
tuulbox-collections = { module = "com.juul.tuulbox:collections", version.ref = "tuulbox" }
1918
uuid = { module = "com.benasher44:uuid", version = "0.7.0" }

0 commit comments

Comments
 (0)