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.Input
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.utils.Align
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.translations.Translations
import com.unciv.ui.LanguagePickerScreen
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.CrashController
import com.unciv.ui.utils.ImageGetter
import com.unciv.ui.utils.center
import com.unciv.ui.utils.*
import com.unciv.ui.worldscreen.PlayerReadyScreen
import com.unciv.ui.worldscreen.WorldScreen
import java.util.*
@ -79,9 +77,23 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
// Whatever needs graphics needs to be done on the main thread,
// So it's basically a long set of deferred actions.
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
screen = LoadingScreen()
thread(name = "LoadJSON") {
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
Gdx.app.postRunnable {
ImageGetter.ruleset = RulesetCache.getBaseRuleset() // so that we can enter the map editor without having to load a game first
thread(name="Music") { startMusic() }
restoreSize()

View File

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

View File

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