SimpleJavaEngine/src/main/java/speiger/src/coreengine/rendering/gui/components/window/debug/PieProfilerWindow.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;
}
}
}