Hopefully improve the synchronization of the networks' transmitter sets

This commit is contained in:
Ben Spiers 2015-01-07 23:13:10 +00:00
parent 5e9131a59f
commit 4b75a2f6a2
4 changed files with 100 additions and 138 deletions

View file

@ -135,12 +135,12 @@ public class GasNetwork extends DynamicNetwork<IGasHandler, GasNetwork>
gasStored = null;
}
public synchronized int getGasNeeded()
public int getGasNeeded()
{
return getCapacity()-(gasStored != null ? gasStored.amount : 0);
}
public synchronized int tickEmit(GasStack stack)
public int tickEmit(GasStack stack)
{
List availableAcceptors = Arrays.asList(getAcceptors(stack.getGas()).toArray());
@ -185,7 +185,7 @@ public class GasNetwork extends DynamicNetwork<IGasHandler, GasNetwork>
return sent;
}
public synchronized int emit(GasStack stack)
public int emit(GasStack stack)
{
if(gasStored != null && gasStored.getGas() != stack.getGas())
{
@ -276,12 +276,12 @@ public class GasNetwork extends DynamicNetwork<IGasHandler, GasNetwork>
}
@Override
public synchronized Set<IGasHandler> getAcceptors(Object... data)
public Set<IGasHandler> getAcceptors(Object... data)
{
Gas type = (Gas)data[0];
Set<IGasHandler> toReturn = new HashSet<IGasHandler>();
for(IGasHandler acceptor : ((Map<Coord4D, IGasHandler>)possibleAcceptors.clone()).values())
for(IGasHandler acceptor : possibleAcceptors.values())
{
if(acceptorDirections.get(acceptor) == null)
{
@ -298,35 +298,7 @@ public class GasNetwork extends DynamicNetwork<IGasHandler, GasNetwork>
}
@Override
public synchronized void refresh()
{
Set<IGridTransmitter<GasNetwork>> iterTubes = (Set<IGridTransmitter<GasNetwork>>)transmitters.clone();
Iterator<IGridTransmitter<GasNetwork>> it = iterTubes.iterator();
boolean networkChanged = false;
while(it.hasNext())
{
IGridTransmitter<GasNetwork> conductor = (IGridTransmitter<GasNetwork>)it.next();
if(conductor == null || conductor.getTile().isInvalid())
{
it.remove();
networkChanged = true;
transmitters.remove(conductor);
}
else {
conductor.setTransmitterNetwork(this);
}
}
if(networkChanged)
{
updateCapacity();
}
}
@Override
public synchronized void refresh(IGridTransmitter<GasNetwork> transmitter)
public void refresh(IGridTransmitter<GasNetwork> transmitter)
{
IGasHandler[] acceptors = GasTransmission.getConnectedAcceptors(transmitter.getTile());

View file

@ -2,6 +2,7 @@ package mekanism.api.transmitters;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@ -24,7 +25,7 @@ import cpw.mods.fml.common.eventhandler.Event;
public abstract class DynamicNetwork<A, N extends DynamicNetwork<A, N>> implements ITransmitterNetwork<A, N>, IClientTicker, INetworkDataHandler
{
public LinkedHashSet<IGridTransmitter<N>> transmitters = new LinkedHashSet<IGridTransmitter<N>>();
public final Set<IGridTransmitter<N>> transmitters = Collections.synchronizedSet(new LinkedHashSet<IGridTransmitter<N>>());
public HashMap<Coord4D, A> possibleAcceptors = new HashMap<Coord4D, A>();
public HashMap<A, ForgeDirection> acceptorDirections = new HashMap<A, ForgeDirection>();
@ -92,14 +93,45 @@ public abstract class DynamicNetwork<A, N extends DynamicNetwork<A, N>> implemen
possibleAcceptors.clear();
acceptorDirections.clear();
for(IGridTransmitter<N> transmitter : transmitters)
synchronized(transmitters)
{
refresh(transmitter);
for(IGridTransmitter<N> transmitter : transmitters)
{
refresh(transmitter);
}
}
refresh();
}
@Override
public void refresh()
{
boolean networkChanged = false;
synchronized(transmitters)
{
for(Iterator<IGridTransmitter<N>> it = transmitters.iterator(); it.hasNext();)
{
IGridTransmitter<N> conductor = it.next();
if(conductor == null || conductor.getTile().isInvalid())
{
it.remove();
networkChanged = true;
} else
{
conductor.setTransmitterNetwork((N)this);
}
}
}
if(networkChanged)
{
updateCapacity();
}
}
public Range4D getPacketRange()
{
if(packetRange == null)
@ -128,7 +160,9 @@ public abstract class DynamicNetwork<A, N extends DynamicNetwork<A, N>> implemen
return null;
}
Coord4D initCoord = Coord4D.get(transmitters.iterator().next().getTile());
Coord4D initCoord;
initCoord = Coord4D.get(transmitters.iterator().next().getTile());
int minX = initCoord.xCoord;
int minY = initCoord.yCoord;
@ -137,16 +171,19 @@ public abstract class DynamicNetwork<A, N extends DynamicNetwork<A, N>> implemen
int maxY = initCoord.yCoord;
int maxZ = initCoord.zCoord;
for(IGridTransmitter transmitter : transmitters)
synchronized(transmitters)
{
Coord4D coord = Coord4D.get(transmitter.getTile());
for(IGridTransmitter transmitter : transmitters)
{
Coord4D coord = Coord4D.get(transmitter.getTile());
if(coord.xCoord < minX) minX = coord.xCoord;
if(coord.yCoord < minY) minY = coord.yCoord;
if(coord.zCoord < minZ) minZ = coord.zCoord;
if(coord.xCoord > maxX) maxX = coord.xCoord;
if(coord.yCoord > maxY) maxY = coord.yCoord;
if(coord.zCoord > maxZ) maxZ = coord.zCoord;
if(coord.xCoord < minX) minX = coord.xCoord;
if(coord.yCoord < minY) minY = coord.yCoord;
if(coord.zCoord < minZ) minZ = coord.zCoord;
if(coord.xCoord > maxX) maxX = coord.xCoord;
if(coord.yCoord > maxY) maxY = coord.yCoord;
if(coord.zCoord > maxZ) maxZ = coord.zCoord;
}
}
return new Range4D(minX, minY, minZ, maxX, maxY, maxZ, getWorld().provider.dimensionId);
@ -175,8 +212,8 @@ public abstract class DynamicNetwork<A, N extends DynamicNetwork<A, N>> implemen
if(!((TileEntity)aTransmitter).getWorldObj().isRemote)
{
TransmitterNetworkRegistry.getInstance().registerNetwork(this);
}
else {
} else
{
MinecraftForge.EVENT_BUS.post(new ClientTickUpdate(this, (byte)1));
}
}
@ -209,7 +246,7 @@ public abstract class DynamicNetwork<A, N extends DynamicNetwork<A, N>> implemen
return possibleAcceptors.size();
}
public synchronized void updateCapacity()
public void updateCapacity()
{
updateMeanCapacity();
capacity = (int)meanCapacity * transmitters.size();
@ -219,7 +256,7 @@ public abstract class DynamicNetwork<A, N extends DynamicNetwork<A, N>> implemen
* Override this if things can have variable capacity along the network.
* @return An 'average' value of capacity. Calculate it how you will.
*/
protected synchronized void updateMeanCapacity()
protected void updateMeanCapacity()
{
if(transmitters.size() > 0)
{
@ -294,7 +331,7 @@ public abstract class DynamicNetwork<A, N extends DynamicNetwork<A, N>> implemen
}
@Override
public synchronized void fixMessedUpNetwork(IGridTransmitter<N> transmitter)
public void fixMessedUpNetwork(IGridTransmitter<N> transmitter)
{
if(transmitter instanceof TileEntity)
{
@ -321,7 +358,7 @@ public abstract class DynamicNetwork<A, N extends DynamicNetwork<A, N>> implemen
}
@Override
public synchronized void split(IGridTransmitter<N> splitPoint)
public void split(IGridTransmitter<N> splitPoint)
{
if(splitPoint instanceof TileEntity)
{

View file

@ -80,15 +80,18 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
}
@Override
protected synchronized void updateMeanCapacity()
protected void updateMeanCapacity()
{
int numCables = transmitters.size();
double reciprocalSum = 0;
for(IGridTransmitter<EnergyNetwork> cable : transmitters)
{
reciprocalSum += 1.0/(double)cable.getCapacity();
}
synchronized(transmitters)
{
for(IGridTransmitter<EnergyNetwork> cable : transmitters)
{
reciprocalSum += 1.0 / (double)cable.getCapacity();
}
}
meanCapacity = (double)numCables / reciprocalSum;
}
@ -119,7 +122,7 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
}
}
public synchronized double getEnergyNeeded()
public double getEnergyNeeded()
{
if(FMLCommonHandler.instance().getEffectiveSide().isClient())
{
@ -129,7 +132,7 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
return getCapacity()-electricityStored;
}
public synchronized double tickEmit(double energyToSend)
public double tickEmit(double energyToSend)
{
if(FMLCommonHandler.instance().getEffectiveSide().isClient())
{
@ -153,7 +156,7 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
return sent;
}
public synchronized double emit(double energyToSend, boolean doEmit)
public double emit(double energyToSend, boolean doEmit)
{
double toUse = Math.min(getEnergyNeeded(), energyToSend);
if(doEmit)
@ -166,7 +169,7 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
/**
* @return sent
*/
public synchronized double doEmit(double energyToSend, boolean tryAgain)
public double doEmit(double energyToSend, boolean tryAgain)
{
double sent = 0;
@ -219,7 +222,7 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
}
@Override
public synchronized Set<TileEntity> getAcceptors(Object... data)
public Set<TileEntity> getAcceptors(Object... data)
{
Set<TileEntity> toReturn = new HashSet<TileEntity>();
@ -228,7 +231,7 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
return toReturn;
}
for(TileEntity acceptor : ((Map<Coord4D, TileEntity>)possibleAcceptors.clone()).values())
for(TileEntity acceptor : possibleAcceptors.values())
{
ForgeDirection side = acceptorDirections.get(acceptor);
@ -246,7 +249,6 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
if(handler.getMaxEnergy() - handler.getEnergy() > 0)
{
toReturn.add(acceptor);
continue;
}
}
}
@ -259,7 +261,6 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
if(handler.receiveEnergy(side.getOpposite(), 1, true) > 0)
{
toReturn.add(acceptor);
continue;
}
}
}
@ -276,7 +277,6 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
if(Math.min(demanded, max) > 0)
{
toReturn.add(acceptor);
continue;
}
}
}
@ -286,37 +286,15 @@ public class EnergyNetwork extends DynamicNetwork<TileEntity, EnergyNetwork>
}
@Override
public synchronized void refresh()
public void refresh()
{
Set<IGridTransmitter<EnergyNetwork>> iterCables = (Set<IGridTransmitter<EnergyNetwork>>)transmitters.clone();
Iterator<IGridTransmitter<EnergyNetwork>> it = iterCables.iterator();
boolean networkChanged = false;
while(it.hasNext())
{
IGridTransmitter<EnergyNetwork> conductor = (IGridTransmitter<EnergyNetwork>)it.next();
if(conductor == null || conductor.getTile().isInvalid())
{
it.remove();
transmitters.remove(conductor);
networkChanged = true;
}
else {
conductor.setTransmitterNetwork(this);
}
}
if(networkChanged)
{
updateCapacity();
}
super.refresh();
needsUpdate = true;
}
@Override
public synchronized void refresh(IGridTransmitter<EnergyNetwork> transmitter)
public void refresh(IGridTransmitter<EnergyNetwork> transmitter)
{
TileEntity[] acceptors = CableUtils.getConnectedEnergyAcceptors(transmitter.getTile());

View file

@ -99,14 +99,17 @@ public class FluidNetwork extends DynamicNetwork<IFluidHandler, FluidNetwork>
}
@Override
protected synchronized void updateMeanCapacity()
protected void updateMeanCapacity()
{
int numCables = transmitters.size();
double sum = 0;
for(IGridTransmitter<FluidNetwork> pipe : transmitters)
synchronized(transmitters)
{
sum += pipe.getCapacity();
for(IGridTransmitter<FluidNetwork> pipe : transmitters)
{
sum += pipe.getCapacity();
}
}
meanCapacity = sum / (double)numCables;
@ -148,12 +151,12 @@ public class FluidNetwork extends DynamicNetwork<IFluidHandler, FluidNetwork>
refFluid = null;
}
public synchronized int getFluidNeeded()
public int getFluidNeeded()
{
return getCapacity()-(fluidStored != null ? fluidStored.amount : 0);
}
public synchronized int tickEmit(FluidStack fluidToSend, boolean doTransfer)
public int tickEmit(FluidStack fluidToSend, boolean doTransfer)
{
List availableAcceptors = Arrays.asList(getAcceptors(fluidToSend).toArray());
@ -197,7 +200,7 @@ public class FluidNetwork extends DynamicNetwork<IFluidHandler, FluidNetwork>
return fluidSent;
}
public synchronized int emit(FluidStack fluidToSend, boolean doTransfer)
public int emit(FluidStack fluidToSend, boolean doTransfer)
{
if(fluidToSend == null || (fluidStored != null && fluidStored.getFluid() != fluidToSend.getFluid()))
{
@ -294,12 +297,12 @@ public class FluidNetwork extends DynamicNetwork<IFluidHandler, FluidNetwork>
}
@Override
public synchronized Set<IFluidHandler> getAcceptors(Object... data)
public Set<IFluidHandler> getAcceptors(Object... data)
{
FluidStack fluidToSend = (FluidStack)data[0];
Set<IFluidHandler> toReturn = new HashSet<IFluidHandler>();
for(IFluidHandler acceptor : ((Map<Coord4D, IFluidHandler>)possibleAcceptors.clone()).values())
for(IFluidHandler acceptor : possibleAcceptors.values())
{
if(acceptorDirections.get(acceptor) == null)
{
@ -316,35 +319,7 @@ public class FluidNetwork extends DynamicNetwork<IFluidHandler, FluidNetwork>
}
@Override
public synchronized void refresh()
{
Set<IGridTransmitter<FluidNetwork>> iterPipes = (Set<IGridTransmitter<FluidNetwork>>)transmitters.clone();
Iterator it = iterPipes.iterator();
boolean networkChanged = false;
while(it.hasNext())
{
IGridTransmitter<FluidNetwork> conductor = (IGridTransmitter<FluidNetwork>)it.next();
if(conductor == null || conductor.getTile().isInvalid())
{
it.remove();
networkChanged = true;
transmitters.remove(conductor);
}
else {
conductor.setTransmitterNetwork(this);
}
}
if(networkChanged)
{
updateCapacity();
}
}
@Override
public synchronized void refresh(IGridTransmitter<FluidNetwork> transmitter)
public void refresh(IGridTransmitter<FluidNetwork> transmitter)
{
IFluidHandler[] acceptors = PipeUtils.getConnectedAcceptors(transmitter.getTile());