Skip to content

Instantly share code, notes, and snippets.

@ShinichiroFunatsu
Last active March 26, 2020 05:55
Show Gist options
  • Save ShinichiroFunatsu/05d885208fc356bd00031cf17cb88901 to your computer and use it in GitHub Desktop.
Save ShinichiroFunatsu/05d885208fc356bd00031cf17cb88901 to your computer and use it in GitHub Desktop.
Paging-Coroutine-DataSource-Wrapper. version-0.1.0-alpha
import androidx.paging.ItemKeyedDataSource
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
class DemoDataSourceFactory() {
fun create(coroutineScope: CoroutineScope) {
val coroutineScope = CoroutineScope(Dispatchers.IO)
val dataSource: ItemKeyedDataSource<String, String> = DemoDataSource(coroutineScope)
}
}
@Suppress("FunctionName")
fun DemoDataSource(coroutineScope: CoroutineScope): ItemKeyedDataSource<String, String> {
return DemoDataSource().loadImpl(coroutineScope)
}
class DemoDataSource : SuspendableItemKeyedDataSource<String, String> {
override suspend fun loadInitial(
params: ItemKeyedDataSource.LoadInitialParams<String>,
callback: ItemKeyedDataSource.LoadInitialCallback<String>
) {
// API Call
}
override suspend fun loadAfter(
params: ItemKeyedDataSource.LoadParams<String>,
callback: ItemKeyedDataSource.LoadCallback<String>
) {
// API Call
}
override fun loadBefore(
params: ItemKeyedDataSource.LoadParams<String>,
callback: ItemKeyedDataSource.LoadCallback<String>
) {
// API Call
}
override fun getKey(item: String): String {
// API Call
}
}
import androidx.paging.ItemKeyedDataSource
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.plus
import kotlinx.coroutines.runBlocking
import kotlin.coroutines.CoroutineContext
interface SuspendableItemKeyedDataSource<Key, Value> {
fun loadImpl(
coroutineScope: CoroutineScope,
coroutineContext: CoroutineContext = Dispatchers.IO
): ItemKeyedDataSource<Key, Value> {
return InternalItemKeyedDataSource(
coroutineScope = coroutineScope,
coroutineContext = coroutineContext,
dataSource = this
)
}
suspend fun loadInitial(
params: ItemKeyedDataSource.LoadInitialParams<Key>,
callback: ItemKeyedDataSource.LoadInitialCallback<Value>
)
suspend fun loadAfter(
params: ItemKeyedDataSource.LoadParams<Key>,
callback: ItemKeyedDataSource.LoadCallback<Value>
)
fun loadBefore(
params: ItemKeyedDataSource.LoadParams<Key>,
callback: ItemKeyedDataSource.LoadCallback<Value>
)
fun getKey(item: Value): Key
private class InternalItemKeyedDataSource<Key, Value>(
coroutineScope: CoroutineScope,
coroutineContext: CoroutineContext,
private val dataSource: SuspendableItemKeyedDataSource<Key, Value>
) : ItemKeyedDataSource<Key, Value>() {
private val job = SupervisorJob()
private val scope = coroutineScope + coroutineContext + job
override fun loadInitial(
params: LoadInitialParams<Key>,
callback: LoadInitialCallback<Value>
) {
runBlocking(scope.coroutineContext) {
dataSource.loadInitial(params, callback)
}
}
override fun loadAfter(params: LoadParams<Key>, callback: LoadCallback<Value>) {
runBlocking(scope.coroutineContext) {
dataSource.loadAfter(params, callback)
}
}
override fun loadBefore(params: LoadParams<Key>, callback: LoadCallback<Value>) {
runBlocking(scope.coroutineContext) {
dataSource.loadBefore(params, callback)
}
}
override fun getKey(item: Value): Key = dataSource.getKey(item)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment