Consola en pantalla 

Algo que siempre he querido tener es la consola visual en pantalla. Lo encuentro útil porque puedo ver el evento directo sin tener que desviar la mirada hacia la consola.

Esta vez lo hago mas fácil y cómodo. Viendo los eventos en el mismo lugar donde ocurren ayuda mucho. LibGDX permite cambiar el «ApplicationLogger» a uno personalizado.

DebugPanelLogger.java

public class DebugPanelLogger implements ApplicationLogger {
  private final DebugPanel debugPanel;
  private final ApplicationLogger defaultLogger;

  public DebugPanelLogger(DebugPanel panel, ApplicationLogger defaultLogger) {
    this.debugPanel = panel;
    this.defaultLogger = defaultLogger;
  }

  @Override
  public void log(String tag, String message) {

    defaultLogger.log(tag, message);

    Gdx.app.postRunnable(() ->
      debugPanel.log("[" + tag + "] " + message, 5f));

  }
}

La clase DebugPanelLogger dirige los eventos hacia la consola regular y también hacia la pantalla por medio de la clase DebugPanel.java

DebugPanel.java

public class DebugPanel extends VerticalGroup {

    private float updateTimer = 0;
    private static final float UPDATE_INTERVAL = 0.25f;

    private final Pool<Label> labelPool;
    private final Label.LabelStyle labelStyle;
    private final Label drawCalls;
    private final Label vertexCount;
    private final Label bindings;
    private final Label drawCount;
    private final Label resolution;
    private final Label fps;
    private final Label javaHeap;
    private final Label nativeHeap;
    public final ProfileData profileData = new ProfileData();
    private final StringBuilder stringBuilder = new StringBuilder();

    public DebugPanel() {

        setTouchable(Touchable.disabled);

        bottom().left().columnLeft().pad(30).space(3f).reverse().setFillParent(true);

        NinePatch backgroundPatch = RM.get().textureAtlas.createPatch("rounded_rectangle");
        NinePatchDrawable drawable = new NinePatchDrawable(backgroundPatch);

        labelStyle = new Label.LabelStyle();
        labelStyle.font = RM.get().font;
        labelStyle.fontColor = Color.WHITE;
        labelStyle.background = drawable;

        labelPool = new Pool<>() {

            @Override
            protected Label newObject() {
                Label label = new Label("", labelStyle);
                label.setFontScale(.5f);
                label.setTouchable(Touchable.disabled);
                return label;
            }
        };

        addActor(resolution = labelPool.obtain());
        addActor(bindings = labelPool.obtain());
        addActor(drawCalls = labelPool.obtain());
        addActor(vertexCount = labelPool.obtain());
        addActor(drawCount = labelPool.obtain());
        addActor(fps = labelPool.obtain());
        addActor(javaHeap = labelPool.obtain());
        addActor(nativeHeap = labelPool.obtain());

        fps.setFontScale(.75f);
    }

    @Override
    public void act(float delta) {
        super.act(delta);

        updateTimer += delta;

        if (updateTimer >= UPDATE_INTERVAL) {
            updateTimer = 0;
            updateStats();
        }
    }

    private void updateStats() {

        updateLabel(fps, "FPS: ", Gdx.graphics.getFramesPerSecond(), "");
        updateLabel(drawCalls, "DRAW CALLS: ",profileData.drawCalls, "");
        updateLabel(vertexCount, "VERTEX COUNT: ", profileData.vertexCount, "");
        updateLabel(bindings, "TEXTURE BINDINGS: ", profileData.textureBindings, "");
        updateLabel(drawCount, "DRAW COUNT: ", profileData.drawCount, "");

        long heap;

        heap = Gdx.app.getJavaHeap() / 1024 / 1024;
        updateLabel(javaHeap, "JAVA HEAP: ", heap, "MB");

        heap = Gdx.app.getNativeHeap() / 1024 / 1024;
        updateLabel(nativeHeap, "NATIVE HEAP: ",heap , "MB");
    }

    private void updateLabel(Label label, String prefix, long value, String suffix) {
        stringBuilder.setLength(0);
        stringBuilder.append(prefix).append(value).append(suffix);
        label.setText(stringBuilder);
    }

    @Override
    protected void sizeChanged() {
        super.sizeChanged();
        if (getStage() != null) {

            stringBuilder.setLength(0);
            stringBuilder.append("RESOLUTION: ");
            stringBuilder.append(Math.round(getStage().getWidth()));
            stringBuilder.append("x");
            stringBuilder.append(Math.round(getStage().getHeight()));

            resolution.setText(stringBuilder);
        }
    }

    public void log(String text, float duration) {

        Label label = labelPool.obtain();
        label.setText(text);

        addActor(label);

        label.addAction(Actions.sequence(
            Actions.delay(duration),
            Actions.fadeOut(0.5f),
            Actions.run(() -> removeAndFree(label))
        ));
    }

    public void addActiveLabel(Label label) {
        addActor(label);
    }

    private void removeAndFree(Label label) {
        label.remove();
        label.clearActions();
        label.getColor().a = 1;
        label.setDebug(false);
        labelPool.free(label);
    }
}

La clase utiliza un Pool the Labels (6, 33) porque los eventos solo duran unos segundos y desaparecen pero también puedo añadir cualquier evento permanente (44 – 51). Como son Labels puedo modificar el tamaño de la letra (53).

Para evitar desperdiciar ciclos de CPU limito la actualización de los eventos permanentes a cuatro veces por segundo. (62).

Y así se ve:

Únete a otros 36 suscriptores

Deja una respuesta

Anuncios


Anuncios