From c30b27fcfe57cb230923a75054eeb75a7004db45 Mon Sep 17 00:00:00 2001 From: LexManos Date: Wed, 12 Jun 2019 19:28:10 -0700 Subject: [PATCH] Add reverse tag cache, to make looking up tags for items/blocks/etc.. less costly. --- .../net/minecraft/block/Block.java.patch | 8 ++- .../net/minecraft/client/Minecraft.java.patch | 9 +++ .../gui/overlay/DebugOverlayGui.java.patch | 28 ++++++++++ .../EntitySpawnPlacementRegistry.java.patch | 2 +- .../minecraft/entity/EntityType.java.patch | 29 ++++++---- .../net/minecraft/fluid/Fluid.java.patch | 11 ++++ .../net/minecraft/item/Item.java.patch | 12 +++- .../net/minecraft/tags/BlockTags.java.patch | 13 +++++ .../minecraft/tags/EntityTypeTags.java.patch | 13 +++++ .../net/minecraft/tags/FluidTags.java.patch | 17 ++++++ .../net/minecraft/tags/ItemTags.java.patch | 13 +++++ .../common/extensions/IForgeBlock.java | 18 +++--- .../common/extensions/IForgeFluid.java | 9 +++ .../common/extensions/IForgeItem.java | 10 +++- .../common/util/ReverseTagWrapper.java | 55 +++++++++++++++++++ 15 files changed, 221 insertions(+), 26 deletions(-) create mode 100644 patches/minecraft/net/minecraft/client/gui/overlay/DebugOverlayGui.java.patch create mode 100644 patches/minecraft/net/minecraft/tags/BlockTags.java.patch create mode 100644 patches/minecraft/net/minecraft/tags/EntityTypeTags.java.patch create mode 100644 patches/minecraft/net/minecraft/tags/FluidTags.java.patch create mode 100644 patches/minecraft/net/minecraft/tags/ItemTags.java.patch create mode 100644 src/main/java/net/minecraftforge/common/util/ReverseTagWrapper.java diff --git a/patches/minecraft/net/minecraft/block/Block.java.patch b/patches/minecraft/net/minecraft/block/Block.java.patch index 5b8c849cb..12e962cc1 100644 --- a/patches/minecraft/net/minecraft/block/Block.java.patch +++ b/patches/minecraft/net/minecraft/block/Block.java.patch @@ -123,7 +123,7 @@ public SoundType func_220072_p(BlockState p_220072_1_) { return this.field_149762_H; } -@@ -779,13 +785,74 @@ +@@ -779,13 +785,80 @@ } public static boolean func_196252_e(Block p_196252_0_) { @@ -140,6 +140,7 @@ + protected Random RANDOM = new Random(); + private net.minecraftforge.common.ToolType harvestTool; + private int harvestLevel; ++ private final net.minecraftforge.common.util.ReverseTagWrapper reverseTags = new net.minecraftforge.common.util.ReverseTagWrapper<>(this, BlockTags::getGeneration, BlockTags::func_199896_a); + + @Override + public float getSlipperiness(BlockState state, IWorldReader world, BlockPos pos, @Nullable Entity entity) { @@ -189,6 +190,11 @@ + return false; + } + ++ @Override ++ public final java.util.Set getTags() { ++ return reverseTags.getTagNames(); ++ } ++ + static { + net.minecraftforge.common.ForgeHooks.setBlockToolSetter((block, tool, level) -> { + block.harvestTool = tool; diff --git a/patches/minecraft/net/minecraft/client/Minecraft.java.patch b/patches/minecraft/net/minecraft/client/Minecraft.java.patch index 3acd5021b..35c3b657c 100644 --- a/patches/minecraft/net/minecraft/client/Minecraft.java.patch +++ b/patches/minecraft/net/minecraft/client/Minecraft.java.patch @@ -96,6 +96,15 @@ if (this.field_71474_y.field_74353_u && !this.field_195558_d.func_198113_j()) { this.field_195558_d.func_198077_g(); this.field_71474_y.field_74353_u = this.field_195558_d.func_198113_j(); +@@ -557,7 +571,7 @@ + return Stream.of(Registry.field_212630_s.func_177774_c(p_213251_0_.func_77973_b())); + }); + SearchTreeReloadable searchtreereloadable = new SearchTreeReloadable<>((p_213235_0_) -> { +- return ItemTags.func_199903_a().func_199913_a(p_213235_0_.func_77973_b()).stream(); ++ return p_213235_0_.func_77973_b().getTags().stream(); + }); + NonNullList nonnulllist = NonNullList.func_191196_a(); + @@ -646,7 +660,7 @@ Bootstrap.func_179870_a(p_71377_1_.func_71502_e()); if (p_71377_1_.func_71497_f() != null) { diff --git a/patches/minecraft/net/minecraft/client/gui/overlay/DebugOverlayGui.java.patch b/patches/minecraft/net/minecraft/client/gui/overlay/DebugOverlayGui.java.patch new file mode 100644 index 000000000..8896538d8 --- /dev/null +++ b/patches/minecraft/net/minecraft/client/gui/overlay/DebugOverlayGui.java.patch @@ -0,0 +1,28 @@ +--- a/net/minecraft/client/gui/overlay/DebugOverlayGui.java ++++ b/net/minecraft/client/gui/overlay/DebugOverlayGui.java +@@ -342,7 +342,7 @@ + list.add(this.func_211534_a(entry)); + } + +- for(ResourceLocation resourcelocation : this.field_175242_a.func_147114_u().func_199724_l().func_199717_a().func_199913_a(blockstate.func_177230_c())) { ++ for(ResourceLocation resourcelocation : blockstate.func_177230_c().getTags()) { + list.add("#" + resourcelocation); + } + } +@@ -358,7 +358,7 @@ + list.add(this.func_211534_a(entry1)); + } + +- for(ResourceLocation resourcelocation1 : this.field_175242_a.func_147114_u().func_199724_l().func_205704_c().func_199913_a(ifluidstate.func_206886_c())) { ++ for(ResourceLocation resourcelocation1 : ifluidstate.func_206886_c().getTags()) { + list.add("#" + resourcelocation1); + } + } +@@ -368,6 +368,7 @@ + list.add(""); + list.add(TextFormatting.UNDERLINE + "Targeted Entity"); + list.add(String.valueOf((Object)Registry.field_212629_r.func_177774_c(entity.func_200600_R()))); ++ entity.func_200600_R().getTags().forEach(t -> list.add("#" + t)); + } + + return list; diff --git a/patches/minecraft/net/minecraft/entity/EntitySpawnPlacementRegistry.java.patch b/patches/minecraft/net/minecraft/entity/EntitySpawnPlacementRegistry.java.patch index b154645b4..601da6d52 100644 --- a/patches/minecraft/net/minecraft/entity/EntitySpawnPlacementRegistry.java.patch +++ b/patches/minecraft/net/minecraft/entity/EntitySpawnPlacementRegistry.java.patch @@ -3,7 +3,7 @@ @@ -9,6 +9,7 @@ private static final Map, EntitySpawnPlacementRegistry.Entry> field_209347_a = Maps.newHashMap(); - private static void func_209343_a(EntityType p_209343_0_, EntitySpawnPlacementRegistry.PlacementType p_209343_1_, Heightmap.Type p_209343_2_) { + public static void func_209343_a(EntityType p_209343_0_, EntitySpawnPlacementRegistry.PlacementType p_209343_1_, Heightmap.Type p_209343_2_) { + if (field_209347_a.containsKey(p_209343_0_)) throw new IllegalArgumentException("Invalid register call, " + p_209343_0_ + " already registered."); field_209347_a.put(p_209343_0_, new EntitySpawnPlacementRegistry.Entry(p_209343_2_, p_209343_1_)); } diff --git a/patches/minecraft/net/minecraft/entity/EntityType.java.patch b/patches/minecraft/net/minecraft/entity/EntityType.java.patch index 22071dc89..9d8cb432d 100644 --- a/patches/minecraft/net/minecraft/entity/EntityType.java.patch +++ b/patches/minecraft/net/minecraft/entity/EntityType.java.patch @@ -9,7 +9,7 @@ private static final Logger field_200731_aJ = LogManager.getLogger(); public static final EntityType field_200788_b = func_200712_a("area_effect_cloud", EntityType.Builder.func_220322_a(AreaEffectCloudEntity::new, EntityClassification.MISC).func_220320_c().func_220321_a(6.0F, 0.5F)); public static final EntityType field_200789_c = func_200712_a("armor_stand", EntityType.Builder.func_220322_a(ArmorStandEntity::new, EntityClassification.MISC).func_220321_a(0.5F, 1.975F)); -@@ -254,6 +254,11 @@ +@@ -254,6 +254,12 @@ private final Type field_206832_aX; private final EntitySize field_220359_bi; @@ -17,11 +17,12 @@ + private final java.util.function.ToIntFunction> trackingRangeSupplier; + private final java.util.function.ToIntFunction> updateIntervalSupplier; + private final java.util.function.BiFunction customClientFactory; ++ private final net.minecraftforge.common.util.ReverseTagWrapper> reverseTags = new net.minecraftforge.common.util.ReverseTagWrapper<>(this, net.minecraft.tags.EntityTypeTags::getGeneration, net.minecraft.tags.EntityTypeTags::func_219762_a); + private static EntityType func_200712_a(String p_200712_0_, EntityType.Builder p_200712_1_) { return Registry.func_218325_a(Registry.field_212629_r, p_200712_0_, p_200712_1_.func_206830_a(p_200712_0_)); } -@@ -266,7 +271,7 @@ +@@ -266,7 +272,7 @@ return Registry.field_212629_r.func_218349_b(ResourceLocation.func_208304_a(p_220327_0_)); } @@ -30,7 +31,7 @@ this.field_200732_aK = p_i50385_1_; this.field_220355_ba = p_i50385_2_; this.field_200733_aL = p_i50385_3_; -@@ -274,6 +279,10 @@ +@@ -274,6 +280,10 @@ this.field_220357_bd = p_i50385_5_; this.field_206832_aX = p_i50385_6_; this.field_220359_bi = p_i50385_7_; @@ -41,7 +42,7 @@ } @Nullable -@@ -284,6 +293,7 @@ +@@ -284,6 +294,7 @@ @Nullable public T func_220342_a(World p_220342_1_, @Nullable CompoundNBT p_220342_2_, @Nullable ITextComponent p_220342_3_, @Nullable PlayerEntity p_220342_4_, BlockPos p_220342_5_, SpawnReason p_220342_6_, boolean p_220342_7_, boolean p_220342_8_) { T t = this.func_220349_b(p_220342_1_, p_220342_2_, p_220342_3_, p_220342_4_, p_220342_5_, p_220342_6_, p_220342_7_, p_220342_8_); @@ -49,7 +50,7 @@ p_220342_1_.func_217376_c(t); return t; } -@@ -462,6 +472,9 @@ +@@ -462,6 +473,9 @@ } public int func_220345_k() { @@ -59,7 +60,7 @@ if (this == field_200729_aH) { return 32; } else if (this == field_200801_o) { -@@ -474,6 +487,9 @@ +@@ -474,6 +488,9 @@ } public int func_220332_l() { @@ -69,7 +70,7 @@ if (this != field_200729_aH && this != field_200805_s) { if (this == field_200808_v) { return 4; -@@ -494,6 +510,9 @@ +@@ -494,6 +511,9 @@ } public boolean func_220340_m() { @@ -79,7 +80,7 @@ return this != field_200729_aH && this != field_200770_J && this != field_200760_az && this != field_200791_e && this != field_200766_F && this != field_200768_H && this != field_200782_V && this != field_200801_o && this != field_200805_s; } -@@ -501,12 +520,22 @@ +@@ -501,12 +521,30 @@ return p_220341_1_.func_199685_a_(this); } @@ -87,6 +88,14 @@ + if (customClientFactory == null) throw new RuntimeException("Missing custom spawn data for entity type "+this); + return customClientFactory.apply(packet, world); + } ++ ++ /** ++ * Retrieves a list of tags names this is known to be associated with. ++ * This should be used in favor of TagCollection.getOwningTags, as this caches the result and automatically updates when the TagCollection changes. ++ */ ++ public java.util.Set getTags() { ++ return reverseTags.getTagNames(); ++ } + public static class Builder { private final EntityType.IFactory field_200709_a; @@ -102,7 +111,7 @@ private EntitySize field_220326_f = EntitySize.func_220314_b(0.6F, 1.8F); private Builder(EntityType.IFactory p_i50479_1_, EntityClassification p_i50479_2_) { -@@ -544,12 +573,32 @@ +@@ -544,12 +582,32 @@ return this; } @@ -136,7 +145,7 @@ if (SharedConstants.field_206244_b) { throw illegalstateexception; } -@@ -558,7 +607,7 @@ +@@ -558,7 +616,7 @@ } } diff --git a/patches/minecraft/net/minecraft/fluid/Fluid.java.patch b/patches/minecraft/net/minecraft/fluid/Fluid.java.patch index a000dfeb9..3a5c08be5 100644 --- a/patches/minecraft/net/minecraft/fluid/Fluid.java.patch +++ b/patches/minecraft/net/minecraft/fluid/Fluid.java.patch @@ -9,3 +9,14 @@ public static final ObjectIntIdentityMap field_207201_d = new ObjectIntIdentityMap<>(); protected final StateContainer field_207202_e; private IFluidState field_207200_b; +@@ -100,4 +100,10 @@ + } + + public abstract VoxelShape func_215664_b(IFluidState p_215664_1_, IBlockReader p_215664_2_, BlockPos p_215664_3_); ++ ++ private final net.minecraftforge.common.util.ReverseTagWrapper reverseTags = new net.minecraftforge.common.util.ReverseTagWrapper<>(this, net.minecraft.tags.FluidTags::getGeneration, net.minecraft.tags.FluidTags::getCollection); ++ @Override ++ public java.util.Set getTags() { ++ return reverseTags.getTagNames(); ++ } + } diff --git a/patches/minecraft/net/minecraft/item/Item.java.patch b/patches/minecraft/net/minecraft/item/Item.java.patch index 499c17fde..f4a506b40 100644 --- a/patches/minecraft/net/minecraft/item/Item.java.patch +++ b/patches/minecraft/net/minecraft/item/Item.java.patch @@ -76,7 +76,7 @@ ItemGroup itemgroup = this.func_77640_w(); return itemgroup != null && (p_194125_1_ == ItemGroup.field_78027_g || p_194125_1_ == itemgroup); } -@@ -316,10 +325,38 @@ +@@ -316,10 +325,44 @@ return false; } @@ -88,6 +88,7 @@ + @Nullable + private final java.util.function.Supplier teisr; + private final java.util.Map toolClasses = Maps.newHashMap(); ++ private final net.minecraftforge.common.util.ReverseTagWrapper reverseTags = new net.minecraftforge.common.util.ReverseTagWrapper<>(this, net.minecraft.tags.ItemTags::getGeneration, net.minecraft.tags.ItemTags::func_199903_a); + protected final boolean canRepair; + + @Override @@ -111,11 +112,16 @@ + net.minecraft.client.renderer.tileentity.ItemStackTileEntityRenderer renderer = teisr != null ? teisr.get() : null; + return renderer != null ? renderer : net.minecraft.client.renderer.tileentity.ItemStackTileEntityRenderer.field_147719_a; + } ++ ++ @Override ++ public java.util.Set getTags() { ++ return reverseTags.getTagNames(); ++ } + public boolean func_219970_i(ItemStack p_219970_1_) { return p_219970_1_.func_77973_b() == Items.field_222114_py; } -@@ -349,6 +386,9 @@ +@@ -349,6 +392,9 @@ private ItemGroup field_200923_d; private Rarity field_208104_e = Rarity.COMMON; private Food field_221541_f; @@ -125,7 +131,7 @@ public Item.Properties func_221540_a(Food p_221540_1_) { this.field_221541_f = p_221540_1_; -@@ -388,5 +428,20 @@ +@@ -388,5 +434,20 @@ this.field_208104_e = p_208103_1_; return this; } diff --git a/patches/minecraft/net/minecraft/tags/BlockTags.java.patch b/patches/minecraft/net/minecraft/tags/BlockTags.java.patch new file mode 100644 index 000000000..67ca59e78 --- /dev/null +++ b/patches/minecraft/net/minecraft/tags/BlockTags.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/tags/BlockTags.java ++++ b/net/minecraft/tags/BlockTags.java +@@ -70,6 +70,10 @@ + return field_199899_c; + } + ++ public static int getGeneration() { ++ return field_199900_d; ++ } ++ + private static Tag func_199894_a(String p_199894_0_) { + return new BlockTags.Wrapper(new ResourceLocation(p_199894_0_)); + } diff --git a/patches/minecraft/net/minecraft/tags/EntityTypeTags.java.patch b/patches/minecraft/net/minecraft/tags/EntityTypeTags.java.patch new file mode 100644 index 000000000..64fe2de17 --- /dev/null +++ b/patches/minecraft/net/minecraft/tags/EntityTypeTags.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/tags/EntityTypeTags.java ++++ b/net/minecraft/tags/EntityTypeTags.java +@@ -22,6 +22,10 @@ + return field_219766_c; + } + ++ public static int getGeneration() { ++ return field_219767_d; ++ } ++ + private static Tag> func_219763_a(String p_219763_0_) { + return new EntityTypeTags.Wrapper(new ResourceLocation(p_219763_0_)); + } diff --git a/patches/minecraft/net/minecraft/tags/FluidTags.java.patch b/patches/minecraft/net/minecraft/tags/FluidTags.java.patch new file mode 100644 index 000000000..29a710c6c --- /dev/null +++ b/patches/minecraft/net/minecraft/tags/FluidTags.java.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/tags/FluidTags.java ++++ b/net/minecraft/tags/FluidTags.java +@@ -18,6 +18,14 @@ + ++field_206962_d; + } + ++ public static TagCollection getCollection() { ++ return field_206961_c; ++ } ++ ++ public static int getGeneration() { ++ return field_206962_d; ++ } ++ + private static Tag func_206956_a(String p_206956_0_) { + return new FluidTags.Wrapper(new ResourceLocation(p_206956_0_)); + } diff --git a/patches/minecraft/net/minecraft/tags/ItemTags.java.patch b/patches/minecraft/net/minecraft/tags/ItemTags.java.patch new file mode 100644 index 000000000..2ce2f918c --- /dev/null +++ b/patches/minecraft/net/minecraft/tags/ItemTags.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/tags/ItemTags.java ++++ b/net/minecraft/tags/ItemTags.java +@@ -59,6 +59,10 @@ + return field_199906_c; + } + ++ public static int getGeneration() { ++ return field_199907_d; ++ } ++ + private static Tag func_199901_a(String p_199901_0_) { + return new ItemTags.Wrapper(new ResourceLocation(p_199901_0_)); + } diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java b/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java index 52498383c..0dc50c163 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java @@ -21,6 +21,7 @@ package net.minecraftforge.common.extensions; import java.util.Collection; import java.util.Optional; +import java.util.Set; import java.util.function.Predicate; import javax.annotation.Nullable; @@ -28,11 +29,9 @@ import javax.annotation.Nullable; import net.minecraft.block.Block; import net.minecraft.block.BedBlock; import net.minecraft.block.FarmlandBlock; -import net.minecraft.block.FenceBlock; import net.minecraft.block.FireBlock; import net.minecraft.block.HorizontalBlock; import net.minecraft.block.IBeaconBeamColorProvider; -import net.minecraft.block.StainedGlassBlock; import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; @@ -52,7 +51,6 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.WitherSkullEntity; import net.minecraft.fluid.IFluidState; import net.minecraft.block.Blocks; -import net.minecraft.item.Items; import net.minecraft.potion.Effects; import net.minecraft.item.DyeColor; import net.minecraft.item.Item; @@ -65,7 +63,6 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.Direction; import net.minecraft.util.Hand; -import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.Rotation; import net.minecraft.util.math.BlockPos; @@ -86,6 +83,7 @@ import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.IPlantable; import net.minecraftforge.common.ToolType; +@SuppressWarnings("deprecation") public interface IForgeBlock { default Block getBlock() @@ -177,7 +175,6 @@ public interface IForgeBlock * @param state State of the current block * @return True if block has a tile entity, false otherwise */ - @SuppressWarnings("deprecation") default boolean hasTileEntity(BlockState state) { return this instanceof ITileEntityProvider; @@ -192,7 +189,6 @@ public interface IForgeBlock * @param world The world to create the TE in * @return A instance of a class extending TileEntity */ - @SuppressWarnings("deprecation") @Nullable default TileEntity createTileEntity(BlockState state, IBlockReader world) { @@ -606,7 +602,6 @@ public interface IForgeBlock return 0; } - @SuppressWarnings("deprecation") default BlockState rotate(BlockState state, IWorld world, BlockPos pos, Rotation direction) { return state.rotate(direction); @@ -855,7 +850,6 @@ public interface IForgeBlock * @param hand The player hand used to place this block * @return The state to be placed in the world */ - @SuppressWarnings("deprecation") default BlockState getStateForPlacement(BlockState state, Direction facing, BlockState state2, IWorld world, BlockPos pos1, BlockPos pos2, Hand hand) { return this.getBlock().updatePostPlacement(state, facing, state2, world, pos1, pos2); @@ -905,7 +899,6 @@ public interface IForgeBlock * @param face The face that the fire is coming from * @return A number ranging from 0 to 300 relating used to determine if the block will be consumed by fire */ - @SuppressWarnings("deprecation") default int getFlammability(BlockState state, IBlockReader world, BlockPos pos, Direction face) { return ((FireBlock)Blocks.FIRE).func_220274_q(state); @@ -1006,9 +999,14 @@ public interface IForgeBlock /** * Determines if this block should drop loot when exploded. */ - @SuppressWarnings("deprecation") default boolean canDropFromExplosion(BlockState state, IBlockReader world, BlockPos pos, Explosion explosion) { return state.getBlock().canDropFromExplosion(explosion); } + + /** + * Retrieves a list of tags names this is known to be associated with. + * This should be used in favor of TagCollection.getOwningTags, as this caches the result and automatically updates when the TagCollection changes. + */ + Set getTags(); } diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeFluid.java b/src/main/java/net/minecraftforge/common/extensions/IForgeFluid.java index 7b559c9de..d66ca0cec 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeFluid.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeFluid.java @@ -19,6 +19,8 @@ package net.minecraftforge.common.extensions; +import java.util.Set; + import javax.annotation.Nullable; import net.minecraft.block.material.Material; @@ -28,6 +30,7 @@ import net.minecraft.fluid.Fluid; import net.minecraft.fluid.IFluidState; import net.minecraft.tags.Tag; import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.world.Explosion; @@ -108,4 +111,10 @@ public interface IForgeFluid { return this.getFluid().getRenderLayer() == layer; } + + /** + * Retrieves a list of tags names this is known to be associated with. + * This should be used in favor of TagCollection.getOwningTags, as this caches the result and automatically updates when the TagCollection changes. + */ + Set getTags(); } diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeItem.java b/src/main/java/net/minecraftforge/common/extensions/IForgeItem.java index c9b72098b..f59055e12 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeItem.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeItem.java @@ -28,6 +28,7 @@ import com.google.common.collect.Multimap; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.entity.model.BipedModel; +import net.minecraft.client.renderer.tileentity.ItemStackTileEntityRenderer; import net.minecraft.entity.Entity; import net.minecraft.entity.MobEntity; import net.minecraft.entity.LivingEntity; @@ -43,6 +44,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.ActionResultType; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; @@ -759,5 +761,11 @@ public interface IForgeItem * one. */ @OnlyIn(Dist.CLIENT) - net.minecraft.client.renderer.tileentity.ItemStackTileEntityRenderer getTileEntityItemStackRenderer(); + ItemStackTileEntityRenderer getTileEntityItemStackRenderer(); + + /** + * Retrieves a list of tags names this is known to be associated with. + * This should be used in favor of TagCollection.getOwningTags, as this caches the result and automatically updates when the TagCollection changes. + */ + Set getTags(); } diff --git a/src/main/java/net/minecraftforge/common/util/ReverseTagWrapper.java b/src/main/java/net/minecraftforge/common/util/ReverseTagWrapper.java new file mode 100644 index 000000000..5ac99479f --- /dev/null +++ b/src/main/java/net/minecraftforge/common/util/ReverseTagWrapper.java @@ -0,0 +1,55 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.common.util; + +import java.util.HashSet; +import java.util.Set; +import java.util.function.IntSupplier; +import java.util.function.Supplier; + +import net.minecraft.tags.TagCollection; +import net.minecraft.util.ResourceLocation; + +public class ReverseTagWrapper +{ + private final T target; + private final IntSupplier genSupplier; + private final Supplier> colSupplier; + + private int generation = -1; + private Set cache = null; + + public ReverseTagWrapper(T target, IntSupplier genSupplier, Supplier> colSupplier) + { + this.target = target; + this.genSupplier = genSupplier; + this.colSupplier = colSupplier; + } + + public Set getTagNames() + { + if (cache == null || generation != genSupplier.getAsInt()) + { + this.cache = new HashSet<>(colSupplier.get().getOwningTags(target)); + this.generation = genSupplier.getAsInt(); + } + return this.cache; + } +}