Revamped Multipart Memory Usage.

This commit is contained in:
AlgorithmX2 2014-08-27 00:57:37 -05:00
parent 59925c9145
commit c6f6319591
5 changed files with 225 additions and 84 deletions

View file

@ -8,9 +8,9 @@ import net.minecraft.client.Minecraft;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.parts.IFacadeContainer;
import appeng.api.parts.IFacadePart;
import appeng.api.parts.IPart;
import appeng.facade.FacadeContainer;
import appeng.parts.BusCollisionHelper;
import appeng.parts.CableBusContainer;
@ -71,7 +71,7 @@ public class CableRenderHelper
BusRenderHelper.instance.setOrientation( ax, ay, az );
}
public void renderStatic(CableBusContainer cableBusContainer, FacadeContainer fc)
public void renderStatic(CableBusContainer cableBusContainer, IFacadeContainer iFacadeContainer)
{
TileEntity te = cableBusContainer.getTile();
RenderBlocksWorkaround renderer = BusRenderer.instance.renderer;
@ -101,7 +101,7 @@ public class CableRenderHelper
}
}
if ( !fc.isEmpty() )
if ( !iFacadeContainer.isEmpty() )
{
/**
* snag list of boxes...
@ -139,7 +139,7 @@ public class CableRenderHelper
for (ForgeDirection s : ForgeDirection.VALID_DIRECTIONS)
{
IFacadePart fPart = fc.getFacade( s );
IFacadePart fPart = iFacadeContainer.getFacade( s );
if ( fPart != null )
{
AxisAlignedBB b = null;
@ -167,7 +167,8 @@ public class CableRenderHelper
renderer.uvRotateBottom = renderer.uvRotateEast = renderer.uvRotateNorth = renderer.uvRotateSouth = renderer.uvRotateTop = renderer.uvRotateWest = 0;
setSide( s );
fPart.renderStatic( te.xCoord, te.yCoord, te.zCoord, BusRenderHelper.instance, renderer, fc, b, cableBusContainer.getPart( s ) == null );
fPart.renderStatic( te.xCoord, te.yCoord, te.zCoord, BusRenderHelper.instance, renderer, iFacadeContainer, b,
cableBusContainer.getPart( s ) == null );
}
}

View file

@ -17,23 +17,29 @@ import appeng.core.AppEng;
import appeng.integration.IntegrationType;
import appeng.integration.abstraction.IBC;
import appeng.items.parts.ItemFacade;
import appeng.parts.CableBusStorage;
public class FacadeContainer implements IFacadeContainer
{
final private IFacadePart facades[] = new FacadePart[6];
final int facades = 6;
final CableBusStorage storage;
public FacadeContainer(CableBusStorage cbs) {
storage = cbs;
}
public void writeToStream(ByteBuf out) throws IOException
{
int facadeSides = 0;
for (int x = 0; x < facades.length; x++)
for (int x = 0; x < facades; x++)
{
if ( getFacade( ForgeDirection.getOrientation( x ) ) != null )
facadeSides = facadeSides | (1 << x);
}
out.writeByte( (byte) facadeSides );
for (int x = 0; x < facades.length; x++)
for (int x = 0; x < facades; x++)
{
IFacadePart part = getFacade( ForgeDirection.getOrientation( x ) );
if ( part != null )
@ -53,7 +59,7 @@ public class FacadeContainer implements IFacadeContainer
boolean changed = false;
int ids[] = new int[2];
for (int x = 0; x < facades.length; x++)
for (int x = 0; x < facades; x++)
{
ForgeDirection side = ForgeDirection.getOrientation( x );
int ix = (1 << x);
@ -67,8 +73,8 @@ public class FacadeContainer implements IFacadeContainer
if ( isBC && AppEng.instance.isIntegrationEnabled( IntegrationType.BC ) )
{
IBC bc = (IBC) AppEng.instance.getIntegration( IntegrationType.BC );
changed = changed || facades[x] == null;
facades[x] = bc.createFacadePart( (Block) Block.blockRegistry.getObjectById( ids[0] ), ids[1], side );
changed = changed || storage.getFacade( x ) == null;
storage.setFacade( x, bc.createFacadePart( (Block) Block.blockRegistry.getObjectById( ids[0] ), ids[1], side ) );
}
else if ( !isBC )
{
@ -76,15 +82,15 @@ public class FacadeContainer implements IFacadeContainer
ItemStack facade = ifa.createFromInts( ids );
if ( facade != null )
{
changed = changed || facades[x] == null;
facades[x] = ifa.createPartFromItemStack( facade, side );
changed = changed || storage.getFacade( x ) == null;
storage.setFacade( x, ifa.createPartFromItemStack( facade, side ) );
}
}
}
else
{
changed = changed || facades[x] != null;
facades[x] = null;
changed = changed || storage.getFacade( x ) != null;
storage.setFacade( x, null );
}
}
@ -93,9 +99,9 @@ public class FacadeContainer implements IFacadeContainer
public void readFromNBT(NBTTagCompound c)
{
for (int x = 0; x < facades.length; x++)
for (int x = 0; x < facades; x++)
{
facades[x] = null;
storage.setFacade( x, null );
NBTTagCompound t = c.getCompoundTag( "facade:" + x );
if ( t != null )
@ -105,14 +111,14 @@ public class FacadeContainer implements IFacadeContainer
{
Item i = is.getItem();
if ( i instanceof IFacadeItem )
facades[x] = ((IFacadeItem) i).createPartFromItemStack( is, ForgeDirection.getOrientation( x ) );
storage.setFacade( x, ((IFacadeItem) i).createPartFromItemStack( is, ForgeDirection.getOrientation( x ) ) );
else
{
if ( AppEng.instance.isIntegrationEnabled( IntegrationType.BC ) )
{
IBC bc = (IBC) AppEng.instance.getIntegration( IntegrationType.BC );
if ( bc.isFacade( is ) )
facades[x] = bc.createFacadePart( is, ForgeDirection.getOrientation( x ) );
storage.setFacade( x, bc.createFacadePart( is, ForgeDirection.getOrientation( x ) ) );
}
}
}
@ -122,12 +128,12 @@ public class FacadeContainer implements IFacadeContainer
public void writeToNBT(NBTTagCompound c)
{
for (int x = 0; x < facades.length; x++)
for (int x = 0; x < facades; x++)
{
if ( facades[x] != null )
if ( storage.getFacade( x ) != null )
{
NBTTagCompound data = new NBTTagCompound();
facades[x].getItemStack().writeToNBT( data );
storage.getFacade( x ).getItemStack().writeToNBT( data );
c.setTag( "facade:" + x, data );
}
}
@ -138,7 +144,7 @@ public class FacadeContainer implements IFacadeContainer
{
if ( getFacade( a.getSide() ) == null )
{
facades[a.getSide().ordinal()] = a;
storage.setFacade( a.getSide().ordinal(), a );
return true;
}
return false;
@ -149,9 +155,9 @@ public class FacadeContainer implements IFacadeContainer
{
if ( side != null && side != ForgeDirection.UNKNOWN )
{
if ( facades[side.ordinal()] != null )
if ( storage.getFacade( side.ordinal() ) != null )
{
facades[side.ordinal()] = null;
storage.setFacade( side.ordinal(), null );
if ( host != null )
host.markForUpdate();
}
@ -161,13 +167,13 @@ public class FacadeContainer implements IFacadeContainer
@Override
public IFacadePart getFacade(ForgeDirection s)
{
return facades[s.ordinal()];
return storage.getFacade( s.ordinal() );
}
public boolean isEmpty()
{
for (int x = 0; x < facades.length; x++)
if ( facades[x] != null )
for (int x = 0; x < facades; x++)
if ( storage.getFacade( x ) != null )
return false;
return true;
}
@ -176,15 +182,16 @@ public class FacadeContainer implements IFacadeContainer
{
IFacadePart newfacades[] = new FacadePart[6];
newfacades[ForgeDirection.UP.ordinal()] = facades[ForgeDirection.UP.ordinal()];
newfacades[ForgeDirection.DOWN.ordinal()] = facades[ForgeDirection.DOWN.ordinal()];
newfacades[ForgeDirection.UP.ordinal()] = storage.getFacade( ForgeDirection.UP.ordinal() );
newfacades[ForgeDirection.DOWN.ordinal()] = storage.getFacade( ForgeDirection.DOWN.ordinal() );
newfacades[ForgeDirection.EAST.ordinal()] = facades[ForgeDirection.NORTH.ordinal()];
newfacades[ForgeDirection.SOUTH.ordinal()] = facades[ForgeDirection.EAST.ordinal()];
newfacades[ForgeDirection.WEST.ordinal()] = facades[ForgeDirection.SOUTH.ordinal()];
newfacades[ForgeDirection.NORTH.ordinal()] = facades[ForgeDirection.WEST.ordinal()];
newfacades[ForgeDirection.EAST.ordinal()] = storage.getFacade( ForgeDirection.NORTH.ordinal() );
newfacades[ForgeDirection.SOUTH.ordinal()] = storage.getFacade( ForgeDirection.EAST.ordinal() );
for (int x = 0; x < facades.length; x++)
facades[x] = newfacades[x];
newfacades[ForgeDirection.WEST.ordinal()] = storage.getFacade( ForgeDirection.SOUTH.ordinal() );
newfacades[ForgeDirection.NORTH.ordinal()] = storage.getFacade( ForgeDirection.WEST.ordinal() );
for (int x = 0; x < facades; x++)
storage.setFacade( x, newfacades[x] );
}
}

View file

@ -9,6 +9,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Vec3;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.parts.IFacadeContainer;
import appeng.api.parts.IFacadePart;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartHost;
import appeng.api.parts.LayerFlags;
@ -16,6 +17,7 @@ import appeng.api.parts.SelectedPart;
import appeng.api.util.AEColor;
import appeng.api.util.DimensionalCoord;
import appeng.facade.FacadeContainer;
import appeng.parts.CableBusStorage;
import appeng.util.Platform;
import codechicken.lib.vec.BlockCoord;
import codechicken.multipart.TMultiPart;
@ -24,6 +26,25 @@ import codechicken.multipart.TileMultipart;
public class FMPPlacementHelper implements IPartHost
{
static class NullStorage extends CableBusStorage
{
@Override
public IFacadePart getFacade(int x)
{
return null;
}
@Override
public void setFacade(int x, IFacadePart facade)
{
}
};
final private static CableBusStorage nullStorage = new NullStorage();
private boolean hasPart = false;
private TileMultipart myMP;
private CableBusPart myPart;
@ -79,7 +100,7 @@ public class FMPPlacementHelper implements IPartHost
public IFacadeContainer getFacadeContainer()
{
if ( myPart == null )
return new FacadeContainer();
return new FacadeContainer( nullStorage );
return myPart.getFacadeContainer();
}

View file

@ -50,12 +50,9 @@ import appeng.util.Platform;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class CableBusContainer implements AEMultiTile, ICableBusContainer
public class CableBusContainer extends CableBusStorage implements AEMultiTile, ICableBusContainer
{
private IPartCable center;
private IPart sides[] = new IPart[6];
private FacadeContainer fc = new FacadeContainer();
private EnumSet<LayerFlags> myLayerFlags = EnumSet.noneOf( LayerFlags.class );
public YesNo hasRedstone = YesNo.UNDECIDED;
@ -84,25 +81,26 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
public IPart getPart(ForgeDirection side)
{
if ( side == ForgeDirection.UNKNOWN )
return center;
return sides[side.ordinal()];
return getCenter();
return getSide( side );
}
public void rotateLeft()
{
IPart newSides[] = new IPart[6];
newSides[ForgeDirection.UP.ordinal()] = sides[ForgeDirection.UP.ordinal()];
newSides[ForgeDirection.DOWN.ordinal()] = sides[ForgeDirection.DOWN.ordinal()];
newSides[ForgeDirection.UP.ordinal()] = getSide( ForgeDirection.UP );
newSides[ForgeDirection.DOWN.ordinal()] = getSide( ForgeDirection.DOWN );
newSides[ForgeDirection.EAST.ordinal()] = sides[ForgeDirection.NORTH.ordinal()];
newSides[ForgeDirection.SOUTH.ordinal()] = sides[ForgeDirection.EAST.ordinal()];
newSides[ForgeDirection.WEST.ordinal()] = sides[ForgeDirection.SOUTH.ordinal()];
newSides[ForgeDirection.NORTH.ordinal()] = sides[ForgeDirection.WEST.ordinal()];
newSides[ForgeDirection.EAST.ordinal()] = getSide( ForgeDirection.NORTH );
newSides[ForgeDirection.SOUTH.ordinal()] = getSide( ForgeDirection.EAST );
newSides[ForgeDirection.WEST.ordinal()] = getSide( ForgeDirection.SOUTH );
newSides[ForgeDirection.NORTH.ordinal()] = getSide( ForgeDirection.WEST );
sides = newSides;
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS)
setSide( dir, newSides[dir.ordinal()] );
fc.rotateLeft();
getFacadeContainer().rotateLeft();
}
public void updateDynamicRender()
@ -121,15 +119,15 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
{
if ( side == ForgeDirection.UNKNOWN )
{
if ( center != null )
center.removeFromWorld();
center = null;
if ( getCenter() != null )
getCenter().removeFromWorld();
setCenter( null );
}
else
{
if ( sides[side.ordinal()] != null )
sides[side.ordinal()].removeFromWorld();
sides[side.ordinal()] = null;
if ( getSide( side ) != null )
getSide( side ).removeFromWorld();
setSide( side, null );
}
if ( !supressUpdate )
@ -146,7 +144,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
*/
public void updateConnections()
{
if ( center != null )
if ( getCenter() != null )
{
EnumSet<ForgeDirection> sides = EnumSet.allOf( ForgeDirection.class );
@ -156,8 +154,8 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
sides.remove( s );
}
center.setValidSides( sides );
IGridNode n = center.getGridNode();
getCenter().setValidSides( sides );
IGridNode n = getCenter().getGridNode();
if ( n != null )
n.updateState();
}
@ -230,7 +228,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
if ( getPart( ForgeDirection.UNKNOWN ) != null )
return null;
center = (IPartCable) bp;
setCenter( (IPartCable) bp );
bp.setPartHostInfo( ForgeDirection.UNKNOWN, this, tcb.getTile() );
if ( player != null )
@ -239,7 +237,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
if ( inWorld )
bp.addToWorld();
IGridNode cn = center.getGridNode();
IGridNode cn = getCenter().getGridNode();
if ( cn != null )
{
for (ForgeDirection ins : ForgeDirection.VALID_DIRECTIONS)
@ -259,7 +257,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
// ekk!
bp.removeFromWorld();
center = null;
setCenter( null );
return null;
}
}
@ -278,7 +276,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
if ( cable != null && !bp.canBePlacedOn( ((IPartCable) cable).supportsBuses() ) )
return null;
sides[side.ordinal()] = bp;
setSide( side, bp );
bp.setPartHostInfo( side, this, this.getTile() );
if ( player != null )
@ -287,9 +285,9 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
if ( inWorld )
bp.addToWorld();
if ( center != null )
if ( getCenter() != null )
{
IGridNode cn = center.getGridNode();
IGridNode cn = getCenter().getGridNode();
IGridNode sn = bp.getGridNode();
if ( cn != null && sn != null )
@ -303,7 +301,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
// ekk!
bp.removeFromWorld();
sides[side.ordinal()] = null;
setSide( side, null );
return null;
}
}
@ -424,8 +422,8 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
return n;
}
if ( center != null )
return center.getGridNode();
if ( getCenter() != null )
return getCenter().getGridNode();
return null;
}
@ -434,6 +432,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
{
List<AxisAlignedBB> boxes = new LinkedList<AxisAlignedBB>();
IFacadeContainer fc = getFacadeContainer();
for (ForgeDirection s : ForgeDirection.values())
{
IPartCollsionHelper bch = new BusCollisionHelper( boxes, s, e, visual );
@ -473,6 +472,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
public boolean isEmpty()
{
IFacadeContainer fc = getFacadeContainer();
for (ForgeDirection s : ForgeDirection.values())
{
IPart part = getPart( s );
@ -514,7 +514,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
return false;
// facades are solid..
IFacadePart fp = fc.getFacade( side );
IFacadePart fp = getFacadeContainer().getFacade( side );
if ( fp != null )
return true;
@ -538,7 +538,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
@SideOnly(Side.CLIENT)
public void renderStatic(double x, double y, double z)
{
CableRenderHelper.getInstance().renderStatic( this, fc );
CableRenderHelper.getInstance().renderStatic( this, getFacadeContainer() );
}
@SideOnly(Side.CLIENT)
@ -577,7 +577,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
}
}
fc.writeToStream( data );
getFacadeContainer().writeToStream( data );
}
public boolean readFromStream(ByteBuf data) throws IOException
@ -621,21 +621,22 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
removePart( side, false );
}
if ( fc.readFromStream( data ) )
if ( getFacadeContainer().readFromStream( data ) )
return true;
return updateBlock;
}
ForgeDirection getSide(IPart part)
{
if ( center == part )
if ( getCenter() == part )
return ForgeDirection.UNKNOWN;
else
{
for (int x = 0; x < 6; x++)
if ( sides[x] == part )
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
if ( getSide( side ) == part )
{
return ForgeDirection.getOrientation( x );
return side;
}
}
throw new RuntimeException( "Uhh Bad Part on Side." );
@ -645,6 +646,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
{
data.setInteger( "hasRedstone", hasRedstone.ordinal() );
IFacadeContainer fc = getFacadeContainer();
for (ForgeDirection s : ForgeDirection.values())
{
fc.writeToNBT( data );
@ -705,7 +707,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
removePart( side, false );
}
fc.readFromNBT( data );
getFacadeContainer().readFromNBT( data );
}
public List getDrops(List drops)
@ -759,9 +761,9 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
return t;
}
if ( center != null )
if ( getCenter() != null )
{
IPartCable c = center;
IPartCable c = getCenter();
return c.getCableConnectionType();
}
return AECableType.NONE;
@ -770,9 +772,9 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
@Override
public AEColor getColor()
{
if ( center != null )
if ( getCenter() != null )
{
IPartCable c = center;
IPartCable c = getCenter();
return c.getCableColor();
}
return AEColor.Transparent;
@ -781,7 +783,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
@Override
public IFacadeContainer getFacadeContainer()
{
return fc;
return new FacadeContainer( this );
}
@Override
@ -860,6 +862,7 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
if ( AEApi.instance().partHelper().getCableRenderMode().opaqueFacades )
{
IFacadeContainer fc = getFacadeContainer();
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
{
IFacadePart p = fc.getFacade( side );
@ -887,10 +890,11 @@ public class CableBusContainer implements AEMultiTile, ICableBusContainer
@Override
public void partChanged()
{
if ( center == null )
if ( getCenter() == null )
{
List<ItemStack> facades = new LinkedList();
IFacadeContainer fc = getFacadeContainer();
for (ForgeDirection d : ForgeDirection.VALID_DIRECTIONS)
{
IFacadePart fp = fc.getFacade( d );

108
parts/CableBusStorage.java Normal file
View file

@ -0,0 +1,108 @@
package appeng.parts;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.implementations.parts.IPartCable;
import appeng.api.parts.IFacadePart;
import appeng.api.parts.IPart;
/**
* Thin data storage to optimize memory usage for cables.
*/
public class CableBusStorage
{
private IPartCable center;
private IPart sides[];
private IFacadePart facades[];
protected IPartCable getCenter()
{
return center;
}
protected void setCenter(IPartCable center)
{
this.center = center;
}
protected IPart getSide(ForgeDirection side)
{
int x = side.ordinal();
if ( sides != null && sides.length > x )
return sides[x];
return null;
}
protected void setSide(ForgeDirection side, IPart part)
{
int x = side.ordinal();
if ( sides != null && sides.length > x && part == null )
{
sides[x] = null;
sides = shrink( sides, true );
}
else if ( part != null )
{
sides = grow( sides, x, true );
sides[x] = part;
}
}
public IFacadePart getFacade(int x)
{
if ( facades != null && facades.length > x )
return facades[x];
return null;
}
public void setFacade(int x, IFacadePart facade)
{
if ( facades != null && facades.length > x && facade == null )
{
facades[x] = null;
facades = shrink( facades, false );
}
else
{
facades = grow( facades, x, false );
facades[x] = facade;
}
}
private <T> T[] grow(T[] in, int new_value, boolean parts)
{
if ( in != null && in.length > new_value )
return in;
int newSize = new_value + 1;
T[] newArray = (T[]) (parts ? new IPart[newSize] : new IFacadePart[newSize]);
if ( in != null )
System.arraycopy( in, 0, newArray, 0, in.length );
return newArray;
}
private <T> T[] shrink(T[] in, boolean parts)
{
int newSize = 0;
for (int x = 0; x < in.length; x++)
if ( in[x] != null )
newSize = x;
if ( newSize == 0 )
return null;
newSize++;
if ( newSize == in.length )
return in;
T[] newArray = (T[]) (parts ? new IPart[newSize] : new IFacadePart[newSize]);
System.arraycopy( in, 0, newArray, 0, newSize );
return newArray;
}
}