217 lines
5.4 KiB
Java
217 lines
5.4 KiB
Java
package speiger.src.coreengine.rendering.gui.components.window.debug;
|
|
|
|
import java.util.List;
|
|
import java.util.function.Consumer;
|
|
import java.util.function.ObjIntConsumer;
|
|
|
|
import speiger.src.collections.ints.queues.IntArrayFIFOQueue;
|
|
import speiger.src.collections.ints.queues.IntPriorityQueue;
|
|
import speiger.src.collections.objects.lists.ObjectArrayList;
|
|
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.components.SingleTabPanelComponent;
|
|
import speiger.src.coreengine.rendering.gui.components.TreeComponent;
|
|
import speiger.src.coreengine.rendering.gui.components.WindowComponent;
|
|
import speiger.src.coreengine.rendering.gui.components.tree.ProfilerTreeEntry;
|
|
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
|
|
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
|
import speiger.src.coreengine.utils.profiler.IProfiler;
|
|
import speiger.src.coreengine.utils.profiler.IProfiler.IProfilerEntry;
|
|
|
|
public class TreeProfilerWindow extends WindowComponent
|
|
{
|
|
IntPriorityQueue todoList = new IntArrayFIFOQueue().synchronizeQueue();
|
|
ObjIntConsumer<IProfiler> listener = (T, V) -> todoList.enqueue(V);
|
|
SingleTabPanelComponent panel = new SingleTabPanelComponent(Facing.SOUTH).onAction(this::onProfilerChanged).cast();
|
|
TreeComponent<ProfilerTreeEntry> tree = panel.addChild(new TreeComponent<>(ColorUtils.GRAY, 9F).disableBackground(true).setSelectionMode(TreeComponent.SELECTION_MODE_INTERACT).cast(), Constrains.parent(Target.WIDTH).parent(4, Target.HEIGHT).build());
|
|
List<ProfilerTab> tabs = new ObjectArrayList<>();
|
|
int previouseTab = -1;
|
|
|
|
|
|
public TreeProfilerWindow(float x, float y, float width, float height, String name)
|
|
{
|
|
super(x, y, width, height, DEFAULT_FLAGS, name);
|
|
}
|
|
|
|
public TreeProfilerWindow addProfiler(IProfiler profiler, String root)
|
|
{
|
|
panel.addTab(profiler.getName());
|
|
tabs.add(new ProfilerTab(profiler, root));
|
|
if(tabs.size() == 1)
|
|
{
|
|
onProfilerChanged();
|
|
}
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public boolean canMoveIntoForground()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public Vec2f getMinimumBounds()
|
|
{
|
|
return Vec2f.of(100F, 50F);
|
|
}
|
|
|
|
@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());
|
|
}
|
|
|
|
@Override
|
|
public void onClosed()
|
|
{
|
|
super.onClosed();
|
|
applyProfiler(false, this::disable);
|
|
}
|
|
|
|
@Override
|
|
protected boolean fixedUpdateSelf()
|
|
{
|
|
ProfilerTab entry = getActiveTab();
|
|
if(entry == null)
|
|
{
|
|
todoList.clear();
|
|
return true;
|
|
}
|
|
while(!todoList.isEmpty())
|
|
{
|
|
int index = todoList.dequeue();
|
|
switch(index)
|
|
{
|
|
case 0:
|
|
addEntries(entry.getRootEntry());
|
|
break;
|
|
case 1:
|
|
tree.setTree(null);
|
|
break;
|
|
case 2:
|
|
if(tree.getTree() == null)
|
|
{
|
|
addEntries(entry.getRootEntry());
|
|
break;
|
|
}
|
|
updateChildren(entry.getRootEntry(), tree.getTree());
|
|
tree.onTreeChanged();
|
|
break;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
protected void onProfilerChanged()
|
|
{
|
|
if(previouseTab == panel.getActiveIndex()) return;
|
|
applyProfiler(true, this::disable);
|
|
applyProfiler(false, this::enable);
|
|
previouseTab = panel.getActiveIndex();
|
|
ProfilerTab tab = tabs.get(previouseTab);
|
|
setCurrentEntry(tab.getRoot());
|
|
}
|
|
|
|
protected void enable(IProfiler profiler)
|
|
{
|
|
profiler.enable();
|
|
profiler.addListener(listener);
|
|
}
|
|
|
|
protected void disable(IProfiler profiler)
|
|
{
|
|
profiler.removeListener(listener);
|
|
profiler.disable();
|
|
}
|
|
|
|
protected void addEntries(IProfilerEntry entry)
|
|
{
|
|
if(entry == null) return;
|
|
ProfilerTreeEntry child = new ProfilerTreeEntry(entry);
|
|
for(int i = 0,m=entry.getChildCount();i<m;i++)
|
|
{
|
|
addChildren(entry.getChild(i), child);
|
|
}
|
|
tree.setTree(child);
|
|
tree.openAll();
|
|
}
|
|
|
|
public TreeProfilerWindow setCurrentEntry(String name)
|
|
{
|
|
addEntries(getActive().getEntry(name));
|
|
return this;
|
|
}
|
|
|
|
protected void updateChildren(IProfilerEntry entry, ProfilerTreeEntry tree)
|
|
{
|
|
if(entry == null || tree == null) return;
|
|
for(int i = 0,m=entry.getChildCount();i<m;i++)
|
|
{
|
|
addChildren(entry.getChild(i), tree);
|
|
}
|
|
}
|
|
|
|
protected void addChildren(IProfilerEntry entry, ProfilerTreeEntry tree)
|
|
{
|
|
if(entry == null || tree == null) return;
|
|
ProfilerTreeEntry child = new ProfilerTreeEntry(entry);
|
|
int index = tree.indexOf(child);
|
|
|
|
if(index != -1) child = (ProfilerTreeEntry)tree.getChild(index);
|
|
else tree.addChild(child);
|
|
|
|
for(int i = 0,m=entry.getChildCount();i<m;i++)
|
|
{
|
|
addChildren(entry.getChild(i), child);
|
|
}
|
|
}
|
|
|
|
protected IProfiler getActive()
|
|
{
|
|
return tabs.get(panel.getActiveIndex()).getProfiler();
|
|
}
|
|
|
|
protected ProfilerTab getActiveTab()
|
|
{
|
|
int index = panel.getActiveIndex();
|
|
return index < 0 || index >= tabs.size() ? null : tabs.get(index);
|
|
}
|
|
|
|
protected void applyProfiler(boolean prev, Consumer<IProfiler> action)
|
|
{
|
|
int index = prev ? previouseTab : panel.getActiveIndex();
|
|
if(index >= 0) action.accept(tabs.get(index).getProfiler());
|
|
}
|
|
|
|
private static class ProfilerTab
|
|
{
|
|
IProfiler profiler;
|
|
String root;
|
|
|
|
public ProfilerTab(IProfiler profiler, String root)
|
|
{
|
|
this.profiler = profiler;
|
|
this.root = root;
|
|
}
|
|
|
|
public IProfiler getProfiler()
|
|
{
|
|
return profiler;
|
|
}
|
|
|
|
public String getRoot()
|
|
{
|
|
return root;
|
|
}
|
|
|
|
public IProfilerEntry getRootEntry()
|
|
{
|
|
return profiler.getEntry(root);
|
|
}
|
|
|
|
}
|
|
}
|