diff --git a/core/src/cz/nic/tablexia/Tablexia.java b/core/src/cz/nic/tablexia/Tablexia.java index 35f18a72098e9a60971282b085dffbb3590516e0..fab42651090f597bdb989d520674ad2ac1ac4854 100644 --- a/core/src/cz/nic/tablexia/Tablexia.java +++ b/core/src/cz/nic/tablexia/Tablexia.java @@ -89,6 +89,7 @@ public class Tablexia extends TablexiaApplication { @Override public void dispose() { + ApplicationBus.getInstance().unsubscribe(this); ApplicationTextureManager.getInstance().dispose(); ApplicationFontManager.getInstance().dispose(); ApplicationTextManager.getInstance().dispose(); diff --git a/core/src/cz/nic/tablexia/TablexiaApplication.java b/core/src/cz/nic/tablexia/TablexiaApplication.java index 6e6610f0ae44ad07096451eccf3fe169f3e4909c..0c43f3ea996e8dafa7712bd25fa3276242bbb206 100644 --- a/core/src/cz/nic/tablexia/TablexiaApplication.java +++ b/core/src/cz/nic/tablexia/TablexiaApplication.java @@ -18,6 +18,9 @@ import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Stage; +import cz.nic.tablexia.bus.ApplicationBus; +import cz.nic.tablexia.bus.ApplicationBus.ApplicationEvent; +import cz.nic.tablexia.debug.DebugInfo; import cz.nic.tablexia.graphics.ColorTexture; import cz.nic.tablexia.screen.AbstractTablexiaScreen; import cz.nic.tablexia.screen.AbstractTablexiaScreen.ScreenLoadingListener; @@ -35,6 +38,7 @@ public abstract class TablexiaApplication implements ApplicationListener { private AbstractTablexiaScreen<?> lastScreen; private AbstractTablexiaScreen<?> screen; private InputMultiplexer inputMultiplexer; + private DebugInfo debugInfo; private Stage stage; @@ -48,6 +52,9 @@ public abstract class TablexiaApplication implements ApplicationListener { @Override public void dispose () { inputMultiplexer.removeProcessor(stage); + if (TablexiaSettings.isDebug()) { + debugInfo.dispose(); + } stage.dispose(); if (lastScreen != null) { lastScreen.hide(); @@ -76,6 +83,7 @@ public abstract class TablexiaApplication implements ApplicationListener { stage = new Stage(); inputMultiplexer = new InputMultiplexer(stage); Gdx.input.setInputProcessor(inputMultiplexer); + prepareDebugInfo(); } @Override @@ -84,6 +92,9 @@ public abstract class TablexiaApplication implements ApplicationListener { Gdx.gl.glClearColor(BACKGROUND_COLOR.r, BACKGROUND_COLOR.g, BACKGROUND_COLOR.b, BACKGROUND_COLOR.a); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + if (TablexiaSettings.isDebug()) { + debugInfo.update(); + } float deltaTime = Gdx.graphics.getDeltaTime(); if (lastScreen != null) lastScreen.render(deltaTime); if (screen != null) screen.render(deltaTime); @@ -99,9 +110,32 @@ public abstract class TablexiaApplication implements ApplicationListener { stage.getViewport().update(width, height, true); } + +//////////////////////////// DEBUG INFO + + private void prepareDebugInfo() { + if (TablexiaSettings.isDebug()) { + debugInfo = new DebugInfo(getStage().getWidth(), getStage().getHeight()); + getStage().addActor(debugInfo); + } + } + //////////////////////////// SCREEN HANDLING + public static class ScreenChangedEvent implements ApplicationEvent { + + private Class<? extends AbstractTablexiaScreen<?>> screenClass; + + public ScreenChangedEvent(Class<? extends AbstractTablexiaScreen<?>> screenClass) { + this.screenClass = screenClass; + } + + public Class<? extends AbstractTablexiaScreen<?>> getScreenClass() { + return screenClass; + } + } + /** * Change current screen if is different from actual screen. * @@ -186,11 +220,13 @@ public abstract class TablexiaApplication implements ApplicationListener { return screen; } + @SuppressWarnings("unchecked") private void processNewScreen(AbstractTablexiaScreen<?> newScreen) { if (newScreen != null) { inputMultiplexer.addProcessor(newScreen.getInputProcessor()); newScreen.show(); newScreen.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + ApplicationBus.getInstance().post(new ScreenChangedEvent((Class<? extends AbstractTablexiaScreen<?>>) newScreen.getClass())).asynchronously(); } } @@ -200,6 +236,7 @@ public abstract class TablexiaApplication implements ApplicationListener { lastScreen.hide(); lastScreen.dispose(); lastScreen = null; + System.gc(); } } diff --git a/core/src/cz/nic/tablexia/debug/DebugInfo.java b/core/src/cz/nic/tablexia/debug/DebugInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..519fa375e5e5f7654606b633012dc3569e2723ae --- /dev/null +++ b/core/src/cz/nic/tablexia/debug/DebugInfo.java @@ -0,0 +1,151 @@ +package cz.nic.tablexia.debug; + +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.alpha; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentLinkedQueue; + +import net.engio.mbassy.listener.Handler; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Cell; +import com.badlogic.gdx.scenes.scene2d.ui.Container; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.Disposable; + +import cz.nic.tablexia.TablexiaApplication.ScreenChangedEvent; +import cz.nic.tablexia.bus.ApplicationBus; +import cz.nic.tablexia.graphics.ColorTexture; +import cz.nic.tablexia.screen.AbstractTablexiaScreen.ScreenInfoEvent; + +/** + * Debug info container + * + * @author Matyáš Latner + * + */ +public class DebugInfo extends Table implements Disposable { + + private static class DebugInfoComponent extends Table { + + private Map<String, Cell<Label>> infoCellMap; + private LabelStyle labelStyle; + + public DebugInfoComponent(float width, float height) { + infoCellMap = new HashMap<String, Cell<Label>>(); + setBounds(0, 0, width, height); + setBackground(new TextureRegionDrawable(new TextureRegion(new ColorTexture(1, 1, BACKGROUND_COLOR)))); + addAction(alpha(BACKGROUND_ALPHA)); + + labelStyle = new LabelStyle(new BitmapFont(), FONT_COLOR); + } + + public synchronized void setInfoValue(String infoKey, String infoValue) { + Cell<Label> cell = infoCellMap.get(infoKey); + if (cell == null) { + createInfoCell(infoKey, infoValue); + } else { + cell.getActor().setText(infoKey + KEY_COLON + infoValue); + } + } + + private void clean() { + clearChildren(); + infoCellMap.clear(); + } + + private void createInfoCell(String infoKey, String infoValue) { + Cell<Label> cell = add(new Label(infoKey + KEY_COLON + infoValue, labelStyle)); + infoCellMap.put(infoKey, cell); + if (getCells().size > 1) { + cell.pad(0, INFO_PADDING, 0, 0); + } + } + + @Override + public void setSize(float width, float height) { + super.setSize(width, height); + } + + } + + + private static final String NATIVE_HEAP = "Native Heap"; + private static final String JAVA_HEAP = "Java Heap"; + private static final String FPS = "FPS"; + + private static final String SCREEN_NAME = "Screen Name"; + + private static final int INFO_PADDING = 20; + private static final int MB_SIZE = 1000000; + private static final String UNIT_MB = " MB"; + private static final String KEY_COLON = ": "; + + private static final Color FONT_COLOR = Color.WHITE; + private static final Color BACKGROUND_COLOR = Color.BLACK; + private static final float BACKGROUND_ALPHA = 0.5f; + + private DebugInfoComponent applicationDebugInfo; + private DebugInfoComponent screenNameInfo; + private DebugInfoComponent screenDebugInfo; + + private ConcurrentLinkedQueue<ScreenInfoEvent> screenDebugInfoQueue = new ConcurrentLinkedQueue<ScreenInfoEvent>(); + private ConcurrentLinkedQueue<ScreenChangedEvent> screenNameInfoQueue = new ConcurrentLinkedQueue<ScreenChangedEvent>(); + + public DebugInfo(float width, float height) { + setBounds(0, 0, width, height); + ApplicationBus.getInstance().subscribe(this); + + applicationDebugInfo = new DebugInfoComponent(width, height); + screenNameInfo = new DebugInfoComponent(width, height); + screenDebugInfo = new DebugInfoComponent(width, height); + + Table topTable = new Table(); + topTable.add(screenNameInfo).expandX(); + topTable.add(screenDebugInfo).pad(0, INFO_PADDING, 0, 0).expandX(); + add(topTable); + row(); + add(new Container<Actor>()).expand(); + row(); + add(applicationDebugInfo).expandX(); + } + + public void update() { + applicationDebugInfo.setInfoValue(FPS, "" + Gdx.graphics.getFramesPerSecond()); + applicationDebugInfo.setInfoValue(JAVA_HEAP, ("" + Gdx.app.getJavaHeap() / MB_SIZE) + UNIT_MB); + applicationDebugInfo.setInfoValue(NATIVE_HEAP, ("" + Gdx.app.getNativeHeap() / MB_SIZE) + UNIT_MB); + + while (!screenDebugInfoQueue.isEmpty()) { + ScreenInfoEvent screenInfoEvent = screenDebugInfoQueue.poll(); + screenDebugInfo.setInfoValue(screenInfoEvent.getInfoKey(), screenInfoEvent.getInfoValue()); + } + + while (!screenNameInfoQueue.isEmpty()) { + screenNameInfo.setInfoValue(SCREEN_NAME, "" + screenNameInfoQueue.poll().getClass().getSimpleName()); + } + } + + @Handler + public void handleScreenChangedEvent(ScreenChangedEvent screenChangedEvent) { + screenDebugInfo.clean(); + screenNameInfoQueue.add(screenChangedEvent); + } + + @Handler + public void handleScreenInfoEvent(ScreenInfoEvent screenInfoEvent) { + screenDebugInfoQueue.add(screenInfoEvent); + } + + @Override + public void dispose() { + ApplicationBus.getInstance().unsubscribe(this); + } +} diff --git a/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java b/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java index f4aa0ec6cbc9f382f615d1280d66506cad243c96..9fc9f448a9c30e6374c4c817c040a3be659653fa 100644 --- a/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java +++ b/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java @@ -20,6 +20,8 @@ import com.badlogic.gdx.utils.I18NBundle; import com.badlogic.gdx.utils.async.AsyncTask; import com.badlogic.gdx.utils.viewport.ScreenViewport; +import cz.nic.tablexia.bus.ApplicationBus; +import cz.nic.tablexia.bus.ApplicationBus.ApplicationEvent; import cz.nic.tablexia.game.loader.AbstractDataManager; import cz.nic.tablexia.loader.IApplicationLoader; import cz.nic.tablexia.util.Log; @@ -71,6 +73,25 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter { void loadingComplete(); } + public static class ScreenInfoEvent implements ApplicationEvent { + + private String infoKey; + private String infoValue; + + public ScreenInfoEvent(String infoKey, String infoValue) { + this.infoKey = infoKey; + this.infoValue = infoValue; + } + + public String getInfoKey() { + return infoKey; + } + + public String getInfoValue() { + return infoValue; + } + } + private Stage stage; private AssetManager textureManager; private AssetManager soundManager; @@ -225,6 +246,10 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter { return null; } + protected void printScreenInfo(String infoKey, String infoValue) { + ApplicationBus.getInstance().post(new ScreenInfoEvent(infoKey, infoValue)).asynchronously(); + } + //////////////////////////// LOADERS