mirror of
https://github.com/Samsuik/Sakura.git
synced 2025-12-19 14:59:30 +00:00
Reimplement vanilla and eigencraft redstone cache
This commit is contained in:
@@ -18,5 +18,7 @@ protected-f net.minecraft.world.entity.Entity eyeHeight
|
||||
protected-f net.minecraft.world.level.ServerExplosion center
|
||||
public net.minecraft.server.level.ServerLevel entityTickList
|
||||
public net.minecraft.world.entity.Entity stuckSpeedMultiplier
|
||||
public net.minecraft.world.level.Level neighborUpdater
|
||||
public net.minecraft.world.level.block.RedStoneWireBlock turbo
|
||||
public net.minecraft.world.level.entity.EntityTickList entities
|
||||
public net.minecraft.world.level.material.FlowingFluid getLegacyLevel(Lnet/minecraft/world/level/material/FluidState;)I
|
||||
|
||||
@@ -17,7 +17,7 @@ index 3a926d4d34a7c68a24b9e00bcbcff271c8992ad2..259c2b2d459d86cb11ab848c77f48c38
|
||||
this.isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
|
||||
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 38fc85d18f737736dcdf5142c8357f9af43e4d19..1165cf61413e9a1cd4373ef5f5858e8c5a040a20 100644
|
||||
index 316dca7b4b20c6d05bf76f64a79984d10807dab5..9fbce0f31a73928a7db752e085fb3d0020fc6387 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -837,6 +837,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
@@ -32,7 +32,7 @@ index 38fc85d18f737736dcdf5142c8357f9af43e4d19..1165cf61413e9a1cd4373ef5f5858e8c
|
||||
protected Level(
|
||||
WritableLevelData levelData,
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 761fdcd4a4e18f45547afd8edff44f61c6eeacb4..7887799c39b6e5b1657aff49d7110cf14bec8a79 100644
|
||||
index 761fdcd4a4e18f45547afd8edff44f61c6eeacb4..2fb04fa82cc7b726df1e42a1cf452ebfbdd4503a 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -126,6 +126,21 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
||||
@@ -48,7 +48,7 @@ index 761fdcd4a4e18f45547afd8edff44f61c6eeacb4..7887799c39b6e5b1657aff49d7110cf1
|
||||
+
|
||||
+ private void blockChange(BlockPos pos, BlockState newBlock, BlockState oldBlock) {
|
||||
+ for (me.samsuik.sakura.listener.BlockChangeTracker.Listener listener : this.blockChangeListeners) {
|
||||
+ if (listener.test(pos, newBlock, oldBlock)) {
|
||||
+ if (listener.test(this.level, pos, newBlock, oldBlock)) {
|
||||
+ listener.call();
|
||||
+ }
|
||||
+ }
|
||||
|
||||
@@ -35,7 +35,7 @@ index 5e48d84c5ab335975f6533472aec1e1789375bbf..30e6492e60fc7b5767d09574304ad3a3
|
||||
public Entity(EntityType<?> entityType, Level level) {
|
||||
this.type = entityType;
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 1165cf61413e9a1cd4373ef5f5858e8c5a040a20..5c61a690327cd1c872cdb3604cfa89d988918360 100644
|
||||
index 9fbce0f31a73928a7db752e085fb3d0020fc6387..869670abd843d6c10babf8ffaa7bfc919f8a818a 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -1514,6 +1514,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
|
||||
@@ -276,7 +276,7 @@ index b6467f9ff64a76104076a01bfd56852ce712d95b..e6aa1d1a5fc5cd2ffc156125c4eef2d0
|
||||
|
||||
@Nullable
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 8688f08fa902445807fe018c44e4a3b3ca01c55e..0db34fe552d65145e5714b4a9adec20c119384e7 100644
|
||||
index 869670abd843d6c10babf8ffaa7bfc919f8a818a..5c4c2823ec6b5e2d9293b9130ddf2bc1c3c12048 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -841,6 +841,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
|
||||
@@ -17,7 +17,7 @@ index 8fec4a46a9cf13d832306bd87a4fe17be79bef86..dce3331c7dbbf9bb6c6342d0a760c040
|
||||
|
||||
// Paper start
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 410a086f2fe2b6f695dd9bcce5a1f064b239f5c2..4314234e1d7f7a0fedf0ecf29ac3284e51be88d7 100644
|
||||
index 5c4c2823ec6b5e2d9293b9130ddf2bc1c3c12048..125f61e6560790bed25e2f7aedaa189caf31a8aa 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -842,6 +842,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
@@ -114,7 +114,7 @@ index 69d490c79e30fb42da69bbd804ecaea7b88fe7b0..497409e04dc4b9366da1fbe0641b8424
|
||||
this.updateNeighbours(level, pos);
|
||||
level.setBlocksDirty(pos, state, blockState);
|
||||
diff --git a/net/minecraft/world/level/block/TripWireHookBlock.java b/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
index 6a7e5a642e2eaf7d5dffadb81738f7385a38c0af..dd2ceb8fd24281a6dd06084145f387cff55c6cc9 100644
|
||||
index 30b97cdcd495490ef65c2ab9dfc39a39c93002ca..e57cc9f0987d9d4cda888bc633e5f24e510ec709 100644
|
||||
--- a/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
+++ b/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
@@ -182,6 +182,11 @@ public class TripWireHookBlock extends Block {
|
||||
|
||||
@@ -83,7 +83,7 @@ index 7554c109c35397bc1a43dd80e87764fd78645bbf..d60f30f7afb15cc90c1bd4b816136d00
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 4314234e1d7f7a0fedf0ecf29ac3284e51be88d7..544617311ccc2573273cebba62e9503caa8a8dc3 100644
|
||||
index 125f61e6560790bed25e2f7aedaa189caf31a8aa..dc3c1d354bd4fb557f295c8dca14a31048def456 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -1795,10 +1795,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
|
||||
@@ -41,7 +41,7 @@ index 68e50c6ade879d263424f244070677cb81c34c33..8467af4ee57b6699227370ada7bf15ca
|
||||
return !interactionResult.consumesAction() && context.getItemInHand().has(DataComponents.CONSUMABLE)
|
||||
? super.use(context.getLevel(), context.getPlayer(), context.getHand())
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 544617311ccc2573273cebba62e9503caa8a8dc3..7d98febf87a51fb7d9b502fa362d1bc4ac1e3eaa 100644
|
||||
index dc3c1d354bd4fb557f295c8dca14a31048def456..f7a341082d78667d34e7832f4567bbf4f3f86a00 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -843,6 +843,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
|
||||
@@ -676,7 +676,7 @@ index 78aa0ae9ce937b7232eac1d65fd987c21489979d..e719be50ff73610046696a2105367133
|
||||
if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, pos, block.defaultBlockState())) {
|
||||
this.fizz(level, pos);
|
||||
diff --git a/net/minecraft/world/level/block/RedStoneWireBlock.java b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
index efdcee032174af1f9a14183e9e8af3e7c4694942..d763a636ecb92a12786f49e2096a95827a3d1717 100644
|
||||
index 945f34971680bb1c90ea133431c900ad1b5a8ced..31a76dc1ee4a02ad91637b27d1927b5a5d38ddb3 100644
|
||||
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
@@ -572,6 +572,10 @@ public class RedStoneWireBlock extends Block {
|
||||
|
||||
@@ -5,7 +5,7 @@ Subject: [PATCH] Allow explosions to destroy lava
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
|
||||
index a4ceca6cfaaf048f3f78b18724d54780675354e7..0ed83fa6b8c8c38cc9f94a381276d300abdac839 100644
|
||||
index 8aa4debbc68530670ba6329554da5e9cf8e64a71..5d8d59fa34c9070d27e3ff38922eee465f03e663 100644
|
||||
--- a/net/minecraft/world/level/ServerExplosion.java
|
||||
+++ b/net/minecraft/world/level/ServerExplosion.java
|
||||
@@ -407,6 +407,11 @@ public class ServerExplosion implements Explosion {
|
||||
|
||||
@@ -46,7 +46,7 @@ index 47c8ed946cb2ad81a4469daf60dabc40c5e8beda..16b66b19157081c7717f73ee3dc91116
|
||||
mutablePos.set(blockX, blockY, blockZ);
|
||||
blockCollision = blockData.getCollisionShape(world, mutablePos, collisionShape);
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index c5b840f990f9f357d4b63f7e450e91c431fd2d03..e72c6eed0280aab425ae1dfa1d104a2d87651b63 100644
|
||||
index 661f913bfa8a8bd0c4929a79745ea2e0f45098e4..a80fd65ea35590a992c6340a2f42f578afdaf1ab 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -537,6 +537,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
|
||||
@@ -5,7 +5,7 @@ Subject: [PATCH] Protect scaffolding from creepers
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
|
||||
index 0ed83fa6b8c8c38cc9f94a381276d300abdac839..b43487bd468179a9634897002df44146e9f24c1b 100644
|
||||
index 5d8d59fa34c9070d27e3ff38922eee465f03e663..95fecb0338bc9c7b6c2ca484994f2f72370c5822 100644
|
||||
--- a/net/minecraft/world/level/ServerExplosion.java
|
||||
+++ b/net/minecraft/world/level/ServerExplosion.java
|
||||
@@ -412,6 +412,11 @@ public class ServerExplosion implements Explosion {
|
||||
|
||||
@@ -42,7 +42,7 @@ index 2d3721e311851c1801b090e99d4f9d0daf4e5f99..2249f5338f97471a833acddcee95f6a7
|
||||
|
||||
boolean isEmpty();
|
||||
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
|
||||
index 7d98febf87a51fb7d9b502fa362d1bc4ac1e3eaa..cfbec037f4314d7425e4abf14c77e57752eb2ae3 100644
|
||||
index f7a341082d78667d34e7832f4567bbf4f3f86a00..850de480eb3408b3a4468266aa7d16a09332b237 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -1499,7 +1499,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
@@ -282,7 +282,7 @@ index 28e3b73507b988f7234cbf29c4024c88180d0aef..a0d247aa883553708c4b921582324255
|
||||
+ // Sakura end - optimise hopper ticking
|
||||
}
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 7887799c39b6e5b1657aff49d7110cf14bec8a79..f71ae8ebf7ce494b2abf350513f826139c18eadc 100644
|
||||
index 2fb04fa82cc7b726df1e42a1cf452ebfbdd4503a..e2b684c630a44d7f84790ad305593823edb241ca 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -972,6 +972,13 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samsuik <kfian294ma4@gmail.com>
|
||||
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 539c2e465d4c89584b5bccaad18fadc41db0643a..ca21ac80c07f6aeecf01791d0eb7b5236063a0ed 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -699,6 +699,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 850de480eb3408b3a4468266aa7d16a09332b237..56161f32e9fb379fc207b0ef2c1ba44e9516b32f 100644
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -844,6 +844,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
|
||||
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 31a76dc1ee4a02ad91637b27d1927b5a5d38ddb3..f1f6159fd097db461032b8bcfdaa8bc761fbf341 100644
|
||||
--- a/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java
|
||||
@@ -331,6 +331,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
|
||||
@@ -338,6 +344,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;
|
||||
@@ -460,8 +467,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 0a233c18fbad92c59b9c001574be3464f2be9d2c..80db5829a8b023ffbc25341168466a398346e1b8 100644
|
||||
--- a/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
+++ b/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
@@ -524,6 +524,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<Property<?>, Comparable<?>> values, MapCodec<BlockState> propertiesCodec) {
|
||||
super(owner, values, propertiesCodec);
|
||||
@@ -638,6 +645,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 2d77780b6727f82ffc3cb216ca5f2d6483496cfd..981ec4e417d07a475a19032b0efe2e188e2e7180 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, Integer.valueOf(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 26c15c60d358273a3b369c286771c81d6f0979dd..485a5a5df6f94ea9793cc4ac8141679fa8527532 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);
|
||||
@@ -1,5 +1,14 @@
|
||||
--- a/net/minecraft/world/level/Level.java
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -118,7 +_,7 @@
|
||||
public final List<TickingBlockEntity> blockEntityTickers = Lists.newArrayList(); // Paper - public
|
||||
public final NeighborUpdater neighborUpdater;
|
||||
private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList();
|
||||
- private boolean tickingBlockEntities;
|
||||
+ public boolean tickingBlockEntities;
|
||||
public final Thread thread;
|
||||
private final boolean isDebug;
|
||||
private int skyDarken;
|
||||
@@ -168,6 +_,18 @@
|
||||
return this.paperConfig;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import me.samsuik.sakura.physics.PhysicsVersion;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.item.FallingBlockEntity;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
|
||||
@@ -165,7 +165,7 @@ public final class LocalConfigManager implements LocalStorageHandler {
|
||||
|
||||
public synchronized LocalValueConfig config(BlockPos position) {
|
||||
long gameTime = this.level.getGameTime();
|
||||
long ticks = this.expirationTick - gameTime;
|
||||
long ticks = gameTime - this.expirationTick;
|
||||
if (ticks >= CONFIG_CACHE_EXPIRATION / 3) {
|
||||
this.chunkConfigCache.values().removeIf(pair -> pair.value().isExpired(gameTime));
|
||||
this.expirationTick = gameTime;
|
||||
|
||||
@@ -12,7 +12,6 @@ import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.LongConsumer;
|
||||
|
||||
@NullMarked
|
||||
@@ -26,7 +25,7 @@ public final class BlockChangeTracker {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public long listenForChangesOnce(BiPredicate<BlockState, BlockState> filter, Set<BlockPos> positions, Runnable callback) {
|
||||
public long listenForChangesOnce(BlockChangeFilter filter, Set<BlockPos> positions, Runnable callback) {
|
||||
LongConsumer singleUseCallback = (identifier) -> {
|
||||
callback.run();
|
||||
this.stopListening(identifier);
|
||||
@@ -34,7 +33,7 @@ public final class BlockChangeTracker {
|
||||
return this.listenForChanges(filter, positions, singleUseCallback);
|
||||
}
|
||||
|
||||
public long listenForChanges(BiPredicate<BlockState, BlockState> filter, Set<BlockPos> positions, LongConsumer callback) {
|
||||
public long listenForChanges(BlockChangeFilter filter, Set<BlockPos> positions, LongConsumer callback) {
|
||||
long identifier = this.identifier++;
|
||||
Listener listener = new Listener(
|
||||
filter, positions, identifier, callback
|
||||
@@ -48,10 +47,12 @@ public final class BlockChangeTracker {
|
||||
|
||||
public void stopListening(long identifier) {
|
||||
Listener listener = this.identifiersInUse.remove(identifier);
|
||||
if (listener != null) {
|
||||
for (ChunkPos chunkPos : getChunkPositions(listener.positions())) {
|
||||
this.removeListenerFronChunk(chunkPos, listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeListenerFronChunk(ChunkPos chunkPos, Listener listener) {
|
||||
long chunkKey = chunkPos.toLong();
|
||||
@@ -88,14 +89,18 @@ public final class BlockChangeTracker {
|
||||
return chunkPositions;
|
||||
}
|
||||
|
||||
public record Listener(BiPredicate<BlockState, BlockState> filter, Set<BlockPos> positions,
|
||||
public interface BlockChangeFilter {
|
||||
boolean test(Level level, BlockPos pos, BlockState newBlock, BlockState oldBlock);
|
||||
}
|
||||
|
||||
public record Listener(BlockChangeFilter filter, Set<BlockPos> positions,
|
||||
long identifier, LongConsumer callback) {
|
||||
public void call() {
|
||||
this.callback.accept(this.identifier);
|
||||
}
|
||||
|
||||
public boolean test(BlockPos pos, BlockState newBlock, BlockState oldBlock) {
|
||||
return this.filter.test(newBlock, oldBlock) && this.positions.contains(pos);
|
||||
public boolean test(Level level, BlockPos pos, BlockState newBlock, BlockState oldBlock) {
|
||||
return this.filter.test(level, pos, newBlock, oldBlock) && this.positions.contains(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
package me.samsuik.sakura.redstone;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import me.samsuik.sakura.utils.TickExpiry;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.*;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.redstone.ExperimentalRedstoneUtils;
|
||||
import net.minecraft.world.level.redstone.NeighborUpdater;
|
||||
import net.minecraft.world.level.redstone.Orientation;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
@NullMarked
|
||||
public final class RedstoneNetwork {
|
||||
private final List<RedstoneWireUpdate> wireUpdates;
|
||||
private final List<BlockPos> updates;
|
||||
private final Object2ObjectMap<BlockPos, RedstoneOriginalPower> originalWirePower;
|
||||
private final LongArrayList listeners = new LongArrayList();
|
||||
private final BitSet redundantUpdates = new BitSet();
|
||||
private final TickExpiry expiry;
|
||||
|
||||
public RedstoneNetwork(List<RedstoneWireUpdate> wireUpdates, List<BlockPos> updates, Object2ObjectMap<BlockPos, RedstoneOriginalPower> originalWirePower, TickExpiry expiry) {
|
||||
this.wireUpdates = new ObjectArrayList<>(wireUpdates);
|
||||
this.updates = new ObjectArrayList<>(updates);
|
||||
this.originalWirePower = new Object2ObjectOpenHashMap<>(originalWirePower);
|
||||
this.expiry = expiry;
|
||||
}
|
||||
|
||||
private static boolean hasRedstoneComponentChanged(Level level, BlockPos pos, BlockState newBlock, BlockState oldBlock) {
|
||||
return newBlock.isRedstoneConductor(level, pos) != oldBlock.isRedstoneConductor(level, pos)
|
||||
|| newBlock.isSignalSource() != oldBlock.isSignalSource();
|
||||
}
|
||||
|
||||
private static boolean hasBlockChanged(Level level, BlockPos pos, BlockState newBlock, BlockState oldBlock) {
|
||||
return newBlock.getBlock() != oldBlock.getBlock();
|
||||
}
|
||||
|
||||
public TickExpiry getExpiry() {
|
||||
return this.expiry;
|
||||
}
|
||||
|
||||
private boolean isRegistered() {
|
||||
return !this.listeners.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasWire(BlockPos pos) {
|
||||
return this.originalWirePower.containsKey(pos);
|
||||
}
|
||||
|
||||
public void invalidate(Level level) {
|
||||
for (long identifier : this.listeners) {
|
||||
level.blockChangeTracker.stopListening(identifier);
|
||||
}
|
||||
this.listeners.clear();
|
||||
}
|
||||
|
||||
private void markNeighboringWiresForShapeUpdates(BlockPos pos, Object2ObjectMap<BlockPos, RedstoneWireUpdate> wires) {
|
||||
for (Direction direction : NeighborUpdater.UPDATE_ORDER) {
|
||||
BlockPos neighborPos = pos.relative(direction);
|
||||
RedstoneWireUpdate wireUpdate = wires.get(neighborPos);
|
||||
//noinspection ConstantValue
|
||||
if (wireUpdate != null) {
|
||||
wireUpdate.updateShapes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean prepareAndRegister(Level level) {
|
||||
Object2ObjectLinkedOpenHashMap<BlockPos, RedstoneWireUpdate> processedWires = new Object2ObjectLinkedOpenHashMap<>();
|
||||
for (RedstoneWireUpdate wireUpdate : this.wireUpdates.reversed()) {
|
||||
BlockPos wirePos = wireUpdate.getPosition();
|
||||
//noinspection ConstantValue
|
||||
if (processedWires.putAndMoveToFirst(wirePos, wireUpdate) == null) {
|
||||
// It's possible for the block below the redstone to break while the network is updating
|
||||
BlockState state = level.getBlockState(wirePos);
|
||||
if (state.is(Blocks.PISTON_HEAD)) {
|
||||
return false;
|
||||
}
|
||||
} else if (this.originalWirePower.get(wirePos).firstPower() != wireUpdate.getPower()) {
|
||||
// Filter out wires updates that are not the first and last update
|
||||
// This significantly reduces the amount of updates when unpowering
|
||||
wireUpdate.skipWireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < this.updates.size(); ++i) {
|
||||
BlockPos updatePos = this.updates.get(i);
|
||||
BlockState state = level.getBlockState(updatePos);
|
||||
|
||||
// Filter out redundant neighbor updates
|
||||
if (state.isAir() || state.liquid() || !state.isSpecialBlock() || processedWires.containsKey(updatePos)) {
|
||||
this.redundantUpdates.set(i);
|
||||
}
|
||||
|
||||
// Look for blocks that actually need shape updates
|
||||
Block block = state.getBlock();
|
||||
if (state.is(Blocks.OBSERVER) || state.liquid() || block instanceof FallingBlock || block instanceof LiquidBlockContainer) {
|
||||
this.markNeighboringWiresForShapeUpdates(updatePos, processedWires);
|
||||
}
|
||||
}
|
||||
|
||||
this.addBlockListeners(level);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void addBlockListeners(Level level) {
|
||||
ObjectOpenHashSet<BlockPos> positions = new ObjectOpenHashSet<>(this.updates);
|
||||
positions.addAll(this.originalWirePower.keySet());
|
||||
|
||||
// Register block change listeners
|
||||
this.listeners.add(level.blockChangeTracker.listenForChangesOnce(
|
||||
RedstoneNetwork::hasRedstoneComponentChanged, positions, () -> this.invalidate(level)
|
||||
));
|
||||
|
||||
this.listeners.add(level.blockChangeTracker.listenForChangesOnce(
|
||||
RedstoneNetwork::hasBlockChanged, positions, this.redundantUpdates::clear
|
||||
));
|
||||
}
|
||||
|
||||
private boolean verifyWiresInNetwork(Level level) {
|
||||
for (Object2ObjectMap.Entry<BlockPos, RedstoneOriginalPower> wireEntry : this.originalWirePower.object2ObjectEntrySet()) {
|
||||
BlockState state = level.getBlockState(wireEntry.getKey());
|
||||
if (!state.is(Blocks.REDSTONE_WIRE)) {
|
||||
this.invalidate(level);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (state.getValue(RedStoneWireBlock.POWER) != wireEntry.getValue().originalPower()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void performUpdates(Level level, Orientation orientation, RedStoneWireBlock wireBlock, int updateFrom, int updateTo) {
|
||||
for (int updateIndex = updateFrom; updateIndex < updateTo; ++updateIndex) {
|
||||
if (this.redundantUpdates.get(updateIndex)) {
|
||||
continue;
|
||||
}
|
||||
BlockPos updatePos = this.updates.get(updateIndex);
|
||||
level.getBlockState(updatePos).handleNeighborChanged(level, updatePos, wireBlock, orientation, false);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean applyFromCache(Level level) {
|
||||
this.expiry.refresh(level.getGameTime());
|
||||
if (!this.isRegistered() || !this.verifyWiresInNetwork(level)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Orientation orientation = ExperimentalRedstoneUtils.initialOrientation(level, null, null);
|
||||
RedStoneWireBlock wireBlock = (RedStoneWireBlock) Blocks.REDSTONE_WIRE;
|
||||
int updateFrom = 0;
|
||||
|
||||
for (RedstoneWireUpdate wireUpdate : this.wireUpdates) {
|
||||
if (wireUpdate.canSkipWireUpdate()) {
|
||||
updateFrom = wireUpdate.getUpdateIndex();
|
||||
continue;
|
||||
}
|
||||
|
||||
int updateTo = wireUpdate.getUpdateIndex();
|
||||
this.performUpdates(level, orientation, wireBlock, updateFrom, updateTo);
|
||||
updateFrom = updateTo;
|
||||
|
||||
BlockPos wirePos = wireUpdate.getPosition();
|
||||
BlockState state = level.getBlockState(wirePos);
|
||||
BlockState newState = state.setValue(RedStoneWireBlock.POWER, wireUpdate.getPower());
|
||||
if (level.setBlock(wirePos, newState, Block.UPDATE_CLIENTS | Block.UPDATE_KNOWN_SHAPE)) {
|
||||
if (wireUpdate.needsShapeUpdate()) {
|
||||
wireBlock.turbo.updateNeighborShapes(level, wirePos, newState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.performUpdates(level, orientation, wireBlock, updateFrom, this.updates.size());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package me.samsuik.sakura.redstone;
|
||||
|
||||
import io.papermc.paper.configuration.WorldConfiguration;
|
||||
import me.samsuik.sakura.configuration.local.LocalValueConfig;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.redstone.Orientation;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public record RedstoneNetworkSource(WorldConfiguration.Misc.RedstoneImplementation redstoneImplementation,
|
||||
BlockPos position, @Nullable Orientation orientation,
|
||||
int updateDepth, int newPower, int oldPower) {
|
||||
|
||||
public static RedstoneNetworkSource createNetworkSource(Level level, BlockPos pos, @Nullable Orientation orientation, int newPower, int oldPower) {
|
||||
LocalValueConfig localConfig = level.localConfig().config(pos);
|
||||
WorldConfiguration.Misc.RedstoneImplementation redstoneImplementation = localConfig.redstoneImplementation;
|
||||
int updateDepth = level.neighborUpdater.getUpdateDepth();
|
||||
return new RedstoneNetworkSource(redstoneImplementation, pos, orientation, updateDepth, newPower, oldPower);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package me.samsuik.sakura.redstone;
|
||||
|
||||
public record RedstoneOriginalPower(int originalPower, int firstPower) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package me.samsuik.sakura.redstone;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import me.samsuik.sakura.utils.TickExpiry;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.redstone.NeighborUpdater;
|
||||
import net.minecraft.world.level.redstone.Orientation;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@NullMarked
|
||||
public final class RedstoneWireCache {
|
||||
private final Map<RedstoneNetworkSource, RedstoneNetwork> networkCache = new Object2ObjectOpenHashMap<>();
|
||||
private @Nullable RedstoneNetworkSource networkSource;
|
||||
private final List<RedstoneWireUpdate> wireUpdates = new ObjectArrayList<>();
|
||||
private final List<BlockPos> updates = new ObjectArrayList<>();
|
||||
private final Object2ObjectMap<BlockPos, RedstoneOriginalPower> originalWirePower = new Object2ObjectOpenHashMap<>();
|
||||
private final Level level;
|
||||
private @Nullable RedstoneNetwork updatingNetwork;
|
||||
|
||||
public RedstoneWireCache(Level level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public boolean isWireUpdating(BlockPos pos) {
|
||||
return this.updatingNetwork != null && this.updatingNetwork.hasWire(pos);
|
||||
}
|
||||
|
||||
private boolean isTrackingWireUpdates() {
|
||||
return this.networkSource != null;
|
||||
}
|
||||
|
||||
public boolean tryApplyFromCache(BlockPos pos, @Nullable Orientation orientation, int newPower, int oldPower) {
|
||||
if (!this.isTrackingWireUpdates()) {
|
||||
if (this.updatingNetwork != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RedstoneNetworkSource networkSource = RedstoneNetworkSource.createNetworkSource(this.level, pos, orientation, newPower, oldPower);
|
||||
RedstoneNetwork network = this.networkCache.get(networkSource);
|
||||
if (network != null) {
|
||||
try {
|
||||
this.updatingNetwork = network;
|
||||
return network.applyFromCache(this.level);
|
||||
} finally {
|
||||
this.updatingNetwork = null;
|
||||
}
|
||||
}
|
||||
|
||||
this.networkSource = networkSource;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void trackWirePower(BlockPos pos, int newPower, int oldPower) {
|
||||
if (this.isTrackingWireUpdates()) {
|
||||
this.originalWirePower.putIfAbsent(pos, new RedstoneOriginalPower(oldPower, newPower));
|
||||
this.wireUpdates.add(new RedstoneWireUpdate(pos, newPower, this.updates.size()));
|
||||
}
|
||||
}
|
||||
|
||||
public void trackNeighbor(BlockPos pos) {
|
||||
if (this.isTrackingWireUpdates()) {
|
||||
this.updates.add(pos);
|
||||
}
|
||||
}
|
||||
|
||||
public void trackNeighborsAt(BlockPos pos) {
|
||||
if (this.isTrackingWireUpdates()) {
|
||||
for (Direction neighbor : NeighborUpdater.UPDATE_ORDER) {
|
||||
this.updates.add(pos.relative(neighbor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void expire(long tick) {
|
||||
this.networkCache.values().removeIf(network -> {
|
||||
if (network.getExpiry().isExpired(tick)) {
|
||||
network.invalidate(this.level);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
public void stopTracking() {
|
||||
if (!this.isTrackingWireUpdates()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.wireUpdates.isEmpty()) {
|
||||
// Cache expires if it has not been used in 600 ticks
|
||||
TickExpiry expiration = new TickExpiry(this.level.getGameTime(), 600);
|
||||
RedstoneNetwork redstoneNetwork = new RedstoneNetwork(
|
||||
this.wireUpdates, this.updates, this.originalWirePower, expiration
|
||||
);
|
||||
|
||||
if (redstoneNetwork.prepareAndRegister(this.level)) {
|
||||
this.networkCache.put(this.networkSource, redstoneNetwork);
|
||||
}
|
||||
}
|
||||
|
||||
this.wireUpdates.clear();
|
||||
this.updates.clear();
|
||||
this.originalWirePower.clear();
|
||||
this.networkSource = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package me.samsuik.sakura.redstone;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
public final class RedstoneWireUpdate {
|
||||
private final BlockPos position;
|
||||
private final int power;
|
||||
private final int updateIndex;
|
||||
private boolean updateShape;
|
||||
private boolean skipWire;
|
||||
|
||||
public RedstoneWireUpdate(BlockPos position, int power, int updateIndex) {
|
||||
this.position = position;
|
||||
this.power = power;
|
||||
this.updateIndex = updateIndex;
|
||||
}
|
||||
|
||||
public BlockPos getPosition() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public int getPower() {
|
||||
return this.power;
|
||||
}
|
||||
|
||||
public int getUpdateIndex() {
|
||||
return this.updateIndex;
|
||||
}
|
||||
|
||||
public boolean needsShapeUpdate() {
|
||||
return this.updateShape;
|
||||
}
|
||||
|
||||
public void updateShapes() {
|
||||
this.updateShape = true;
|
||||
}
|
||||
|
||||
public boolean canSkipWireUpdate() {
|
||||
return this.skipWire;
|
||||
}
|
||||
|
||||
public void skipWireUpdate() {
|
||||
this.skipWire = true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user