From 1aa278dfe39a00b4b398ffd6f3709f639f11c5c4 Mon Sep 17 00:00:00 2001 From: Nightenom <17338378+Nightenom@users.noreply.github.com> Date: Mon, 23 Sep 2024 23:22:45 +0200 Subject: [PATCH] Do this instead --- .../ldtteam/common/fakelevel/FakeChunk.java | 11 ++++ .../ldtteam/common/fakelevel/FakeLevel.java | 8 ++- .../fakelevel/FakeLevelChunkSection.java | 4 ++ .../fakelevel/SingleBlockFakeLevelGetter.java | 66 +++++++++---------- .../common/util/BlockToItemHelper.java | 11 ++-- 5 files changed, 58 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/ldtteam/common/fakelevel/FakeChunk.java b/src/main/java/com/ldtteam/common/fakelevel/FakeChunk.java index dd2ab736..4da1546d 100644 --- a/src/main/java/com/ldtteam/common/fakelevel/FakeChunk.java +++ b/src/main/java/com/ldtteam/common/fakelevel/FakeChunk.java @@ -57,6 +57,11 @@ public FakeChunk(final FakeLevel worldIn, final int x, final int z) { super(worldIn, new ChunkPos(x, z)); this.fakeLevel = worldIn; + + // set itself to cache + fakeLevel.lastX = x; + fakeLevel.lastZ = z; + fakeLevel.lastChunk = this; } // ======================================== @@ -217,9 +222,15 @@ public LevelChunkSection[] getSections() return new LevelChunkSection[0]; } + int lastY; + LevelChunkSection lastSection = null; @Override public LevelChunkSection getSection(int yIdx) { + if (lastY == yIdx && lastSection != null) + { + return lastSection; + } return new FakeLevelChunkSection(this, yIdx); } diff --git a/src/main/java/com/ldtteam/common/fakelevel/FakeLevel.java b/src/main/java/com/ldtteam/common/fakelevel/FakeLevel.java index 7161570c..337b2cc5 100644 --- a/src/main/java/com/ldtteam/common/fakelevel/FakeLevel.java +++ b/src/main/java/com/ldtteam/common/fakelevel/FakeLevel.java @@ -293,9 +293,15 @@ public BlockState getBlockState(final BlockPos pos) return levelSource.isPosInside(pos) ? levelSource.getBlockState(pos) : Blocks.AIR.defaultBlockState(); } + int lastX, lastZ; + ChunkAccess lastChunk = null; @Override public ChunkAccess getChunk(int x, int z, ChunkStatus requiredStatus, boolean nonnull) { + if (lastX == x && lastZ == z && lastChunk != null) + { + return lastChunk; + } return nonnull || hasChunk(x, z) ? new FakeChunk(this, x, z) : null; } @@ -368,7 +374,7 @@ public boolean isInWorldBounds(final BlockPos pos) @Override public CrashReportCategory fillReportDetails(CrashReport report) { - CrashReportCategory crashreportcategory = report.addCategory("Structurize fake level"); + CrashReportCategory crashreportcategory = report.addCategory("BlockUI fake level"); levelSource.describeSelfInCrashReport(crashreportcategory); return crashreportcategory; } diff --git a/src/main/java/com/ldtteam/common/fakelevel/FakeLevelChunkSection.java b/src/main/java/com/ldtteam/common/fakelevel/FakeLevelChunkSection.java index 4b15c725..a0b3e10f 100644 --- a/src/main/java/com/ldtteam/common/fakelevel/FakeLevelChunkSection.java +++ b/src/main/java/com/ldtteam/common/fakelevel/FakeLevelChunkSection.java @@ -30,6 +30,10 @@ public FakeLevelChunkSection(final FakeChunk fakeChunk, final int yIdx) super(null, null); this.fakeChunk = fakeChunk; this.yIdx = yIdx; + + // set itself to cache + fakeChunk.lastY = yIdx; + fakeChunk.lastSection = this; } private BlockPos formGlobalPos(int x, int y, int z) diff --git a/src/main/java/com/ldtteam/common/fakelevel/SingleBlockFakeLevelGetter.java b/src/main/java/com/ldtteam/common/fakelevel/SingleBlockFakeLevelGetter.java index 02e2bd33..3f8a20d9 100644 --- a/src/main/java/com/ldtteam/common/fakelevel/SingleBlockFakeLevelGetter.java +++ b/src/main/java/com/ldtteam/common/fakelevel/SingleBlockFakeLevelGetter.java @@ -1,6 +1,8 @@ package com.ldtteam.common.fakelevel; +import net.minecraft.CrashReportCategory; import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -13,8 +15,6 @@ */ public class SingleBlockFakeLevelGetter implements IFakeLevelBlockGetter { - public static final ThreadLocal> THREAD_LOCAL = new ThreadLocal<>(); - public BlockState blockState = null; public BlockEntity blockEntity = null; @@ -48,63 +48,59 @@ public int getSizeZ() return 1; } - private static void prepareThreadLocal(final Level realLevel) + @Override + public void describeSelfInCrashReport(final CrashReportCategory category) + { + category.setDetail("Single block", blockState::toString); + category.setDetail("Single block entity type", + () -> blockEntity == null ? null : BuiltInRegistries.BLOCK_ENTITY_TYPE.getKey(blockEntity.getType()).toString()); + } + + /** + * Creates simple fakeLevel instance + * + * @param realLevel actual valid vanilla instance to provide eg. registries + * @return new fakeLevel instance + */ + public static FakeLevel createSimpleInstance(final Level realLevel) { - THREAD_LOCAL.set(new FakeLevel<>(new SingleBlockFakeLevelGetter(), IFakeLevelLightProvider.USE_CLIENT_LEVEL, realLevel, null, true)); + return new FakeLevel<>(new SingleBlockFakeLevelGetter(), IFakeLevelLightProvider.USE_CLIENT_LEVEL, realLevel, null, true); } /** * Do not forget to unset to prevent potential memory leaks * - * @param state related to blockEntity + * @param blockState related to blockEntity * @param blockEntity related to blockState * @param realLevel actual valid vanilla instance to provide eg. registries * @return prepared {@link FakeLevel} instance - * @see #unsetThreadLocal() - * @see #unsetThreadLocal(BlockEntity) + * @see #unset(FakeLevel, BlockEntity) * @see FakeLevel#setEntities(Collection) FakeLevel#setEntities(Collection) if you want to add entities, do not forget to reset */ - public static FakeLevel prepareThreadLocal(final BlockState state, + public static void prepare(final FakeLevel fakeLevel, + final BlockState blockState, @Nullable final BlockEntity blockEntity, final Level realLevel) { - final FakeLevel level = THREAD_LOCAL.get(); - if (level == null) - { - prepareThreadLocal(realLevel); - return prepareThreadLocal(state, blockEntity, realLevel); - } - - level.getLevelSource().blockEntity = blockEntity; - level.getLevelSource().blockState = state; - level.setRealLevel(realLevel); + fakeLevel.getLevelSource().blockEntity = blockEntity; + fakeLevel.getLevelSource().blockState = blockState; + fakeLevel.setRealLevel(realLevel); if (blockEntity != null) { - blockEntity.setLevel(level); + blockEntity.setLevel(fakeLevel); } - - return level; - } - - /** - * @see #prepareThreadLocal(Level) - */ - public static void unsetThreadLocal() - { - unsetThreadLocal(null); } /** * @param blockEntity to unlink level if needed - * @see #prepareThreadLocal(Level) + * @see #prepare(FakeLevel, BlockState, BlockEntity, Level) */ - public static void unsetThreadLocal(@Nullable final BlockEntity blockEntity) + public static void unset(final FakeLevel fakeLevel, @Nullable final BlockEntity blockEntity) { - final FakeLevel level = THREAD_LOCAL.get(); - level.getLevelSource().blockEntity = null; - level.getLevelSource().blockState = null; - level.setRealLevel(null); + fakeLevel.getLevelSource().blockEntity = null; + fakeLevel.getLevelSource().blockState = null; + fakeLevel.setRealLevel(null); if (blockEntity != null) { diff --git a/src/main/java/com/ldtteam/common/util/BlockToItemHelper.java b/src/main/java/com/ldtteam/common/util/BlockToItemHelper.java index 6c1b2b90..5da1a0bf 100644 --- a/src/main/java/com/ldtteam/common/util/BlockToItemHelper.java +++ b/src/main/java/com/ldtteam/common/util/BlockToItemHelper.java @@ -2,7 +2,6 @@ import com.ldtteam.blockui.mod.item.BlockStateRenderingData; import com.ldtteam.common.fakelevel.FakeLevel; -import com.ldtteam.common.fakelevel.IFakeLevelLightProvider; import com.ldtteam.common.fakelevel.SingleBlockFakeLevelGetter; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -60,14 +59,14 @@ public static ItemStack getItemStack(final BlockState blockState, final BlockEnt if (fakeLevel == null) { - fakeLevel = new FakeLevel<>(new SingleBlockFakeLevelGetter(), IFakeLevelLightProvider.USE_CLIENT_LEVEL, player.level(), null, true); + fakeLevel = SingleBlockFakeLevelGetter.createSimpleInstance(player.level()); } - fakeLevel.setRealLevel(player.level()); - fakeLevel.getLevelSource().blockState = blockState; - fakeLevel.getLevelSource().blockEntity = blockEntity; + SingleBlockFakeLevelGetter.prepare(fakeLevel, blockState, blockEntity, player.level()); + final ItemStack result = getItemStackUsingPlayerPick(fakeLevel, BlockPos.ZERO, player, ZERO_POS_HIT_RESULT); + SingleBlockFakeLevelGetter.unset(fakeLevel, blockEntity); - return getItemStackUsingPlayerPick(fakeLevel, BlockPos.ZERO, player, ZERO_POS_HIT_RESULT); + return result; } /**