Discord thread shutdown, last Autosave singlethreaded (#2318)
* Bring Incas into the main game (also changes slinger withdraw ability to inheritable) * Update Nations.json * Discord thread is now a timer and gets notified to shut down Solved truncated Autosaves: Made it singlethreaded within shutdown. Co-authored-by: Yair Morgenstern <yairm210@hotmail.com>
This commit is contained in:
parent
adb52acd24
commit
cee794b29c
3 changed files with 39 additions and 29 deletions
|
@ -24,7 +24,8 @@ import kotlin.concurrent.thread
|
|||
class UncivGame(
|
||||
val version: String,
|
||||
private val crashReportSender: CrashReportSender? = null,
|
||||
val exitEvent: (()->Unit)? = null
|
||||
val exitEvent: (()->Unit)? = null,
|
||||
val cancelDiscordEvent: (()->Unit)? = null
|
||||
) : Game() {
|
||||
// we need this secondary constructor because Java code for iOS can't handle Kotlin lambda parameters
|
||||
constructor(version: String) : this(version, null)
|
||||
|
@ -177,10 +178,19 @@ class UncivGame(
|
|||
}
|
||||
|
||||
override fun dispose() {
|
||||
if (::gameInfo.isInitialized) {
|
||||
GameSaver().autoSave(gameInfo)
|
||||
cancelDiscordEvent?.invoke()
|
||||
if (::gameInfo.isInitialized){
|
||||
GameSaver().autoSaveSingleThreaded(gameInfo) // NO new thread
|
||||
settings.save()
|
||||
}
|
||||
|
||||
// Log still running threads (should be only this one and "DestroyJavaVM")
|
||||
val numThreads = Thread.activeCount()
|
||||
val threadList = Array<Thread>(numThreads) { _ -> Thread() }
|
||||
Thread.enumerate(threadList)
|
||||
threadList.filter { it !== Thread.currentThread() && it.name != "DestroyJavaVM"}.forEach {
|
||||
println (" Thread ${it.name} still running in UncivGame.dispose().")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -80,25 +80,26 @@ class GameSaver {
|
|||
// On the other hand if we alter the game data while it's being serialized we could get a concurrent modification exception.
|
||||
// So what we do is we clone all the game data and serialize the clone.
|
||||
val gameInfoClone = gameInfo.clone()
|
||||
thread(name="Autosave") {
|
||||
saveGame(gameInfoClone, "Autosave")
|
||||
|
||||
// keep auto-saves for the last 10 turns for debugging purposes
|
||||
val newAutosaveFilename = saveFilesFolder + File.separator + "Autosave-${gameInfo.currentPlayer}-${gameInfoClone.turns}"
|
||||
getSave("Autosave").copyTo(Gdx.files.local(newAutosaveFilename))
|
||||
|
||||
fun getAutosaves(): List<String> { return getSaves().filter { it.startsWith("Autosave") } }
|
||||
while(getAutosaves().size>10){
|
||||
val saveToDelete = getAutosaves().minBy { getSave(it).lastModified() }!!
|
||||
deleteSave(saveToDelete)
|
||||
}
|
||||
|
||||
thread(name = "Autosave") {
|
||||
autoSaveSingleThreaded(gameInfoClone)
|
||||
// do this on main thread
|
||||
Gdx.app.postRunnable {
|
||||
postRunnable()
|
||||
}
|
||||
}
|
||||
}
|
||||
fun autoSaveSingleThreaded (gameInfo: GameInfo) {
|
||||
saveGame(gameInfo, "Autosave")
|
||||
|
||||
// keep auto-saves for the last 10 turns for debugging purposes
|
||||
val newAutosaveFilename = saveFilesFolder + File.separator + "Autosave-${gameInfo.currentPlayer}-${gameInfo.turns}"
|
||||
getSave("Autosave").copyTo(Gdx.files.local(newAutosaveFilename))
|
||||
|
||||
fun getAutosaves(): List<String> { return getSaves().filter { it.startsWith("Autosave") } }
|
||||
while(getAutosaves().size>10){
|
||||
val saveToDelete = getAutosaves().minBy { getSave(it).lastModified() }!!
|
||||
deleteSave(saveToDelete)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,11 +11,14 @@ import com.badlogic.gdx.tools.texturepacker.TexturePacker
|
|||
import com.unciv.UncivGame
|
||||
import com.unciv.models.translations.tr
|
||||
import java.io.File
|
||||
import kotlin.concurrent.thread
|
||||
import java.util.*
|
||||
import kotlin.concurrent.timer
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
|
||||
internal object DesktopLauncher {
|
||||
private var discordTimer: Timer? = null
|
||||
|
||||
@JvmStatic
|
||||
fun main(arg: Array<String>) {
|
||||
|
||||
|
@ -27,9 +30,9 @@ internal object DesktopLauncher {
|
|||
config.title = "Unciv"
|
||||
config.useHDPI = true
|
||||
|
||||
val versionFromJar = DesktopLauncher.javaClass.`package`.specificationVersion
|
||||
val versionFromJar = DesktopLauncher.javaClass.`package`.specificationVersion ?: "Desktop"
|
||||
|
||||
val game = UncivGame(if (versionFromJar != null) versionFromJar else "Desktop", null){exitProcess(0)}
|
||||
val game = UncivGame ( versionFromJar, null, { exitProcess(0) }, { discordTimer?.cancel() } )
|
||||
|
||||
if(!RaspberryPiDetector.isRaspberryPi()) // No discord RPC for Raspberry Pi, see https://github.com/yairm210/Unciv/issues/1624
|
||||
tryActivateDiscord(game)
|
||||
|
@ -71,27 +74,23 @@ internal object DesktopLauncher {
|
|||
}
|
||||
|
||||
private fun tryActivateDiscord(game: UncivGame) {
|
||||
|
||||
try {
|
||||
val handlers = DiscordEventHandlers()
|
||||
DiscordRPC.INSTANCE.Discord_Initialize("647066573147996161", handlers, true, null)
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(Thread { DiscordRPC.INSTANCE.Discord_Shutdown() })
|
||||
|
||||
thread {
|
||||
while (true) {
|
||||
try {
|
||||
updateRpc(game)
|
||||
}catch (ex:Exception){}
|
||||
Thread.sleep(1000)
|
||||
}
|
||||
discordTimer = timer(name = "Discord", daemon = true, period = 1000) {
|
||||
try {
|
||||
updateRpc(game)
|
||||
} catch (ex:Exception){}
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
print("Could not initialize Discord")
|
||||
println("Could not initialize Discord")
|
||||
}
|
||||
}
|
||||
|
||||
fun updateRpc(game: UncivGame) {
|
||||
private fun updateRpc(game: UncivGame) {
|
||||
if(!game.isInitialized) return
|
||||
val presence = DiscordRichPresence()
|
||||
val currentPlayerCiv = game.gameInfo.getCurrentPlayerCivilization()
|
||||
|
|
Loading…
Reference in a new issue