android: Fix games list loading thread safety
Previously we relied on a stateflow for reloading state. Now we use an atomic boolean.
This commit is contained in:
parent
7ea7c72dde
commit
f9d4827102
1 changed files with 38 additions and 36 deletions
|
@ -20,8 +20,8 @@ import kotlinx.serialization.json.Json
|
|||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
import org.yuzu.yuzu_emu.YuzuApplication
|
||||
import org.yuzu.yuzu_emu.utils.GameHelper
|
||||
import org.yuzu.yuzu_emu.utils.GameMetadata
|
||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
class GamesViewModel : ViewModel() {
|
||||
val games: StateFlow<List<Game>> get() = _games
|
||||
|
@ -33,6 +33,8 @@ class GamesViewModel : ViewModel() {
|
|||
val isReloading: StateFlow<Boolean> get() = _isReloading
|
||||
private val _isReloading = MutableStateFlow(false)
|
||||
|
||||
private val reloading = AtomicBoolean(false)
|
||||
|
||||
val shouldSwapData: StateFlow<Boolean> get() = _shouldSwapData
|
||||
private val _shouldSwapData = MutableStateFlow(false)
|
||||
|
||||
|
@ -49,38 +51,8 @@ class GamesViewModel : ViewModel() {
|
|||
// Ensure keys are loaded so that ROM metadata can be decrypted.
|
||||
NativeLibrary.reloadKeys()
|
||||
|
||||
// Retrieve list of cached games
|
||||
val storedGames = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
||||
.getStringSet(GameHelper.KEY_GAMES, emptySet())
|
||||
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
getGameDirs()
|
||||
if (storedGames!!.isNotEmpty()) {
|
||||
val deserializedGames = mutableSetOf<Game>()
|
||||
storedGames.forEach {
|
||||
val game: Game
|
||||
try {
|
||||
game = Json.decodeFromString(it)
|
||||
} catch (e: Exception) {
|
||||
// We don't care about any errors related to parsing the game cache
|
||||
return@forEach
|
||||
}
|
||||
|
||||
val gameExists =
|
||||
DocumentFile.fromSingleUri(
|
||||
YuzuApplication.appContext,
|
||||
Uri.parse(game.path)
|
||||
)?.exists()
|
||||
if (gameExists == true) {
|
||||
deserializedGames.add(game)
|
||||
}
|
||||
}
|
||||
setGames(deserializedGames.toList())
|
||||
}
|
||||
reloadGames(false)
|
||||
}
|
||||
}
|
||||
getGameDirs()
|
||||
reloadGames(directoriesChanged = false, firstStartup = true)
|
||||
}
|
||||
|
||||
fun setGames(games: List<Game>) {
|
||||
|
@ -110,16 +82,46 @@ class GamesViewModel : ViewModel() {
|
|||
_searchFocused.value = searchFocused
|
||||
}
|
||||
|
||||
fun reloadGames(directoriesChanged: Boolean) {
|
||||
if (isReloading.value) {
|
||||
fun reloadGames(directoriesChanged: Boolean, firstStartup: Boolean = false) {
|
||||
if (reloading.get()) {
|
||||
return
|
||||
}
|
||||
reloading.set(true)
|
||||
_isReloading.value = true
|
||||
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
GameMetadata.resetMetadata()
|
||||
if (firstStartup) {
|
||||
// Retrieve list of cached games
|
||||
val storedGames =
|
||||
PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
||||
.getStringSet(GameHelper.KEY_GAMES, emptySet())
|
||||
if (storedGames!!.isNotEmpty()) {
|
||||
val deserializedGames = mutableSetOf<Game>()
|
||||
storedGames.forEach {
|
||||
val game: Game
|
||||
try {
|
||||
game = Json.decodeFromString(it)
|
||||
} catch (e: Exception) {
|
||||
// We don't care about any errors related to parsing the game cache
|
||||
return@forEach
|
||||
}
|
||||
|
||||
val gameExists =
|
||||
DocumentFile.fromSingleUri(
|
||||
YuzuApplication.appContext,
|
||||
Uri.parse(game.path)
|
||||
)?.exists()
|
||||
if (gameExists == true) {
|
||||
deserializedGames.add(game)
|
||||
}
|
||||
}
|
||||
setGames(deserializedGames.toList())
|
||||
}
|
||||
}
|
||||
|
||||
setGames(GameHelper.getGames())
|
||||
reloading.set(false)
|
||||
_isReloading.value = false
|
||||
|
||||
if (directoriesChanged) {
|
||||
|
|
Loading…
Reference in a new issue