Skip to content

Commit 389a211

Browse files
committed
opti
1 parent 31c2017 commit 389a211

10 files changed

Lines changed: 103 additions & 34 deletions

File tree

src/main/java/com/hfstudio/guidenh/compat/carpentersblocks/CarpentersBlocksHelpers.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public static boolean isCarpentersBlock(@Nullable Block block) {
2626
}
2727
for (Class<?> type = block.getClass(); type != null; type = type.getSuperclass()) {
2828
String name = type.getName();
29-
if (name != null && name.startsWith(CARPENTERS_BLOCK_PACKAGE)) {
29+
if (name.startsWith(CARPENTERS_BLOCK_PACKAGE)) {
3030
return true;
3131
}
3232
}

src/main/java/com/hfstudio/guidenh/guide/document/block/LytImage.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,15 @@ private void drawAnnotationBorders(RenderContext context) {
142142
if (!ann.isShowBorder()) {
143143
continue;
144144
}
145-
LytRect borderRect;
145+
int bx;
146+
int by;
147+
int bw;
148+
int bh;
146149
if (ann.isWholeImage()) {
147-
borderRect = bounds;
150+
bx = bounds.x();
151+
by = bounds.y();
152+
bw = bounds.width();
153+
bh = bounds.height();
148154
} else {
149155
// Clamp the annotation region to [0, natW] x [0, natH] so the border
150156
// cannot extend beyond the displayed image area regardless of scaling.
@@ -155,13 +161,12 @@ private void drawAnnotationBorders(RenderContext context) {
155161
if (clampedW <= 0 || clampedH <= 0) {
156162
continue;
157163
}
158-
int bx = bounds.x() + clampedX * dispW / natW;
159-
int by = bounds.y() + clampedY * dispH / natH;
160-
int bw = Math.max(1, clampedW * dispW / natW);
161-
int bh = Math.max(1, clampedH * dispH / natH);
162-
borderRect = new LytRect(bx, by, bw, bh);
164+
bx = bounds.x() + clampedX * dispW / natW;
165+
by = bounds.y() + clampedY * dispH / natH;
166+
bw = Math.max(1, clampedW * dispW / natW);
167+
bh = Math.max(1, clampedH * dispH / natH);
163168
}
164-
context.drawBorder(borderRect, context.resolveColor(ann.getBorderColor()), ann.getBorderThickness());
169+
context.drawBorder(bx, by, bw, bh, context.resolveColor(ann.getBorderColor()), ann.getBorderThickness());
165170
}
166171
}
167172

src/main/java/com/hfstudio/guidenh/guide/document/block/LytItemImage.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ public class LytItemImage extends LytBlock implements InteractiveElement {
4141
private String labelPosition = null;
4242
@Nullable
4343
private String labelFormat = null;
44+
@Nullable
45+
private ResolvedTextStyle cachedLabelStyle = null;
46+
@Nullable
47+
private String cachedLabelTemplate = null;
4448

4549
public LytItemImage(ItemStack stack) {
4650
this.stack = stack;
@@ -84,6 +88,8 @@ public void setLabelPosition(@Nullable String position) {
8488
*/
8589
public void setLabelFormat(@Nullable String format) {
8690
this.labelFormat = format;
91+
this.cachedLabelStyle = null;
92+
this.cachedLabelTemplate = null;
8793
}
8894

8995
/**
@@ -205,19 +211,23 @@ public List<ItemStack> getStacks() {
205211
protected String resolveLabelText() {
206212
if (stack == null) return "";
207213
if (labelFormat == null) return stack.getDisplayName();
208-
String template = stripFormatMarkers(labelFormat);
209-
return template.contains("%s") ? String.format(template, stack.getDisplayName()) : template;
214+
if (cachedLabelTemplate == null) {
215+
cachedLabelTemplate = stripFormatMarkers(labelFormat);
216+
}
217+
return cachedLabelTemplate.contains("%s") ? String.format(cachedLabelTemplate, stack.getDisplayName())
218+
: cachedLabelTemplate;
210219
}
211220

212221
/** Resolves the {@link ResolvedTextStyle} for the label based on the format pattern. */
213222
protected ResolvedTextStyle resolveLabelStyle() {
214-
if (labelFormat == null) {
215-
return TextStyle.builder()
223+
if (cachedLabelStyle == null) {
224+
cachedLabelStyle = labelFormat == null ? TextStyle.builder()
216225
.italic(true)
217226
.build()
218-
.mergeWith(DefaultStyles.BASE_STYLE);
227+
.mergeWith(DefaultStyles.BASE_STYLE)
228+
: buildFormatStyle(labelFormat).mergeWith(DefaultStyles.BASE_STYLE);
219229
}
220-
return buildFormatStyle(labelFormat).mergeWith(DefaultStyles.BASE_STYLE);
230+
return cachedLabelStyle;
221231
}
222232

223233
private int measureTextWidth(LayoutContext context, String text, ResolvedTextStyle style) {

src/main/java/com/hfstudio/guidenh/guide/document/block/LytSlot.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public class LytSlot extends LytBlock implements InteractiveElement {
3030
private boolean largeSlot;
3131
private boolean renderSlotBackground = true;
3232
private final List<ItemStack> stacks;
33+
private long cachedCycleId = -1;
34+
private int cachedStackIdx = 0;
3335

3436
public LytSlot(ItemStack stack) {
3537
this.stacks = stack == null ? Collections.emptyList() : Collections.singletonList(stack);
@@ -105,7 +107,11 @@ private ItemStack getDisplayedStack() {
105107
if (stacks.isEmpty()) {
106108
return null;
107109
}
108-
var cycle = System.nanoTime() / TimeUnit.MILLISECONDS.toNanos(CYCLE_TIME);
109-
return stacks.get((int) (cycle % stacks.size()));
110+
long cycle = System.nanoTime() / TimeUnit.MILLISECONDS.toNanos(CYCLE_TIME);
111+
if (cycle != cachedCycleId) {
112+
cachedCycleId = cycle;
113+
cachedStackIdx = (int) (cycle % stacks.size());
114+
}
115+
return stacks.get(cachedStackIdx);
110116
}
111117
}

src/main/java/com/hfstudio/guidenh/guide/internal/screen/GuideNavBar.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,9 @@ public void render(Minecraft mc, @Nullable ResourceLocation currentPageId, int m
141141
textX += ICON_SIZE + 2;
142142
}
143143

144-
String title = row.node.title();
145144
int maxTw = (x + w - 2) - textX;
146145
if (maxTw > 0) {
147-
if (fr.getStringWidth(title) > maxTw) {
148-
title = fr.trimStringToWidth(title, maxTw - 4) + "\u2026";
149-
}
146+
String title = row.getTitle(fr, maxTw);
150147
boolean failed = row.node.pageId() != null && pageCollection != null
151148
&& pageCollection.isPageFailed(row.node.pageId());
152149
int color = getRowTextColor(current, hovered, failed);
@@ -328,12 +325,24 @@ public static void drawMiniTextureIcon(@Nullable GuidePageTexture texture, int x
328325

329326
public static class Row {
330327

331-
final NavigationNode node;
332-
final int depth;
328+
public final NavigationNode node;
329+
public final int depth;
330+
private String cachedTitle = null;
331+
private int cachedMaxTw = -1;
333332

334-
Row(NavigationNode node, int depth) {
333+
public Row(NavigationNode node, int depth) {
335334
this.node = node;
336335
this.depth = depth;
337336
}
337+
338+
public String getTitle(FontRenderer fr, int maxTw) {
339+
if (maxTw == cachedMaxTw && cachedTitle != null) {
340+
return cachedTitle;
341+
}
342+
String title = node.title();
343+
cachedTitle = fr.getStringWidth(title) > maxTw ? fr.trimStringToWidth(title, maxTw - 4) + "\u2026" : title;
344+
cachedMaxTw = maxTw;
345+
return cachedTitle;
346+
}
338347
}
339348
}

src/main/java/com/hfstudio/guidenh/guide/internal/search/GuideSearchResultDocumentBuilder.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ public static boolean isCenteredStateDocument(@Nullable LytDocument document) {
6060
return document != null && document.getBlocks()
6161
.size() == 1
6262
&& document.getBlocks()
63-
.get(0)
64-
.getClass() == CenteredStateBlock.class;
63+
.get(0) instanceof CenteredStateBlock;
6564
}
6665

6766
public static CenteredStateBlock buildCenteredMessage(String message) {
@@ -152,15 +151,13 @@ public static LytBlock buildResultIcon(GuidePageIcon icon) {
152151
}
153152

154153
public static LytFlowContent copySnippetContent(LytFlowContent content) {
155-
if (content.getClass() == LytFlowText.class) {
156-
var text = (LytFlowText) content;
154+
if (content instanceof LytFlowText text) {
157155
var copy = copyFlowContent(text, new LytFlowText());
158156
copy.setText(text.getText());
159157
return copy;
160158
}
161159

162-
if (content.getClass() == LytFlowSpan.class) {
163-
var span = (LytFlowSpan) content;
160+
if (content instanceof LytFlowSpan span) {
164161
var copy = copyFlowContent(span, new LytFlowSpan());
165162
for (var child : span.getChildren()) {
166163
copy.append(copySnippetContent(child));

src/main/java/com/hfstudio/guidenh/guide/layout/flow/FlowBuilder.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,27 @@
1616

1717
public class FlowBuilder {
1818

19+
/** Sentinel used to force containsMouse recalculation after a layout rebuild. */
20+
private static final LytFlowContent LAYOUT_DIRTY = new LytFlowContent();
21+
1922
private final List<Line> lines = new ArrayList<>();
2023

2124
private final List<LytFlowContent> rootContent = new ArrayList<>();
2225

2326
// Bounding rectangles for any floats in this flow
2427
private final List<LineBlock> floats = new ArrayList<>();
2528

29+
/** Tracks the last hovered content so containsMouse is only recalculated on changes. */
30+
private LytFlowContent lastHoveredForContainsMouse = LAYOUT_DIRTY;
31+
2632
public void append(LytFlowContent content) {
2733
this.rootContent.add(content);
2834
}
2935

3036
public LytRect computeLayout(LayoutContext context, int x, int y, int availableWidth, TextAlignment alignment) {
3137
lines.clear();
3238
floats.clear();
39+
lastHoveredForContainsMouse = LAYOUT_DIRTY;
3340
var lineBuilder = new LineBuilder(context, x, y, availableWidth, lines, floats, alignment);
3441
for (var content : rootContent) {
3542
visitInDocumentOrder(content, lineBuilder);
@@ -41,21 +48,36 @@ public LytRect computeLayout(LayoutContext context, int x, int y, int availableW
4148
}
4249

4350
public void render(RenderContext context, @Nullable LytFlowContent hoveredContent) {
51+
updateContainsMouse(hoveredContent);
4452
for (var line : lines) {
4553
for (var el = line.firstElement(); el != null; el = el.next) {
46-
el.containsMouse = hoveredContent != null && hoveredContent.isInclusiveAncestor(el.getFlowContent());
4754
el.render(context);
4855
}
4956
}
5057
}
5158

5259
public void renderFloats(RenderContext context, @Nullable LytFlowContent hoveredContent) {
60+
updateContainsMouse(hoveredContent);
5361
for (var el : floats) {
54-
el.containsMouse = hoveredContent != null && hoveredContent.isInclusiveAncestor(el.getFlowContent());
5562
el.render(context);
5663
}
5764
}
5865

66+
private void updateContainsMouse(@Nullable LytFlowContent hoveredContent) {
67+
if (lastHoveredForContainsMouse == hoveredContent) {
68+
return;
69+
}
70+
lastHoveredForContainsMouse = hoveredContent;
71+
for (var line : lines) {
72+
for (var el = line.firstElement(); el != null; el = el.next) {
73+
el.containsMouse = hoveredContent != null && hoveredContent.isInclusiveAncestor(el.getFlowContent());
74+
}
75+
}
76+
for (var el : floats) {
77+
el.containsMouse = hoveredContent != null && hoveredContent.isInclusiveAncestor(el.getFlowContent());
78+
}
79+
}
80+
5981
private void visitInDocumentOrder(LytFlowContent content, Consumer<LytFlowContent> visitor) {
6082
if (content instanceof LytFlowSpan flowSpan) {
6183
for (var child : flowSpan.getChildren()) {

src/main/java/com/hfstudio/guidenh/guide/layout/flow/LineBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class LineBuilder implements Consumer<LytFlowContent> {
4343
@Nullable
4444
private LineElement openLineTail;
4545
private final TextAlignment alignment;
46+
private final StringBuilder lineBuffer = new StringBuilder();
4647

4748
public LineBuilder(LayoutContext context, int x, int y, int availableWidth, List<Line> lines,
4849
List<LineBlock> floats, TextAlignment alignment) {
@@ -201,7 +202,7 @@ private void appendText(String text, LytFlowContent flowContent) {
201202
private void iterateRuns(CharSequence text, ResolvedTextStyle style, char lastChar, LineConsumer consumer) {
202203
float curLineWidth = 0;
203204

204-
var lineBuffer = new StringBuilder();
205+
lineBuffer.setLength(0);
205206

206207
boolean lastCharWasWhitespace = Character.isWhitespace(lastChar);
207208
boolean canBreakAtStart = lastCharWasWhitespace;

src/main/java/com/hfstudio/guidenh/guide/render/RenderContext.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ default void fillRect(int x, int y, int width, int height, int argbColor) {
5757

5858
void drawBorder(LytRect rect, int argbColor, int thickness);
5959

60+
/**
61+
* Draws a border around (x, y, width, height) with the given ARGB color and thickness.
62+
* Prefer this overload over {@link #drawBorder(LytRect, int, int)} in hot rendering paths
63+
* to avoid allocating a temporary {@link LytRect}.
64+
*/
65+
default void drawBorder(int x, int y, int width, int height, int argbColor, int thickness) {
66+
drawBorder(new LytRect(x, y, width, height), argbColor, thickness);
67+
}
68+
6069
void drawText(String text, int x, int y, ResolvedTextStyle style);
6170

6271
int getStringWidth(String text, ResolvedTextStyle style);
@@ -130,7 +139,7 @@ default void fillRect(LytRect rect, ColorValue color) {
130139
}
131140

132141
default void fillRect(int x, int y, int width, int height, ColorValue color) {
133-
fillRect(new LytRect(x, y, width, height), resolveColor(color));
142+
fillRect(x, y, width, height, resolveColor(color));
134143
}
135144

136145
default int getWidth(String text, ResolvedTextStyle style) {

src/main/java/com/hfstudio/guidenh/guide/render/VanillaRenderContext.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,16 @@ public void drawBorder(LytRect rect, int argbColor, int thickness) {
135135
argbColor);
136136
}
137137

138+
@Override
139+
public void drawBorder(int x, int y, int width, int height, int argbColor, int thickness) {
140+
int right = x + width;
141+
int bottom = y + height;
142+
Gui.drawRect(x, y, right, y + thickness, argbColor);
143+
Gui.drawRect(x, bottom - thickness, right, bottom, argbColor);
144+
Gui.drawRect(x, y + thickness, x + thickness, bottom - thickness, argbColor);
145+
Gui.drawRect(right - thickness, y + thickness, right, bottom - thickness, argbColor);
146+
}
147+
138148
@Override
139149
public void drawText(String text, int x, int y, ResolvedTextStyle style) {
140150
if (text == null || text.isEmpty()) return;

0 commit comments

Comments
 (0)