Skip to content

Commit

Permalink
Optimize quest database searching redux (#114)
Browse files Browse the repository at this point in the history
* Optimize quest database searching
* Use unique icon key

---------

Co-authored-by: KatatsumuriPan <[email protected]>
  • Loading branch information
WaitingIdly and KatatsumuriPan authored May 23, 2024
1 parent 5409ade commit f5960d5
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
import java.util.concurrent.CopyOnWriteArrayList;

public class CanvasScrolling implements IGuiCanvas {
private final List<IGuiPanel> guiPanels = new CopyOnWriteArrayList<>();

protected final List<IGuiPanel> guiPanels = new CopyOnWriteArrayList<>();
private final IGuiRect transform;
private boolean enabled = true;

Expand Down Expand Up @@ -50,7 +51,7 @@ public class CanvasScrolling implements IGuiCanvas {

// Enables the auto-disabling panels outside the cropped region. Useful for very large lists
private boolean useBlocking = true;
private final CanvasCullingManager cullingManager = new CanvasCullingManager();
protected final CanvasCullingManager cullingManager = new CanvasCullingManager();
private final GuiRectangle refRect = new GuiRectangle(0, 0, 0, 0);

public CanvasScrolling(IGuiRect rect) {
Expand Down Expand Up @@ -410,8 +411,8 @@ public boolean onKeyTyped(char c, int keycode) {
break;
}
}
/*if(!used && c == 'c')

/*if(!used && c == 'c')
{
setScrollX(0);
setScrollY(0);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package betterquesting.api2.client.gui.panels.lists;

import java.util.ArrayList;

import betterquesting.api2.client.gui.misc.ComparatorGuiDepth;
import betterquesting.api2.client.gui.misc.IGuiRect;
import betterquesting.api2.client.gui.panels.IGuiPanel;

public class CanvasScrollingBuffered extends CanvasScrolling {

private final ArrayList<IGuiPanel> buffer = new ArrayList<>();

public CanvasScrollingBuffered(IGuiRect rect) {
super(rect);
}

public void addPanelToBuffer(IGuiPanel panel) {
if (panel != null)
buffer.add(panel);
}

public void flushBuffer() {
if (buffer.isEmpty())
return;
for (IGuiPanel panel : buffer) {
if (guiPanels.contains(panel))
continue;

guiPanels.add(panel);
cullingManager.addPanel(panel, true);
panel.initPanel();
}
buffer.clear();

guiPanels.sort(ComparatorGuiDepth.INSTANCE);

this.refreshScrollBounds();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import java.util.*;
import java.util.concurrent.TimeUnit;

public abstract class CanvasSearch<T, E> extends CanvasScrolling {
public abstract class CanvasSearch<T, E> extends CanvasScrollingBuffered {

private String searchTerm = "";
private Iterator<E> searching = null;
Expand Down Expand Up @@ -39,6 +39,10 @@ public void drawPanel(int mx, int my, float partialTick) {
super.drawPanel(mx, my, partialTick);
}

public boolean isSearching() {
return searching != null || !pendingResults.isEmpty();
}

public void refreshSearch() {
this.resetCanvas();
this.searchIdx = 0;
Expand Down Expand Up @@ -71,6 +75,10 @@ private void updateSearch() {
savedResults.addAll(tmp);

searchTime.stop();

if (!searching.hasNext())
searching = null;

}

private void updateResults() {
Expand All @@ -80,11 +88,16 @@ private void updateResults() {

searchTime.reset().start();

while (!pendingResults.isEmpty() && searchTime.elapsed(TimeUnit.MILLISECONDS) < 100) {
if (addResult(pendingResults.poll(), searchIdx, resultWidth)) searchIdx++;
int count = 0;
while (!pendingResults.isEmpty() && searchTime.elapsed(TimeUnit.MILLISECONDS) < 10 && count < 200) {
if (addResult(pendingResults.poll(), searchIdx, resultWidth)) {
searchIdx++;
count++;
}
}

searchTime.stop();
flushBuffer();
}

public List<T> getResults() {
Expand All @@ -96,4 +109,5 @@ public List<T> getResults() {
protected abstract void queryMatches(E value, String query, final ArrayDeque<T> results);

protected abstract boolean addResult(T entry, int index, int cachedWidth);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package betterquesting.api2.client.gui.resources.textures;

import org.lwjgl.opengl.GL11;

import betterquesting.api2.client.gui.misc.IGuiRect;
import betterquesting.api2.client.gui.resources.colors.GuiColorStatic;
import betterquesting.api2.client.gui.resources.colors.IGuiColor;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.client.config.GuiUtils;

public class RotatingTexture implements IGuiTexture {

private static final IGuiColor defColor = new GuiColorStatic(255, 255, 255, 255);

private final ResourceLocation texture;
private final IGuiRect texBounds;
private boolean maintainAspect = false;
private float period;

public RotatingTexture(ResourceLocation texture, IGuiRect bounds) {
this.texture = texture;
this.texBounds = bounds;
setPeriod(1);
}

public RotatingTexture maintainAspect(boolean enable) {
this.maintainAspect = enable;
return this;
}

public void setPeriod(float period) { this.period = period; }

@Override
public void drawTexture(int x, int y, int width, int height, float zLevel, float partialTick) {
drawTexture(x, y, width, height, zLevel, partialTick, defColor);
}

@Override
public void drawTexture(int x, int y, int width, int height, float zLevel, float partialTick, IGuiColor color) {
if (width <= 0 || height <= 0)
return;

GlStateManager.pushMatrix();

float sx = (float) width / (float) texBounds.getWidth();
float sy = (float) height / (float) texBounds.getHeight();

if (maintainAspect) {
float sa = Math.min(sx, sy);
float dx = (sx - sa) * texBounds.getWidth() / 2F;
float dy = (sy - sa) * texBounds.getHeight() / 2F;
sx = sa;
sy = sa;
GlStateManager.translate(x + dx, y + dy, 0F);
} else {
GlStateManager.translate(x, y, 0F);
}

GlStateManager.scale(sx, sy, 1F);
float w2 = texBounds.getWidth() * 0.5f;
float h2 = texBounds.getHeight() * 0.5f;
GlStateManager.translate(w2, h2, 0);
GlStateManager.rotate(getAngle(period), 0, 0, 1);
GlStateManager.translate(-w2, -h2, 0);
color.applyGlColor();

GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0);

Minecraft.getMinecraft().renderEngine.bindTexture(texture);
GuiUtils.drawTexturedModalRect(0, 0, texBounds.getX(), texBounds.getY(), texBounds.getWidth(), texBounds.getHeight(), zLevel);

GlStateManager.popMatrix();
}

@Override
public ResourceLocation getTexture() { return this.texture; }

@Override
public IGuiRect getBounds() { return this.texBounds; }

private static float getAngle(float period) {
float phase = 0;
// Period in milliseconds
double pms = 1000D * period;
// Current period time
double time = System.currentTimeMillis() % pms;
// Shift current time by phase, wrap value and scale between 0.0 - 1.0
time = (time + (pms * phase)) % pms / pms;
return (float) time * 360;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import betterquesting.api2.client.gui.misc.GuiRectangle;
import betterquesting.api2.client.gui.resources.textures.IGuiTexture;
import betterquesting.api2.client.gui.resources.textures.RotatingTexture;
import betterquesting.api2.client.gui.resources.textures.SimpleTexture;
import betterquesting.api2.client.gui.themes.IThemeRegistry;
import betterquesting.client.themes.ThemeRegistry;
Expand Down Expand Up @@ -99,7 +100,8 @@ public enum PresetIcon {
ICON_MENU("icon_menu"),

ICON_PATREON("icon_patreon"),
ICON_TWITCH("icon_twitch");
ICON_TWITCH("icon_twitch"),
ICON_LOADING("icon_loading");

public static final ResourceLocation TX_ICONS = new ResourceLocation(ModReference.MODID, "textures/gui/editor_icons.png");

Expand Down Expand Up @@ -197,5 +199,6 @@ public static void registerIcons(IThemeRegistry reg) {

reg.setDefaultTexture(ICON_PATREON.key, new SimpleTexture(TX_ICONS, new GuiRectangle(144, 80, 16, 16)).maintainAspect(true));
reg.setDefaultTexture(ICON_TWITCH.key, new SimpleTexture(TX_ICONS, new GuiRectangle(160, 80, 16, 16)).maintainAspect(true));
reg.setDefaultTexture(ICON_LOADING.key, new RotatingTexture(TX_ICONS, new GuiRectangle(128, 16, 16, 16)).maintainAspect(true));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
import betterquesting.api2.client.gui.panels.CanvasEmpty;
import betterquesting.api2.client.gui.panels.CanvasTextured;
import betterquesting.api2.client.gui.panels.bars.PanelVScrollBar;
import betterquesting.api2.client.gui.panels.content.PanelGeneric;
import betterquesting.api2.client.gui.panels.content.PanelLine;
import betterquesting.api2.client.gui.panels.content.PanelTextBox;
import betterquesting.api2.client.gui.panels.lists.CanvasQuestDatabase;
import betterquesting.api2.client.gui.panels.lists.CanvasScrolling;
import betterquesting.api2.client.gui.resources.colors.GuiColorStatic;
import betterquesting.api2.client.gui.themes.presets.PresetColor;
import betterquesting.api2.client.gui.themes.presets.PresetIcon;
import betterquesting.api2.client.gui.themes.presets.PresetLine;
Expand All @@ -45,12 +47,14 @@
import java.util.List;

public class GuiQuestLineAddRemove extends GuiScreenCanvas implements IPEventListener, IVolatileScreen, INeedsRefresh {

@Nullable
private IQuestLine questLine;
private final int lineID;

private CanvasQuestDatabase canvasDB;
private CanvasScrolling canvasQL;
private PanelGeneric pnLoading;

public GuiQuestLineAddRemove(GuiScreen parent, @Nullable IQuestLine questLine) {
super(parent);
Expand Down Expand Up @@ -107,28 +111,34 @@ public void initPanel() {
PanelTextBox txtDb = new PanelTextBox(new GuiTransform(GuiAlign.TOP_EDGE, new GuiPadding(0, 0, 0, -16), 0), QuestTranslation.translate("betterquesting.gui.database")).setAlignment(1).setColor(PresetColor.TEXT_MAIN.getColor());
cvRight.addPanel(txtDb);

PanelTextField<String> searchBox = new PanelTextField<>(new GuiTransform(GuiAlign.TOP_EDGE, new GuiPadding(0, 16, 8, -32), 0), "", FieldFilterString.INSTANCE);
PanelTextField<String> searchBox = new PanelTextField<>(new GuiTransform(GuiAlign.TOP_EDGE, new GuiPadding(0, 16, 24, -32), 0), "", FieldFilterString.INSTANCE);
searchBox.setWatermark("Search...");
cvRight.addPanel(searchBox);

pnLoading = new PanelGeneric(new GuiTransform(GuiAlign.TOP_RIGHT, new GuiPadding(-24, 16, 8, -32), 0), PresetIcon.ICON_LOADING.getTexture(), new GuiColorStatic(0, 255, 0, 255));
pnLoading.setEnabled(false);
cvRight.addPanel(pnLoading);

canvasDB = new CanvasQuestDatabase(new GuiTransform(GuiAlign.FULL_BOX, new GuiPadding(0, 32, 8, 24), 0)) {

@Override
protected boolean addResult(DBEntry<IQuest> entry, int index, int width) {

PanelButtonStorage<DBEntry<IQuest>> btnAdd = new PanelButtonStorage<>(new GuiRectangle(0, index * 16, 16, 16, 0), 2, "", entry);
btnAdd.setIcon(PresetIcon.ICON_POSITIVE.getTexture());
btnAdd.setActive(questLine != null && questLine.getValue(entry.getID()) == null);
this.addPanel(btnAdd);
this.addPanelToBuffer(btnAdd);

PanelButtonStorage<DBEntry<IQuest>> btnEdit = new PanelButtonStorage<>(new GuiRectangle(16, index * 16, width - 32, 16, 0), 1, QuestTranslation.translate(entry.getValue().getProperty(NativeProps.NAME)), entry);
this.addPanel(btnEdit);
this.addPanelToBuffer(btnEdit);

PanelButtonStorage<DBEntry<IQuest>> btnDel = new PanelButtonStorage<>(new GuiRectangle(width - 16, index * 16, 16, 16, 0), 4, "", entry);
btnDel.setIcon(PresetIcon.ICON_TRASH.getTexture());
this.addPanel(btnDel);
this.addPanelToBuffer(btnDel);

return true;
}

};
cvRight.addPanel(canvasDB);

Expand All @@ -153,6 +163,12 @@ protected boolean addResult(DBEntry<IQuest> entry, int index, int width) {
refreshQuestList();
}

@Override
public void drawPanel(int mx, int my, float partialTick) {
pnLoading.setEnabled(canvasDB.isSearching());
super.drawPanel(mx, my, partialTick);
}

@Override
public void onPanelEvent(PanelEvent event) {
if (event instanceof PEventButton) {
Expand Down Expand Up @@ -273,4 +289,5 @@ private void SendChanges() {
payload.setInteger("action", 0);
NetChapterEdit.sendEdit(payload);
}

}

0 comments on commit f5960d5

Please sign in to comment.