mirror of
https://github.com/yairm210/Unciv.git
synced 2024-12-22 17:44:24 +07:00
Cache online mod list for fast load
This commit is contained in:
parent
f5946bc08f
commit
f9d21d2767
1
.gitignore
vendored
1
.gitignore
vendored
@ -144,6 +144,7 @@ android/release/
|
|||||||
|
|
||||||
# Transient Unciv files
|
# Transient Unciv files
|
||||||
android/assets/GameSettings.json
|
android/assets/GameSettings.json
|
||||||
|
/android/assets/ModListCache.json
|
||||||
android/assets/lasterror.txt
|
android/assets/lasterror.txt
|
||||||
android/assets/fonts/
|
android/assets/fonts/
|
||||||
android/assets/maps/
|
android/assets/maps/
|
||||||
|
@ -22,6 +22,7 @@ import com.unciv.models.metadata.GameSettings
|
|||||||
import com.unciv.models.metadata.doMigrations
|
import com.unciv.models.metadata.doMigrations
|
||||||
import com.unciv.models.metadata.isMigrationNecessary
|
import com.unciv.models.metadata.isMigrationNecessary
|
||||||
import com.unciv.models.ruleset.RulesetCache
|
import com.unciv.models.ruleset.RulesetCache
|
||||||
|
import com.unciv.ui.screens.modmanager.ModUIData
|
||||||
import com.unciv.ui.screens.savescreens.Gzip
|
import com.unciv.ui.screens.savescreens.Gzip
|
||||||
import com.unciv.utils.Concurrency
|
import com.unciv.utils.Concurrency
|
||||||
import com.unciv.utils.Log
|
import com.unciv.utils.Log
|
||||||
@ -34,6 +35,7 @@ private const val SAVE_FILES_FOLDER = "SaveFiles"
|
|||||||
private const val MULTIPLAYER_FILES_FOLDER = "MultiplayerGames"
|
private const val MULTIPLAYER_FILES_FOLDER = "MultiplayerGames"
|
||||||
private const val AUTOSAVE_FILE_NAME = "Autosave"
|
private const val AUTOSAVE_FILE_NAME = "Autosave"
|
||||||
const val SETTINGS_FILE_NAME = "GameSettings.json"
|
const val SETTINGS_FILE_NAME = "GameSettings.json"
|
||||||
|
const val MOD_LIST_CACHE_FILE_NAME = "ModListCache.json"
|
||||||
|
|
||||||
class UncivFiles(
|
class UncivFiles(
|
||||||
/**
|
/**
|
||||||
@ -142,14 +144,6 @@ class UncivFiles(
|
|||||||
return deleteSave(getSave(gameName))
|
return deleteSave(getSave(gameName))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return `true` if successful.
|
|
||||||
* @throws SecurityException when delete access was denied
|
|
||||||
*/
|
|
||||||
fun deleteMultiplayerSave(gameName: String): Boolean {
|
|
||||||
return deleteSave(getMultiplayerSave(gameName))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only use this with a [FileHandle] obtained by one of the methods of this class!
|
* Only use this with a [FileHandle] obtained by one of the methods of this class!
|
||||||
*
|
*
|
||||||
@ -162,6 +156,7 @@ class UncivFiles(
|
|||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
//region Saving
|
//region Saving
|
||||||
|
|
||||||
fun saveGame(game: GameInfo, gameName: String, saveCompletionCallback: (Exception?) -> Unit = { if (it != null) throw it }): FileHandle {
|
fun saveGame(game: GameInfo, gameName: String, saveCompletionCallback: (Exception?) -> Unit = { if (it != null) throw it }): FileHandle {
|
||||||
@ -253,9 +248,6 @@ class UncivFiles(
|
|||||||
return gameInfoFromString(gameData)
|
return gameInfoFromString(gameData)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadGamePreviewByName(gameName: String) =
|
|
||||||
loadGamePreviewFromFile(getMultiplayerSave(gameName))
|
|
||||||
|
|
||||||
fun loadGamePreviewFromFile(gameFile: FileHandle): GameInfoPreview {
|
fun loadGamePreviewFromFile(gameFile: FileHandle): GameInfoPreview {
|
||||||
return json().fromJson(GameInfoPreview::class.java, gameFile) ?: throw emptyFile(gameFile)
|
return json().fromJson(GameInfoPreview::class.java, gameFile) ?: throw emptyFile(gameFile)
|
||||||
}
|
}
|
||||||
@ -296,6 +288,7 @@ class UncivFiles(
|
|||||||
|
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
//region Settings
|
//region Settings
|
||||||
|
|
||||||
private fun getGeneralSettingsFile(): FileHandle {
|
private fun getGeneralSettingsFile(): FileHandle {
|
||||||
@ -357,6 +350,34 @@ class UncivFiles(
|
|||||||
return game
|
return game
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region Mod caching
|
||||||
|
fun saveModCache(modDataList: List<ModUIData>){
|
||||||
|
val file = getLocalFile(MOD_LIST_CACHE_FILE_NAME)
|
||||||
|
try {
|
||||||
|
json().toJson(modDataList, file)
|
||||||
|
}
|
||||||
|
catch (ex: Exception){ // Not a huge deal if this fails
|
||||||
|
Log.error("Error saving mod cache", ex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun loadModCache(): List<ModUIData>{
|
||||||
|
val file = getLocalFile(MOD_LIST_CACHE_FILE_NAME)
|
||||||
|
if (!file.exists()) return emptyList()
|
||||||
|
try {
|
||||||
|
return json().fromJsonFile(Array<ModUIData>::class.java, file)
|
||||||
|
.toList()
|
||||||
|
}
|
||||||
|
catch (ex: Exception){ // Not a huge deal if this fails
|
||||||
|
Log.error("Error loading mod cache", ex)
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -109,8 +109,8 @@ class ModManagementScreen private constructor(
|
|||||||
|
|
||||||
// Enable re-sorting and syncing entries in 'installed' and 'repo search' ScrollPanes
|
// Enable re-sorting and syncing entries in 'installed' and 'repo search' ScrollPanes
|
||||||
// Keep metadata and buttons in separate pools
|
// Keep metadata and buttons in separate pools
|
||||||
private val installedModInfo = previousInstalledMods ?: HashMap(10) // HashMap<String, ModUIData> inferred
|
private val installedModInfo = previousInstalledMods ?: HashMap(10)
|
||||||
private val onlineModInfo = previousOnlineMods ?: HashMap(90) // HashMap<String, ModUIData> inferred
|
private val onlineModInfo = previousOnlineMods ?: HashMap(game.files.loadModCache().associateBy { it.name })
|
||||||
private val modButtons: HashMap<ModUIData, ModDecoratedButton> = HashMap(100)
|
private val modButtons: HashMap<ModUIData, ModDecoratedButton> = HashMap(100)
|
||||||
|
|
||||||
// cleanup - background processing needs to be stopped on exit and memory freed
|
// cleanup - background processing needs to be stopped on exit and memory freed
|
||||||
@ -349,6 +349,10 @@ class ModManagementScreen private constructor(
|
|||||||
onlineModsTable.add(getCachedModButton(mod)).row()
|
onlineModsTable.add(getCachedModButton(mod)).row()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Concurrency.run("Cache mod list"){
|
||||||
|
game.files.saveModCache(onlineModInfo.values.toList())
|
||||||
|
}
|
||||||
|
|
||||||
// Now the tasks after the 'page' of search results has been fully processed
|
// Now the tasks after the 'page' of search results has been fully processed
|
||||||
// The search has reached the last page!
|
// The search has reached the last page!
|
||||||
if (repoSearch.items.size < amountPerPage) {
|
if (repoSearch.items.size < amountPerPage) {
|
||||||
|
@ -12,14 +12,17 @@ import com.unciv.ui.components.fonts.Fonts
|
|||||||
* (This is important on resize - ModUIData are passed to the new screen)
|
* (This is important on resize - ModUIData are passed to the new screen)
|
||||||
* Note it is guaranteed either ruleset or repo are non-null, never both.
|
* Note it is guaranteed either ruleset or repo are non-null, never both.
|
||||||
*/
|
*/
|
||||||
internal class ModUIData private constructor(
|
class ModUIData private constructor(
|
||||||
val name: String,
|
val name: String,
|
||||||
val description: String,
|
val description: String,
|
||||||
val ruleset: Ruleset?,
|
val ruleset: Ruleset? = null,
|
||||||
val repo: GithubAPI.Repo?,
|
val repo: GithubAPI.Repo? = null,
|
||||||
var isVisual: Boolean = false,
|
var isVisual: Boolean = false,
|
||||||
var hasUpdate: Boolean = false
|
var hasUpdate: Boolean = false
|
||||||
) {
|
) {
|
||||||
|
// For deserialization from cache file
|
||||||
|
constructor():this("","")
|
||||||
|
|
||||||
constructor(ruleset: Ruleset, isVisual: Boolean): this (
|
constructor(ruleset: Ruleset, isVisual: Boolean): this (
|
||||||
ruleset.name,
|
ruleset.name,
|
||||||
ruleset.getSummary().let {
|
ruleset.getSummary().let {
|
||||||
@ -46,7 +49,7 @@ internal class ModUIData private constructor(
|
|||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
|
|
||||||
fun matchesFilter(filter: ModManagementOptions.Filter): Boolean = when {
|
internal fun matchesFilter(filter: ModManagementOptions.Filter): Boolean = when {
|
||||||
!matchesCategory(filter) -> false
|
!matchesCategory(filter) -> false
|
||||||
filter.text.isEmpty() -> true
|
filter.text.isEmpty() -> true
|
||||||
name.contains(filter.text, true) -> true
|
name.contains(filter.text, true) -> true
|
||||||
|
Loading…
Reference in New Issue
Block a user