aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/gregtech/GT_Mod.java6
-rw-r--r--src/main/java/gregtech/api/GregTech_API.java8
-rw-r--r--src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java26
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IGregTechTileEntity.java21
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IMachineBlockUpdateable.java7
-rw-r--r--src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java11
-rw-r--r--src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java11
-rw-r--r--src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java4
-rw-r--r--src/main/java/gregtech/api/metatileentity/MetaTileEntity.java1
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Frame.java5
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java3
-rw-r--r--src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java152
-rw-r--r--src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_PrimitiveBlastFurnace.java2
13 files changed, 218 insertions, 39 deletions
diff --git a/src/main/java/gregtech/GT_Mod.java b/src/main/java/gregtech/GT_Mod.java
index 6d5c9e375c..22b677337e 100644
--- a/src/main/java/gregtech/GT_Mod.java
+++ b/src/main/java/gregtech/GT_Mod.java
@@ -12,6 +12,7 @@ import gregtech.api.enums.*;
import gregtech.api.interfaces.internal.IGT_Mod;
import gregtech.api.objects.ItemData;
import gregtech.api.objects.XSTR;
+import gregtech.api.threads.GT_Runnable_MachineBlockUpdate;
import gregtech.api.util.*;
import gregtech.common.GT_DummyWorld;
import gregtech.common.GT_Network;
@@ -1187,6 +1188,8 @@ public class GT_Mod implements IGT_Mod {
}
aEvent.registerServerCommand(new GT_Command());
+ //Sets a new Machine Block Update Thread everytime a world is loaded
+ GT_Runnable_MachineBlockUpdate.initExecutorService();
}
public boolean isServerSide() {
@@ -1229,7 +1232,6 @@ public class GT_Mod implements IGT_Mod {
@Mod.EventHandler
public void onServerStopping(FMLServerStoppingEvent aEvent) {
-
for (Runnable tRunnable : GregTech_API.sBeforeGTServerstop) {
try {
tRunnable.run();
@@ -1312,6 +1314,8 @@ public class GT_Mod implements IGT_Mod {
e.printStackTrace(GT_Log.err);
}
}
+ //Interrupt IDLE Threads to close down cleanly
+ GT_Runnable_MachineBlockUpdate.shutdownExecutorService();
}
private void addSolidFakeLargeBoilerFuels() {
diff --git a/src/main/java/gregtech/api/GregTech_API.java b/src/main/java/gregtech/api/GregTech_API.java
index dac494d9bc..1cc19e7de4 100644
--- a/src/main/java/gregtech/api/GregTech_API.java
+++ b/src/main/java/gregtech/api/GregTech_API.java
@@ -389,9 +389,11 @@ public class GregTech_API {
* @param aZ is the Z-Coord of the update causing Block
*/
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();
- return true;
+ if (!aWorld.isRemote) {
+ GT_Runnable_MachineBlockUpdate.setMachineUpdateValues(aWorld, aX, aY, aZ);
+ return true;
+ }
+ return false;
}
/**
diff --git a/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java
index a518b3baaf..f0ca426616 100644
--- a/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java
+++ b/src/main/java/gregtech/api/interfaces/metatileentity/IMetaTileEntity.java
@@ -5,6 +5,7 @@ import cpw.mods.fml.relauncher.SideOnly;
import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.tileentity.IGearEnergyTileEntity;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable;
import gregtech.api.objects.GT_ItemStack;
import gregtech.api.util.GT_Config;
import net.minecraft.block.Block;
@@ -31,7 +32,7 @@ import java.util.List;
* <p/>
* Don't implement this yourself and expect it to work. Extend @MetaTileEntity itself.
*/
-public interface IMetaTileEntity extends ISidedInventory, IFluidTank, IFluidHandler, IGearEnergyTileEntity {
+public interface IMetaTileEntity extends ISidedInventory, IFluidTank, IFluidHandler, IGearEnergyTileEntity, IMachineBlockUpdateable {
/**
* This determines the BaseMetaTileEntity belonging to this MetaTileEntity by using the Meta ID of the Block itself.
* <p/>
@@ -234,11 +235,6 @@ public interface IMetaTileEntity extends ISidedInventory, IFluidTank, IFluidHand
boolean isAccessAllowed(EntityPlayer aPlayer);
/**
- * When a Machine Update occurs
- */
- void onMachineBlockUpdate();
-
- /**
* a Player rightclicks the Machine
* Sneaky rightclicks are not getting passed to this!
*
@@ -408,4 +404,22 @@ public interface IMetaTileEntity extends ISidedInventory, IFluidTank, IFluidHand
String getAlternativeModeText();
boolean shouldJoinIc2Enet();
+
+ /**
+ * The Machine Update, which is called when the Machine needs an Update of its Parts.
+ * I suggest to wait 1-5 seconds before actually checking the Machine Parts.
+ * RP-Frames could for example cause Problems when you instacheck the Machine Parts.
+ *
+ * just do stuff since we are already in meta tile...
+ */
+ @Override
+ void onMachineBlockUpdate();
+
+ /**
+ * just return in should recurse since we are already in meta tile...
+ */
+ @Override
+ default boolean isMachineBlockUpdateRecursive(){
+ return true;
+ }
}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IGregTechTileEntity.java b/src/main/java/gregtech/api/interfaces/tileentity/IGregTechTileEntity.java
index af9ead9543..8e135fbc85 100644
--- a/src/main/java/gregtech/api/interfaces/tileentity/IGregTechTileEntity.java
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IGregTechTileEntity.java
@@ -135,4 +135,25 @@ public interface IGregTechTileEntity extends ITexturedTileEntity, IGearEnergyTil
AxisAlignedBB getCollisionBoundingBoxFromPool(World aWorld, int aX, int aY, int aZ);
void onEntityCollidedWithBlock(World aWorld, int aX, int aY, int aZ, Entity collider);
+
+ /**
+ * Checks validity of meta tile and delegates to it
+ */
+ @Override
+ default void onMachineBlockUpdate(){
+ if(!isDead() && getMetaTileEntity()!=null &&
+ getMetaTileEntity().getBaseMetaTileEntity()==this){
+ getMetaTileEntity().onMachineBlockUpdate();
+ }
+ }
+
+ /**
+ * Checks validity of meta tile and delegates to it
+ */
+ @Override
+ default boolean isMachineBlockUpdateRecursive() {
+ return !isDead() && getMetaTileEntity()!=null &&
+ getMetaTileEntity().getBaseMetaTileEntity()==this &&
+ getMetaTileEntity().isMachineBlockUpdateRecursive();
+ }
} \ No newline at end of file
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IMachineBlockUpdateable.java b/src/main/java/gregtech/api/interfaces/tileentity/IMachineBlockUpdateable.java
index c7f6fe5f23..31590f3d57 100644
--- a/src/main/java/gregtech/api/interfaces/tileentity/IMachineBlockUpdateable.java
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IMachineBlockUpdateable.java
@@ -13,4 +13,11 @@ public interface IMachineBlockUpdateable {
* RP-Frames could for example cause Problems when you instacheck the Machine Parts.
*/
void onMachineBlockUpdate();
+
+ /**
+ * Should recurse?
+ */
+ default boolean isMachineBlockUpdateRecursive(){
+ return true;
+ }
}
diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java
index 881d4a814e..ae8fc7324d 100644
--- a/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java
@@ -584,11 +584,22 @@ public class BaseMetaPipeEntity extends BaseTileEntity implements IGregTechTileE
return stack;
}
+ /**
+ * Checks validity of meta tile and delegates to it
+ */
@Override
public void onMachineBlockUpdate() {
if (canAccessData()) mMetaTileEntity.onMachineBlockUpdate();
}
+ /**
+ * Checks validity of meta tile and delegates to it
+ */
+ @Override
+ public boolean isMachineBlockUpdateRecursive() {
+ return canAccessData() && mMetaTileEntity.isMachineBlockUpdateRecursive();
+ }
+
@Override
public int getProgress() {
return canAccessData() ? mMetaTileEntity.getProgresstime() : 0;
diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
index 58a97f644a..1ae88ade41 100644
--- a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
@@ -913,11 +913,22 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
return stack;
}
+ /**
+ * Checks validity of meta tile and delegates to it
+ */
@Override
public void onMachineBlockUpdate() {
if (canAccessData()) mMetaTileEntity.onMachineBlockUpdate();
}
+ /**
+ * Checks validity of meta tile and delegates to it
+ */
+ @Override
+ public boolean isMachineBlockUpdateRecursive() {
+ return canAccessData() && mMetaTileEntity.isMachineBlockUpdateRecursive();
+ }
+
@Override
public int getProgress() {
return canAccessData() ? mMetaTileEntity.getProgresstime() : 0;
diff --git a/src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java b/src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java
index 6614cca210..9fa16b9890 100644
--- a/src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/MetaPipeEntity.java
@@ -840,4 +840,8 @@ public abstract class MetaPipeEntity implements IMetaTileEntity, IConnectable {
public boolean shouldJoinIc2Enet() { return false; }
+ @Override
+ public boolean isMachineBlockUpdateRecursive() {
+ return false;
+ }
}
diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
index 1753d2677c..d08a8d9da5 100644
--- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
@@ -85,7 +85,6 @@ public abstract class MetaTileEntity implements IMetaTileEntity {
getBaseMetaTileEntity().setMetaTileID((short) aID);
GT_LanguageManager.addStringLocalization("gt.blockmachines." + mName + ".name", aRegionalName);
mInventory = new ItemStack[aInvSlotCount];
-
}
/**
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Frame.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Frame.java
index 9db9ad910e..7074d63422 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Frame.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Frame.java
@@ -97,4 +97,9 @@ public class GT_MetaPipeEntity_Frame extends MetaPipeEntity {
@Override
public void disconnect(byte aSide) {/* Do nothing*/}
+
+ @Override
+ public boolean isMachineBlockUpdateRecursive() {
+ return true;
+ }
} \ No newline at end of file
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java
index da80a9e231..3efbe0d57b 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_MultiBlockBase.java
@@ -33,7 +33,8 @@ public abstract class GT_MetaTileEntity_MultiBlockBase extends MetaTileEntity {
public static boolean disableMaintenance;
public boolean mMachine = false, mWrench = false, mScrewdriver = false, mSoftHammer = false, mHardHammer = false, mSolderingTool = false, mCrowbar = false, mRunningOnLoad = false;
- public int mPollution = 0, mProgresstime = 0, mMaxProgresstime = 0, mEUt = 0, mEfficiencyIncrease = 0, mUpdate = 0, mStartUpCheck = 100, mRuntime = 0, mEfficiency = 0;
+ public int mPollution = 0, mProgresstime = 0, mMaxProgresstime = 0, mEUt = 0, mEfficiencyIncrease = 0, mStartUpCheck = 100, mRuntime = 0, mEfficiency = 0;
+ public volatile int mUpdate = 0;
public ItemStack[] mOutputItems = null;
public FluidStack[] mOutputFluids = null;
public String mNEI;
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..3d28a94de9 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,143 @@
package gregtech.api.threads;
+import gregtech.GT_Mod;
import gregtech.api.GregTech_API;
import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.ChunkPosition;
import net.minecraft.world.World;
-import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
public class GT_Runnable_MachineBlockUpdate implements Runnable {
- private final int mX, mY, mZ;
- private final World mWorld;
-
- public GT_Runnable_MachineBlockUpdate(World aWorld, int aX, int aY, int aZ) {
- mWorld = aWorld;
- mX = aX;
- mY = aY;
- mZ = aZ;
- }
-
- private static void stepToUpdateMachine(World aWorld, int aX, int aY, int aZ, ArrayList<ChunkPosition> aList) {
- aList.add(new ChunkPosition(aX, aY, aZ));
- TileEntity tTileEntity = aWorld.getTileEntity(aX, aY, aZ);
- 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);
+ //used by runner thread
+ private final int x, y, z;
+ private final World world;
+ private final Set<ChunkPosition> visited = new HashSet<>(80);
+
+ //Threading
+ private static final ThreadFactory THREAD_FACTORY = r -> {
+ Thread thread = new Thread(r);
+ thread.setName("GT_MachineBlockUpdate");
+ return thread;
+ };
+ private static ExecutorService EXECUTOR_SERVICE;
+
+ //This class should never be initiated outside of this class!
+ private GT_Runnable_MachineBlockUpdate(World aWorld, int aX, int aY, int aZ) {
+ this.world = aWorld;
+ this.x = aX;
+ this.y = aY;
+ this.z = aZ;
+ }
+
+ public static void setMachineUpdateValues(World aWorld, int aX, int aY, int aZ) {
+ EXECUTOR_SERVICE.submit(new GT_Runnable_MachineBlockUpdate(aWorld, aX, aY, aZ));
+ }
+
+ public static void initExecutorService() {
+ EXECUTOR_SERVICE = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), THREAD_FACTORY);
+ //Executors.newSingleThreadExecutor(THREAD_FACTORY);
+ //Executors.newCachedThreadPool(THREAD_FACTORY);
+ //Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(),THREAD_FACTORY);
+ }
+
+ public static void shutdownExecutorService() {
+ try {
+ GT_Mod.GT_FML_LOGGER.info("Shutting down Machine block update executor service");
+ EXECUTOR_SERVICE.shutdown(); // Disable new tasks from being submitted
+ // Wait a while for existing tasks to terminate
+ if (!EXECUTOR_SERVICE.awaitTermination(60, TimeUnit.SECONDS)) {
+ EXECUTOR_SERVICE.shutdownNow(); // Cancel currently executing tasks
+ // Wait a while for tasks to respond to being cancelled
+ if (!EXECUTOR_SERVICE.awaitTermination(60, TimeUnit.SECONDS)) {
+ GT_Mod.GT_FML_LOGGER.error("Well this didn't terminated well... GT_Runnable_MachineBlockUpdate.shutdownExecutorService");
+ }
+ }
+ } catch (InterruptedException ie) {
+ GT_Mod.GT_FML_LOGGER.error("Well this interruption got interrupted...", ie);
+ // (Re-)Cancel if current thread also interrupted
+ EXECUTOR_SERVICE.shutdownNow();
+ // Preserve interrupt status
+ Thread.currentThread().interrupt();
+ }catch (Exception e){
+ GT_Mod.GT_FML_LOGGER.error("Well this didn't terminated well...",e);
+ // (Re-)Cancel in case
+ EXECUTOR_SERVICE.shutdownNow();
+ }finally {
+ GT_Mod.GT_FML_LOGGER.info("Leaving... GT_Runnable_MachineBlockUpdate.shutdownExecutorService");
+ }
+ }
+
+ private boolean shouldRecurse(TileEntity aTileEntity, int aX, int aY, int aZ) {
+ //no check on IGregTechTileEntity as it should call the underlying meta tile isMachineBlockUpdateRecursive
+ //if (aTileEntity instanceof IGregTechTileEntity) {
+ // return ((IGregTechTileEntity) aTileEntity).isMachineBlockUpdateRecursive();
+ //}
+ return (aTileEntity instanceof IMachineBlockUpdateable &&
+ ((IMachineBlockUpdateable) aTileEntity).isMachineBlockUpdateRecursive()) ||
+ GregTech_API.isMachineBlock(world.getBlock(aX, aY, aZ), world.getBlockMetadata(aX, aY, aZ));
+ }
+
+ private void causeUpdate(TileEntity tileEntity) {
+ //no check for IGregTechTileEntity as it should call the underlying meta tile onMachineBlockUpdate
+ if (tileEntity instanceof IMachineBlockUpdateable) {
+ ((IMachineBlockUpdateable) tileEntity).onMachineBlockUpdate();
+ }
+ }
+
+ private void stepToUpdateMachine(int aX, int aY, int aZ) {
+ if (!visited.add(new ChunkPosition(aX, aY, aZ)))
+ return;
+ TileEntity tTileEntity = world.getTileEntity(aX, aY, aZ);
+
+ causeUpdate(tTileEntity);
+
+ if (visited.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, new ArrayList<ChunkPosition>());
- } catch (Throwable e) {/**/}
+ stepToUpdateMachine(x, y, z);
+ } catch (Exception e) {
+ GT_Mod.GT_FML_LOGGER.error("Well this update was broken... " + new Coordinates(x, y, z, world), e);
+ }
+ }
+
+ public static class Coordinates {
+ public final int mX;
+ public final int mY;
+ public final int mZ;
+ public final World mWorld;
+
+ public Coordinates(int mX, int mY, int mZ, World mWorld) {
+ this.mX = mX;
+ this.mY = mY;
+ this.mZ = mZ;
+ this.mWorld = mWorld;
+ }
+
+ @Override
+ public String toString() {
+ return "Coordinates{" +
+ "mX=" + mX +
+ ", mY=" + mY +
+ ", mZ=" + mZ +
+ ", mWorld=" + mWorld.getProviderName() + " @dimId " + mWorld.provider.dimensionId +
+ '}';
+ }
}
-} \ No newline at end of file
+}
diff --git a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_PrimitiveBlastFurnace.java b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_PrimitiveBlastFurnace.java
index c0eb143f25..eeeef95dc3 100644
--- a/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_PrimitiveBlastFurnace.java
+++ b/src/main/java/gregtech/common/tileentities/machines/multi/GT_MetaTileEntity_PrimitiveBlastFurnace.java
@@ -25,7 +25,7 @@ public abstract class GT_MetaTileEntity_PrimitiveBlastFurnace extends MetaTileEn
public static final int INPUT_SLOTS = 3, OUTPUT_SLOTS = 3;
public int mMaxProgresstime = 0;
- public int mUpdate = 5;
+ public volatile int mUpdate = 5;
public int mProgresstime = 0;
public boolean mMachine = false;