aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/api')
-rw-r--r--src/main/java/gregtech/api/GregTech_API.java5
-rw-r--r--src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java40
-rw-r--r--src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java101
3 files changed, 92 insertions, 54 deletions
diff --git a/src/main/java/gregtech/api/GregTech_API.java b/src/main/java/gregtech/api/GregTech_API.java
index 2e39cd2181..47c99403ab 100644
--- a/src/main/java/gregtech/api/GregTech_API.java
+++ b/src/main/java/gregtech/api/GregTech_API.java
@@ -31,7 +31,6 @@ import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.ChunkCoordinates;
import net.minecraft.world.World;
import com.google.common.collect.Multimap;
@@ -408,7 +407,7 @@ public class GregTech_API {
*/
public static boolean causeMachineUpdate(World aWorld, int aX, int aY, int aZ) {
if (aWorld != null && !aWorld.isRemote && !isDummyWorld(aWorld)) { // World might be null during World-gen
- GT_Runnable_MachineBlockUpdate.setMachineUpdateValues(aWorld, new ChunkCoordinates(aX, aY, aZ));
+ GT_Runnable_MachineBlockUpdate.setMachineUpdateValues(aWorld, aX, aY, aZ);
return true;
}
return false;
@@ -419,7 +418,7 @@ public class GregTech_API {
if (aWorld == null || aWorld.isRemote || isDummyWorld(aWorld)) {
return false;
} // World might be null during World-gen
- GT_Runnable_Cable_Update.setCableUpdateValues(aWorld, new ChunkCoordinates(aX, aY, aZ));
+ GT_Runnable_Cable_Update.setCableUpdateValues(aWorld, aX, aY, aZ);
return true;
}
diff --git a/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java b/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java
index 31c3c56aa8..4375d21e40 100644
--- a/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java
+++ b/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java
@@ -1,7 +1,6 @@
package gregtech.api.threads;
import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.ChunkCoordinates;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
@@ -13,29 +12,34 @@ import gregtech.common.GT_Proxy;
public class GT_Runnable_Cable_Update extends GT_Runnable_MachineBlockUpdate {
- protected GT_Runnable_Cable_Update(World aWorld, ChunkCoordinates aCoords) {
- super(aWorld, aCoords);
+ protected GT_Runnable_Cable_Update(World aWorld, int posX, int posY, int posZ) {
+ super(aWorld, posX, posY, posZ);
}
- public static void setCableUpdateValues(World aWorld, ChunkCoordinates aCoords) {
+ public static void setCableUpdateValues(World aWorld, int posX, int posY, int posZ) {
if (isEnabled) {
- EXECUTOR_SERVICE.submit(new GT_Runnable_Cable_Update(aWorld, aCoords));
+ EXECUTOR_SERVICE.submit(new GT_Runnable_Cable_Update(aWorld, posX, posY, posZ));
}
}
@Override
public void run() {
+ int posX, posY, posZ;
try {
while (!tQueue.isEmpty()) {
- final ChunkCoordinates aCoords = tQueue.poll();
+ final long packedCoords = tQueue.dequeueLong();
+ posX = unpackLongX(packedCoords);
+ posY = unpackLongY(packedCoords);
+ posZ = unpackLongZ(packedCoords);
+
final TileEntity tTileEntity;
GT_Proxy.TICK_LOCK.lock();
try {
// we dont want to go over cables that are in unloaded chunks
// keeping the lock just to make sure no CME happens
- if (world.blockExists(aCoords.posX, aCoords.posY, aCoords.posZ)) {
- tTileEntity = world.getTileEntity(aCoords.posX, aCoords.posY, aCoords.posZ);
+ if (world.blockExists(posX, posY, posZ)) {
+ tTileEntity = world.getTileEntity(posX, posY, posZ);
} else {
tTileEntity = null;
}
@@ -51,22 +55,24 @@ public class GT_Runnable_Cable_Update extends GT_Runnable_MachineBlockUpdate {
// only add blocks the cable is connected to
if (tTileEntity instanceof BaseMetaPipeEntity metaPipe
&& metaPipe.getMetaTileEntity() instanceof GT_MetaPipeEntity_Cable cable) {
- ChunkCoordinates tCoords;
- for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
+ for (int i = 0; i < ForgeDirection.VALID_DIRECTIONS.length; i++) {
+ final ForgeDirection side = ForgeDirection.VALID_DIRECTIONS[i];
if (cable.isConnectedAtSide(side)) {
- if (visited.add(
- tCoords = new ChunkCoordinates(
- aCoords.posX + side.offsetX,
- aCoords.posY + side.offsetY,
- aCoords.posZ + side.offsetZ)))
- tQueue.add(tCoords);
+ final long tCoords = asLong(posX + side.offsetX, posY + side.offsetY, posZ + side.offsetZ);
+ if (visited.add(tCoords)) {
+ tQueue.enqueue(tCoords);
+ }
}
}
}
}
} catch (Exception e) {
GT_Mod.GT_FML_LOGGER.error(
- "Well this update was broken... " + mCoords
+ "Well this update was broken... " + initialX
+ + ", "
+ + initialY
+ + ", "
+ + initialZ
+ ", mWorld={"
+ world.getProviderName()
+ " @dimId "
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 ceb6adfa7a..3670655eaf 100644
--- a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java
+++ b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java
@@ -1,30 +1,59 @@
package gregtech.api.threads;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Queue;
-import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.ChunkCoordinates;
import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
import gregtech.GT_Mod;
import gregtech.api.GregTech_API;
import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable;
import gregtech.common.GT_Proxy;
+import it.unimi.dsi.fastutil.longs.LongArrayFIFOQueue;
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+import it.unimi.dsi.fastutil.longs.LongSet;
public class GT_Runnable_MachineBlockUpdate implements Runnable {
+ // Borrowed from Angelica until moving to GTNHLib or something
+ final static int SIZE_BITS_X = 26; // 1 + log2(MathHelper.roundUpToPowerOfTwo(30000000), RoundingMode.UNNECESSARY);
+ final static int SIZE_BITS_Z = SIZE_BITS_X;
+ final static int SIZE_BITS_Y = 64 - SIZE_BITS_X - SIZE_BITS_Z;
+ final static long BITS_X = (1L << SIZE_BITS_X) - 1L;
+ final static long BITS_Y = (1L << SIZE_BITS_Y) - 1L;
+ final static long BITS_Z = (1L << SIZE_BITS_Z) - 1L;
+ final static int BIT_SHIFT_Z = SIZE_BITS_Y;
+ final static int BIT_SHIFT_X = SIZE_BITS_Y + SIZE_BITS_Z;
+
+ static long asLong(int x, int y, int z) {
+ long l = 0L;
+ l |= ((long) x & BITS_X) << BIT_SHIFT_X;
+ l |= ((long) y & BITS_Y) << 0;
+ l |= ((long) z & BITS_Z) << BIT_SHIFT_Z;
+ return l;
+ }
+
+ public static int unpackLongX(long packedPos) {
+ return (int) (packedPos << 64 - BIT_SHIFT_X - SIZE_BITS_X >> 64 - SIZE_BITS_X);
+ }
+
+ public static int unpackLongY(long packedPos) {
+ return (int) (packedPos << 64 - SIZE_BITS_Y >> 64 - SIZE_BITS_Y);
+ }
+
+ public static int unpackLongZ(long packedPos) {
+ return (int) (packedPos << 64 - BIT_SHIFT_Z - SIZE_BITS_Z >> 64 - SIZE_BITS_Z);
+ }
+
// used by runner thread
- protected final ChunkCoordinates mCoords;
+ protected final int initialX, initialY, initialZ;
protected final World world;
- protected final Set<ChunkCoordinates> visited = new HashSet<>(80);
- protected final Queue<ChunkCoordinates> tQueue = new LinkedList<>();
+ protected final LongSet visited = new LongOpenHashSet();
+ protected final LongArrayFIFOQueue tQueue = new LongArrayFIFOQueue();
// Threading
private static final ThreadFactory THREAD_FACTORY = r -> {
@@ -35,11 +64,14 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable {
protected static ExecutorService EXECUTOR_SERVICE;
// This class should never be initiated outside of this class!
- protected GT_Runnable_MachineBlockUpdate(World aWorld, ChunkCoordinates aCoords) {
+ protected GT_Runnable_MachineBlockUpdate(World aWorld, int posX, int posY, int posZ) {
this.world = aWorld;
- this.mCoords = aCoords;
- visited.add(aCoords);
- tQueue.add(aCoords);
+ this.initialX = posX;
+ this.initialY = posY;
+ this.initialZ = posZ;
+ final long coords = asLong(posX, posY, posZ);
+ visited.add(coords);
+ tQueue.enqueue(coords);
}
public static boolean isEnabled() {
@@ -69,9 +101,9 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable {
protected static boolean isEnabled = true;
protected static final ThreadLocal<Boolean> perThreadEnable = ThreadLocal.withInitial(() -> true);
- public static void setMachineUpdateValues(World aWorld, ChunkCoordinates aCoords) {
+ public static void setMachineUpdateValues(World aWorld, int posX, int posY, int posZ) {
if (isEnabled() && isCurrentThreadEnabled()) {
- EXECUTOR_SERVICE.submit(new GT_Runnable_MachineBlockUpdate(aWorld, aCoords));
+ EXECUTOR_SERVICE.submit(new GT_Runnable_MachineBlockUpdate(aWorld, posX, posY, posZ));
}
}
@@ -116,9 +148,14 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable {
@Override
public void run() {
+ int posX, posY, posZ;
try {
while (!tQueue.isEmpty()) {
- final ChunkCoordinates aCoords = tQueue.poll();
+ final long packedCoords = tQueue.dequeueLong();
+ posX = unpackLongX(packedCoords);
+ posY = unpackLongY(packedCoords);
+ posZ = unpackLongZ(packedCoords);
+
final TileEntity tTileEntity;
final boolean isMachineBlock;
@@ -128,10 +165,9 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable {
// ConcurrentModificationException. So, lock that shit.
GT_Proxy.TICK_LOCK.lock();
try {
- tTileEntity = world.getTileEntity(aCoords.posX, aCoords.posY, aCoords.posZ);
- isMachineBlock = GregTech_API.isMachineBlock(
- world.getBlock(aCoords.posX, aCoords.posY, aCoords.posZ),
- world.getBlockMetadata(aCoords.posX, aCoords.posY, aCoords.posZ));
+ tTileEntity = world.getTileEntity(posX, posY, posZ);
+ isMachineBlock = GregTech_API
+ .isMachineBlock(world.getBlock(posX, posY, posZ), world.getBlockMetadata(posX, posY, posZ));
} finally {
GT_Proxy.TICK_LOCK.unlock();
}
@@ -148,25 +184,22 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable {
|| (tTileEntity instanceof IMachineBlockUpdateable
&& ((IMachineBlockUpdateable) tTileEntity).isMachineBlockUpdateRecursive())
|| isMachineBlock) {
- ChunkCoordinates tCoords;
-
- if (visited.add(tCoords = new ChunkCoordinates(aCoords.posX + 1, aCoords.posY, aCoords.posZ)))
- tQueue.add(tCoords);
- if (visited.add(tCoords = new ChunkCoordinates(aCoords.posX - 1, aCoords.posY, aCoords.posZ)))
- tQueue.add(tCoords);
- if (visited.add(tCoords = new ChunkCoordinates(aCoords.posX, aCoords.posY + 1, aCoords.posZ)))
- tQueue.add(tCoords);
- if (visited.add(tCoords = new ChunkCoordinates(aCoords.posX, aCoords.posY - 1, aCoords.posZ)))
- tQueue.add(tCoords);
- if (visited.add(tCoords = new ChunkCoordinates(aCoords.posX, aCoords.posY, aCoords.posZ + 1)))
- tQueue.add(tCoords);
- if (visited.add(tCoords = new ChunkCoordinates(aCoords.posX, aCoords.posY, aCoords.posZ - 1)))
- tQueue.add(tCoords);
+ for (int i = 0; i < ForgeDirection.VALID_DIRECTIONS.length; i++) {
+ final ForgeDirection side = ForgeDirection.VALID_DIRECTIONS[i];
+ final long tCoords = asLong(posX + side.offsetX, posY + side.offsetY, posZ + side.offsetZ);
+ if (visited.add(tCoords)) {
+ tQueue.enqueue(tCoords);
+ }
+ }
}
}
} catch (Exception e) {
GT_Mod.GT_FML_LOGGER.error(
- "Well this update was broken... " + mCoords
+ "Well this update was broken... " + initialX
+ + ", "
+ + initialY
+ + ", "
+ + initialZ
+ ", mWorld={"
+ world.getProviderName()
+ " @dimId "