Skip to content

Commit 0b074fd

Browse files
committed
Rename ViewModelScopeImpl to NativeViewModelScope
1 parent 49087e1 commit 0b074fd

File tree

3 files changed

+57
-56
lines changed

3 files changed

+57
-56
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.rickclephas.kmp.observableviewmodel
2+
3+
import kotlinx.coroutines.CoroutineScope
4+
import kotlinx.coroutines.flow.MutableStateFlow
5+
import kotlinx.coroutines.flow.StateFlow
6+
import kotlinx.coroutines.flow.asStateFlow
7+
import kotlinx.coroutines.flow.update
8+
import platform.darwin.NSObject
9+
10+
/**
11+
* Implementation of [ViewModelScope] for Apple platforms.
12+
* @property coroutineScope The [CoroutineScope] associated with the [ViewModel].
13+
*/
14+
internal class NativeViewModelScope internal constructor(
15+
val coroutineScope: CoroutineScope
16+
): NSObject(), ViewModelScope {
17+
18+
private val _subscriptionCount = MutableStateFlow(0)
19+
/**
20+
* A [StateFlow] that emits the number of subscribers to the [ViewModel].
21+
*/
22+
val subscriptionCount: StateFlow<Int> = _subscriptionCount.asStateFlow()
23+
24+
override fun increaseSubscriptionCount() {
25+
_subscriptionCount.update { it + 1 }
26+
}
27+
28+
override fun decreaseSubscriptionCount() {
29+
_subscriptionCount.update { it - 1 }
30+
}
31+
32+
private var sendObjectWillChange: (() -> Unit)? = null
33+
34+
override fun setSendObjectWillChange(sendObjectWillChange: () -> Unit) {
35+
if (this.sendObjectWillChange != null) {
36+
throw IllegalStateException("ViewModel can't be wrapped more than once")
37+
}
38+
this.sendObjectWillChange = sendObjectWillChange
39+
}
40+
41+
/**
42+
* Invokes the object will change listener set by [setSendObjectWillChange].
43+
*/
44+
fun sendObjectWillChange() {
45+
sendObjectWillChange?.invoke()
46+
}
47+
}
48+
49+
/**
50+
* Casts `this` [ViewModelScope] to a [NativeViewModelScope].
51+
*/
52+
internal inline fun ViewModelScope.asNative(): NativeViewModelScope = this as NativeViewModelScope

kmp-observableviewmodel-core/src/appleMain/kotlin/com/rickclephas/kmp/observableviewmodel/StateFlow.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ import kotlin.coroutines.EmptyCoroutineContext
1111
public actual fun <T> MutableStateFlow(
1212
viewModelScope: ViewModelScope,
1313
value: T
14-
): MutableStateFlow<T> = MutableStateFlowImpl(viewModelScope.asImpl(), MutableStateFlow(value))
14+
): MutableStateFlow<T> = MutableStateFlowImpl(viewModelScope.asNative(), MutableStateFlow(value))
1515

