reading savefiles won't freeze the ui (too much)

This commit is contained in:
minjaesong
2021-10-01 22:54:18 +09:00
parent ba25e4f203
commit ea507d4d8e
6 changed files with 256 additions and 173 deletions

View File

@@ -16,7 +16,6 @@ import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.JsonValue; import com.badlogic.gdx.utils.JsonValue;
import com.github.strikerx3.jxinput.XInputDevice; import com.github.strikerx3.jxinput.XInputDevice;
import kotlin.Pair;
import net.torvald.gdx.graphics.PixmapIO2; import net.torvald.gdx.graphics.PixmapIO2;
import net.torvald.getcpuname.GetCpuName; import net.torvald.getcpuname.GetCpuName;
import net.torvald.terrarum.concurrent.ThreadExecutor; import net.torvald.terrarum.concurrent.ThreadExecutor;
@@ -32,9 +31,7 @@ import net.torvald.terrarum.modulebasegame.IngameRenderer;
import net.torvald.terrarum.modulebasegame.TerrarumIngame; import net.torvald.terrarum.modulebasegame.TerrarumIngame;
import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory; import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory;
import net.torvald.terrarum.serialise.WriteConfig; import net.torvald.terrarum.serialise.WriteConfig;
import net.torvald.terrarum.serialise.WriteMeta;
import net.torvald.terrarum.tvda.DiskSkimmer; import net.torvald.terrarum.tvda.DiskSkimmer;
import net.torvald.terrarum.tvda.VirtualDisk;
import net.torvald.terrarum.utils.JsonFetcher; import net.torvald.terrarum.utils.JsonFetcher;
import net.torvald.terrarum.worlddrawer.CreateTileAtlas; import net.torvald.terrarum.worlddrawer.CreateTileAtlas;
import net.torvald.terrarumsansbitmap.gdx.GameFontBase; import net.torvald.terrarumsansbitmap.gdx.GameFontBase;
@@ -235,7 +232,7 @@ public class App implements ApplicationListener {
private static com.badlogic.gdx.graphics.Color gradWhiteTop = new com.badlogic.gdx.graphics.Color(0xf8f8f8ff); private static com.badlogic.gdx.graphics.Color gradWhiteTop = new com.badlogic.gdx.graphics.Color(0xf8f8f8ff);
private static com.badlogic.gdx.graphics.Color gradWhiteBottom = new com.badlogic.gdx.graphics.Color(0xd8d8d8ff); private static com.badlogic.gdx.graphics.Color gradWhiteBottom = new com.badlogic.gdx.graphics.Color(0xd8d8d8ff);
private static Screen currenScreen; private static Screen currentScreen;
private static LoadScreenBase currentSetLoadScreen; private static LoadScreenBase currentSetLoadScreen;
public static Texture textureWhiteSquare; public static Texture textureWhiteSquare;
@@ -288,6 +285,10 @@ public class App implements ApplicationListener {
"xinput", "xbox", "game", "joy", "pad" "xinput", "xbox", "game", "joy", "pad"
}; };
public static Screen getCurrentScreen() {
return currentScreen;
}
public static void main(String[] args) { public static void main(String[] args) {
// print copyright message // print copyright message
System.out.println(csiB+GAME_NAME+" "+csiG+getVERSION_STRING()+" "+csiK+"\u2014"+" "+csi0+TerrarumAppConfiguration.COPYRIGHT_DATE_NAME); System.out.println(csiB+GAME_NAME+" "+csiG+getVERSION_STRING()+" "+csiK+"\u2014"+" "+csi0+TerrarumAppConfiguration.COPYRIGHT_DATE_NAME);
@@ -521,7 +522,7 @@ public class App implements ApplicationListener {
// draw splash screen when predefined screen is null // draw splash screen when predefined screen is null
// because in normal operation, the only time screen == null is when the app is cold-launched // because in normal operation, the only time screen == null is when the app is cold-launched
// you can't have a text drawn here :v // you can't have a text drawn here :v
if (currenScreen == null) { if (currentScreen == null) {
drawSplash(); drawSplash();
loadTimer += Gdx.graphics.getDeltaTime(); loadTimer += Gdx.graphics.getDeltaTime();
@@ -539,10 +540,10 @@ public class App implements ApplicationListener {
} }
// draw the screen // draw the screen
else { else {
currenScreen.render(UPDATE_RATE); currentScreen.render(UPDATE_RATE);
} }
KeyToggler.INSTANCE.update(currenScreen instanceof TerrarumIngame); KeyToggler.INSTANCE.update(currentScreen instanceof TerrarumIngame);
// nested FBOs are just not a thing in GL! // nested FBOs are just not a thing in GL!
net.torvald.terrarum.FrameBufferManager.end(); net.torvald.terrarum.FrameBufferManager.end();
@@ -663,7 +664,7 @@ public class App implements ApplicationListener {
scr.setDimension(width, height); scr.setDimension(width, height);
if (currenScreen != null) currenScreen.resize(scr.getWidth(), scr.getHeight()); if (currentScreen != null) currentScreen.resize(scr.getWidth(), scr.getHeight());
updateFullscreenQuad(scr.getWidth(), scr.getHeight()); updateFullscreenQuad(scr.getWidth(), scr.getHeight());
@@ -692,9 +693,9 @@ public class App implements ApplicationListener {
System.out.println("Goodbye !"); System.out.println("Goodbye !");
if (currenScreen != null) { if (currentScreen != null) {
currenScreen.hide(); currentScreen.hide();
currenScreen.dispose(); currentScreen.dispose();
} }
//IngameRenderer.INSTANCE.dispose(); //IngameRenderer.INSTANCE.dispose();
@@ -741,12 +742,12 @@ public class App implements ApplicationListener {
@Override @Override
public void pause() { public void pause() {
if (currenScreen != null) currenScreen.pause(); if (currentScreen != null) currentScreen.pause();
} }
@Override @Override
public void resume() { public void resume() {
if (currenScreen != null) currenScreen.resume(); if (currentScreen != null) currentScreen.resume();
} }
public static LoadScreenBase getLoadScreen() { public static LoadScreenBase getLoadScreen() {
@@ -773,26 +774,26 @@ public class App implements ApplicationListener {
// this whole thing is directtly copied from com.badlogic.gdx.Game // this whole thing is directtly copied from com.badlogic.gdx.Game
if (currenScreen != null) { if (currentScreen != null) {
printdbg("AppLoader-Static", "Screen before change: " + currenScreen.getClass().getCanonicalName()); printdbg("AppLoader-Static", "Screen before change: " + currentScreen.getClass().getCanonicalName());
currenScreen.hide(); currentScreen.hide();
currenScreen.dispose(); currentScreen.dispose();
} }
else { else {
printdbg("AppLoader-Static", "Screen before change: null"); printdbg("AppLoader-Static", "Screen before change: null");
} }
currenScreen = screen; currentScreen = screen;
currenScreen.show(); currentScreen.show();
currenScreen.resize(scr.getWidth(), scr.getHeight()); currentScreen.resize(scr.getWidth(), scr.getHeight());
System.gc(); System.gc();
printdbg("AppLoader-Static", "Screen transition complete: " + currenScreen.getClass().getCanonicalName()); printdbg("AppLoader-Static", "Screen transition complete: " + currentScreen.getClass().getCanonicalName());
} }
/** /**

View File

@@ -113,7 +113,7 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) {
val uiContainer = UIContainer() val uiContainer = UIContainer()
private lateinit var uiMenu: UICanvas internal lateinit var uiRemoCon: UICanvas
internal lateinit var uiFakeBlurOverlay: UICanvas internal lateinit var uiFakeBlurOverlay: UICanvas
private lateinit var worldFBO: FrameBuffer private lateinit var worldFBO: FrameBuffer
@@ -189,12 +189,12 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) {
uiContainer.add(uiFakeBlurOverlay) uiContainer.add(uiFakeBlurOverlay)
uiMenu = UIRemoCon(this, UITitleRemoConYaml(App.savegames.isNotEmpty())) uiRemoCon = UIRemoCon(this, UITitleRemoConYaml(App.savegames.isNotEmpty()))
uiMenu.setPosition(0, 0) uiRemoCon.setPosition(0, 0)
uiMenu.setAsOpen() uiRemoCon.setAsOpen()
uiContainer.add(uiMenu) uiContainer.add(uiRemoCon)
CommandDict // invoke CommandDict // invoke
// TODO add console here // TODO add console here
@@ -340,10 +340,10 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) {
// resize UI by re-creating it (!!) // resize UI by re-creating it (!!)
uiMenu.resize(App.scr.width, App.scr.height) uiRemoCon.resize(App.scr.width, App.scr.height)
// TODO I forgot what the fuck kind of hack I was talking about // TODO I forgot what the fuck kind of hack I was talking about
//uiMenu.setPosition(0, UITitleRemoConRoot.menubarOffY) //uiMenu.setPosition(0, UITitleRemoConRoot.menubarOffY)
uiMenu.setPosition(0, 0) // shitty hack. Could be: uiRemoCon.setPosition(0, 0) // shitty hack. Could be:
// 1: Init code and resize code are different // 1: Init code and resize code are different
// 2: The UI is coded shit // 2: The UI is coded shit
@@ -354,7 +354,7 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) {
} }
override fun dispose() { override fun dispose() {
uiMenu.dispose() uiRemoCon.dispose()
demoWorld.dispose() demoWorld.dispose()
} }

View File

@@ -15,10 +15,8 @@ import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.serialise.Common import net.torvald.terrarum.serialise.Common
import net.torvald.terrarum.serialise.LoadSavegame import net.torvald.terrarum.serialise.LoadSavegame
import net.torvald.terrarum.serialise.ReadMeta import net.torvald.terrarum.serialise.ReadMeta
import net.torvald.terrarum.tvda.ByteArray64InputStream import net.torvald.terrarum.serialise.WriteMeta
import net.torvald.terrarum.tvda.DiskSkimmer import net.torvald.terrarum.tvda.*
import net.torvald.terrarum.tvda.EntryFile
import net.torvald.terrarum.tvda.VDUtil
import net.torvald.terrarum.ui.* import net.torvald.terrarum.ui.*
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import java.time.Instant import java.time.Instant
@@ -29,6 +27,8 @@ import java.util.zip.GZIPInputStream
import kotlin.math.roundToInt import kotlin.math.roundToInt
/** /**
* Only works if current screen set by the App is [TitleScreen]
*
* Created by minjaesong on 2021-09-09. * Created by minjaesong on 2021-09-09.
*/ */
class UILoadDemoSavefiles : UICanvas() { class UILoadDemoSavefiles : UICanvas() {
@@ -37,6 +37,9 @@ class UILoadDemoSavefiles : UICanvas() {
CommonResourcePool.addToLoadingList("terrarum-defaultsavegamethumb") { CommonResourcePool.addToLoadingList("terrarum-defaultsavegamethumb") {
TextureRegion(Texture(Gdx.files.internal("assets/graphics/gui/savegame_thumb_placeholder.png"))) TextureRegion(Texture(Gdx.files.internal("assets/graphics/gui/savegame_thumb_placeholder.png")))
} }
CommonResourcePool.addToLoadingList("savegame_status_icon") {
TextureRegionPack("assets/graphics/gui/savegame_status_icon.tga", 24, 24)
}
CommonResourcePool.loadAll() CommonResourcePool.loadAll()
} }
@@ -52,21 +55,21 @@ class UILoadDemoSavefiles : UICanvas() {
private val shapeRenderer = ShapeRenderer() private val shapeRenderer = ShapeRenderer()
private val uiWidth = UIItemDemoSaveCells.WIDTH // 480 internal val uiWidth = UIItemDemoSaveCells.WIDTH // 480
private val uiX = (width - uiWidth) / 2 internal val uiX = (width - uiWidth) / 2
private val textH = App.fontGame.lineHeight.toInt() internal val textH = App.fontGame.lineHeight.toInt()
private val cellGap = 20 internal val cellGap = 20
private val cellInterval = cellGap + UIItemDemoSaveCells.HEIGHT internal val cellInterval = cellGap + UIItemDemoSaveCells.HEIGHT
private val gradAreaHeight = 32 internal val gradAreaHeight = 32
private val titleTextPosY: Int = App.scr.tvSafeGraphicsHeight + 10 internal val titleTextPosY: Int = App.scr.tvSafeGraphicsHeight + 10
private val titleTopGradStart: Int = titleTextPosY + textH internal val titleTopGradStart: Int = titleTextPosY + textH
private val titleTopGradEnd: Int = titleTopGradStart + gradAreaHeight internal val titleTopGradEnd: Int = titleTopGradStart + gradAreaHeight
private val titleBottomGradStart: Int = height - App.scr.tvSafeGraphicsHeight - gradAreaHeight internal val titleBottomGradStart: Int = height - App.scr.tvSafeGraphicsHeight - gradAreaHeight
private val titleBottomGradEnd: Int = titleBottomGradStart + gradAreaHeight internal val titleBottomGradEnd: Int = titleBottomGradStart + gradAreaHeight
private val controlHelperY: Int = titleBottomGradStart + gradAreaHeight - textH internal val controlHelperY: Int = titleBottomGradStart + gradAreaHeight - textH
private val controlHelp: String private val controlHelp: String
@@ -89,24 +92,42 @@ class UILoadDemoSavefiles : UICanvas() {
private var sliderFBO = FrameBuffer(Pixmap.Format.RGBA8888, uiWidth + 10, height, true) private var sliderFBO = FrameBuffer(Pixmap.Format.RGBA8888, uiWidth + 10, height, true)
private var showSpinner = false
override fun show() { override fun show() {
printdbg(this, "savefiles show()") printdbg(this, "savefiles show()")
// read savegames try {
var savegamesCount = 0 val remoCon = (App.getCurrentScreen() as TitleScreen).uiRemoCon
App.savegames.forEach { skimmer ->
val x = uiX remoCon.handler.lockToggle()
val y = titleTopGradEnd + cellInterval * savegamesCount showSpinner = true
try {
addUIitem(UIItemDemoSaveCells(this, x, y, skimmer)) Thread {
savegamesCount += 1 // read savegames
} var savegamesCount = 0
catch (e: Throwable) { App.savegames.forEach { skimmer ->
System.err.println("[UILoadDemoSavefiles] Savefile '${skimmer.diskFile.absolutePath}' cannot be loaded") val x = uiX
e.printStackTrace() val y = titleTopGradEnd + cellInterval * savegamesCount
} try {
addUIitem(UIItemDemoSaveCells(this, x, y, skimmer))
savegamesCount += 1
}
catch (e: Throwable) {
System.err.println("[UILoadDemoSavefiles] Savefile '${skimmer.diskFile.absolutePath}' cannot be loaded")
e.printStackTrace()
}
}
remoCon.handler.unlockToggle()
showSpinner = false
}.start()
} }
catch (e: UninitializedPropertyAccessException) {}
} }
override fun hide() { override fun hide() {
@@ -132,8 +153,8 @@ class UILoadDemoSavefiles : UICanvas() {
} }
} }
for (index in 0 until uiItems.size) {
uiItems.forEachIndexed { index, it -> val it = uiItems[index]
if (index in listScroll - 2 until listScroll + savesVisible + 2) { if (index in listScroll - 2 until listScroll + savesVisible + 2) {
// re-position // re-position
it.posY = (it.initialY - uiScroll).roundToInt() it.posY = (it.initialY - uiScroll).roundToInt()
@@ -155,7 +176,8 @@ class UILoadDemoSavefiles : UICanvas() {
setCameraPosition(batch, camera, 0f, 0f) setCameraPosition(batch, camera, 0f, 0f)
batch.color = Color.WHITE batch.color = Color.WHITE
batch.inUse { batch.inUse {
uiItems.forEachIndexed { index, it -> for (index in 0 until uiItems.size) {
val it = uiItems[index]
if (index in listScroll - 2 until listScroll + savesVisible + 2) { if (index in listScroll - 2 until listScroll + savesVisible + 2) {
it.render(batch, camera) it.render(batch, camera)
} }
@@ -303,27 +325,37 @@ class UIItemDemoSaveCells(
const val HEIGHT = 120 const val HEIGHT = 120
} }
init {
CommonResourcePool.addToLoadingList("savegame_status_icon") {
TextureRegionPack("assets/graphics/gui/savegame_status_icon.tga", 24, 24)
}
CommonResourcePool.loadAll()
private val metaFile: DiskEntry?
private val saveName: String
private val saveMode: Int
private val isQuick: Boolean
private val isAuto: Boolean
private val meta: WriteMeta.WorldMeta?
private val saveDamaged: Boolean
private val lastPlayedTimestamp: String
init {
printdbg(this, "Rebuilding skimmer for savefile ${skimmer.diskFile.absolutePath}") printdbg(this, "Rebuilding skimmer for savefile ${skimmer.diskFile.absolutePath}")
skimmer.rebuild() skimmer.rebuild()
metaFile = skimmer.requestFile(-1)
saveName = skimmer.getDiskName(Common.CHARSET)
saveMode = skimmer.getSaveMode()
isQuick = (saveMode % 2 == 1)
isAuto = (saveMode.ushr(1) != 0)
meta = if (metaFile != null) ReadMeta.fromDiskEntry(metaFile) else null
saveDamaged = checkForSavegameDamage(skimmer)
lastPlayedTimestamp = if (meta != null)
Instant.ofEpochSecond(meta.lastplay_t)
.atZone(TimeZone.getDefault().toZoneId())
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +
"/${parseDuration(meta.playtime_t)}"
else "--:--:--/--h--m--s"
} }
private var saveDamaged = checkForSavegameDamage(skimmer)
override val width: Int = WIDTH
override val height: Int = HEIGHT
private var thumbPixmap: Pixmap? = null
private var thumb: TextureRegion? = null
private val grad = CommonResourcePool.getAsTexture("title_halfgrad")
private val icons = CommonResourcePool.getAsTextureRegionPack("savegame_status_icon")
private fun parseDuration(seconds: Long): String { private fun parseDuration(seconds: Long): String {
val s = seconds % 60 val s = seconds % 60
val m = (seconds / 60) % 60 val m = (seconds / 60) % 60
@@ -335,36 +367,20 @@ class UIItemDemoSaveCells(
"${d}d${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s" "${d}d${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s"
} }
private val metaFile = skimmer.requestFile(-1) override val width: Int = WIDTH
override val height: Int = HEIGHT
private val saveName = skimmer.getDiskName(Common.CHARSET) private var thumbPixmap: Pixmap? = null
private val saveMode = skimmer.getSaveMode() private var thumb: TextureRegion? = null
private val isQuick = (saveMode % 2 == 1) private val grad = CommonResourcePool.getAsTexture("title_halfgrad")
private val isAuto = (saveMode.ushr(1) != 0)
private val meta = if (metaFile != null) ReadMeta.fromDiskEntry(metaFile) else null
private val colourBad = Color(0xFF8888FF.toInt()) private val icons = CommonResourcePool.getAsTextureRegionPack("savegame_status_icon")
private val colourBad = Color(0xFF0011FF.toInt())
private val lastPlayedTimestamp = if (meta != null)
Instant.ofEpochSecond(meta.lastplay_t)
.atZone(TimeZone.getDefault().toZoneId())
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +
"/${parseDuration(meta.playtime_t)}"
else "--:--:--/--h--m--s"
init { init {
// load thumbnail or use stock if the file is not there
skimmer.requestFile(-2)?.let {
val zippedTga = (it.contents as EntryFile).bytes
val gzin = GZIPInputStream(ByteArray64InputStream(zippedTga))
val tgaFileContents = gzin.readAllBytes(); gzin.close()
thumbPixmap = Pixmap(tgaFileContents, 0, tgaFileContents.size)
val thumbTex = Texture(thumbPixmap)
thumbTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
thumb = TextureRegion(thumbTex)
thumb!!.setRegion(0, (thumbTex.height - 2 * height) / 2, width * 2, height * 2)
}
} }
@@ -372,7 +388,29 @@ class UIItemDemoSaveCells(
LoadSavegame(VDUtil.readDiskArchive(skimmer.diskFile, Level.INFO)) LoadSavegame(VDUtil.readDiskArchive(skimmer.diskFile, Level.INFO))
} }
internal var hasTexture = false
private set
override fun render(batch: SpriteBatch, camera: Camera) { override fun render(batch: SpriteBatch, camera: Camera) {
// try to generate a texture
if (skimmer.initialised && !hasTexture) {
// load thumbnail or use stock if the file is not there
skimmer.requestFile(-2)?.let {
val zippedTga = (it.contents as EntryFile).bytes
val gzin = GZIPInputStream(ByteArray64InputStream(zippedTga))
val tgaFileContents = gzin.readAllBytes(); gzin.close()
thumbPixmap = Pixmap(tgaFileContents, 0, tgaFileContents.size)
val thumbTex = Texture(thumbPixmap)
thumbTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
thumb = TextureRegion(thumbTex)
thumb!!.setRegion(0, (thumbTex.height - 2 * height) / 2, width * 2, height * 2)
}
hasTexture = true
}
val highlightCol = if (mouseUp) UIItemTextButton.defaultActiveCol else Color.WHITE val highlightCol = if (mouseUp) UIItemTextButton.defaultActiveCol else Color.WHITE
val x = posX.toFloat() val x = posX.toFloat()
val y = posY.toFloat() val y = posY.toFloat()

View File

@@ -5,8 +5,11 @@ import com.badlogic.gdx.Input
import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.* import net.torvald.terrarum.App
import net.torvald.terrarum.App.printdbgerr import net.torvald.terrarum.App.printdbgerr
import net.torvald.terrarum.QNDTreeNode
import net.torvald.terrarum.TitleScreen
import net.torvald.terrarum.Yaml
import net.torvald.terrarum.serialise.WriteConfig import net.torvald.terrarum.serialise.WriteConfig
import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.ui.UIItemTextButton import net.torvald.terrarum.ui.UIItemTextButton
@@ -85,69 +88,71 @@ open class UIRemoCon(val parent: TitleScreen, treeRepresentation: QNDTreeNode<St
val selectedItem = remoConTray.selectedItem val selectedItem = remoConTray.selectedItem
val selectedIndex = remoConTray.selectedIndex val selectedIndex = remoConTray.selectedIndex
selectedItem?.let { if (!handler.uiToggleLocked) {
// selection change selectedItem?.let {
if (it.labelText == "MENU_LABEL_QUIT") { // selection change
//System.exit(0) if (it.labelText == "MENU_LABEL_QUIT") {
Gdx.app.exit() //System.exit(0)
} Gdx.app.exit()
else if (it.labelText.startsWith("MENU_LABEL_RETURN")) {
val tag = it.tags
if (tag.contains("WRITETOCONFIG")) WriteConfig()
if (currentRemoConContents.parent != null) {
remoConTray.consume()
currentRemoConContents = currentRemoConContents.parent!!
currentlySelectedRemoConItem = currentRemoConContents.data
remoConTray = generateNewRemoCon(currentRemoConContents)
parent.uiFakeBlurOverlay.setAsClose()
} }
else { else if (it.labelText.startsWith("MENU_LABEL_RETURN")) {
throw NullPointerException("No parent node to return") val tag = it.tags
} if (tag.contains("WRITETOCONFIG")) WriteConfig()
}
else {
// check if target exists
//println("current node: ${currentRemoConContents.data}")
//currentRemoConContents.children.forEach { println("- ${it.data}") }
if (currentRemoConContents.children.size > selectedIndex ?: 0x7FFFFFFF) {
val newCurrentRemoConContents = currentRemoConContents.children[selectedIndex!!] if (currentRemoConContents.parent != null) {
// only go deeper if that node has child to navigate
if (currentRemoConContents.children[selectedIndex].children.size != 0) {
remoConTray.consume() remoConTray.consume()
remoConTray = generateNewRemoCon(newCurrentRemoConContents)
currentRemoConContents = newCurrentRemoConContents currentRemoConContents = currentRemoConContents.parent!!
currentlySelectedRemoConItem = currentRemoConContents.data
remoConTray = generateNewRemoCon(currentRemoConContents)
parent.uiFakeBlurOverlay.setAsClose()
}
else {
throw NullPointerException("No parent node to return")
} }
currentlySelectedRemoConItem = newCurrentRemoConContents.data
} }
else { else {
throw RuntimeException("Index: $selectedIndex, Size: ${currentRemoConContents.children.size}") // check if target exists
//println("current node: ${currentRemoConContents.data}")
//currentRemoConContents.children.forEach { println("- ${it.data}") }
if (currentRemoConContents.children.size > selectedIndex ?: 0x7FFFFFFF) {
val newCurrentRemoConContents = currentRemoConContents.children[selectedIndex!!]
// only go deeper if that node has child to navigate
if (currentRemoConContents.children[selectedIndex].children.size != 0) {
remoConTray.consume()
remoConTray = generateNewRemoCon(newCurrentRemoConContents)
currentRemoConContents = newCurrentRemoConContents
}
currentlySelectedRemoConItem = newCurrentRemoConContents.data
}
else {
throw RuntimeException("Index: $selectedIndex, Size: ${currentRemoConContents.children.size}")
}
} }
}
// do something with the actual selection // do something with the actual selection
//printdbg(this, "$currentlySelectedRemoConItem") //printdbg(this, "$currentlySelectedRemoConItem")
screens.forEach { screens.forEach {
//printdbg(this, "> ${it.first}") //printdbg(this, "> ${it.first}")
if (currentlySelectedRemoConItem == it.first) { if (currentlySelectedRemoConItem == it.first) {
parent.uiFakeBlurOverlay.setAsOpen() parent.uiFakeBlurOverlay.setAsOpen()
it.second.setAsOpen() it.second.setAsOpen()
//printdbg(this, ">> ding - ${it.second.javaClass.canonicalName}") //printdbg(this, ">> ding - ${it.second.javaClass.canonicalName}")
} }
else { else {
it.second.setAsClose() it.second.setAsClose()
}
} }
} }
} }
@@ -277,30 +282,11 @@ open class UIRemoCon(val parent: TitleScreen, treeRepresentation: QNDTreeNode<St
tagsCollection = tags tagsCollection = tags
) )
private val spinner = CommonResourcePool.getAsTextureRegionPack("inline_loading_spinner")
private var spinnerTimer = 0f
private var spinnerFrame = 0
private val spinnerInterval = 1f / 60f
fun update(delta: Float) { fun update(delta: Float) {
spinnerTimer += delta
if (spinnerTimer > spinnerInterval) {
spinnerFrame = (spinnerFrame + 1) % 32
spinnerTimer -= spinnerInterval
}
menubar.update(delta) menubar.update(delta)
} }
fun render(batch: SpriteBatch, camera: Camera) { fun render(batch: SpriteBatch, camera: Camera) {
val spin = spinner.get(spinnerFrame % 8, spinnerFrame / 8)
val inlineOffsetY = if (App.GAME_LOCALE.startsWith("th")) 0f
else if (App.GAME_LOCALE.startsWith("ko")) 0f
else 1f
batch.draw(spin, menubar.posX + paddingLeft - 5f, menubar.posY + (lineHeight - 20) / 2 - inlineOffsetY)
menubar.render(batch, camera) menubar.render(batch, camera)
} }

View File

@@ -0,0 +1,58 @@
package net.torvald.terrarum.ui
import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.App
import net.torvald.terrarum.CommonResourcePool
/**
* Created by minjaesong on 2021-10-01.
*/
class UIAutosaveNotifier : UICanvas() {
override var width: Int
get() = TODO("Not yet implemented")
set(value) {}
override var height: Int
get() = TODO("Not yet implemented")
set(value) {}
override var openCloseTime = 0.2f
private val spinner = CommonResourcePool.getAsTextureRegionPack("inline_loading_spinner")
private var spinnerTimer = 0f
private var spinnerFrame = 0
private val spinnerInterval = 1f / 60f
override fun updateUI(delta: Float) {
spinnerTimer += delta
if (spinnerTimer > spinnerInterval) {
spinnerFrame = (spinnerFrame + 1) % 32
spinnerTimer -= spinnerInterval
}
}
override fun renderUI(batch: SpriteBatch, camera: Camera) {
val spin = spinner.get(spinnerFrame % 8, spinnerFrame / 8)
val inlineOffsetY = if (App.GAME_LOCALE.startsWith("th")) 0f
else if (App.GAME_LOCALE.startsWith("ko")) 0f
else 1f
batch.draw(spin, posX.toFloat(), posY.toFloat())
}
override fun doOpening(delta: Float) {
}
override fun doClosing(delta: Float) {
}
override fun endOpening(delta: Float) {
}
override fun endClosing(delta: Float) {
}
override fun dispose() {
}
}

View File

@@ -118,7 +118,7 @@ void main() {
private val shader = App.loadShaderInline(SHADER_PROG_VERT, SHADER_PROG_FRAG) private val shader = App.loadShaderInline(SHADER_PROG_VERT, SHADER_PROG_FRAG)
private var uiToggleLocked = false var uiToggleLocked = false; private set
init { init {
//UI.handler = this //UI.handler = this