Resolved #3401, Resolved #3598, possibly resolved #3643 - game can be instantly closed and reopened on Android

From a practical standpoint - Reset all GL objects upon create(), since they lose all relevance when we have a new GL context
This commit is contained in:
Yair Morgenstern 2021-03-15 21:56:16 +02:00
parent d7214b7a46
commit 4fa0a2b4b8
3 changed files with 27 additions and 11 deletions

View File

@ -5,6 +5,7 @@ import com.badlogic.gdx.Game
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Input import com.badlogic.gdx.Input
import com.badlogic.gdx.audio.Music import com.badlogic.gdx.audio.Music
import com.badlogic.gdx.graphics.g2d.TextureAtlas
import com.badlogic.gdx.scenes.scene2d.actions.Actions import com.badlogic.gdx.scenes.scene2d.actions.Actions
import com.badlogic.gdx.utils.Align import com.badlogic.gdx.utils.Align
import com.unciv.logic.GameInfo import com.unciv.logic.GameInfo
@ -14,10 +15,7 @@ import com.unciv.models.metadata.GameSettings
import com.unciv.models.ruleset.RulesetCache import com.unciv.models.ruleset.RulesetCache
import com.unciv.models.translations.Translations import com.unciv.models.translations.Translations
import com.unciv.ui.LanguagePickerScreen import com.unciv.ui.LanguagePickerScreen
import com.unciv.ui.utils.CameraStageBaseScreen import com.unciv.ui.utils.*
import com.unciv.ui.utils.CrashController
import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.center
import com.unciv.ui.worldscreen.PlayerReadyScreen import com.unciv.ui.worldscreen.PlayerReadyScreen
import com.unciv.ui.worldscreen.WorldScreen import com.unciv.ui.worldscreen.WorldScreen
import java.util.* import java.util.*
@ -79,9 +77,23 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
// Whatever needs graphics needs to be done on the main thread, // Whatever needs graphics needs to be done on the main thread,
// So it's basically a long set of deferred actions. // So it's basically a long set of deferred actions.
settings = GameSaver.getGeneralSettings() // needed for the screen settings = GameSaver.getGeneralSettings() // needed for the screen
screen = LoadingScreen()
/** When we recreate the GL context for whatever reason (say - we moved to a split screen on Android),
* ALL objects that were related to the old context - need to be recreated.
* So far we have:
* - All textures (hence the texture atlas)
* - SpriteBatch (hence CameraStageBaseScreen uses a new SpriteBatch for each screen)
* - Skin (hence CameraStageBaseScreen.setSkin())
* - Font (hence Fonts.resetFont() inside setSkin())
*/
ImageGetter.atlas = TextureAtlas("game.atlas")
ImageGetter.setNewRuleset(ImageGetter.ruleset)
CameraStageBaseScreen.setSkin() // needs to come AFTER the Texture reset, since the buttons depend on it
Gdx.graphics.isContinuousRendering = settings.continuousRendering Gdx.graphics.isContinuousRendering = settings.continuousRendering
screen = LoadingScreen()
thread(name = "LoadJSON") { thread(name = "LoadJSON") {
RulesetCache.loadRulesets(printOutput = true) RulesetCache.loadRulesets(printOutput = true)
@ -96,6 +108,8 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
// This stuff needs to run on the main thread because it needs the GL context // This stuff needs to run on the main thread because it needs the GL context
Gdx.app.postRunnable { Gdx.app.postRunnable {
ImageGetter.ruleset = RulesetCache.getBaseRuleset() // so that we can enter the map editor without having to load a game first ImageGetter.ruleset = RulesetCache.getBaseRuleset() // so that we can enter the map editor without having to load a game first
thread(name="Music") { startMusic() } thread(name="Music") { startMusic() }
restoreSize() restoreSize()

View File

@ -41,7 +41,7 @@ open class CameraStageBaseScreen : Screen {
val width = resolutions[0] val width = resolutions[0]
val height = resolutions[1] val height = resolutions[1]
stage = Stage(ExtendViewport(width, height), batch) stage = Stage(ExtendViewport(width, height), SpriteBatch())
stage.addListener( stage.addListener(
@ -91,8 +91,10 @@ open class CameraStageBaseScreen : Screen {
} }
companion object { companion object {
val skin by lazy { lateinit var skin:Skin
val skin = Skin().apply { fun setSkin() {
Fonts.resetFont()
skin = Skin().apply {
add("Nativefont", Fonts.font, BitmapFont::class.java) add("Nativefont", Fonts.font, BitmapFont::class.java)
add("Button", ImageGetter.getRoundedEdgeTableBackground(), Drawable::class.java) add("Button", ImageGetter.getRoundedEdgeTableBackground(), Drawable::class.java)
addRegions(TextureAtlas("skin/flat-earth-ui.atlas")) addRegions(TextureAtlas("skin/flat-earth-ui.atlas"))

View File

@ -107,11 +107,11 @@ class NativeBitmapFontData(val fontImplementation: NativeFontImplementation) : B
} }
object Fonts { object Fonts {
val font by lazy { lateinit var font:BitmapFont
fun resetFont() {
val fontData = NativeBitmapFontData(UncivGame.Current.fontImplementation!!) val fontData = NativeBitmapFontData(UncivGame.Current.fontImplementation!!)
val font = BitmapFont(fontData, fontData.regions, false) font = BitmapFont(fontData, fontData.regions, false)
font.setOwnsTexture(true) font.setOwnsTexture(true)
font
} }
// From https://stackoverflow.com/questions/29451787/libgdx-textureregion-to-pixmap // From https://stackoverflow.com/questions/29451787/libgdx-textureregion-to-pixmap