1616
/**
1717
* A [MutableStateFlow] that triggers [ViewModelScopeImpl.sendObjectWillChange]
1818
* and accounts for the [ViewModelScopeImpl.subscriptionCount].
1919
*/
2020
@OptIn(ExperimentalForInheritanceCoroutinesApi::class)
2121
private class MutableStateFlowImpl<T>(
22-
private val viewModelScope: ViewModelScopeImpl,
22+
private val viewModelScope: NativeViewModelScope,
2323
private val stateFlow: MutableStateFlow<T>
2424
): MutableStateFlow<T> {
2525

@@ -97,7 +97,7 @@ public actual fun <T> Flow<T>.stateIn(
9797
): StateFlow<T> {
9898
// Similar to kotlinx.coroutines, but using our custom MutableStateFlowImpl and CoroutineContext logic.
9999
// https://github.com/Kotlin/kotlinx.coroutines/blob/6dfabf763fe9fc91fbb73eb0f2d5b488f53043f1/kotlinx-coroutines-core/common/src/flow/operators/Share.kt#L135
100-
val scope = viewModelScope.asImpl()
100+
val scope = viewModelScope.asNative()
101101
val state = MutableStateFlowImpl(scope, MutableStateFlow(initialValue))
102102
val job = scope.coroutineScope.launchSharing(EmptyCoroutineContext, this, state, started, initialValue)
103103
return ReadonlyStateFlow(state, job)

kmp-observableviewmodel-core/src/appleMain/kotlin/com/rickclephas/kmp/observableviewmodel/ViewModelScope.kt

Lines changed: 2 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@ package com.rickclephas.kmp.observableviewmodel
22

33
import com.rickclephas.kmp.observableviewmodel.objc.KMPOVMViewModelScopeProtocol
44
import kotlinx.coroutines.CoroutineScope
5-
import kotlinx.coroutines.flow.MutableStateFlow
6-
import kotlinx.coroutines.flow.StateFlow
7-
import kotlinx.coroutines.flow.asStateFlow
8-
import kotlinx.coroutines.flow.update
9-
import platform.darwin.NSObject
105

116
/**
127
* Holds the [CoroutineScope] of a [ViewModel].
@@ -18,56 +13,10 @@ public actual typealias ViewModelScope = KMPOVMViewModelScopeProtocol
1813
* Creates a new [ViewModelScope] for the provided [coroutineScope].
1914
*/
2015
internal actual fun ViewModelScope(coroutineScope: CoroutineScope): ViewModelScope =
21-
ViewModelScopeImpl(coroutineScope)
16+
NativeViewModelScope(coroutineScope)
2217

2318
/**
2419
* Gets the [CoroutineScope] associated with the [ViewModel] of `this` [ViewModelScope].
2520
*/
2621
public actual val ViewModelScope.coroutineScope: CoroutineScope
27-
get() = asImpl().coroutineScope
28-
29-
/**
30-
* Casts `this` [ViewModelScope] to a [ViewModelScopeImpl].
31-
*/
32-
@InternalKMPObservableViewModelApi
33-
public inline fun ViewModelScope.asImpl(): ViewModelScopeImpl = this as ViewModelScopeImpl
34-
35-
/**
36-
* Implementation of [ViewModelScope].
37-
* @property coroutineScope The [CoroutineScope] associated with the [ViewModel].
38-
*/
39-
@InternalKMPObservableViewModelApi
40-
public class ViewModelScopeImpl internal constructor(
41-
public val coroutineScope: CoroutineScope
42-
): NSObject(), ViewModelScope {
43-
44-
private val _subscriptionCount = MutableStateFlow(0)
45-
/**
46-
* A [StateFlow] that emits the number of subscribers to the [ViewModel].
47-
*/
48-
public val subscriptionCount: StateFlow<Int> = _subscriptionCount.asStateFlow()
49-
50-
override fun increaseSubscriptionCount() {
51-
_subscriptionCount.update { it + 1 }
52-
}
53-
54-
override fun decreaseSubscriptionCount() {
55-
_subscriptionCount.update { it - 1 }
56-
}
57-
58-
private var sendObjectWillChange: (() -> Unit)? = null
59-
60-
override fun setSendObjectWillChange(sendObjectWillChange: () -> Unit) {
61-
if (this.sendObjectWillChange != null) {
62-
throw IllegalStateException("ViewModel can't be wrapped more than once")
63-
}
64-
this.sendObjectWillChange = sendObjectWillChange
65-
}
66-
67-
/**
68-
* Invokes the object will change listener set by [setSendObjectWillChange].
69-
*/
70-
public fun sendObjectWillChange() {
71-
sendObjectWillChange?.invoke()
72-
}
73-
}
22+
get() = asNative().coroutineScope

0 commit comments

Comments
 (0)