Skip to content

Instantly share code, notes, and snippets.

@bj0
Forked from aartikov/DelegateAccess.kt
Created July 6, 2022 20:16
Show Gist options
  • Save bj0/d86fb34f589cc31d47d6ee566945aba7 to your computer and use it in GitHub Desktop.
Save bj0/d86fb34f589cc31d47d6ee566945aba7 to your computer and use it in GitHub Desktop.
Wrap MutableStateFlow to property delegate
internal object DelegateAccess {
internal val delegate = ThreadLocal<Any?>()
internal val delegateRequested = ThreadLocal<Boolean>().apply { set(false) }
}
internal val <T> KProperty0<T>.delegate: Any?
get() {
try {
DelegateAccess.delegateRequested.set(true)
this.get()
return DelegateAccess.delegate.get()
} finally {
DelegateAccess.delegate.set(null)
DelegateAccess.delegateRequested.set(false)
}
}
@Suppress("UNCHECKED_CAST")
val <T> KProperty0<T>.flow: StateFlow<T>
get() = delegate as StateFlow<T>
class MutableStateDelegate<T> internal constructor(
private val flow: MutableStateFlow<T>
) : MutableStateFlow<T> by flow {
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
if (DelegateAccess.delegateRequested.get() == true) {
DelegateAccess.delegate.set(this)
}
return flow.value
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
flow.value = value
}
}
fun <T> state(initialValue: T): MutableStateDelegate<T> {
return MutableStateDelegate(MutableStateFlow(initialValue))
}
val count by state(0)
count++
::count.flow
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment