Excessive block updates with bundled cables
SquidDev opened this issue ยท 2 comments
- Minecraft version: 1.16.5
- Mod version: 2.1.1.0
- Forge version: 36.1.0 in a dev environment.
I'm currently adding MoreRed integration to ComputerCraft (see #19 and cc-tweaked/CC-Tweaked#772). However, I was surprised to see that changing redstone signals causes an excessive number of block updates.
Placing a long cable and turning a lever off a lever caused 54 calls to a single block's IForgeBlockState.onNeighborChange
method. Turning the same lever on only caused 4 calls (though ideally this would still be 1).
I'm afraid I've not done much debugging here, but it appears that setChanged()
updates the neighbours once, and then notifyConnections
does it again, which may be at least part of the problem.
Example stack trace for one onNeighborChange
call
Breakpoint reached
at dan200.computercraft.shared.integration.morered.MoreRedIntegration.getBundledPower(MoreRedIntegration.java:101)
at dan200.computercraft.shared.integration.morered.MoreRedIntegration$$Lambda$4128.148815426.getBundledRedstoneOutput(Unknown Source:-1)
at dan200.computercraft.shared.BundledRedstone.getUnmaskedOutput(BundledRedstone.java:46)
at dan200.computercraft.shared.BundledRedstone.getOutput(BundledRedstone.java:63)
at dan200.computercraft.shared.computer.blocks.TileComputerBase.updateSideInput(TileComputerBase.java:236)
at dan200.computercraft.shared.computer.blocks.TileComputerBase.updateInput(TileComputerBase.java:291)
at dan200.computercraft.shared.computer.blocks.TileComputerBase.onNeighbourTileEntityChange(TileComputerBase.java:153)
at dan200.computercraft.shared.common.BlockGeneric.onNeighborChange(BlockGeneric.java:70)
at net.minecraftforge.common.extensions.IForgeBlockState.onNeighborChange(IForgeBlockState.java:475)
at net.minecraft.world.World.updateNeighbourForOutputSignal(World.java:1009)
at net.minecraft.tileentity.TileEntity.setChanged(TileEntity.java:105)
at commoble.morered.wires.BundledCableTileEntity.setPower(BundledCableTileEntity.java:88)
at commoble.morered.wires.BundledCableBlock.updatePowerAfterBlockUpdate(BundledCableBlock.java:237)
at commoble.morered.wires.BundledCableBlock.lambda$onNeighborChange$0(BundledCableBlock.java:81)
at commoble.morered.wires.BundledCableBlock$$Lambda$5910.902165049.accept(Unknown Source:-1)
at net.minecraftforge.common.util.LazyOptional.ifPresent(LazyOptional.java:165)
at commoble.morered.wires.BundledCableBlock.onNeighborChange(BundledCableBlock.java:81)
at net.minecraftforge.common.extensions.IForgeBlockState.onNeighborChange(IForgeBlockState.java:475)
at net.minecraft.world.World.updateNeighbourForOutputSignal(World.java:1009)
at net.minecraft.world.World.blockEntityChanged(World.java:805)
at net.minecraft.tileentity.TileEntity.setChanged(TileEntity.java:103)
at commoble.morered.wires.BundledCableTileEntity.setPower(BundledCableTileEntity.java:88)
at commoble.morered.wires.BundledCableBlock.updatePowerAfterBlockUpdate(BundledCableBlock.java:237)
at commoble.morered.wires.BundledCableBlock.lambda$onNeighborChange$0(BundledCableBlock.java:81)
at commoble.morered.wires.BundledCableBlock$$Lambda$5910.902165049.accept(Unknown Source:-1)
at net.minecraftforge.common.util.LazyOptional.ifPresent(LazyOptional.java:165)
at commoble.morered.wires.BundledCableBlock.onNeighborChange(BundledCableBlock.java:81)
at net.minecraftforge.common.extensions.IForgeBlockState.onNeighborChange(IForgeBlockState.java:475)
at net.minecraft.world.World.updateNeighbourForOutputSignal(World.java:1009)
at net.minecraft.world.World.blockEntityChanged(World.java:805)
at net.minecraft.tileentity.TileEntity.setChanged(TileEntity.java:103)
at commoble.morered.wires.WireTileEntity.setPower(WireTileEntity.java:39)
at commoble.morered.wires.ColoredCableBlock.updatePowerAfterBlockUpdate(ColoredCableBlock.java:250)
at commoble.morered.wires.AbstractWireBlock.neighborChanged(AbstractWireBlock.java:428)
at net.minecraft.block.AbstractBlock$AbstractBlockState.neighborChanged(AbstractBlock.java:583)
at net.minecraft.world.World.neighborChanged(World.java:339)
at net.minecraft.world.World.updateNeighborsAt(World.java:299)
at net.minecraft.world.server.ServerWorld.blockUpdated(ServerWorld.java:1372)
at net.minecraft.world.World.markAndNotifyBlock(World.java:236)
at net.minecraft.world.World.setBlock(World.java:212)
at net.minecraft.world.World.setBlock(World.java:176)
at net.minecraft.block.LeverBlock.pull(LeverBlock.java:93)
at net.minecraft.block.LeverBlock.use(LeverBlock.java:84)
at net.minecraft.block.AbstractBlock$AbstractBlockState.use(AbstractBlock.java:640)
at net.minecraft.server.management.PlayerInteractionManager.useItemOn(PlayerInteractionManager.java:338)
at net.minecraft.network.play.ServerPlayNetHandler.handleUseItemOn(ServerPlayNetHandler.java:958)
at net.minecraft.network.play.client.CPlayerTryUseItemOnBlockPacket.handle(CPlayerTryUseItemOnBlockPacket.java:36)
at net.minecraft.network.play.client.CPlayerTryUseItemOnBlockPacket.handle(CPlayerTryUseItemOnBlockPacket.java:12)
at net.minecraft.network.PacketThreadUtil.lambda$ensureRunningOnSameThread$0(PacketThreadUtil.java:19)
at net.minecraft.network.PacketThreadUtil$$Lambda$6177.994330152.run(Unknown Source:-1)
at net.minecraft.util.concurrent.TickDelayedTask.run(TickDelayedTask.java:17)
at net.minecraft.util.concurrent.ThreadTaskExecutor.doRunTask(ThreadTaskExecutor.java:136)
at net.minecraft.util.concurrent.RecursiveEventLoop.doRunTask(RecursiveEventLoop.java:22)
at net.minecraft.server.MinecraftServer.doRunTask(MinecraftServer.java:734)
at net.minecraft.server.MinecraftServer.doRunTask(MinecraftServer.java:159)
at net.minecraft.util.concurrent.ThreadTaskExecutor.pollTask(ThreadTaskExecutor.java:109)
at net.minecraft.server.MinecraftServer.pollTaskInternal(MinecraftServer.java:717)
at net.minecraft.server.MinecraftServer.pollTask(MinecraftServer.java:711)
at net.minecraft.util.concurrent.ThreadTaskExecutor.managedBlock(ThreadTaskExecutor.java:119)
at net.minecraft.server.MinecraftServer.waitUntilNextTick(MinecraftServer.java:697)
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:646)
at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:232)
at net.minecraft.server.MinecraftServer$$Lambda$5583.1827583378.run(Unknown Source:-1)
at java.lang.Thread.run(Thread.java:748)
Testing with the following setup, though I do not believe ComputerCraft is a requirement for this:
Bundled cables are just really badly implemented, they're similar to vanilla redstone in how they propagate updates. I might rewrite them to use a more graphlike implementation at some point.
Not entirely related, but I do have my own version of morered-computercraft integration that should be approved on curseforge after the weekend's over (I found that just making an adapter block was simpler than making the cables use the computercraft API directly)
https://github.com/Commoble/morered_computercraft_integration
https://www.curseforge.com/minecraft/mc-mods/more-red-computercraft-integration