Skip to content

Commit

Permalink
Fix #7066: Lazily initalize AEKey display name cache (#7108)
Browse files Browse the repository at this point in the history
  • Loading branch information
Technici4n committed May 22, 2023
1 parent ca60112 commit 738554f
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 13 deletions.
7 changes: 6 additions & 1 deletion src/main/java/appeng/api/stacks/AEFluidKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import net.minecraft.core.Registry;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.ItemStack;
Expand All @@ -30,7 +31,6 @@ public final class AEFluidKey extends AEKey {
private final int hashCode;

private AEFluidKey(Fluid fluid, @Nullable CompoundTag tag) {
super(Platform.getFluidDisplayName(fluid, tag));
this.fluid = fluid;
this.tag = tag;
this.hashCode = Objects.hash(fluid, tag);
Expand Down Expand Up @@ -134,6 +134,11 @@ public void addDrops(long amount, List<ItemStack> drops, Level level, BlockPos p
// Fluids are voided
}

@Override
protected Component computeDisplayName() {
return Platform.getFluidDisplayName(fluid, tag);
}

@SuppressWarnings("unchecked")
@Override
public boolean isTagged(TagKey<?> tag) {
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/appeng/api/stacks/AEItemKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NumericTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
Expand Down Expand Up @@ -56,7 +57,6 @@ private static CompoundTag serializeStackCaps(ItemStack stack) {
private final int cachedDamage;

private AEItemKey(Item item, InternedTag internedTag, InternedTag internedCaps) {
super(Platform.getItemDisplayName(item, internedTag.tag));
this.item = item;
this.internedTag = internedTag;
this.internedCaps = internedCaps;
Expand Down Expand Up @@ -245,6 +245,11 @@ public void addDrops(long amount, List<ItemStack> drops, Level level, BlockPos p
}
}

@Override
protected Component computeDisplayName() {
return Platform.getItemDisplayName(item, internedTag.tag);
}

@SuppressWarnings("unchecked")
@Override
public boolean isTagged(TagKey<?> tag) {
Expand Down
34 changes: 23 additions & 11 deletions src/main/java/appeng/api/stacks/AEKey.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package appeng.api.stacks;

import java.util.List;
import java.util.Objects;

import javax.annotation.Nullable;

Expand Down Expand Up @@ -37,24 +36,23 @@
public abstract class AEKey {

/**
* The display name, which is used to sort by name in client terminal
* The display name, which is used to sort by name in client terminal. Lazily initialized to avoid unnecessary work
* on the server. Volatile ensures that this cache is thread-safe (but can be initialized multiple times).
*/
private final Component displayName;
private volatile Component cachedDisplayName;

/**
* @deprecated It has been deprecated because we should cache the display name in the initialization to speed up the
* sorting process.
*/
@Deprecated
// Need an explicit noargs constructor since there is already another constructor.
public AEKey() {
this.displayName = null;
}

/**
* @param displayName the display name, which is used to sort by name in client terminal
* @deprecated Use {@link #AEKey()} instead and override {@link #computeDisplayName()} instead to lazily compute the
* display name for better performance.
*/
@Deprecated(forRemoval = true)
public AEKey(Component displayName) {
this.displayName = displayName;
this.cachedDisplayName = displayName;
}

@Nullable
Expand Down Expand Up @@ -279,7 +277,21 @@ public final boolean supportsFuzzyRangeSearch() {
}

public Component getDisplayName() {
return Objects.requireNonNull(this.displayName);
var ret = cachedDisplayName;

if (ret == null) {
cachedDisplayName = ret = computeDisplayName();
}

return ret;
}

/**
* Compute the display name, which is used to sort by name in client terminal. Will be cached by
* {@link #getDisplayName()}.
*/
protected Component computeDisplayName() {
throw new UnsupportedOperationException("Must be overriden for lazy display name computation.");
}

/**
Expand Down

0 comments on commit 738554f

Please sign in to comment.