mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-27 01:45:29 +03:00
Improve the robustness of the ROMs auto-refresh feature
This commit is contained in:
parent
e6efaf26bc
commit
24d4f5e3cd
@ -4,18 +4,18 @@ import android.app.Application
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.lifecycle.*
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import emu.skyline.loader.AppEntry
|
import emu.skyline.loader.AppEntry
|
||||||
import emu.skyline.loader.RomFormat
|
|
||||||
import emu.skyline.utils.fromFile
|
import emu.skyline.utils.fromFile
|
||||||
import emu.skyline.utils.toFile
|
import emu.skyline.utils.toFile
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
sealed class MainState {
|
sealed class MainState {
|
||||||
@ -42,7 +42,8 @@ class MainViewModel @Inject constructor(@ApplicationContext context : Context, p
|
|||||||
* @param loadFromFile If this is false then trying to load cached adapter data is skipped entirely
|
* @param loadFromFile If this is false then trying to load cached adapter data is skipped entirely
|
||||||
*/
|
*/
|
||||||
fun loadRoms(context : Context, loadFromFile : Boolean, searchLocation : Uri, systemLanguage : Int) {
|
fun loadRoms(context : Context, loadFromFile : Boolean, searchLocation : Uri, systemLanguage : Int) {
|
||||||
if (state == MainState.Loading) return
|
if (state == MainState.Loading)
|
||||||
|
return
|
||||||
state = MainState.Loading
|
state = MainState.Loading
|
||||||
|
|
||||||
val romsFile = File(getApplication<SkylineApplication>().filesDir.canonicalPath + "/roms.bin")
|
val romsFile = File(getApplication<SkylineApplication>().filesDir.canonicalPath + "/roms.bin")
|
||||||
@ -51,6 +52,7 @@ class MainViewModel @Inject constructor(@ApplicationContext context : Context, p
|
|||||||
if (loadFromFile && romsFile.exists()) {
|
if (loadFromFile && romsFile.exists()) {
|
||||||
try {
|
try {
|
||||||
state = MainState.Loaded(fromFile(romsFile))
|
state = MainState.Loaded(fromFile(romsFile))
|
||||||
|
checkRomHash(searchLocation, systemLanguage)
|
||||||
return@launch
|
return@launch
|
||||||
} catch (e : Exception) {
|
} catch (e : Exception) {
|
||||||
Log.w(TAG, "Ran into exception while loading: ${e.message}")
|
Log.w(TAG, "Ran into exception while loading: ${e.message}")
|
||||||
@ -58,7 +60,6 @@ class MainViewModel @Inject constructor(@ApplicationContext context : Context, p
|
|||||||
}
|
}
|
||||||
|
|
||||||
state = if (searchLocation.toString().isEmpty()) {
|
state = if (searchLocation.toString().isEmpty()) {
|
||||||
@Suppress("ReplaceWithEnumMap")
|
|
||||||
MainState.Loaded(ArrayList())
|
MainState.Loaded(ArrayList())
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
@ -74,18 +75,31 @@ class MainViewModel @Inject constructor(@ApplicationContext context : Context, p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks whether an auto refresh is already in progress
|
||||||
|
*/
|
||||||
|
private var isAutoRefreshingRoms = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This checks if the roms have changed since the last time they were loaded and if so it reloads them
|
* This checks if the roms have changed since the last time they were loaded and if so it reloads them
|
||||||
*/
|
*/
|
||||||
fun checkRomHash(searchLocation : Uri, systemLanguage : Int) {
|
fun checkRomHash(searchLocation : Uri, systemLanguage : Int) {
|
||||||
if(state !is MainState.Loaded) return
|
// Skip if an auto refresh is already in progress or if the state hasn't already loaded
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
if (isAutoRefreshingRoms || state !is MainState.Loaded)
|
||||||
val currentHash = (state as MainState.Loaded).items.hashCode()
|
return
|
||||||
|
isAutoRefreshingRoms = true
|
||||||
|
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
val currentHash = when (val currentState = state) {
|
||||||
|
is MainState.Loaded -> currentState.items.hashCode()
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
val romElements = romProvider.loadRoms(searchLocation, systemLanguage)
|
val romElements = romProvider.loadRoms(searchLocation, systemLanguage)
|
||||||
val newHash = romElements.hashCode()
|
val newHash = romElements.hashCode()
|
||||||
if (newHash != currentHash) {
|
if (newHash != currentHash)
|
||||||
state = MainState.Loaded(romElements)
|
state = MainState.Loaded(romElements)
|
||||||
}
|
|
||||||
|
isAutoRefreshingRoms = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user