mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-05 21:11:35 +07:00
Resolved ANRs on new game screen when user has a lot of maps, by deferring the parsing of most of the map files until after the screen has loaded
This commit is contained in:
parent
2028c0569b
commit
ac85888cfd
@ -16,6 +16,7 @@ import com.unciv.ui.components.input.onChange
|
||||
import com.unciv.ui.screens.basescreen.BaseScreen
|
||||
import com.unciv.ui.screens.victoryscreen.LoadMapPreview
|
||||
import com.unciv.utils.Concurrency
|
||||
import io.ktor.util.collections.*
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.isActive
|
||||
import com.badlogic.gdx.utils.Array as GdxArray
|
||||
@ -34,7 +35,7 @@ class MapFileSelectTable(
|
||||
private class MapWrapper(val fileHandle: FileHandle, val mapParameters: MapParameters) {
|
||||
override fun toString(): String = mapParameters.baseRuleset + " | " + fileHandle.name()
|
||||
}
|
||||
private val mapWrappers= ArrayList<MapWrapper>()
|
||||
private val mapWrappers = ConcurrentSet<MapWrapper>()
|
||||
|
||||
private val columnWidth = newGameScreen.getColumnWidth()
|
||||
|
||||
@ -53,6 +54,10 @@ class MapFileSelectTable(
|
||||
|
||||
mapFileSelectBox.onChange { onSelectBoxChange() }
|
||||
|
||||
addMapWrappersSemiAsync()
|
||||
}
|
||||
|
||||
private fun addMapWrappersSemiAsync(){
|
||||
val mapFilesSequence = sequence<FileHandle> {
|
||||
yieldAll(MapSaver.getMaps().asSequence())
|
||||
for (modFolder in RulesetCache.values.mapNotNull { it.folderLocation }) {
|
||||
@ -60,17 +65,25 @@ class MapFileSelectTable(
|
||||
if (mapsFolder.exists())
|
||||
yieldAll(mapsFolder.list().asSequence())
|
||||
}
|
||||
}
|
||||
}.sortedByDescending { it.lastModified() }
|
||||
|
||||
|
||||
for (mapFile in mapFilesSequence) {
|
||||
// We only really need ONE map to be loaded to tell us "isNotEmpty" and "recentlySavedMapExists"
|
||||
// The rest we can defer, so that users don't get ANRs when opening the new game screen
|
||||
// because the game wants to load ALL the maps before first render
|
||||
fun tryAddMapFile(mapFile: FileHandle){
|
||||
val mapParameters = try {
|
||||
MapSaver.loadMapParameters(mapFile)
|
||||
} catch (_: Exception) {
|
||||
continue
|
||||
return
|
||||
}
|
||||
mapWrappers.add(MapWrapper(mapFile, mapParameters))
|
||||
}
|
||||
|
||||
for (mapFile in mapFilesSequence) {
|
||||
if (mapWrappers.isEmpty()) tryAddMapFile(mapFile)
|
||||
// Each other map is loaded in another thread, so we can multiplex the IO and CPU capabilities
|
||||
else Concurrency.run { tryAddMapFile(mapFile) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user