Skip to content

Instantly share code, notes, and snippets.

@yshrsmz
Created March 4, 2019 06:50
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save yshrsmz/3f2df32562bc72cea08bdea7bdb5e76e to your computer and use it in GitHub Desktop.
SQLDelight Kotlin Multiplatform Project sample
internal expect fun <B> backToFront(b: () -> B, job: (B) -> Unit)
private val btfHandler = Handler(Looper.getMainLooper())
internal actual fun <B> backToFront(b: () -> B, job: (B) -> Unit) {
btfHandler.post { job(b()) }
}
internal actual fun <B> backToFront(b: () -> B, job: (B) -> Unit) {
dispatch_async_f(
dispatch_get_main_queue(),
DetachedObjectGraph { JobAndThing(job.freeze(), b()) }.asCPointer(),
staticCFunction { p: COpaquePointer? ->
initRuntimeIfNeeded()
@Suppress("UNCHECKED_CAST") val result = DetachedObjectGraph<Any>(p).attach() as JobAndThing<B>
result.job(result.thing)
})
}
import com.codingfeline.github.platform.backToFront
import com.squareup.sqldelight.Query
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.consumeEach
import co.touchlab.stately.concurrency.ThreadLocalRef
@ExperimentalCoroutinesApi
fun <T : Any> Query<T>.asChannel(): ReceiveChannel<Query<T>> {
val channel = Channel<Query<T>>(Channel.CONFLATED)
channel.offer(this)
val ref = ThreadLocalRef<(Query<T>) -> Unit>()
ref.set { channel.offer(it) }
val listener = object : Query.Listener, (Throwable?) -> Unit {
override fun queryResultsChanged() {
backToFront({ this@asChannel }, { q -> ref.get()?.let { it(q) } })
}
override fun invoke(t: Throwable?) {
ref.remove()
removeListener(this)
}
}
addListener(listener)
channel.invokeOnClose(listener)
return channel
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment