Delay Block Updates, and save the world!
This commit is contained in:
parent
5c8327f040
commit
2ea77d35bc
15 changed files with 102 additions and 41 deletions
|
@ -517,9 +517,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 );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,8 +3,10 @@ package appeng.hooks;
|
|||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import appeng.api.networking.IGridNode;
|
||||
|
@ -17,6 +19,7 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
|||
import cpw.mods.fml.common.gameevent.TickEvent;
|
||||
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
|
||||
import cpw.mods.fml.common.gameevent.TickEvent.Type;
|
||||
import cpw.mods.fml.common.gameevent.TickEvent.WorldTickEvent;
|
||||
|
||||
public class TickHandler
|
||||
{
|
||||
|
@ -38,7 +41,8 @@ public class TickHandler
|
|||
|
||||
final public static TickHandler instance = new TickHandler();
|
||||
|
||||
final private Queue<Callable> callQueue = new LinkedList();
|
||||
final private WeakHashMap<World, Queue<Callable>> callQueue = new WeakHashMap<World, Queue<Callable>>();
|
||||
Queue<Callable> serverQueue = new LinkedList<Callable>();
|
||||
|
||||
final private HandlerRep server = new HandlerRep();
|
||||
final private HandlerRep client = new HandlerRep();
|
||||
|
@ -50,9 +54,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<Callable> queue = callQueue.get( w );
|
||||
|
||||
if ( queue == null )
|
||||
callQueue.put( w, queue = new LinkedList<Callable>() );
|
||||
|
||||
queue.add( c );
|
||||
}
|
||||
}
|
||||
|
||||
public void addInit(AEBaseTile tile)
|
||||
|
@ -122,6 +136,7 @@ public class TickHandler
|
|||
if ( ev.type == Type.SERVER && ev.phase == Phase.END ) // for no there is no reason to care about this on the
|
||||
// client...
|
||||
{
|
||||
// ready tiles.
|
||||
HandlerRep repo = getRepo();
|
||||
while (!repo.tiles.isEmpty())
|
||||
{
|
||||
|
@ -129,24 +144,37 @@ public class TickHandler
|
|||
bt.onReady();
|
||||
}
|
||||
|
||||
// tick networks.
|
||||
for (Grid g : getRepo().networks)
|
||||
{
|
||||
g.update();
|
||||
}
|
||||
|
||||
Callable c = null;
|
||||
while ((c = callQueue.poll()) != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
c.call();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
AELog.error( e );
|
||||
}
|
||||
}
|
||||
// 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<Callable> queue)
|
||||
{
|
||||
if ( queue == null )
|
||||
return;
|
||||
|
||||
Callable c = null;
|
||||
while ((c = queue.poll()) != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
c.call();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
AELog.error( e );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -136,7 +136,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() )
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,8 +106,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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<PartP2PRedstone>
|
|||
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
|
||||
|
|
|
@ -178,7 +178,7 @@ public class PartP2PTunnel<T extends 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,19 +125,19 @@ public class PartP2PTunnelME extends PartP2PTunnel<PartP2PTunnelME> 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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -437,7 +437,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();
|
||||
}
|
||||
}
|
||||
|
|
27
util/BlockUpdate.java
Normal file
27
util/BlockUpdate.java
Normal file
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
@ -1638,4 +1639,10 @@ public class Platform
|
|||
return null;
|
||||
}
|
||||
|
||||
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 ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue