diff options
author | Technus <daniel112092@gmail.com> | 2020-04-15 19:01:06 +0200 |
---|---|---|
committer | Technus <daniel112092@gmail.com> | 2020-04-15 19:09:15 +0200 |
commit | 9bef8b3a8a8270db9c289c05c998e71273ca20fc (patch) | |
tree | d7fe3a40384a96eca093ada09bc133eef03c53ad /src/main/java/gregtech | |
parent | 9b05c6573762117ab1b60ef195e8be321b6e2bb8 (diff) | |
download | GT5-Unofficial-9bef8b3a8a8270db9c289c05c998e71273ca20fc.tar.gz GT5-Unofficial-9bef8b3a8a8270db9c289c05c998e71273ca20fc.tar.bz2 GT5-Unofficial-9bef8b3a8a8270db9c289c05c998e71273ca20fc.zip |
Refactor to fixed thread pool executor
Use actually something made for this task...
Diffstat (limited to 'src/main/java/gregtech')
10 files changed, 161 insertions, 147 deletions
diff --git a/src/main/java/gregtech/GT_Mod.java b/src/main/java/gregtech/GT_Mod.java index 9272ed20e2..22b677337e 100644 --- a/src/main/java/gregtech/GT_Mod.java +++ b/src/main/java/gregtech/GT_Mod.java @@ -1189,7 +1189,7 @@ 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.initThread(); + GT_Runnable_MachineBlockUpdate.initExecutorService(); } public boolean isServerSide() { @@ -1232,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(); @@ -1316,7 +1315,7 @@ public class GT_Mod implements IGT_Mod { } } //Interrupt IDLE Threads to close down cleanly - GT_Runnable_MachineBlockUpdate.getINSTANCETHREAD().interrupt(); + GT_Runnable_MachineBlockUpdate.shutdownExecutorService(); } private void addSolidFakeLargeBoilerFuels() { 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/threads/GT_Runnable_MachineBlockUpdate.java b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java index c811f3a614..fedf13673d 100644 --- a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java +++ b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java @@ -1,152 +1,90 @@ package gregtech.api.threads; +import gregtech.GT_Mod; import gregtech.api.GregTech_API; -import gregtech.api.interfaces.metatileentity.IMetaTileEntity; -import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable; -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.HashSet; -import java.util.Queue; import java.util.Set; -import java.util.concurrent.ConcurrentLinkedQueue; +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 static int mX; - private static int mY; - private static int mZ; - private static World mWorld; - private static final Set<ChunkPosition> mVisited = new HashSet<>(80); + //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 boolean allowedToRun; //makes if this thread is idle - private static final Queue<Coordinates> toUpdate = new ConcurrentLinkedQueue<>(); //blocks added while this thread ran - private static Thread INSTANCETHREAD; //Instance of this thread + 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() { - } - - public static synchronized void setmX(int mX) { - GT_Runnable_MachineBlockUpdate.mX = mX; - } - - public static synchronized void setmY(int mY) { - GT_Runnable_MachineBlockUpdate.mY = mY; - } - - public static synchronized void setmZ(int mZ) { - GT_Runnable_MachineBlockUpdate.mZ = mZ; - } - - public static synchronized void setmWorld(World mWorld) { - GT_Runnable_MachineBlockUpdate.mWorld = mWorld; + private GT_Runnable_MachineBlockUpdate(World aWorld, int aX, int aY, int aZ) { + this.world = aWorld; + this.x = aX; + this.y = aY; + this.z = aZ; } /** - * Clears the mVisited HashSet + * If the thread is idle, sets new values and remove the idle flag, otherwise, queue the cooridinates. */ - public static synchronized void resetVisited() { - synchronized (GT_Runnable_MachineBlockUpdate.mVisited) { - GT_Runnable_MachineBlockUpdate.mVisited.clear(); - } + public static void setMachineUpdateValues(World aWorld, int aX, int aY, int aZ) { + EXECUTOR_SERVICE.submit(new GT_Runnable_MachineBlockUpdate(aWorld,aX,aY,aZ)); } - /** - * Never call this Method without checking if the thead is NOT allowed to run! - */ - private static void setMachineUpdateValuesUnsafe(World aWorld, int aX, int aY, int aZ){ - setmZ(aZ); - setmY(aY); - setmX(aX); - setmWorld(aWorld); - resetVisited(); - setAllowedToRun(true); - synchronized (toUpdate) { - if (getINSTANCETHREAD().getState() == Thread.State.WAITING) - toUpdate.notify(); - } + 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); } - /** - * If the thread is idleing, sets new values and remove the idle flag, otherwise, queue the cooridinates. - */ - public static synchronized void setMachineUpdateValues(World aWorld, int aX, int aY, int aZ) { - if (GT_Runnable_MachineBlockUpdate.isAllowedToRun()) { - toUpdate.add(new Coordinates(aX, aY, aZ, aWorld)); - } else { - GT_Runnable_MachineBlockUpdate.setMachineUpdateValuesUnsafe(aWorld, aX, aY, aZ); - } - } - - public static class Coordinates { - - protected final int mX; - protected final int mY; - protected final int mZ; - protected 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; - } - - /** - * Updated the Main Update Thread while its Idle - */ - public void update() { - GT_Runnable_MachineBlockUpdate.setMachineUpdateValues(this.mWorld,this.mX,this.mY,this.mZ); + public static void shutdownExecutorService() { + try { + EXECUTOR_SERVICE.awaitTermination(60, TimeUnit.SECONDS); + } catch (InterruptedException e) { + GT_Mod.GT_FML_LOGGER.error("Well this interruption got interrupted...", e); } - } - - public static synchronized boolean isAllowedToRun() { - return allowedToRun; - } - - public static synchronized void setAllowedToRun(boolean unlocked) { - GT_Runnable_MachineBlockUpdate.allowedToRun = unlocked; - } - - public static synchronized void initThread() { - GT_Runnable_MachineBlockUpdate.INSTANCETHREAD = new Thread(new GT_Runnable_MachineBlockUpdate(), "GT Machine Block Updates"); - GT_Runnable_MachineBlockUpdate.INSTANCETHREAD.start(); - } - - public static synchronized Thread getINSTANCETHREAD() { - return INSTANCETHREAD; + //terminates executor permanently + EXECUTOR_SERVICE.shutdownNow(); } private boolean shouldRecurse(TileEntity aTileEntity, int aX, int aY, int aZ) { - 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; + //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(); } - - return (aTileEntity instanceof IMachineBlockUpdateable) || - GregTech_API.isMachineBlock(mWorld.getBlock(aX, aY, aZ), mWorld.getBlockMetadata(aX, aY, aZ)); } private void stepToUpdateMachine(int aX, int aY, int aZ) { - if (!mVisited.add(new ChunkPosition(aX, aY, aZ))) + if (!visited.add(new ChunkPosition(aX, aY, aZ))) return; + TileEntity tTileEntity = world.getTileEntity(aX, aY, aZ); - TileEntity tTileEntity = mWorld.getTileEntity(aX, aY, aZ); - if (tTileEntity instanceof IMachineBlockUpdateable) - ((IMachineBlockUpdateable) tTileEntity).onMachineBlockUpdate(); + causeUpdate(tTileEntity); - if (mVisited.size() < 5 || shouldRecurse(tTileEntity, aX, aY, aZ)) { + if (visited.size() < 5 || shouldRecurse(tTileEntity, aX, aY, aZ)) { stepToUpdateMachine(aX + 1, aY, aZ); stepToUpdateMachine(aX - 1, aY, aZ); stepToUpdateMachine(aX, aY + 1, aZ); @@ -154,33 +92,38 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable { stepToUpdateMachine(aX, aY, aZ + 1); stepToUpdateMachine(aX, aY, aZ - 1); } - } @Override public void run() { - for(;;) { //infinite loop - if (isAllowedToRun()) {//Are we ready to work? - try { - stepToUpdateMachine(mX, mY, mZ); - } catch (Throwable e) {/**/} - setAllowedToRun(false); //Work is finished, wait for new Coords. - } else { - //Checkes if the Update Queue has members - //DO NOT USE OPTIONALS HERE! - synchronized (toUpdate) { - Coordinates coordinates = toUpdate.poll(); - if (coordinates != null) { - coordinates.update(); - } else { - try { - toUpdate.wait(); - } catch (InterruptedException ignored) { - return; - } - } - } - } + try { + 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 |