325 lines
10 KiB
Java
325 lines
10 KiB
Java
package speiger.src.coreengine.rendering.gui.components.window.debug;
|
|
|
|
import java.text.DecimalFormat;
|
|
import java.util.List;
|
|
import java.util.function.Consumer;
|
|
import java.util.function.Supplier;
|
|
|
|
import org.lwjgl.glfw.GLFW;
|
|
|
|
import speiger.src.collections.objects.lists.ObjectArrayList;
|
|
import speiger.src.collections.objects.utils.ObjectLists;
|
|
import speiger.src.coreengine.math.MathUtils;
|
|
import speiger.src.coreengine.math.misc.ColorUtils;
|
|
import speiger.src.coreengine.math.misc.Facing;
|
|
import speiger.src.coreengine.math.vector.floats.Vec2f;
|
|
import speiger.src.coreengine.rendering.gui.base.IKeyComponent;
|
|
import speiger.src.coreengine.rendering.gui.components.PieComponent;
|
|
import speiger.src.coreengine.rendering.gui.components.PieComponent.IPieIndex;
|
|
import speiger.src.coreengine.rendering.gui.components.PieComponent.PieIndex;
|
|
import speiger.src.coreengine.rendering.gui.components.SingleTabPanelComponent;
|
|
import speiger.src.coreengine.rendering.gui.components.TextComponent;
|
|
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
|
|
import speiger.src.coreengine.rendering.gui.helper.Align;
|
|
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
|
|
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
|
|
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
|
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
|
|
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
|
|
import speiger.src.coreengine.rendering.input.Keyboard;
|
|
import speiger.src.coreengine.utils.profiler.IProfiler;
|
|
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
|
|
import speiger.src.coreengine.utils.profiler.IProfiler.ProfilerData;
|
|
|
|
public class PieProfilerWindow extends WindowComponent implements Supplier<List<IPieIndex>>, IKeyComponent
|
|
{
|
|
public static final DecimalFormat PERCENT_FORMAT = new DecimalFormat("##0.00");
|
|
|
|
SingleTabPanelComponent panel = new SingleTabPanelComponent(Facing.SOUTH).onAction(this::onProfilerChanged).cast();
|
|
PieComponent pie = panel.getPanel().addChild(new PieComponent(127, this).setAutoUpdate(true), Constrains.parent(Target.WIDTH).dynamic(this::calculatePieHeight, Target.HEIGHT).build());
|
|
TextComponent[] extraFeatures = new TextComponent[] {
|
|
new TextComponent(0F, 0F, 18F, 7F),
|
|
new TextComponent(0F, 0F, 0F, 8F),
|
|
new TextComponent(0F, 8F, 0F, 7F)
|
|
};
|
|
List<TextComponent[]> entries = new ObjectArrayList<>();
|
|
List<ProfilerTab> tabs = new ObjectArrayList<>();
|
|
int previouseTab = -1;
|
|
int textInUse = 0;
|
|
IProfilerEntry currentEntry;
|
|
String entryName;
|
|
List<ProfilerData> lastValues = null;
|
|
|
|
public PieProfilerWindow(float x, float y, float width, float height, String name)
|
|
{
|
|
super(x, y, width, height, DEFAULT_FLAGS, name);
|
|
}
|
|
|
|
@Override
|
|
public boolean canMoveIntoForground()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void init()
|
|
{
|
|
super.init();
|
|
addChild(panel.set(0F, 7.5F).onChange(minimizedListener), Constrains.parent(0.25F, Target.WIDTH).parent(4F, Target.HEIGHT).build());
|
|
extraFeatures[0].setTextScale(0.3F).setText("[0] Back").horizontal(Align.LEFT_TOP);
|
|
extraFeatures[0].onChange(T -> T.setVisible(currentEntry != null && currentEntry.getParent() != null));
|
|
panel.getPanel().addChild(extraFeatures[0], Constrains.dynamic(() -> pie.getBox().getBaseHeight() - 7F, Target.Y).invPixel(38F, Target.WIDTH).build());
|
|
|
|
panel.getPanel().addChild(extraFeatures[1].setTextScale(0.4F), Constrains.parent(0F, Target.Y).parent(Target.WIDTH).build());
|
|
panel.getPanel().addChild(extraFeatures[2].setTextScale(0.33F), Constrains.pixel(8F, Target.Y).parent(Target.WIDTH).build());
|
|
}
|
|
|
|
public PieProfilerWindow addProfiler(IProfiler profiler, String root)
|
|
{
|
|
String name = profiler.getName();
|
|
panel.addTab(name);
|
|
tabs.add(new ProfilerTab(name, profiler, root));
|
|
if(tabs.size() == 1)
|
|
{
|
|
onProfilerChanged();
|
|
}
|
|
return this;
|
|
}
|
|
|
|
protected IProfiler getActive()
|
|
{
|
|
return tabs.get(panel.getActiveIndex()).getProfiler();
|
|
}
|
|
|
|
protected void applyProfiler(boolean prev, Consumer<IProfiler> action)
|
|
{
|
|
int index = prev ? previouseTab : panel.getActiveIndex();
|
|
if(index >= 0) action.accept(tabs.get(index).getProfiler());
|
|
}
|
|
|
|
@Override
|
|
public void onClosed()
|
|
{
|
|
super.onClosed();
|
|
applyProfiler(false, IProfiler::disable);
|
|
}
|
|
|
|
protected void onProfilerChanged()
|
|
{
|
|
if(previouseTab == panel.getActiveIndex()) return;
|
|
applyProfiler(true, IProfiler::disable);
|
|
applyProfiler(false, IProfiler::enable);
|
|
previouseTab = panel.getActiveIndex();
|
|
ProfilerTab tab = tabs.get(previouseTab);
|
|
extraFeatures[1].setText(tab.getName());
|
|
setCurrentEntry(tab.getRoot());
|
|
}
|
|
|
|
public SingleTabPanelComponent getTab()
|
|
{
|
|
return panel;
|
|
}
|
|
|
|
public PieProfilerWindow setCurrentEntry(String name)
|
|
{
|
|
entryName = name;
|
|
currentEntry = getActive().getEntry(name);
|
|
lastValues = null;
|
|
extraFeatures[2].setText(currentEntry == null ? "Unknown" : currentEntry.getName());
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
|
{
|
|
for(int i = 0,m=entries.size();i<m;i++)
|
|
{
|
|
TextComponent[] comp = entries.get(i);
|
|
float brightness = comp[0].isTopHovered(mouseX, mouseY) || comp[1].isTopHovered(mouseX, mouseY) || comp[2].isTopHovered(mouseX, mouseY) ? 0.7F : 1F;
|
|
comp[0].setBrightness(brightness);
|
|
comp[1].setBrightness(brightness);
|
|
comp[2].setBrightness(brightness);
|
|
}
|
|
extraFeatures[0].setBrightness(extraFeatures[0].isHovered(mouseX, mouseY) ? 0.7F : 1F);
|
|
return super.updateSelf(mouseX, mouseY, particalTicks);
|
|
}
|
|
|
|
@Override
|
|
protected boolean fixedUpdateSelf()
|
|
{
|
|
if(panel.getActiveIndex() < 0)
|
|
{
|
|
return true;
|
|
}
|
|
if(currentEntry == null)
|
|
{
|
|
setCurrentEntry(entryName);
|
|
return true;
|
|
}
|
|
if(currentEntry.getNanoTime() == 0L || (Keyboard.isAltDown() && lastValues != null) || (lastValues != null && getGlobalClock() % 2 != 0))
|
|
{
|
|
return true;
|
|
}
|
|
while(entries.size() < currentEntry.getChildCount() + 1)
|
|
{
|
|
entries.add(new TextComponent[] {createComponent(0), createComponent(1), createComponent(2) });
|
|
}
|
|
boolean lastEmpty = lastValues == null;
|
|
lastValues = currentEntry.getData();
|
|
int last = textInUse;
|
|
textInUse = lastValues.size();
|
|
for(int i = 0;i < textInUse;i++)
|
|
{
|
|
ProfilerData data = lastValues.get(i);
|
|
TextComponent[] info = entries.get(i);
|
|
int color = data.getColor();
|
|
info[0].setMassChanging(TextComponent.class).textColor(color).setText("[" + (i + 1) + "] " + data.getName()).finishMassChanging();
|
|
info[1].setMassChanging(TextComponent.class).textColor(color).setText(PERCENT_FORMAT.format(data.getEffect()) + "%").finishMassChanging();
|
|
info[2].setMassChanging(TextComponent.class).textColor(color).setText(PERCENT_FORMAT.format(data.getTotalEffect()) + "%").finishMassChanging();
|
|
}
|
|
if(last != textInUse)
|
|
{
|
|
float diff = 80F + (textInUse * 7F) - this.getBox().getHeight();
|
|
if(diff > 0) {
|
|
resize(0F, diff);
|
|
}
|
|
onChanged(true);
|
|
}
|
|
else if(lastEmpty)
|
|
{
|
|
onChanged(true);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onClick(int button, int mouseX, int mouseY)
|
|
{
|
|
if(super.onClick(button, mouseX, mouseY))
|
|
{
|
|
return true;
|
|
}
|
|
if(currentEntry != null && currentEntry.getParent() != null && extraFeatures[0].isHovered(mouseX, mouseY))
|
|
{
|
|
setCurrentEntry(currentEntry.getParent().getPathName());
|
|
}
|
|
if(lastValues != null)
|
|
{
|
|
for(int i = 0;i<textInUse;i++)
|
|
{
|
|
TextComponent[] comp = entries.get(i);
|
|
if(comp[0].isHovered(mouseX, mouseY) || comp[1].isHovered(mouseX, mouseY) || comp[2].isHovered(mouseX, mouseY))
|
|
{
|
|
String s = comp[0].getText();
|
|
s = s.substring(s.indexOf("] ")+2);
|
|
if(!s.equalsIgnoreCase("Nameless"))
|
|
{
|
|
setCurrentEntry(currentEntry.getPathName() + "/" + s);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean isAcceptingInput()
|
|
{
|
|
return isEnabled() && isVisible() && !isMinimized() && currentEntry != null && hasFocus();
|
|
}
|
|
|
|
@Override
|
|
public boolean onKeyPressed(int key)
|
|
{
|
|
if(key == GLFW.GLFW_KEY_0 && currentEntry != null && currentEntry.getParent() != null)
|
|
{
|
|
setCurrentEntry(currentEntry.getParent().getPathName());
|
|
return true;
|
|
}
|
|
else if(key >= GLFW.GLFW_KEY_1 && key <= GLFW.GLFW_KEY_9)
|
|
{
|
|
key -= GLFW.GLFW_KEY_1;
|
|
if(key < textInUse)
|
|
{
|
|
String s = entries.get(key)[0].getText();
|
|
s = s.substring(s.indexOf("] ")+2);
|
|
if(!s.equalsIgnoreCase("Nameless"))
|
|
{
|
|
setCurrentEntry(currentEntry.getPathName() + "/" + s);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public Vec2f getMinimumBounds()
|
|
{
|
|
return Vec2f.of(80F, 80F + (textInUse * 7F));
|
|
}
|
|
|
|
@Override
|
|
public List<IPieIndex> get()
|
|
{
|
|
if(lastValues != null)
|
|
{
|
|
List<IPieIndex> entries = new ObjectArrayList<>();
|
|
for(int i = 0, m = lastValues.size();i < m;i++)
|
|
{
|
|
entries.add(new PieIndex(MathUtils.floor(lastValues.get(i).getEffect() * 1.28D), lastValues.get(i).getColor()));
|
|
}
|
|
return entries;
|
|
}
|
|
return ObjectLists.singleton(new PieIndex(pie.getMaxSteps(), ColorUtils.LIGHT_BLUE));
|
|
}
|
|
|
|
protected float calculatePieHeight()
|
|
{
|
|
return getBox().getBaseHeight() - ((textInUse * 7) + 17F);
|
|
}
|
|
|
|
protected TextComponent createComponent(int column)
|
|
{
|
|
final int index = entries.size();
|
|
String text = column == 0 ? "[" + (entries.size() + 1) + "] Unknown" : PERCENT_FORMAT.format(0D) + "%";
|
|
TextComponent comp = new TextComponent(0F, 0F, 18F, 7F).setTextScale(0.33F).setText(text).align(column == 0 ? Align.LEFT_TOP : Align.RIGHT_BOTTOM, Align.CENTER);
|
|
comp.onChange(T -> T.setVisible(index < textInUse));
|
|
Constrain xPos = column == 0 ? null : (column == 1 ? new PixelConstrain(38F).setInverted() : new PixelConstrain(19F).setInverted());
|
|
panel.getPanel().addChild(comp, new Constrains(xPos, new DynamicConstrain(() -> pie.getBox().getBaseHeight() + (index * 7F)), column == 0 ? new PixelConstrain(38).setInverted() : null, null));
|
|
return comp;
|
|
}
|
|
|
|
private static class ProfilerTab
|
|
{
|
|
String name;
|
|
IProfiler profiler;
|
|
String root;
|
|
|
|
public ProfilerTab(String name, IProfiler profiler, String root)
|
|
{
|
|
this.name = name;
|
|
this.profiler = profiler;
|
|
this.root = root;
|
|
}
|
|
|
|
public String getName()
|
|
{
|
|
return name;
|
|
}
|
|
|
|
public IProfiler getProfiler()
|
|
{
|
|
return profiler;
|
|
}
|
|
|
|
public String getRoot()
|
|
{
|
|
return root;
|
|
}
|
|
}
|
|
}
|