Skip to content

Instantly share code, notes, and snippets.

@aartikov
Created January 14, 2021 11:03
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save aartikov/b64f462f50b5e5452c3df707db090a5f to your computer and use it in GitHub Desktop.
Save aartikov/b64f462f50b5e5452c3df707db090a5f 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
@gabrielsantanaa
Copy link

tests?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment