Skip to content

Instantly share code, notes, and snippets.

@TYZRPVX
Created May 25, 2022 07:13
Show Gist options
  • Save TYZRPVX/f4095c8fddba6e19107aba51e9a91388 to your computer and use it in GitHub Desktop.
Save TYZRPVX/f4095c8fddba6e19107aba51e9a91388 to your computer and use it in GitHub Desktop.
package droid.hooker.experiment.language.kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.collect
import kotlin.random.Random
class AvatarLoaderMock {
fun placeholder(): String {
return "placeholder"
}
fun randomBoolean() = Random(System.currentTimeMillis()).nextBoolean()
fun memoryCache(url: String): String? {
if (randomBoolean()) {
return "[M] $url"
} else {
return null
}
}
suspend fun diskCache(url: String): String? {
delay(100L)
if (randomBoolean()) {
return "[D] $url"
} else {
return null
}
}
suspend fun networkImage(url: String): String? {
delay(300L)
if (randomBoolean()) {
return "[Net] $url"
} else {
return "[Net][must not null] $url"
}
}
sealed class Key {
object NewM : Key()
object OldM : Key()
object NewD : Key()
object OldD : Key()
object NewNetwork : Key()
object Placeholder : Key()
}
@OptIn(ExperimentalCoroutinesApi::class)
fun loadFlow(): Flow<Pair<Key, String?>> {
val channelFlow = channelFlow<Pair<Key, String?>> {
val newMemoryCache = memoryCache("new")
if (newMemoryCache != null) {
send(Pair(Key.NewM, newMemoryCache))
} else {
val oldMemoryCache = memoryCache("old")
if (oldMemoryCache != null) {
send(Pair(Key.OldM, oldMemoryCache))
} else {
send(Pair(Key.Placeholder, placeholder()))
}
val newDiskCache = diskCache("new")
if (newDiskCache != null) {
send(Pair(Key.NewD, newDiskCache))
} else {
val oldDiskCache = diskCache("old")
if (oldDiskCache != null) {
send(Pair(Key.OldD, oldDiskCache))
}
val newNetworkImage = networkImage("new")
send(Pair(Key.NewNetwork, newNetworkImage))
}
}
}
return channelFlow
}
suspend fun load() {
loadFlow().collect {
"loading: ${it.second}".let(::println)
}
}
}
fun main() = runBlocking {
(1..10).forEach {
val launch = GlobalScope.launch {
AvatarLoaderMock().load()
}
launch.join()
"============ Load END ============".let(::println)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment