From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Samsuik Date: Sun, 16 Feb 2025 23:27:59 +0000 Subject: [PATCH] Cache vanilla and eigencraft redstone wires diff --git a/io/papermc/paper/redstone/RedstoneWireTurbo.java b/io/papermc/paper/redstone/RedstoneWireTurbo.java index ff747a1ecdf3c888bca0d69de4f85dcd810b6139..d90f6aa4557b5863eba6a206226f763c1e89dc31 100644 --- a/io/papermc/paper/redstone/RedstoneWireTurbo.java +++ b/io/papermc/paper/redstone/RedstoneWireTurbo.java @@ -658,6 +658,7 @@ public final class RedstoneWireTurbo { // while these updates are dispatched to non-wires only, so we can // pass null. worldIn.getBlockState(upd.self).handleNeighborChanged(worldIn, upd.self, wire, null, false); + worldIn.redstoneWireCache.trackNeighbor(upd.self); // Sakura - cache vanilla and eigencraft wires } } @@ -801,6 +802,7 @@ public final class RedstoneWireTurbo { // Perform the walk over all directly reachable redstone wire blocks, propagating wire value // updates in a breadth first order out from the initial update received for the block at 'pos'. breadthFirstWalk(worldIn); + worldIn.redstoneWireCache.stopTracking(); // Sakura - cache vanilla and eigencraft wires // With the whole search completed, clear the list of all known blocks. // We do not want to keep around state information that may be changed by other code. @@ -909,6 +911,7 @@ public final class RedstoneWireTurbo { // bypass the new neighbor update stack. if (worldIn.setBlock(upd.self, state, Block.UPDATE_KNOWN_SHAPE | Block.UPDATE_CLIENTS)) updateNeighborShapes(worldIn, upd.self, state); + worldIn.redstoneWireCache.trackWirePower(upd.self, j, i); // Sakura - cache vanilla and eigencraft wires } } diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java index 8f17606889b767539c19015ae7f1cb7795616b88..529c412890993600d52287e0446757d1598bb45a 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -689,6 +689,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.levelTickScheduler.registerNewTask(this.explosionPositions::clear, 0); // Sakura - client visibility settings this.levelTickScheduler.registerNewTask(this.mergeHandler::expire, 200); // Sakura - merge cannon entities this.levelTickScheduler.registerNewTask(this.densityCache::invalidate, 0); // Sakura - explosion density cache + this.levelTickScheduler.registerNewTask(this.redstoneWireCache::expire, 300); // Sakura - cache vanilla and eigencraft wires } // Paper start diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java index 701a48ba3b0f4515a791684d63b3454dbed317f9..8156e920d76a92fd74b90de816aaff0ced480b5f 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -831,6 +831,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl public final me.samsuik.sakura.entity.merge.EntityMergeHandler mergeHandler = new me.samsuik.sakura.entity.merge.EntityMergeHandler(); // Sakura - merge cannon entities public final me.samsuik.sakura.explosion.density.BlockDensityCache densityCache = new me.samsuik.sakura.explosion.density.BlockDensityCache(); // Sakura - explosion density cache public final me.samsuik.sakura.explosion.durable.DurableBlockManager durabilityManager = new me.samsuik.sakura.explosion.durable.DurableBlockManager(); // Sakura - explosion durable blocks + public final me.samsuik.sakura.redstone.RedstoneWireCache redstoneWireCache = new me.samsuik.sakura.redstone.RedstoneWireCache(this); // Sakura - cache vanilla and eigencraft wires protected Level( WritableLevelData levelData, diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java index 270c405a7384e3290b4eea58e0b231aa6235d85a..a1428aab6923a58c04d206d63babd93242ed1ff9 100644 --- a/net/minecraft/world/level/block/RedStoneWireBlock.java +++ b/net/minecraft/world/level/block/RedStoneWireBlock.java @@ -306,6 +306,12 @@ public class RedStoneWireBlock extends Block { newPower = event.getNewCurrent(); + // Sakura start - cache vanilla and eigencraft wires + if (level.redstoneWireCache.tryApplyFromCache(pos, null, newPower, oldPower)) { + return state; + } + // Sakura end - cache vanilla and eigencraft wires + if (level.getBlockState(pos) == state) { state = state.setValue(POWER, newPower); // [Space Walker] suppress shape updates and emit those manually to @@ -313,6 +319,7 @@ public class RedStoneWireBlock extends Block { if (level.setBlock(pos, state, Block.UPDATE_KNOWN_SHAPE | Block.UPDATE_CLIENTS)) { turbo.updateNeighborShapes(level, pos, state); } + level.redstoneWireCache.trackWirePower(pos, newPower, oldPower); // Sakura - cache vanilla and eigencraft wires } } return state; @@ -432,8 +439,14 @@ public class RedStoneWireBlock extends Block { if (powerValue == 0) { return 0; } else { - return side != Direction.UP - && !this.getConnectionState(blockAccess, blockState, pos).getValue(PROPERTY_BY_DIRECTION.get(side.getOpposite())).isConnected() + // Sakura start - cache vanilla and eigencraft wires + if (side == Direction.UP) { + return powerValue; + } + final boolean updating = blockAccess instanceof Level level && level.redstoneWireCache.isWireUpdating(pos); + final BlockState state = updating ? blockState : this.getConnectionState(blockAccess, blockState, pos); + return !state.getValue(PROPERTY_BY_DIRECTION.get(side.getOpposite())).isConnected() + // Sakura end - cache vanilla and eigencraft wires ? 0 : powerValue; } diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java index fed11ed5ab97826915710b66395d1bdc926935b0..d6131c5ec6a4229291f7cecb9cec9251d54244ed 100644 --- a/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/net/minecraft/world/level/block/state/BlockBehaviour.java @@ -521,6 +521,13 @@ public abstract class BlockBehaviour implements FeatureElement { return this.constantCollisionShape; } // Paper end - optimise collisions + // Sakura start - cache vanilla and eigencraft wires + private boolean specialBlock; + + public final boolean isSpecialBlock() { + return this.specialBlock; + } + // Sakura end - cache vanilla and eigencraft wires protected BlockStateBase(Block owner, Reference2ObjectArrayMap, Comparable> values, MapCodec propertiesCodec) { super(owner, values, propertiesCodec); @@ -635,6 +642,7 @@ public abstract class BlockBehaviour implements FeatureElement { } } // Paper end - optimise collisions + this.specialBlock = !Block.class.equals(this.owner.getClass()); // Sakura - cache vanilla and eigencraft wires } public Block getBlock() { diff --git a/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java index 028eae2f9a459b60e92f3344091083aa93b54485..9fbf679b54088f89ac4ba727ccb645d645f01bd7 100644 --- a/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java +++ b/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java @@ -26,6 +26,13 @@ public class CollectingNeighborUpdater implements NeighborUpdater { this.maxChainedNeighborUpdates = maxChainedNeighborUpdates; } + // Sakura start - cache vanilla and eigencraft wires + @Override + public final int getUpdateDepth() { + return this.count; + } + // Sakura end - cache vanilla and eigencraft wires + @Override public void shapeUpdate(Direction direction, BlockState state, BlockPos pos, BlockPos neighborPos, int flags, int recursionLevel) { this.addAndRun(pos, new CollectingNeighborUpdater.ShapeUpdate(direction, state, pos.immutable(), neighborPos.immutable(), flags, recursionLevel)); @@ -83,6 +90,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater { } } } finally { + this.level.redstoneWireCache.stopTracking(); // Sakura - cache vanilla and eigencraft wires this.stack.clear(); this.addedThisLayer.clear(); this.count = 0; diff --git a/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java b/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java index abcc144a086a45bf4cfa4d1a33e2ae10952e0da2..3fc901aa038e65e3e219b92d0fa37e5dd620926f 100644 --- a/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java +++ b/net/minecraft/world/level/redstone/DefaultRedstoneWireEvaluator.java @@ -27,7 +27,14 @@ public class DefaultRedstoneWireEvaluator extends RedstoneWireEvaluator { } if (oldPower != i) { // CraftBukkit end + // Sakura start - cache vanilla and eigencraft wires + final me.samsuik.sakura.redstone.RedstoneWireCache wireCache = level.redstoneWireCache; + if (wireCache.tryApplyFromCache(pos, orientation, i, oldPower)) { + return; + } if (level.getBlockState(pos) == state) { + wireCache.trackWirePower(pos, i, oldPower); + // Sakura end - cache vanilla and eigencraft wires level.setBlock(pos, state.setValue(RedStoneWireBlock.POWER, i), 2); } @@ -39,6 +46,7 @@ public class DefaultRedstoneWireEvaluator extends RedstoneWireEvaluator { } for (BlockPos blockPos : set) { + wireCache.trackNeighborsAt(blockPos); // Sakura - cache vanilla and eigencraft wires level.updateNeighborsAt(blockPos, this.wireBlock); } } diff --git a/net/minecraft/world/level/redstone/NeighborUpdater.java b/net/minecraft/world/level/redstone/NeighborUpdater.java index 332b33a004ab11150cca0cc2cefc26d0286648f5..3691a8b2306ad4fb555ea3b4cefb8e1ea0c14b6b 100644 --- a/net/minecraft/world/level/redstone/NeighborUpdater.java +++ b/net/minecraft/world/level/redstone/NeighborUpdater.java @@ -17,6 +17,12 @@ import net.minecraft.world.level.block.state.BlockState; public interface NeighborUpdater { Direction[] UPDATE_ORDER = new Direction[]{Direction.WEST, Direction.EAST, Direction.DOWN, Direction.UP, Direction.NORTH, Direction.SOUTH}; + // Sakura start - cache vanilla and eigencraft wires + default int getUpdateDepth() { + return 0; + } + // Sakura end - cache vanilla and eigencraft wires + void shapeUpdate(Direction direction, BlockState state, BlockPos pos, BlockPos neighborPos, int flags, int recursionLevel); void neighborChanged(BlockPos pos, Block neighborBlock, @Nullable Orientation orientation);