diff --git a/container/implementations/ContainerMEMonitorable.java b/container/implementations/ContainerMEMonitorable.java index a16649a6c..802a645c0 100644 --- a/container/implementations/ContainerMEMonitorable.java +++ b/container/implementations/ContainerMEMonitorable.java @@ -1,7 +1,5 @@ package appeng.container.implementations; -import invtweaks.api.container.IgnoreContainer; - import java.io.IOException; import java.nio.BufferOverflowException; @@ -49,7 +47,6 @@ import appeng.util.ConfigManager; import appeng.util.IConfigManagerHost; import appeng.util.Platform; -@IgnoreContainer public class ContainerMEMonitorable extends AEBaseContainer implements IConfigManagerHost, IConfigureableObject, IMEMonitorHandlerReceiver { diff --git a/helpers/DualityInterface.java b/helpers/DualityInterface.java index 68d44377e..0d2f55276 100644 --- a/helpers/DualityInterface.java +++ b/helpers/DualityInterface.java @@ -881,9 +881,7 @@ public class DualityInterface implements IGridTickable, ISegmentedInventory, ISt TileEntity te = iHost.getTileEntity(); if ( te != null && te.getWorldObj() != null ) - { - // te.getWorldObj().notifyBlocksOfNeighborChange( te.xCoord, te.yCoord, te.zCoord, Platform.air ); - } + Platform.notifyBlocksOfNeighbors( te.getWorldObj(), te.xCoord, te.yCoord, te.zCoord ); } public IUpgradeableHost getHost() diff --git a/hooks/TickHandler.java b/hooks/TickHandler.java index 6997654ca..0b856428f 100644 --- a/hooks/TickHandler.java +++ b/hooks/TickHandler.java @@ -4,6 +4,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.Queue; +import java.util.WeakHashMap; import java.util.concurrent.Callable; import net.minecraft.world.World; @@ -47,7 +48,8 @@ public class TickHandler final public static TickHandler instance = new TickHandler(); - final private Queue callQueue = new LinkedList(); + final private WeakHashMap> callQueue = new WeakHashMap>(); + Queue serverQueue = new LinkedList(); final private HandlerRep server = new HandlerRep(); final private HandlerRep client = new HandlerRep(); @@ -59,9 +61,19 @@ public class TickHandler return client; } - public void addCallable(Callable c) + public void addCallable(World w, Callable c) { - callQueue.add( c ); + if ( w == null ) + serverQueue.add( c ); + else + { + Queue queue = callQueue.get( w ); + + if ( queue == null ) + callQueue.put( w, queue = new LinkedList() ); + + queue.add( c ); + } } public void addInit(AEBaseTile tile) @@ -153,6 +165,7 @@ public class TickHandler // for no there is no reason to care about this on the client... else if ( ev.type == Type.SERVER && ev.phase == Phase.END ) { + // ready tiles. HandlerRep repo = getRepo(); while (!repo.tiles.isEmpty()) { @@ -160,22 +173,36 @@ public class TickHandler bt.onReady(); } + // tick networks. for (Grid g : getRepo().networks) - { g.update(); - } - Callable c = null; - while ((c = callQueue.poll()) != null) + // cross world queue. + processQueue( serverQueue ); + } + + // world synced queue(s) + if ( ev.type == Type.WORLD && ev.phase == Phase.START ) + { + processQueue( callQueue.get( ((WorldTickEvent) ev).world ) ); + } + } + + private void processQueue(Queue queue) + { + if ( queue == null ) + return; + + Callable c = null; + while ((c = queue.poll()) != null) + { + try { - try - { - c.call(); - } - catch (Exception e) - { - AELog.error( e ); - } + c.call(); + } + catch (Exception e) + { + AELog.error( e ); } } } @@ -189,4 +216,5 @@ public class TickHandler craftingJobs.put( world, craftingJob ); } } + } diff --git a/me/GridNode.java b/me/GridNode.java index c33008a7d..918d4968c 100644 --- a/me/GridNode.java +++ b/me/GridNode.java @@ -286,7 +286,7 @@ public class GridNode implements IGridNode, IPathItem } catch (FailedConnection e) { - TickHandler.instance.addCallable( new Callable() { + TickHandler.instance.addCallable( node.getWorld(), new Callable() { @Override public Object call() throws Exception @@ -321,7 +321,7 @@ public class GridNode implements IGridNode, IPathItem } catch (FailedConnection e) { - TickHandler.instance.addCallable( new Callable() { + TickHandler.instance.addCallable( node.getWorld(), new Callable() { @Override public Object call() throws Exception diff --git a/me/cache/TickManagerCache.java b/me/cache/TickManagerCache.java index 314bc66a2..18ff54feb 100644 --- a/me/cache/TickManagerCache.java +++ b/me/cache/TickManagerCache.java @@ -113,8 +113,14 @@ public class TickManagerCache implements ITickManager sleeping.remove( node ); awake.put( node, tt ); + // configure sort. tt.lastTick = tt.lastTick - tt.request.maxTickRate; + tt.current_rate = tt.request.minTickRate; + + // prevent dupes and tick build up. + upcomingTicks.remove( tt ); upcomingTicks.add( tt ); + return true; } diff --git a/me/helpers/StorageInterestManager.java b/me/helpers/StorageInterestManager.java index c4e9761f8..4917e6e1e 100644 --- a/me/helpers/StorageInterestManager.java +++ b/me/helpers/StorageInterestManager.java @@ -25,6 +25,7 @@ public class StorageInterestManager { private final SetMultimap container; private LinkedList transactions = null; + private int transDepth=0; public StorageInterestManager(SetMultimap interests) { container = interests; @@ -32,20 +33,28 @@ public class StorageInterestManager { public void enableTransactions() { - transactions = new LinkedList(); + if ( transDepth == 0 ) + transactions = new LinkedList(); + + transDepth++; } public void disableTransactions() { - LinkedList myActions = transactions; - transactions = null; - - for ( SavedTransactions t : myActions ) + transDepth--; + + if ( transDepth == 0 ) { - if ( t.put ) - put( t.stack, t.iw ); - else - remove( t.stack, t.iw ); + LinkedList myActions = transactions; + transactions = null; + + for ( SavedTransactions t : myActions ) + { + if ( t.put ) + put( t.stack, t.iw ); + else + remove( t.stack, t.iw ); + } } } diff --git a/parts/PartPlacement.java b/parts/PartPlacement.java index 1c10dff0e..f06cab20f 100644 --- a/parts/PartPlacement.java +++ b/parts/PartPlacement.java @@ -138,7 +138,7 @@ public class PartPlacement { is.add( sp.facade.getItemStack() ); host.getFacadeContainer().removeFacade( host, sp.side ); - world.notifyBlocksOfNeighborChange( x, y, z, Platform.air ); + Platform.notifyBlocksOfNeighbors( world, x, y, z ); } if ( host.isEmpty() ) diff --git a/parts/automation/PartAnnihilationPlane.java b/parts/automation/PartAnnihilationPlane.java index 386153454..a2add866b 100644 --- a/parts/automation/PartAnnihilationPlane.java +++ b/parts/automation/PartAnnihilationPlane.java @@ -312,7 +312,7 @@ public class PartAnnihilationPlane extends PartBasicState implements IGridTickab else { breaking = true; - TickHandler.instance.addCallable( this ); + TickHandler.instance.addCallable( this.tile.getWorldObj(), this ); return TickRateModulation.URGENT; } } diff --git a/parts/automation/PartLevelEmitter.java b/parts/automation/PartLevelEmitter.java index f975f6fbc..f10b5ed53 100644 --- a/parts/automation/PartLevelEmitter.java +++ b/parts/automation/PartLevelEmitter.java @@ -107,8 +107,8 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH host.markForUpdate(); TileEntity te = host.getTile(); prevState = isLevelEmitterOn(); - te.getWorldObj().notifyBlocksOfNeighborChange( te.xCoord, te.yCoord, te.zCoord, Platform.air ); - te.getWorldObj().notifyBlocksOfNeighborChange( te.xCoord + side.offsetX, te.yCoord + side.offsetY, te.zCoord + side.offsetZ, Platform.air ); + Platform.notifyBlocksOfNeighbors( te.getWorldObj(), te.xCoord, te.yCoord, te.zCoord ); + Platform.notifyBlocksOfNeighbors( te.getWorldObj(), te.xCoord + side.offsetX, te.yCoord + side.offsetY, te.zCoord + side.offsetZ ); } } diff --git a/parts/p2p/PartP2PRedstone.java b/parts/p2p/PartP2PRedstone.java index 12d32227f..417daefcb 100644 --- a/parts/p2p/PartP2PRedstone.java +++ b/parts/p2p/PartP2PRedstone.java @@ -13,6 +13,7 @@ import appeng.api.networking.events.MENetworkChannelsChanged; import appeng.api.networking.events.MENetworkEventSubscribe; import appeng.api.networking.events.MENetworkPowerStatusChange; import appeng.me.GridAccessException; +import appeng.util.Platform; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -111,15 +112,15 @@ public class PartP2PRedstone extends PartP2PTunnel int yCoord = tile.yCoord; int zCoord = tile.zCoord; - worldObj.notifyBlocksOfNeighborChange( xCoord, yCoord, zCoord, worldObj.getBlock( xCoord, yCoord, zCoord ) ); + Platform.notifyBlocksOfNeighbors( worldObj, xCoord, yCoord, zCoord ); // and this cause somtimes it can go thought walls. - worldObj.notifyBlocksOfNeighborChange( xCoord - 1, yCoord, zCoord, worldObj.getBlock( xCoord, yCoord, zCoord ) ); - worldObj.notifyBlocksOfNeighborChange( xCoord, yCoord - 1, zCoord, worldObj.getBlock( xCoord, yCoord, zCoord ) ); - worldObj.notifyBlocksOfNeighborChange( xCoord, yCoord, zCoord - 1, worldObj.getBlock( xCoord, yCoord, zCoord ) ); - worldObj.notifyBlocksOfNeighborChange( xCoord, yCoord, zCoord + 1, worldObj.getBlock( xCoord, yCoord, zCoord ) ); - worldObj.notifyBlocksOfNeighborChange( xCoord, yCoord + 1, zCoord, worldObj.getBlock( xCoord, yCoord, zCoord ) ); - worldObj.notifyBlocksOfNeighborChange( xCoord + 1, yCoord, zCoord, worldObj.getBlock( xCoord, yCoord, zCoord ) ); + Platform.notifyBlocksOfNeighbors( worldObj, xCoord - 1, yCoord, zCoord ); + Platform.notifyBlocksOfNeighbors( worldObj, xCoord, yCoord - 1, zCoord ); + Platform.notifyBlocksOfNeighbors( worldObj, xCoord, yCoord, zCoord - 1 ); + Platform.notifyBlocksOfNeighbors( worldObj, xCoord, yCoord, zCoord + 1 ); + Platform.notifyBlocksOfNeighbors( worldObj, xCoord, yCoord + 1, zCoord ); + Platform.notifyBlocksOfNeighbors( worldObj, xCoord + 1, yCoord, zCoord ); } @Override diff --git a/parts/p2p/PartP2PTunnel.java b/parts/p2p/PartP2PTunnel.java index bf61d8cc8..ba3c93697 100644 --- a/parts/p2p/PartP2PTunnel.java +++ b/parts/p2p/PartP2PTunnel.java @@ -178,7 +178,7 @@ public class PartP2PTunnel extends PartBasicState } } - tile.getWorldObj().notifyBlocksOfNeighborChange( tile.xCoord, tile.yCoord, tile.zCoord, Platform.air ); + Platform.notifyBlocksOfNeighbors( tile.getWorldObj(), tile.xCoord, tile.yCoord, tile.zCoord ); return true; } } diff --git a/parts/p2p/PartP2PTunnelME.java b/parts/p2p/PartP2PTunnelME.java index b1a4d5d4e..13de17ebb 100644 --- a/parts/p2p/PartP2PTunnelME.java +++ b/parts/p2p/PartP2PTunnelME.java @@ -125,19 +125,19 @@ public class PartP2PTunnelME extends PartP2PTunnel implements I if ( !proxy.getEnergy().isNetworkPowered() ) { connection.markDestroy(); - TickHandler.instance.addCallable( connection ); + TickHandler.instance.addCallable( tile.getWorldObj(), connection ); } else { if ( proxy.isActive() ) { connection.markCreate(); - TickHandler.instance.addCallable( connection ); + TickHandler.instance.addCallable( tile.getWorldObj(), connection ); } else { connection.markDestroy(); - TickHandler.instance.addCallable( connection ); + TickHandler.instance.addCallable( tile.getWorldObj(), connection ); } } diff --git a/tile/AEBaseTile.java b/tile/AEBaseTile.java index 88d5a30c6..acf82e0bb 100644 --- a/tile/AEBaseTile.java +++ b/tile/AEBaseTile.java @@ -259,7 +259,7 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile, forward = inForward; up = inUp; markForUpdate(); - worldObj.notifyBlocksOfNeighborChange( xCoord, yCoord, zCoord, Platform.air ); + Platform.notifyBlocksOfNeighbors( worldObj, xCoord, yCoord, zCoord ); } public void onPlacement(ItemStack stack, EntityPlayer player, int side) diff --git a/tile/networking/TileCableBus.java b/tile/networking/TileCableBus.java index 56c1e1e7c..f65c4056c 100644 --- a/tile/networking/TileCableBus.java +++ b/tile/networking/TileCableBus.java @@ -290,7 +290,7 @@ public class TileCableBus extends AEBaseTile implements AEMultiTile, ICustomColl public void notifyNeighbors() { if ( worldObj != null && worldObj.blockExists( xCoord, yCoord, zCoord ) && !CableBusContainer.isLoading() ) - worldObj.notifyBlocksOfNeighborChange( xCoord, yCoord, zCoord, Platform.air ); + Platform.notifyBlocksOfNeighbors( worldObj, xCoord, yCoord, zCoord ); } @Override diff --git a/tile/spatial/TileSpatialIOPort.java b/tile/spatial/TileSpatialIOPort.java index 81c9ba7a8..841830e83 100644 --- a/tile/spatial/TileSpatialIOPort.java +++ b/tile/spatial/TileSpatialIOPort.java @@ -54,7 +54,7 @@ public class TileSpatialIOPort extends AENetworkInvTile implements Callable ItemStack cell = getStackInSlot( 0 ); if ( isSpatialCell( cell ) ) { - TickHandler.instance.addCallable( this ); + TickHandler.instance.addCallable( null, this );// this needs to be cross world sycned. } } } diff --git a/tile/storage/TileChest.java b/tile/storage/TileChest.java index d25cf0070..9a4fff0c3 100644 --- a/tile/storage/TileChest.java +++ b/tile/storage/TileChest.java @@ -438,7 +438,7 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, IFluidHan // update the neighbors if ( worldObj != null ) { - worldObj.notifyBlocksOfNeighborChange( xCoord, yCoord, zCoord, Platform.air ); + Platform.notifyBlocksOfNeighbors( worldObj, xCoord, yCoord, zCoord ); markForUpdate(); } } diff --git a/util/BlockUpdate.java b/util/BlockUpdate.java new file mode 100644 index 000000000..d54b2d4ba --- /dev/null +++ b/util/BlockUpdate.java @@ -0,0 +1,27 @@ +package appeng.util; + +import java.util.concurrent.Callable; + +import net.minecraft.world.World; + +public class BlockUpdate implements Callable +{ + + final World w; + final int x, y, z; + + public BlockUpdate(World w, int x, int y, int z) { + this.w = w; + this.x = x; + this.y = y; + this.z = z; + } + + @Override + public Object call() throws Exception + { + w.notifyBlocksOfNeighborChange( x, y, z, Platform.air ); + return true; + } + +} diff --git a/util/Platform.java b/util/Platform.java index 47f70b187..1601e6f6e 100644 --- a/util/Platform.java +++ b/util/Platform.java @@ -84,6 +84,7 @@ import appeng.core.AEConfig; import appeng.core.AELog; import appeng.core.AppEng; import appeng.core.sync.GuiBridge; +import appeng.hooks.TickHandler; import appeng.me.GridAccessException; import appeng.me.GridNode; import appeng.me.helpers.AENetworkProxy; @@ -1673,4 +1674,10 @@ public class Platform return ci; } + public static void notifyBlocksOfNeighbors(World worldObj, int xCoord, int yCoord, int zCoord) + { + if ( !worldObj.isRemote ) + TickHandler.instance.addCallable( worldObj, new BlockUpdate( worldObj, xCoord, yCoord, zCoord ) ); + } + }