From 481ff7cc3aad20dda680aff943ad366a02f4dbee Mon Sep 17 00:00:00 2001 From: Mogball Date: Sun, 12 Apr 2020 16:05:29 -0400 Subject: Use HashSet for machine block update and limit recursion depth --- src/main/java/gregtech/api/GregTech_API.java | 2 +- .../threads/GT_Runnable_MachineBlockUpdate.java | 56 +++++++++++++++++----- 2 files changed, 45 insertions(+), 13 deletions(-) (limited to 'src/main') diff --git a/src/main/java/gregtech/api/GregTech_API.java b/src/main/java/gregtech/api/GregTech_API.java index dac494d9bc..0a6b7e96fe 100644 --- a/src/main/java/gregtech/api/GregTech_API.java +++ b/src/main/java/gregtech/api/GregTech_API.java @@ -390,7 +390,7 @@ public class GregTech_API { */ public static boolean causeMachineUpdate(World aWorld, int aX, int aY, int aZ) { if (!aWorld.isRemote) - new Thread(new GT_Runnable_MachineBlockUpdate(aWorld, aX, aY, aZ), "Machine Block Updating").start(); + new GT_Runnable_MachineBlockUpdate(aWorld, aX, aY, aZ).run(); return true; } diff --git a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java index 92944d3e32..523d504884 100644 --- a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java +++ b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java @@ -1,43 +1,75 @@ package gregtech.api.threads; import gregtech.api.GregTech_API; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Cable; +import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Fluid; +import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Item; + import net.minecraft.tileentity.TileEntity; import net.minecraft.world.ChunkPosition; import net.minecraft.world.World; -import java.util.ArrayList; +import java.util.Set; +import java.util.HashSet; public class GT_Runnable_MachineBlockUpdate implements Runnable { private final int mX, mY, mZ; private final World mWorld; + private final Set mVisited; + + private static final int MAX_UPDATE_DEPTH = 128; public GT_Runnable_MachineBlockUpdate(World aWorld, int aX, int aY, int aZ) { mWorld = aWorld; mX = aX; mY = aY; mZ = aZ; + mVisited = new HashSet(80); + } + + private boolean shouldVisit(int aX, int aY, int aZ) { + return !mVisited.contains(new ChunkPosition(aX, aY, aZ)); } - private static void stepToUpdateMachine(World aWorld, int aX, int aY, int aZ, ArrayList aList) { - aList.add(new ChunkPosition(aX, aY, aZ)); + private boolean shouldUpdate(TileEntity aTileEntity) { + // Stop recursion on cables and pipes + if (aTileEntity == null || !(aTileEntity instanceof IGregTechTileEntity)) + return false; + IMetaTileEntity tMetaTileEntity = ((IGregTechTileEntity) aTileEntity).getMetaTileEntity(); + return + !(tMetaTileEntity instanceof GT_MetaPipeEntity_Cable) && + !(tMetaTileEntity instanceof GT_MetaPipeEntity_Fluid) && + !(tMetaTileEntity instanceof GT_MetaPipeEntity_Item); + } + + private void stepToUpdateMachine(World aWorld, int aX, int aY, int aZ) { + mVisited.add(new ChunkPosition(aX, aY, aZ)); TileEntity tTileEntity = aWorld.getTileEntity(aX, aY, aZ); + if (!shouldUpdate(tTileEntity) || mVisited.size() > MAX_UPDATE_DEPTH) + return; + if (tTileEntity instanceof IMachineBlockUpdateable) ((IMachineBlockUpdateable) tTileEntity).onMachineBlockUpdate(); - if (aList.size() < 5 || (tTileEntity instanceof IMachineBlockUpdateable) || GregTech_API.isMachineBlock(aWorld.getBlock(aX, aY, aZ), aWorld.getBlockMetadata(aX, aY, aZ))) { - if (!aList.contains(new ChunkPosition(aX + 1, aY, aZ))) stepToUpdateMachine(aWorld, aX + 1, aY, aZ, aList); - if (!aList.contains(new ChunkPosition(aX - 1, aY, aZ))) stepToUpdateMachine(aWorld, aX - 1, aY, aZ, aList); - if (!aList.contains(new ChunkPosition(aX, aY + 1, aZ))) stepToUpdateMachine(aWorld, aX, aY + 1, aZ, aList); - if (!aList.contains(new ChunkPosition(aX, aY - 1, aZ))) stepToUpdateMachine(aWorld, aX, aY - 1, aZ, aList); - if (!aList.contains(new ChunkPosition(aX, aY, aZ + 1))) stepToUpdateMachine(aWorld, aX, aY, aZ + 1, aList); - if (!aList.contains(new ChunkPosition(aX, aY, aZ - 1))) stepToUpdateMachine(aWorld, aX, aY, aZ - 1, aList); + + if (mVisited.size() < 5 || + (tTileEntity instanceof IMachineBlockUpdateable) || + GregTech_API.isMachineBlock(aWorld.getBlock(aX, aY, aZ), aWorld.getBlockMetadata(aX, aY, aZ))) { + if (shouldVisit(aX + 1, aY, aZ)) stepToUpdateMachine(aWorld, aX + 1, aY, aZ); + if (shouldVisit(aX - 1, aY, aZ)) stepToUpdateMachine(aWorld, aX - 1, aY, aZ); + if (shouldVisit(aX, aY + 1, aZ)) stepToUpdateMachine(aWorld, aX, aY + 1, aZ); + if (shouldVisit(aX, aY - 1, aZ)) stepToUpdateMachine(aWorld, aX, aY - 1, aZ); + if (shouldVisit(aX, aY, aZ + 1)) stepToUpdateMachine(aWorld, aX, aY, aZ + 1); + if (shouldVisit(aX, aY, aZ - 1)) stepToUpdateMachine(aWorld, aX, aY, aZ - 1); } } @Override public void run() { try { - stepToUpdateMachine(mWorld, mX, mY, mZ, new ArrayList()); + stepToUpdateMachine(mWorld, mX, mY, mZ); } catch (Throwable e) {/**/} } -} \ No newline at end of file +} -- cgit From 209d62576be81d919b1db916c3c8540c1ca03eed Mon Sep 17 00:00:00 2001 From: Mogball Date: Sun, 12 Apr 2020 16:32:50 -0400 Subject: Fix non GT tileentities should still propagate --- .../java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/main') diff --git a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java index 523d504884..1f47ed3bfe 100644 --- a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java +++ b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java @@ -20,6 +20,7 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable { private final World mWorld; private final Set mVisited; + // Hopefully large enough for most multi-block machines private static final int MAX_UPDATE_DEPTH = 128; public GT_Runnable_MachineBlockUpdate(World aWorld, int aX, int aY, int aZ) { @@ -35,9 +36,12 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable { } private boolean shouldUpdate(TileEntity aTileEntity) { - // Stop recursion on cables and pipes - if (aTileEntity == null || !(aTileEntity instanceof IGregTechTileEntity)) + if (aTileEntity == null) return false; + + // Stop recursion on GregTech cables, item pipes, and fluid pipes + if (!(aTileEntity instanceof IGregTechTileEntity)) + return true; IMetaTileEntity tMetaTileEntity = ((IGregTechTileEntity) aTileEntity).getMetaTileEntity(); return !(tMetaTileEntity instanceof GT_MetaPipeEntity_Cable) && -- cgit From 15359ee04e8773b256aa3cbd7230947528453660 Mon Sep 17 00:00:00 2001 From: Mogball Date: Sun, 12 Apr 2020 22:16:11 -0400 Subject: Review comments --- .../threads/GT_Runnable_MachineBlockUpdate.java | 54 ++++++++++------------ 1 file changed, 25 insertions(+), 29 deletions(-) (limited to 'src/main') diff --git a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java index 1f47ed3bfe..03cd53c3dd 100644 --- a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java +++ b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java @@ -31,49 +31,45 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable { mVisited = new HashSet(80); } - private boolean shouldVisit(int aX, int aY, int aZ) { - return !mVisited.contains(new ChunkPosition(aX, aY, aZ)); - } - - private boolean shouldUpdate(TileEntity aTileEntity) { + private boolean shouldRecurse(TileEntity aTileEntity, int aX, int aY, int aZ) { if (aTileEntity == null) - return false; + return false; + + if (aTileEntity instanceof IGregTechTileEntity) { + // Stop recursion on GregTech cables, item pipes, and fluid pipes + IMetaTileEntity tMetaTileEntity = ((IGregTechTileEntity) aTileEntity).getMetaTileEntity(); + if ((tMetaTileEntity instanceof GT_MetaPipeEntity_Cable) || + (tMetaTileEntity instanceof GT_MetaPipeEntity_Fluid) || + (tMetaTileEntity instanceof GT_MetaPipeEntity_Item)) + return false; + } - // Stop recursion on GregTech cables, item pipes, and fluid pipes - if (!(aTileEntity instanceof IGregTechTileEntity)) - return true; - IMetaTileEntity tMetaTileEntity = ((IGregTechTileEntity) aTileEntity).getMetaTileEntity(); - return - !(tMetaTileEntity instanceof GT_MetaPipeEntity_Cable) && - !(tMetaTileEntity instanceof GT_MetaPipeEntity_Fluid) && - !(tMetaTileEntity instanceof GT_MetaPipeEntity_Item); + return (aTileEntity instanceof IMachineBlockUpdateable) || + GregTech_API.isMachineBlock(mWorld.getBlock(aX, aY, aZ), mWorld.getBlockMetadata(aX, aY, aZ)); } - private void stepToUpdateMachine(World aWorld, int aX, int aY, int aZ) { - mVisited.add(new ChunkPosition(aX, aY, aZ)); - TileEntity tTileEntity = aWorld.getTileEntity(aX, aY, aZ); - if (!shouldUpdate(tTileEntity) || mVisited.size() > MAX_UPDATE_DEPTH) + private void stepToUpdateMachine(int aX, int aY, int aZ) { + if (!mVisited.add(new ChunkPosition(aX, aY, aZ)) || mVisited.size() > MAX_UPDATE_DEPTH) return; - if (tTileEntity instanceof IMachineBlockUpdateable) + TileEntity tTileEntity = mWorld.getTileEntity(aX, aY, aZ); + if (tTileEntity != null && tTileEntity instanceof IMachineBlockUpdateable) ((IMachineBlockUpdateable) tTileEntity).onMachineBlockUpdate(); - if (mVisited.size() < 5 || - (tTileEntity instanceof IMachineBlockUpdateable) || - GregTech_API.isMachineBlock(aWorld.getBlock(aX, aY, aZ), aWorld.getBlockMetadata(aX, aY, aZ))) { - if (shouldVisit(aX + 1, aY, aZ)) stepToUpdateMachine(aWorld, aX + 1, aY, aZ); - if (shouldVisit(aX - 1, aY, aZ)) stepToUpdateMachine(aWorld, aX - 1, aY, aZ); - if (shouldVisit(aX, aY + 1, aZ)) stepToUpdateMachine(aWorld, aX, aY + 1, aZ); - if (shouldVisit(aX, aY - 1, aZ)) stepToUpdateMachine(aWorld, aX, aY - 1, aZ); - if (shouldVisit(aX, aY, aZ + 1)) stepToUpdateMachine(aWorld, aX, aY, aZ + 1); - if (shouldVisit(aX, aY, aZ - 1)) stepToUpdateMachine(aWorld, aX, aY, aZ - 1); + if (mVisited.size() < 5 || shouldRecurse(tTileEntity, aX, aY, aZ)) { + stepToUpdateMachine(aX + 1, aY, aZ); + stepToUpdateMachine(aX - 1, aY, aZ); + stepToUpdateMachine(aX, aY + 1, aZ); + stepToUpdateMachine(aX, aY - 1, aZ); + stepToUpdateMachine(aX, aY, aZ + 1); + stepToUpdateMachine(aX, aY, aZ - 1); } } @Override public void run() { try { - stepToUpdateMachine(mWorld, mX, mY, mZ); + stepToUpdateMachine(mX, mY, mZ); } catch (Throwable e) {/**/} } } -- cgit From 3c8c99ce5e3c850ca7ec46e88771845718d8cfc3 Mon Sep 17 00:00:00 2001 From: Mogball Date: Mon, 13 Apr 2020 00:12:03 -0400 Subject: remove recursion depth limit and nullcheck on instanceof --- .../gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/main') diff --git a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java index 03cd53c3dd..5261303838 100644 --- a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java +++ b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java @@ -20,9 +20,6 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable { private final World mWorld; private final Set mVisited; - // Hopefully large enough for most multi-block machines - private static final int MAX_UPDATE_DEPTH = 128; - public GT_Runnable_MachineBlockUpdate(World aWorld, int aX, int aY, int aZ) { mWorld = aWorld; mX = aX; @@ -32,9 +29,6 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable { } private boolean shouldRecurse(TileEntity aTileEntity, int aX, int aY, int aZ) { - if (aTileEntity == null) - return false; - if (aTileEntity instanceof IGregTechTileEntity) { // Stop recursion on GregTech cables, item pipes, and fluid pipes IMetaTileEntity tMetaTileEntity = ((IGregTechTileEntity) aTileEntity).getMetaTileEntity(); @@ -49,11 +43,11 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable { } private void stepToUpdateMachine(int aX, int aY, int aZ) { - if (!mVisited.add(new ChunkPosition(aX, aY, aZ)) || mVisited.size() > MAX_UPDATE_DEPTH) + if (!mVisited.add(new ChunkPosition(aX, aY, aZ))) return; TileEntity tTileEntity = mWorld.getTileEntity(aX, aY, aZ); - if (tTileEntity != null && tTileEntity instanceof IMachineBlockUpdateable) + if (tTileEntity instanceof IMachineBlockUpdateable) ((IMachineBlockUpdateable) tTileEntity).onMachineBlockUpdate(); if (mVisited.size() < 5 || shouldRecurse(tTileEntity, aX, aY, aZ)) { -- cgit