Basic reformat, hit once, hope never again

This commit is contained in:
thatsIch
2015-04-03 08:54:31 +02:00
parent 4ff1631f89
commit d34c988c88
886 changed files with 31400 additions and 30990 deletions
+24 -24
View File
@@ -55,7 +55,7 @@ public class Grid implements IGrid
this.pivot = center;
Map<Class<? extends IGridCache>, IGridCache> myCaches = AEApi.instance().registries().gridCache().createCacheInstance( this );
for ( Entry<Class<? extends IGridCache>, IGridCache> c : myCaches.entrySet() )
for( Entry<Class<? extends IGridCache>, IGridCache> c : myCaches.entrySet() )
{
Class<? extends IGridCache> key = c.getKey();
IGridCache value = c.getValue();
@@ -94,14 +94,14 @@ public class Grid implements IGrid
public int size()
{
int out = 0;
for ( Collection<?> x : this.machines.values() )
for( Collection<?> x : this.machines.values() )
out += x.size();
return out;
}
public void remove( GridNode gridNode )
{
for ( IGridCache c : this.caches.values() )
for( IGridCache c : this.caches.values() )
{
IGridHost machine = gridNode.getMachine();
c.removeNode( gridNode, machine );
@@ -109,16 +109,16 @@ public class Grid implements IGrid
Class<? extends IGridHost> machineClass = gridNode.getMachineClass();
Set<IGridNode> nodes = this.machines.get( machineClass );
if ( nodes != null )
if( nodes != null )
nodes.remove( gridNode );
gridNode.setGridStorage( null );
if ( this.pivot == gridNode )
if( this.pivot == gridNode )
{
Iterator<IGridNode> n = this.getNodes().iterator();
if ( n.hasNext() )
this.pivot = ( GridNode ) n.next();
if( n.hasNext() )
this.pivot = (GridNode) n.next();
else
{
this.pivot = null;
@@ -133,7 +133,7 @@ public class Grid implements IGrid
Class<? extends IGridHost> mClass = gridNode.getMachineClass();
MachineSet nodes = this.machines.get( mClass );
if ( nodes == null )
if( nodes == null )
{
nodes = new MachineSet( mClass );
this.machines.put( mClass, nodes );
@@ -141,41 +141,41 @@ public class Grid implements IGrid
}
// handle loading grid storages.
if ( gridNode.getGridStorage() != null )
if( gridNode.getGridStorage() != null )
{
GridStorage gs = gridNode.getGridStorage();
IGrid grid = gs.getGrid();
if ( grid == null )
if( grid == null )
{
this.myStorage = gs;
this.myStorage.setGrid( this );
for ( IGridCache gc : this.caches.values() )
for( IGridCache gc : this.caches.values() )
gc.onJoin( this.myStorage );
}
else if ( grid != this )
else if( grid != this )
{
if ( this.myStorage == null )
if( this.myStorage == null )
{
this.myStorage = WorldSettings.getInstance().getNewGridStorage();
this.myStorage.setGrid( this );
}
IGridStorage tmp = new GridStorage();
if ( !gs.hasDivided( this.myStorage ) )
if( !gs.hasDivided( this.myStorage ) )
{
gs.addDivided( this.myStorage );
for ( IGridCache gc : ( ( Grid ) grid ).caches.values() )
for( IGridCache gc : ( (Grid) grid ).caches.values() )
gc.onSplit( tmp );
for ( IGridCache gc : this.caches.values() )
for( IGridCache gc : this.caches.values() )
gc.onJoin( tmp );
}
}
}
else if ( this.myStorage == null )
else if( this.myStorage == null )
{
this.myStorage = WorldSettings.getInstance().getNewGridStorage();
this.myStorage.setGrid( this );
@@ -187,7 +187,7 @@ public class Grid implements IGrid
// track node.
nodes.add( gridNode );
for ( IGridCache cache : this.caches.values() )
for( IGridCache cache : this.caches.values() )
{
IGridHost machine = gridNode.getMachine();
cache.addNode( gridNode, machine );
@@ -201,7 +201,7 @@ public class Grid implements IGrid
@SuppressWarnings( "unchecked" )
public <C extends IGridCache> C getCache( Class<? extends IGridCache> iface )
{
return ( C ) this.caches.get( iface ).myCache;
return (C) this.caches.get( iface ).myCache;
}
@Override
@@ -213,7 +213,7 @@ public class Grid implements IGrid
@Override
public MENetworkEvent postEventTo( IGridNode node, MENetworkEvent ev )
{
return this.eventBus.postEventTo( this, ( GridNode ) node, ev );
return this.eventBus.postEventTo( this, (GridNode) node, ev );
}
@Override
@@ -228,7 +228,7 @@ public class Grid implements IGrid
public IMachineSet getMachines( Class<? extends IGridHost> c )
{
MachineSet s = this.machines.get( c );
if ( s == null )
if( s == null )
return new MachineSet( c );
return s;
}
@@ -258,17 +258,17 @@ public class Grid implements IGrid
public void update()
{
for ( IGridCache gc : this.caches.values() )
for( IGridCache gc : this.caches.values() )
{
// are there any nodes left?
if ( this.pivot != null )
if( this.pivot != null )
gc.onUpdateTick();
}
}
public void saveState()
{
for ( IGridCache c : this.caches.values() )
for( IGridCache c : this.caches.values() )
{
c.populateGridStorage( this.myStorage );
}
@@ -18,9 +18,9 @@
package appeng.me;
public class GridAccessException extends Exception
{
private static final long serialVersionUID = 3914554394866375300L;
}
+24 -22
View File
@@ -18,18 +18,21 @@
package appeng.me;
import appeng.api.networking.IGridCache;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IGridStorage;
public class GridCacheWrapper implements IGridCache
{
final IGridCache myCache;
final String name;
public GridCacheWrapper(final IGridCache gc) {
public GridCacheWrapper( final IGridCache gc )
{
this.myCache = gc;
this.name = this.myCache.getClass().getName();
}
@@ -41,38 +44,37 @@ public class GridCacheWrapper implements IGridCache
}
@Override
public void removeNode(final IGridNode gridNode, final IGridHost machine)
public void removeNode( final IGridNode gridNode, final IGridHost machine )
{
this.myCache.removeNode( gridNode, machine );
}
@Override
public void addNode(final IGridNode gridNode, final IGridHost machine)
public void addNode( final IGridNode gridNode, final IGridHost machine )
{
this.myCache.addNode( gridNode, machine );
}
@Override
public void onSplit( final IGridStorage storageB )
{
this.myCache.onSplit( storageB );
}
@Override
public void onJoin( final IGridStorage storageB )
{
this.myCache.onJoin( storageB );
}
@Override
public void populateGridStorage( final IGridStorage storage )
{
this.myCache.populateGridStorage( storage );
}
public String getName()
{
return this.name;
}
@Override
public void onSplit(final IGridStorage storageB)
{
this.myCache.onSplit( storageB );
}
@Override
public void onJoin(final IGridStorage storageB)
{
this.myCache.onJoin( storageB );
}
@Override
public void populateGridStorage(final IGridStorage storage)
{
this.myCache.populateGridStorage( storage );
}
}
+70 -74
View File
@@ -44,24 +44,21 @@ public class GridConnection implements IGridConnection, IPathItem
{
private static final MENetworkChannelsChanged EVENT = new MENetworkChannelsChanged();
public int channelData = 0;
Object visitorIterationNumber = null;
private GridNode sideA;
private ForgeDirection fromAtoB;
private GridNode sideB;
Object visitorIterationNumber = null;
public int channelData = 0;
public GridConnection( IGridNode aNode, IGridNode bNode, ForgeDirection fromAtoB ) throws FailedConnection
{
GridNode a = ( GridNode ) aNode;
GridNode b = ( GridNode ) bNode;
GridNode a = (GridNode) aNode;
GridNode b = (GridNode) bNode;
if ( Platform.securityCheck( a, b ) )
if( Platform.securityCheck( a, b ) )
{
if ( AEConfig.instance.isFeatureEnabled( AEFeature.LogSecurityAudits ) )
if( AEConfig.instance.isFeatureEnabled( AEFeature.LogSecurityAudits ) )
{
final DimensionalCoord aCoordinates = a.getGridBlock().getLocation();
final DimensionalCoord bCoordinates = b.getGridBlock().getLocation();
@@ -73,10 +70,10 @@ public class GridConnection implements IGridConnection, IPathItem
throw new FailedConnection();
}
if ( a == null || b == null )
if( a == null || b == null )
throw new GridException( "Connection Forged Between null entities." );
if ( a.hasConnection( b ) || b.hasConnection( a ) )
if( a.hasConnection( b ) || b.hasConnection( a ) )
{
final String aCoords = a.getGridBlock().getLocation().toString();
final String bCoords = b.getGridBlock().getLocation().toString();
@@ -87,23 +84,23 @@ public class GridConnection implements IGridConnection, IPathItem
this.fromAtoB = fromAtoB;
this.sideB = b;
if ( b.getMyGrid() == null )
if( b.getMyGrid() == null )
{
b.setGrid( a.getInternalGrid() );
}
else
{
if ( a.getMyGrid() == null )
if( a.getMyGrid() == null )
{
GridPropagator gp = new GridPropagator( b.getInternalGrid() );
a.beginVisit( gp );
}
else if ( b.getMyGrid() == null )
else if( b.getMyGrid() == null )
{
GridPropagator gp = new GridPropagator( a.getInternalGrid() );
b.beginVisit( gp );
}
else if ( this.isNetworkABetter( a, b ) )
else if( this.isNetworkABetter( a, b ) )
{
GridPropagator gp = new GridPropagator( a.getInternalGrid() );
b.beginVisit( gp );
@@ -128,6 +125,29 @@ public class GridConnection implements IGridConnection, IPathItem
return a.getMyGrid().getPriority() > b.getMyGrid().getPriority() || a.getMyGrid().size() > b.getMyGrid().size();
}
@Override
public IGridNode getOtherSide( IGridNode gridNode )
{
if( gridNode == this.sideA )
return this.sideB;
if( gridNode == this.sideB )
return this.sideA;
throw new GridException( "Invalid Side of Connection" );
}
@Override
public ForgeDirection getDirection( IGridNode side )
{
if( this.fromAtoB == ForgeDirection.UNKNOWN )
return this.fromAtoB;
if( this.sideA == side )
return this.fromAtoB;
else
return this.fromAtoB.getOpposite();
}
@Override
public void destroy()
{
@@ -148,74 +168,28 @@ public class GridConnection implements IGridConnection, IPathItem
return this.sideA;
}
@Override
public ForgeDirection getDirection( IGridNode side )
{
if ( this.fromAtoB == ForgeDirection.UNKNOWN )
return this.fromAtoB;
if ( this.sideA == side )
return this.fromAtoB;
else
return this.fromAtoB.getOpposite();
}
@Override
public IGridNode b()
{
return this.sideB;
}
@Override
public IGridNode getOtherSide( IGridNode gridNode )
{
if ( gridNode == this.sideA )
return this.sideB;
if ( gridNode == this.sideB )
return this.sideA;
throw new GridException( "Invalid Side of Connection" );
}
@Override
public boolean hasDirection()
{
return this.fromAtoB != ForgeDirection.UNKNOWN;
}
@Override
public IReadOnlyCollection<IPathItem> getPossibleOptions()
{
return new ReadOnlyCollection<IPathItem>( Arrays.asList( ( IPathItem ) this.a(), ( IPathItem ) this.b() ) );
}
@Override
public void incrementChannelCount( int usedChannels )
{
this.channelData += usedChannels;
}
@Override
public boolean canSupportMoreChannels()
{
return this.getLastUsedChannels() < 32; // max, PERIOD.
}
@Override
public int getUsedChannels()
{
return ( this.channelData >> 8 ) & 0xff;
}
public int getLastUsedChannels()
{
return this.channelData & 0xff;
}
@Override
public IPathItem getControllerRoute()
{
if ( this.sideA.getFlags().contains( GridFlags.CANNOT_CARRY ) )
if( this.sideA.getFlags().contains( GridFlags.CANNOT_CARRY ) )
return null;
return this.sideA;
}
@@ -223,10 +197,10 @@ public class GridConnection implements IGridConnection, IPathItem
@Override
public void setControllerRoute( IPathItem fast, boolean zeroOut )
{
if ( zeroOut )
if( zeroOut )
this.channelData &= ~0xff;
if ( this.sideB == fast )
if( this.sideB == fast )
{
GridNode tmp = this.sideA;
this.sideA = this.sideB;
@@ -236,19 +210,21 @@ public class GridConnection implements IGridConnection, IPathItem
}
@Override
public void finalizeChannels()
public boolean canSupportMoreChannels()
{
if ( this.getUsedChannels() != this.getLastUsedChannels() )
{
this.channelData &= 0xff;
this.channelData |= this.channelData << 8;
return this.getLastUsedChannels() < 32; // max, PERIOD.
}
if ( this.sideA.getInternalGrid() != null )
this.sideA.getInternalGrid().postEventTo( this.sideA, EVENT );
@Override
public IReadOnlyCollection<IPathItem> getPossibleOptions()
{
return new ReadOnlyCollection<IPathItem>( Arrays.asList( (IPathItem) this.a(), (IPathItem) this.b() ) );
}
if ( this.sideB.getInternalGrid() != null )
this.sideB.getInternalGrid().postEventTo( this.sideB, EVENT );
}
@Override
public void incrementChannelCount( int usedChannels )
{
this.channelData += usedChannels;
}
@Override
@@ -257,4 +233,24 @@ public class GridConnection implements IGridConnection, IPathItem
return EnumSet.noneOf( GridFlags.class );
}
@Override
public void finalizeChannels()
{
if( this.getUsedChannels() != this.getLastUsedChannels() )
{
this.channelData &= 0xff;
this.channelData |= this.channelData << 8;
if( this.sideA.getInternalGrid() != null )
this.sideA.getInternalGrid().postEventTo( this.sideA, EVENT );
if( this.sideB.getInternalGrid() != null )
this.sideB.getInternalGrid().postEventTo( this.sideB, EVENT );
}
}
public int getLastUsedChannels()
{
return this.channelData & 0xff;
}
}
+3 -1
View File
@@ -18,12 +18,14 @@
package appeng.me;
public class GridException extends RuntimeException
{
private static final long serialVersionUID = -8110077032108243076L;
public GridException(String s) {
public GridException( String s )
{
super( s );
}
+81 -81
View File
@@ -101,7 +101,7 @@ public class GridNode implements IGridNode, IPathItem
public void addConnection( IGridConnection gridConnection )
{
this.connections.add( gridConnection );
if ( gridConnection.hasDirection() )
if( gridConnection.hasDirection() )
this.gridProxy.onGridNotification( GridNotification.ConnectionsChanged );
final IGridNode gn = this;
@@ -112,15 +112,15 @@ public class GridNode implements IGridNode, IPathItem
public void removeConnection( IGridConnection gridConnection )
{
this.connections.remove( gridConnection );
if ( gridConnection.hasDirection() )
if( gridConnection.hasDirection() )
this.gridProxy.onGridNotification( GridNotification.ConnectionsChanged );
}
public boolean hasConnection( IGridNode otherSide )
{
for ( IGridConnection gc : this.connections )
for( IGridConnection gc : this.connections )
{
if ( gc.a() == otherSide || gc.b() == otherSide )
if( gc.a() == otherSide || gc.b() == otherSide )
return true;
}
return false;
@@ -130,23 +130,16 @@ public class GridNode implements IGridNode, IPathItem
{
GridSplitDetector gsd = new GridSplitDetector( this.getInternalGrid().getPivot() );
this.beginVisit( gsd );
if ( !gsd.pivotFound )
if( !gsd.pivotFound )
{
IGridVisitor gp = new GridPropagator( new Grid( this ) );
this.beginVisit( gp );
}
}
@Override
public void setPlayerID( int playerID )
{
if ( playerID >= 0 )
this.playerID = playerID;
}
public Grid getInternalGrid()
{
if ( this.myGrid == null )
if( this.myGrid == null )
this.myGrid = new Grid( this );
return this.myGrid;
@@ -162,31 +155,31 @@ public class GridNode implements IGridNode, IPathItem
this.visitorIterationNumber = tracker;
if ( g instanceof IGridConnectionVisitor )
if( g instanceof IGridConnectionVisitor )
{
LinkedList<IGridConnection> nextConn = new LinkedList<IGridConnection>();
IGridConnectionVisitor gcv = ( IGridConnectionVisitor ) g;
IGridConnectionVisitor gcv = (IGridConnectionVisitor) g;
while ( !nextRun.isEmpty() )
while( !nextRun.isEmpty() )
{
while ( !nextConn.isEmpty() )
while( !nextConn.isEmpty() )
gcv.visitConnection( nextConn.poll() );
LinkedList<GridNode> thisRun = nextRun;
nextRun = new LinkedList<GridNode>();
for ( GridNode n : thisRun )
for( GridNode n : thisRun )
n.visitorConnection( tracker, g, nextRun, nextConn );
}
}
else
{
while ( !nextRun.isEmpty() )
while( !nextRun.isEmpty() )
{
LinkedList<GridNode> thisRun = nextRun;
nextRun = new LinkedList<GridNode>();
for ( GridNode n : thisRun )
for( GridNode n : thisRun )
n.visitorNode( tracker, g, nextRun );
}
}
@@ -201,7 +194,7 @@ public class GridNode implements IGridNode, IPathItem
this.compressedData |= ( this.gridProxy.getGridColor().ordinal() << 3 );
for ( ForgeDirection dir : this.gridProxy.getConnectableSides() )
for( ForgeDirection dir : this.gridProxy.getConnectableSides() )
this.compressedData |= ( 1 << ( dir.ordinal() + 8 ) );
this.FindConnections();
@@ -222,18 +215,18 @@ public class GridNode implements IGridNode, IPathItem
public void setGrid( Grid grid )
{
if ( this.myGrid == grid )
if( this.myGrid == grid )
return;
if ( this.myGrid != null )
if( this.myGrid != null )
{
this.myGrid.remove( this );
if ( this.myGrid.isEmpty() )
if( this.myGrid.isEmpty() )
{
this.myGrid.saveState();
for ( IGridCache c : grid.getCaches().values() )
for( IGridCache c : grid.getCaches().values() )
c.onJoin( this.myGrid.getMyStorage() );
}
}
@@ -245,19 +238,19 @@ public class GridNode implements IGridNode, IPathItem
@Override
public void destroy()
{
while ( !this.connections.isEmpty() )
while( !this.connections.isEmpty() )
{
// not part of this network for real anymore.
if ( this.connections.size() == 1 )
if( this.connections.size() == 1 )
this.setGridStorage( null );
IGridConnection c = this.connections.listIterator().next();
GridNode otherSide = ( GridNode ) c.getOtherSide( this );
GridNode otherSide = (GridNode) c.getOtherSide( this );
otherSide.getInternalGrid().setPivot( otherSide );
c.destroy();
}
if ( this.myGrid != null )
if( this.myGrid != null )
this.myGrid.remove( this );
}
@@ -271,7 +264,7 @@ public class GridNode implements IGridNode, IPathItem
public EnumSet<ForgeDirection> getConnectedSides()
{
EnumSet<ForgeDirection> set = EnumSet.noneOf( ForgeDirection.class );
for ( IGridConnection gc : this.connections )
for( IGridConnection gc : this.connections )
set.add( gc.getDirection( this ) );
return set;
}
@@ -292,7 +285,7 @@ public class GridNode implements IGridNode, IPathItem
public boolean isActive()
{
IGrid g = this.getGrid();
if ( g != null )
if( g != null )
{
IPathingGrid pg = g.getCache( IPathingGrid.class );
IEnergyGrid eg = g.getCache( IEnergyGrid.class );
@@ -304,7 +297,7 @@ public class GridNode implements IGridNode, IPathItem
@Override
public void loadFromNBT( String name, NBTTagCompound nodeData )
{
if ( this.myGrid == null )
if( this.myGrid == null )
{
NBTTagCompound node = nodeData.getCompoundTag( name );
this.playerID = node.getInteger( "p" );
@@ -318,7 +311,7 @@ public class GridNode implements IGridNode, IPathItem
@Override
public void saveToNBT( String name, NBTTagCompound nodeData )
{
if ( this.myStorage != null )
if( this.myStorage != null )
{
NBTTagCompound node = new NBTTagCompound();
@@ -344,6 +337,19 @@ public class GridNode implements IGridNode, IPathItem
return this.gridProxy.getFlags().contains( flag );
}
@Override
public int getPlayerID()
{
return this.playerID;
}
@Override
public void setPlayerID( int playerID )
{
if( playerID >= 0 )
this.playerID = playerID;
}
public int getUsedChannels()
{
return this.channelData & 0xff;
@@ -351,41 +357,41 @@ public class GridNode implements IGridNode, IPathItem
public void FindConnections()
{
if ( !this.gridProxy.isWorldAccessible() )
if( !this.gridProxy.isWorldAccessible() )
return;
EnumSet<ForgeDirection> newSecurityConnections = EnumSet.noneOf( ForgeDirection.class );
DimensionalCoord dc = this.gridProxy.getLocation();
for ( ForgeDirection f : ForgeDirection.VALID_DIRECTIONS )
for( ForgeDirection f : ForgeDirection.VALID_DIRECTIONS )
{
IGridHost te = this.findGridHost( dc.getWorld(), dc.x + f.offsetX, dc.y + f.offsetY, dc.z + f.offsetZ );
if ( te != null )
if( te != null )
{
GridNode node = ( GridNode ) te.getGridNode( f.getOpposite() );
if ( node == null )
GridNode node = (GridNode) te.getGridNode( f.getOpposite() );
if( node == null )
continue;
boolean isValidConnection = this.canConnect( node, f ) && node.canConnect( this, f.getOpposite() );
IGridConnection con = null; // find the connection for this
// direction..
for ( IGridConnection c : this.getConnections() )
for( IGridConnection c : this.getConnections() )
{
if ( c.getDirection( this ) == f )
if( c.getDirection( this ) == f )
{
con = c;
break;
}
}
if ( con != null )
if( con != null )
{
IGridNode os = con.getOtherSide( this );
if ( os == node )
if( os == node )
{
// if this connection is no longer valid, destroy it.
if ( !isValidConnection )
if( !isValidConnection )
con.destroy();
}
else
@@ -394,9 +400,9 @@ public class GridNode implements IGridNode, IPathItem
// throw new GridException( "invalid state found, encountered connection to phantom block." );
}
}
else if ( isValidConnection )
else if( isValidConnection )
{
if ( node.lastSecurityKey != -1 )
if( node.lastSecurityKey != -1 )
newSecurityConnections.add( f );
else
{
@@ -405,7 +411,7 @@ public class GridNode implements IGridNode, IPathItem
{
new GridConnection( node, this, f.getOpposite() );
}
catch ( FailedConnection e )
catch( FailedConnection e )
{
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
@@ -416,13 +422,13 @@ public class GridNode implements IGridNode, IPathItem
}
}
for ( ForgeDirection f : newSecurityConnections )
for( ForgeDirection f : newSecurityConnections )
{
IGridHost te = this.findGridHost( dc.getWorld(), dc.x + f.offsetX, dc.y + f.offsetY, dc.z + f.offsetZ );
if ( te != null )
if( te != null )
{
GridNode node = ( GridNode ) te.getGridNode( f.getOpposite() );
if ( node == null )
GridNode node = (GridNode) te.getGridNode( f.getOpposite() );
if( node == null )
continue;
// construct a new connection between these two nodes.
@@ -430,7 +436,7 @@ public class GridNode implements IGridNode, IPathItem
{
new GridConnection( node, this, f.getOpposite() );
}
catch ( FailedConnection e )
catch( FailedConnection e )
{
TickHandler.INSTANCE.addCallable( node.getWorld(), new MachineSecurityBreak( this ) );
@@ -442,21 +448,21 @@ public class GridNode implements IGridNode, IPathItem
private IGridHost findGridHost( World world, int x, int y, int z )
{
if ( world.blockExists( x, y, z ) )
if( world.blockExists( x, y, z ) )
{
TileEntity te = world.getTileEntity( x, y, z );
if ( te instanceof IGridHost )
return ( IGridHost ) te;
if( te instanceof IGridHost )
return (IGridHost) te;
}
return null;
}
public boolean canConnect( GridNode from, ForgeDirection dir )
{
if ( !this.isValidDirection( dir ) )
if( !this.isValidDirection( dir ) )
return false;
if ( !from.getColor().matches( this.getColor() ) )
if( !from.getColor().matches( this.getColor() ) )
return false;
return true;
@@ -474,20 +480,20 @@ public class GridNode implements IGridNode, IPathItem
private void visitorConnection( Object tracker, IGridVisitor g, Deque<GridNode> nextRun, Deque<IGridConnection> nextConnections )
{
if ( g.visitNode( this ) )
if( g.visitNode( this ) )
{
for ( IGridConnection gc : this.getConnections() )
for( IGridConnection gc : this.getConnections() )
{
GridNode gn = ( GridNode ) gc.getOtherSide( this );
GridConnection gcc = ( GridConnection ) gc;
GridNode gn = (GridNode) gc.getOtherSide( this );
GridConnection gcc = (GridConnection) gc;
if ( gcc.visitorIterationNumber != tracker )
if( gcc.visitorIterationNumber != tracker )
{
gcc.visitorIterationNumber = tracker;
nextConnections.add( gc );
}
if ( tracker == gn.visitorIterationNumber )
if( tracker == gn.visitorIterationNumber )
continue;
gn.visitorIterationNumber = tracker;
@@ -499,13 +505,13 @@ public class GridNode implements IGridNode, IPathItem
private void visitorNode( Object tracker, IGridVisitor g, Deque<GridNode> nextRun )
{
if ( g.visitNode( this ) )
if( g.visitNode( this ) )
{
for ( IGridConnection gc : this.getConnections() )
for( IGridConnection gc : this.getConnections() )
{
GridNode gn = ( GridNode ) gc.getOtherSide( this );
GridNode gn = (GridNode) gc.getOtherSide( this );
if ( tracker == gn.visitorIterationNumber )
if( tracker == gn.visitorIterationNumber )
continue;
gn.visitorIterationNumber = tracker;
@@ -529,23 +535,23 @@ public class GridNode implements IGridNode, IPathItem
@Override
public IPathItem getControllerRoute()
{
if ( this.connections.isEmpty() || this.getFlags().contains( GridFlags.CANNOT_CARRY ) )
if( this.connections.isEmpty() || this.getFlags().contains( GridFlags.CANNOT_CARRY ) )
return null;
return ( IPathItem ) this.connections.get( 0 );
return (IPathItem) this.connections.get( 0 );
}
@Override
public void setControllerRoute( IPathItem fast, boolean zeroOut )
{
if ( zeroOut )
if( zeroOut )
this.channelData &= ~0xff;
int idx = this.connections.indexOf( fast );
if ( idx > 0 )
if( idx > 0 )
{
this.connections.remove( fast );
this.connections.add( 0, ( IGridConnection ) fast );
this.connections.add( 0, (IGridConnection) fast );
}
}
@@ -563,7 +569,7 @@ public class GridNode implements IGridNode, IPathItem
@Override
public IReadOnlyCollection<IPathItem> getPossibleOptions()
{
return ( ReadOnlyCollection ) this.getConnections();
return (ReadOnlyCollection) this.getConnections();
}
@Override
@@ -581,15 +587,15 @@ public class GridNode implements IGridNode, IPathItem
@Override
public void finalizeChannels()
{
if ( this.getFlags().contains( GridFlags.CANNOT_CARRY ) )
if( this.getFlags().contains( GridFlags.CANNOT_CARRY ) )
return;
if ( this.getLastUsedChannels() != this.getUsedChannels() )
if( this.getLastUsedChannels() != this.getUsedChannels() )
{
this.channelData &= 0xff;
this.channelData |= this.channelData << 8;
if ( this.getInternalGrid() != null )
if( this.getInternalGrid() != null )
this.getInternalGrid().postEventTo( this, EVENT );
}
}
@@ -636,10 +642,4 @@ public class GridNode implements IGridNode, IPathItem
return preferredA == preferredB ? 0 : ( preferredA ? -1 : 1 );
}
}
@Override
public int getPlayerID()
{
return this.playerID;
}
}
@@ -48,7 +48,7 @@ public class GridNodeCollection implements IReadOnlyCollection<IGridNode>
{
int size = 0;
for ( Set<IGridNode> o : this.machines.values() )
for( Set<IGridNode> o : this.machines.values() )
size += o.size();
return size;
@@ -57,8 +57,8 @@ public class GridNodeCollection implements IReadOnlyCollection<IGridNode>
@Override
public boolean isEmpty()
{
for ( Set<IGridNode> o : this.machines.values() )
if ( !o.isEmpty() )
for( Set<IGridNode> o : this.machines.values() )
if( !o.isEmpty() )
return false;
return true;
@@ -69,9 +69,9 @@ public class GridNodeCollection implements IReadOnlyCollection<IGridNode>
{
final boolean doesContainNode;
if ( maybeGridNode instanceof IGridNode )
if( maybeGridNode instanceof IGridNode )
{
final IGridNode node = ( IGridNode ) maybeGridNode;
final IGridNode node = (IGridNode) maybeGridNode;
IGridHost machine = node.getMachine();
Class<? extends IGridHost> machineClass = machine.getClass();
@@ -47,7 +47,7 @@ public class GridNodeIterator implements Iterator<IGridNode>
{
final boolean hasNext = this.outerIterator.hasNext();
if ( hasNext )
if( hasNext )
{
final MachineSet nextElem = this.outerIterator.next();
this.innerIterator = nextElem.iterator();
@@ -59,13 +59,13 @@ public class GridNodeIterator implements Iterator<IGridNode>
@Override
public boolean hasNext()
{
while ( true )
while( true )
{
if ( this.innerIterator.hasNext() )
if( this.innerIterator.hasNext() )
{
return true;
}
else if ( !this.innerHasNext() )
else if( !this.innerHasNext() )
{
return false;
}
+2 -2
View File
@@ -35,8 +35,8 @@ public class GridPropagator implements IGridVisitor
@Override
public boolean visitNode( IGridNode n )
{
GridNode gn = ( GridNode ) n;
if ( gn.getMyGrid() != this.g || this.g.getPivot() == n )
GridNode gn = (GridNode) n;
if( gn.getMyGrid() != this.g || this.g.getPivot() == n )
{
gn.setGrid( this.g );
@@ -18,23 +18,26 @@
package appeng.me;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IGridVisitor;
class GridSplitDetector implements IGridVisitor
{
final IGridNode pivot;
boolean pivotFound;
public GridSplitDetector(IGridNode pivot) {
public GridSplitDetector( IGridNode pivot )
{
this.pivot = pivot;
}
@Override
public boolean visitNode(IGridNode n)
public boolean visitNode( IGridNode n )
{
if ( n == this.pivot )
if( n == this.pivot )
this.pivotFound = true;
return !this.pivotFound;
+30 -28
View File
@@ -18,6 +18,7 @@
package appeng.me;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -32,26 +33,26 @@ import appeng.api.networking.IGridStorage;
import appeng.core.AELog;
import appeng.core.WorldSettings;
public class GridStorage implements IGridStorage
{
private WeakReference<IGrid> internalGrid = null;
final long myID;
final NBTTagCompound data;
public boolean isDirty = false;
private final WeakHashMap<GridStorage,Boolean> divided = new WeakHashMap<GridStorage,Boolean>();
final GridStorageSearch mySearchEntry; // keep myself in the list until I'm
// lost...
private final WeakHashMap<GridStorage, Boolean> divided = new WeakHashMap<GridStorage, Boolean>();
public boolean isDirty = false;
private WeakReference<IGrid> internalGrid = null;
// lost...
/**
* for use with world settings
*
* @param id ID of grid storage
* @param id ID of grid storage
* @param gss grid storage search
*/
public GridStorage(long id, GridStorageSearch gss) {
public GridStorage( long id, GridStorageSearch gss )
{
this.myID = id;
this.mySearchEntry = gss;
this.data = new NBTTagCompound();
@@ -61,10 +62,11 @@ public class GridStorage implements IGridStorage
* for use with world settings
*
* @param input array of bytes string
* @param id ID of grid storage
* @param gss grid storage search
* @param id ID of grid storage
* @param gss grid storage search
*/
public GridStorage(String input, long id, GridStorageSearch gss) {
public GridStorage( String input, long id, GridStorageSearch gss )
{
this.myID = id;
this.mySearchEntry = gss;
NBTTagCompound myTag = null;
@@ -74,7 +76,7 @@ public class GridStorage implements IGridStorage
byte[] byteData = javax.xml.bind.DatatypeConverter.parseBase64Binary( input );
myTag = CompressedStreamTools.readCompressed( new ByteArrayInputStream( byteData ) );
}
catch (Throwable t)
catch( Throwable t )
{
myTag = new NBTTagCompound();
}
@@ -85,7 +87,8 @@ public class GridStorage implements IGridStorage
/**
* fake storage.
*/
public GridStorage() {
public GridStorage()
{
this.myID = 0;
this.mySearchEntry = null;
this.data = new NBTTagCompound();
@@ -96,7 +99,7 @@ public class GridStorage implements IGridStorage
this.isDirty = false;
Grid currentGrid = (Grid) this.getGrid();
if ( currentGrid != null )
if( currentGrid != null )
{
currentGrid.saveState();
}
@@ -107,7 +110,7 @@ public class GridStorage implements IGridStorage
CompressedStreamTools.writeCompressed( this.data, out );
return javax.xml.bind.DatatypeConverter.printBase64Binary( out.toByteArray() );
}
catch (IOException e)
catch( IOException e )
{
AELog.error( e );
}
@@ -115,6 +118,16 @@ public class GridStorage implements IGridStorage
return "";
}
public IGrid getGrid()
{
return this.internalGrid == null ? null : this.internalGrid.get();
}
public void setGrid( Grid grid )
{
this.internalGrid = new WeakReference<IGrid>( grid );
}
@Override
public NBTTagCompound dataObject()
{
@@ -132,22 +145,12 @@ public class GridStorage implements IGridStorage
this.isDirty = true;
}
public IGrid getGrid()
{
return this.internalGrid == null ? null : this.internalGrid.get();
}
public void setGrid(Grid grid)
{
this.internalGrid = new WeakReference<IGrid>( grid );
}
public void addDivided(GridStorage gs)
public void addDivided( GridStorage gs )
{
this.divided.put( gs, true );
}
public boolean hasDivided(GridStorage myStorage)
public boolean hasDivided( GridStorage myStorage )
{
return this.divided.containsKey( myStorage );
}
@@ -156,5 +159,4 @@ public class GridStorage implements IGridStorage
{
WorldSettings.getInstance().destroyGridStorage( this.myID );
}
}
+19 -17
View File
@@ -18,8 +18,10 @@
package appeng.me;
import java.lang.ref.WeakReference;
public class GridStorageSearch
{
@@ -31,29 +33,29 @@ public class GridStorageSearch
*
* @param id ID of grid storage search
*/
public GridStorageSearch(long id) {
this.id = id;
}
@Override
public boolean equals(Object obj)
public GridStorageSearch( long id )
{
if ( obj == null )
return false;
if ( this.getClass() != obj.getClass() )
return false;
GridStorageSearch other = (GridStorageSearch) obj;
if ( this.id == other.id )
return true;
return false;
this.id = id;
}
@Override
public int hashCode()
{
return ((Long) this.id).hashCode();
return ( (Long) this.id ).hashCode();
}
@Override
public boolean equals( Object obj )
{
if( obj == null )
return false;
if( this.getClass() != obj.getClass() )
return false;
GridStorageSearch other = (GridStorageSearch) obj;
if( this.id == other.id )
return true;
return false;
}
}
+4 -2
View File
@@ -18,12 +18,14 @@
package appeng.me;
import java.util.HashSet;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IMachineSet;
public class MachineSet extends HashSet<IGridNode> implements IMachineSet
{
@@ -31,7 +33,8 @@ public class MachineSet extends HashSet<IGridNode> implements IMachineSet
private final Class<? extends IGridHost> machine;
MachineSet(Class<? extends IGridHost> m) {
MachineSet( Class<? extends IGridHost> m )
{
this.machine = m;
}
@@ -40,5 +43,4 @@ public class MachineSet extends HashSet<IGridNode> implements IMachineSet
{
return this.machine;
}
}
+19 -19
View File
@@ -41,29 +41,29 @@ public class NetworkEventBus
public void readClass( Class listAs, Class c )
{
if ( READ_CLASSES.contains( c ) )
if( READ_CLASSES.contains( c ) )
return;
READ_CLASSES.add( c );
try
{
for ( Method m : c.getMethods() )
for( Method m : c.getMethods() )
{
MENetworkEventSubscribe s = m.getAnnotation( MENetworkEventSubscribe.class );
if ( s != null )
if( s != null )
{
Class[] types = m.getParameterTypes();
if ( types.length == 1 )
if( types.length == 1 )
{
if ( MENetworkEvent.class.isAssignableFrom( types[0] ) )
if( MENetworkEvent.class.isAssignableFrom( types[0] ) )
{
Map<Class, MENetworkEventInfo> classEvents = EVENTS.get( types[0] );
if ( classEvents == null )
if( classEvents == null )
EVENTS.put( types[0], classEvents = new HashMap<Class, MENetworkEventInfo>() );
MENetworkEventInfo thisEvent = classEvents.get( listAs );
if ( thisEvent == null )
if( thisEvent == null )
thisEvent = new MENetworkEventInfo();
thisEvent.Add( types[0], c, m );
@@ -78,7 +78,7 @@ public class NetworkEventBus
}
}
}
catch ( Throwable t )
catch( Throwable t )
{
throw new RuntimeException( "Error while adding " + c.getName() + " to event bus", t );
}
@@ -91,19 +91,19 @@ public class NetworkEventBus
try
{
if ( subscribers != null )
if( subscribers != null )
{
for ( Entry<Class, MENetworkEventInfo> subscriber : subscribers.entrySet() )
for( Entry<Class, MENetworkEventInfo> subscriber : subscribers.entrySet() )
{
MENetworkEventInfo target = subscriber.getValue();
GridCacheWrapper cache = g.getCaches().get( subscriber.getKey() );
if ( cache != null )
if( cache != null )
{
x++;
target.invoke( cache.myCache, e );
}
for ( IGridNode obj : g.getMachines( subscriber.getKey() ) )
for( IGridNode obj : g.getMachines( subscriber.getKey() ) )
{
x++;
target.invoke( obj.getMachine(), e );
@@ -111,7 +111,7 @@ public class NetworkEventBus
}
}
}
catch ( NetworkEventDone done )
catch( NetworkEventDone done )
{
// Early out.
}
@@ -127,17 +127,17 @@ public class NetworkEventBus
try
{
if ( subscribers != null )
if( subscribers != null )
{
MENetworkEventInfo target = subscribers.get( node.getMachineClass() );
if ( target != null )
if( target != null )
{
x++;
target.invoke( node.getMachine(), e );
}
}
}
catch ( NetworkEventDone done )
catch( NetworkEventDone done )
{
// Early out.
}
@@ -173,7 +173,7 @@ public class NetworkEventBus
{
this.objMethod.invoke( obj, e );
}
catch ( Throwable e1 )
catch( Throwable e1 )
{
AELog.severe( "[AppEng] Network Event caused exception:" );
AELog.severe( "Offending Class: " + obj.getClass().getName() );
@@ -182,7 +182,7 @@ public class NetworkEventBus
throw new RuntimeException( e1 );
}
if ( e.isCanceled() )
if( e.isCanceled() )
throw new NetworkEventDone();
}
}
@@ -200,7 +200,7 @@ public class NetworkEventBus
public void invoke( Object obj, MENetworkEvent e ) throws NetworkEventDone
{
for ( EventMethod em : this.methods )
for( EventMethod em : this.methods )
em.invoke( obj, e );
}
}
+64 -63
View File
@@ -18,46 +18,22 @@
package appeng.me;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class NetworkList implements Collection<Grid>
{
private List<Grid> networks = new LinkedList<Grid>();
@Override
public boolean add(Grid e)
public int size()
{
this.copy();
return this.networks.add( e );
}
@Override
public boolean addAll(Collection<? extends Grid> c)
{
this.copy();
return this.networks.addAll( c );
}
@Override
public void clear()
{
this.networks = new LinkedList<Grid>();
}
@Override
public boolean contains(Object o)
{
return this.networks.contains( o );
}
@Override
public boolean containsAll(Collection<?> c)
{
return this.networks.containsAll( c );
return this.networks.size();
}
@Override
@@ -66,46 +42,18 @@ public class NetworkList implements Collection<Grid>
return this.networks.isEmpty();
}
@Override
public boolean contains( Object o )
{
return this.networks.contains( o );
}
@Override
public Iterator<Grid> iterator()
{
return this.networks.iterator();
}
@Override
public boolean remove(Object o)
{
this.copy();
return this.networks.remove( o );
}
@Override
public boolean removeAll(Collection<?> c)
{
this.copy();
return this.networks.removeAll( c );
}
@Override
public boolean retainAll(Collection<?> c)
{
this.copy();
return this.networks.retainAll( c );
}
private void copy()
{
List<Grid> old = this.networks;
this.networks = new LinkedList<Grid>();
this.networks.addAll( old );
}
@Override
public int size()
{
return this.networks.size();
}
@Override
public Object[] toArray()
{
@@ -113,9 +61,62 @@ public class NetworkList implements Collection<Grid>
}
@Override
public <T> T[] toArray(T[] a)
public <T> T[] toArray( T[] a )
{
return this.networks.toArray( a );
}
@Override
public boolean add( Grid e )
{
this.copy();
return this.networks.add( e );
}
@Override
public boolean remove( Object o )
{
this.copy();
return this.networks.remove( o );
}
@Override
public boolean containsAll( Collection<?> c )
{
return this.networks.containsAll( c );
}
@Override
public boolean addAll( Collection<? extends Grid> c )
{
this.copy();
return this.networks.addAll( c );
}
@Override
public boolean removeAll( Collection<?> c )
{
this.copy();
return this.networks.removeAll( c );
}
@Override
public boolean retainAll( Collection<?> c )
{
this.copy();
return this.networks.retainAll( c );
}
@Override
public void clear()
{
this.networks = new LinkedList<Grid>();
}
private void copy()
{
List<Grid> old = this.networks;
this.networks = new LinkedList<Grid>();
this.networks.addAll( old );
}
}
File diff suppressed because it is too large Load Diff
+345 -357
View File
@@ -18,6 +18,7 @@
package appeng.me.cache;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -53,96 +54,60 @@ import appeng.me.GridNode;
import appeng.me.energy.EnergyThreshold;
import appeng.me.energy.EnergyWatcher;
public class EnergyGridCache implements IEnergyGrid
{
final public TreeSet<EnergyThreshold> interests = new TreeSet<EnergyThreshold>();
final double AvgLength = 40.0;
final Set<IAEPowerStorage> providers = new LinkedHashSet<IAEPowerStorage>();
final Set<IAEPowerStorage> requesters = new LinkedHashSet<IAEPowerStorage>();
final Multiset<IEnergyGridProvider> energyGridProviders = HashMultiset.create();
final IGrid myGrid;
final private HashMap<IGridNode, IEnergyWatcher> watchers = new HashMap<IGridNode, IEnergyWatcher>();
final private Set<IEnergyGrid> localSeen = new HashSet<IEnergyGrid>();
/**
* estimated power available.
*/
int availableTicksSinceUpdate = 0;
double globalAvailablePower = 0;
double globalMaxPower = 0;
/**
* idle draw.
*/
double drainPerTick = 0;
final double AvgLength = 40.0;
double avgDrainPerTick = 0;
double avgInjectionPerTick = 0;
double tickDrainPerTick = 0;
double tickInjectionPerTick = 0;
/**
* power status
*/
boolean publicHasPower = false;
boolean hasPower = true;
long ticksSinceHasPowerChange = 900;
/**
* excess power in the system.
*/
double extra = 0;
IAEPowerStorage lastProvider;
final Set<IAEPowerStorage> providers = new LinkedHashSet<IAEPowerStorage>();
IAEPowerStorage lastRequester;
final Set<IAEPowerStorage> requesters = new LinkedHashSet<IAEPowerStorage>();
final public TreeSet<EnergyThreshold> interests = new TreeSet<EnergyThreshold>();
final private HashMap<IGridNode, IEnergyWatcher> watchers = new HashMap<IGridNode, IEnergyWatcher>();
final private Set<IEnergyGrid> localSeen = new HashSet<IEnergyGrid>();
private double buffer()
{
return this.providers.isEmpty() ? 1000.0 : 0.0;
}
private IAEPowerStorage getFirstRequester()
{
if ( this.lastRequester == null )
{
Iterator<IAEPowerStorage> i = this.requesters.iterator();
this.lastRequester = i.hasNext() ? i.next() : null;
}
return this.lastRequester;
}
private IAEPowerStorage getFirstProvider()
{
if ( this.lastProvider == null )
{
Iterator<IAEPowerStorage> i = this.providers.iterator();
this.lastProvider = i.hasNext() ? i.next() : null;
}
return this.lastProvider;
}
final Multiset<IEnergyGridProvider> energyGridProviders = HashMultiset.create();
final IGrid myGrid;
PathGridCache pgc;
double lastStoredPower = -1;
public EnergyGridCache(IGrid g) {
public EnergyGridCache( IGrid g )
{
this.myGrid = g;
}
@MENetworkEventSubscribe
public void postInit(MENetworkPostCacheConstruction pcc)
public void postInit( MENetworkPostCacheConstruction pcc )
{
this.pgc = this.myGrid.getCache( IPathingGrid.class );
}
@MENetworkEventSubscribe
public void EnergyNodeChanges(MENetworkPowerIdleChange ev)
public void EnergyNodeChanges( MENetworkPowerIdleChange ev )
{
// update power usage based on event.
GridNode node = (GridNode) ev.node;
@@ -156,88 +121,188 @@ public class EnergyGridCache implements IEnergyGrid
}
@MENetworkEventSubscribe
public void EnergyNodeChanges(MENetworkPowerStorage ev)
public void EnergyNodeChanges( MENetworkPowerStorage ev )
{
if ( ev.storage.isAEPublicPowerStorage() )
if( ev.storage.isAEPublicPowerStorage() )
{
switch (ev.type)
switch( ev.type )
{
case PROVIDE_POWER:
if ( ev.storage.getPowerFlow() != AccessRestriction.WRITE )
this.providers.add( ev.storage );
break;
case REQUEST_POWER:
if ( ev.storage.getPowerFlow() != AccessRestriction.READ )
this.requesters.add( ev.storage );
break;
case PROVIDE_POWER:
if( ev.storage.getPowerFlow() != AccessRestriction.WRITE )
this.providers.add( ev.storage );
break;
case REQUEST_POWER:
if( ev.storage.getPowerFlow() != AccessRestriction.READ )
this.requesters.add( ev.storage );
break;
}
}
else
{
(new RuntimeException( "Attempt to ask the IEnergyGrid to charge a non public energy store." )).printStackTrace();
( new RuntimeException( "Attempt to ask the IEnergyGrid to charge a non public energy store." ) ).printStackTrace();
}
}
@Override
public double getEnergyDemand(double maxRequired)
public void onUpdateTick()
{
this.localSeen.clear();
return this.getEnergyDemand( maxRequired, this.localSeen );
if( !this.interests.isEmpty() )
{
double oldPower = this.lastStoredPower;
this.lastStoredPower = this.getStoredPower();
EnergyThreshold low = new EnergyThreshold( Math.min( oldPower, this.lastStoredPower ), null );
EnergyThreshold high = new EnergyThreshold( Math.max( oldPower, this.lastStoredPower ), null );
for( EnergyThreshold th : this.interests.subSet( low, true, high, true ) )
{
( (EnergyWatcher) th.watcher ).post( this );
}
}
this.avgDrainPerTick *= ( this.AvgLength - 1 ) / this.AvgLength;
this.avgInjectionPerTick *= ( this.AvgLength - 1 ) / this.AvgLength;
this.avgDrainPerTick += this.tickDrainPerTick / this.AvgLength;
this.avgInjectionPerTick += this.tickInjectionPerTick / this.AvgLength;
this.tickDrainPerTick = 0;
this.tickInjectionPerTick = 0;
// power information.
boolean currentlyHasPower = false;
if( this.drainPerTick > 0.0001 )
{
double drained = this.extractAEPower( this.getIdlePowerUsage(), Actionable.MODULATE, PowerMultiplier.CONFIG );
currentlyHasPower = drained >= this.drainPerTick - 0.001;
}
else
{
currentlyHasPower = this.extractAEPower( 0.1, Actionable.SIMULATE, PowerMultiplier.CONFIG ) > 0;
}
// ticks since change..
if( currentlyHasPower == this.hasPower )
this.ticksSinceHasPowerChange++;
else
this.ticksSinceHasPowerChange = 0;
// update status..
this.hasPower = currentlyHasPower;
// update public status, this buffers power ups for 30 ticks.
if( this.hasPower && this.ticksSinceHasPowerChange > 30 )
this.publicPowerState( true, this.myGrid );
else if( !this.hasPower )
this.publicPowerState( false, this.myGrid );
this.availableTicksSinceUpdate++;
}
@Override
public double getEnergyDemand(double maxRequired, Set<IEnergyGrid> seen)
public double extractAEPower( double amt, Actionable mode, PowerMultiplier pm )
{
if ( !seen.add( this ) )
this.localSeen.clear();
return pm.divide( this.extractAEPower( pm.multiply( amt ), mode, this.localSeen ) );
}
@Override
public double getIdlePowerUsage()
{
return this.drainPerTick + this.pgc.channelPowerUsage;
}
private void publicPowerState( boolean newState, IGrid grid )
{
if( this.publicHasPower == newState )
return;
this.publicHasPower = newState;
( (Grid) this.myGrid ).setImportantFlag( 0, this.publicHasPower );
grid.postEvent( new MENetworkPowerStatusChange() );
}
/**
* refresh current stored power.
*/
public void refreshPower()
{
this.availableTicksSinceUpdate = 0;
this.globalAvailablePower = 0;
for( IAEPowerStorage p : this.providers )
this.globalAvailablePower += p.getAECurrentPower();
}
@Override
public double extractAEPower( double amt, Actionable mode, Set<IEnergyGrid> seen )
{
if( !seen.add( this ) )
return 0;
double required = this.buffer() - this.extra;
double extractedPower = this.extra;
Iterator<IAEPowerStorage> it = this.requesters.iterator();
while (required < maxRequired && it.hasNext())
if( mode == Actionable.SIMULATE )
{
IAEPowerStorage node = it.next();
if ( node.getPowerFlow() != AccessRestriction.READ )
required += Math.max( 0.0, node.getAEMaxPower() - node.getAECurrentPower() );
extractedPower += this.simulateExtract( extractedPower, amt );
if( extractedPower < amt )
{
Iterator<IEnergyGridProvider> i = this.energyGridProviders.iterator();
while( extractedPower < amt && i.hasNext() )
extractedPower += i.next().extractAEPower( amt - extractedPower, mode, seen );
}
return extractedPower;
}
else
{
this.extra = 0;
extractedPower = this.doExtract( extractedPower, amt );
}
Iterator<IEnergyGridProvider> ix = this.energyGridProviders.iterator();
while (required < maxRequired && ix.hasNext())
// got more then we wanted?
if( extractedPower > amt )
{
IEnergyGridProvider node = ix.next();
required += node.getEnergyDemand( maxRequired - required, seen );
this.extra = extractedPower - amt;
this.globalAvailablePower -= amt;
this.tickDrainPerTick += amt;
return amt;
}
return required;
if( extractedPower < amt )
{
Iterator<IEnergyGridProvider> i = this.energyGridProviders.iterator();
while( extractedPower < amt && i.hasNext() )
extractedPower += i.next().extractAEPower( amt - extractedPower, mode, seen );
}
// go less or the correct amount?
this.globalAvailablePower -= extractedPower;
this.tickDrainPerTick += extractedPower;
return extractedPower;
}
@Override
public double injectPower(double amt, Actionable mode)
public double injectAEPower( double amt, Actionable mode, Set<IEnergyGrid> seen )
{
this.localSeen.clear();
return this.injectAEPower( amt, mode, this.localSeen );
}
@Override
public double injectAEPower(double amt, Actionable mode, Set<IEnergyGrid> seen)
{
if ( !seen.add( this ) )
if( !seen.add( this ) )
return 0;
double ignore = this.extra;
amt += this.extra;
if ( mode == Actionable.SIMULATE )
if( mode == Actionable.SIMULATE )
{
Iterator<IAEPowerStorage> it = this.requesters.iterator();
while (amt > 0 && it.hasNext())
while( amt > 0 && it.hasNext() )
{
IAEPowerStorage node = it.next();
amt = node.injectAEPower( amt, Actionable.SIMULATE );
}
Iterator<IEnergyGridProvider> i = this.energyGridProviders.iterator();
while (amt > 0 && i.hasNext())
while( amt > 0 && i.hasNext() )
amt = i.next().injectAEPower( amt, mode, seen );
}
else
@@ -245,12 +310,12 @@ public class EnergyGridCache implements IEnergyGrid
this.tickInjectionPerTick += amt - ignore;
// totalInjectionPastTicks[0] += i;
while (amt > 0 && !this.requesters.isEmpty())
while( amt > 0 && !this.requesters.isEmpty() )
{
IAEPowerStorage node = this.getFirstRequester();
amt = node.injectAEPower( amt, Actionable.MODULATE );
if ( amt > 0 )
if( amt > 0 )
{
this.requesters.remove( node );
this.lastRequester = null;
@@ -258,7 +323,7 @@ public class EnergyGridCache implements IEnergyGrid
}
Iterator<IEnergyGridProvider> i = this.energyGridProviders.iterator();
while (amt > 0 && i.hasNext())
while( amt > 0 && i.hasNext() )
{
IEnergyGridProvider what = i.next();
Set<IEnergyGrid> listCopy = new HashSet<IEnergyGrid>();
@@ -277,275 +342,36 @@ public class EnergyGridCache implements IEnergyGrid
}
@Override
public double extractAEPower(double amt, Actionable mode, PowerMultiplier pm)
public double getEnergyDemand( double maxRequired, Set<IEnergyGrid> seen )
{
this.localSeen.clear();
return pm.divide( this.extractAEPower( pm.multiply( amt ), mode, this.localSeen ) );
}
@Override
public void addNode(IGridNode node, IGridHost machine)
{
if ( machine instanceof IEnergyGridProvider )
this.energyGridProviders.add( (IEnergyGridProvider) machine );
// idle draw...
GridNode gridNode = (GridNode) node;
IGridBlock gb = gridNode.getGridBlock();
gridNode.previousDraw = gb.getIdlePowerUsage();
this.drainPerTick += gridNode.previousDraw;
// power storage
if ( machine instanceof IAEPowerStorage )
{
IAEPowerStorage ps = (IAEPowerStorage) machine;
if ( ps.isAEPublicPowerStorage() )
{
double max = ps.getAEMaxPower();
double current = ps.getAECurrentPower();
if ( ps.getPowerFlow() != AccessRestriction.WRITE )
{
this.globalMaxPower += ps.getAEMaxPower();
}
if ( current > 0 && ps.getPowerFlow() != AccessRestriction.WRITE )
{
this.globalAvailablePower += current;
this.providers.add( ps );
}
if ( current < max && ps.getPowerFlow() != AccessRestriction.READ )
this.requesters.add( ps );
}
}
if ( machine instanceof IEnergyWatcherHost )
{
IEnergyWatcherHost swh = (IEnergyWatcherHost) machine;
EnergyWatcher iw = new EnergyWatcher( this, swh );
this.watchers.put( node, iw );
swh.updateWatcher( iw );
}
this.myGrid.postEventTo( node, new MENetworkPowerStatusChange() );
}
@Override
public void removeNode(IGridNode node, IGridHost machine)
{
if ( machine instanceof IEnergyGridProvider )
this.energyGridProviders.remove( machine );
// idle draw.
GridNode gridNode = (GridNode) node;
this.drainPerTick -= gridNode.previousDraw;
// power storage.
if ( machine instanceof IAEPowerStorage )
{
IAEPowerStorage ps = (IAEPowerStorage) machine;
if ( ps.isAEPublicPowerStorage() )
{
if ( ps.getPowerFlow() != AccessRestriction.WRITE )
{
this.globalMaxPower -= ps.getAEMaxPower();
this.globalAvailablePower -= ps.getAECurrentPower();
}
if ( this.lastProvider == machine )
this.lastProvider = null;
if ( this.lastRequester == machine )
this.lastRequester = null;
this.providers.remove( machine );
this.requesters.remove( machine );
}
}
if ( machine instanceof IStackWatcherHost )
{
IEnergyWatcher myWatcher = this.watchers.get( machine );
if ( myWatcher != null )
{
myWatcher.clear();
this.watchers.remove( machine );
}
}
}
double lastStoredPower = -1;
@Override
public void onUpdateTick()
{
if ( !this.interests.isEmpty() )
{
double oldPower = this.lastStoredPower;
this.lastStoredPower = this.getStoredPower();
EnergyThreshold low = new EnergyThreshold( Math.min( oldPower, this.lastStoredPower ), null );
EnergyThreshold high = new EnergyThreshold( Math.max( oldPower, this.lastStoredPower ), null );
for (EnergyThreshold th : this.interests.subSet( low, true, high, true ))
{
((EnergyWatcher) th.watcher).post( this );
}
}
this.avgDrainPerTick *= (this.AvgLength - 1) / this.AvgLength;
this.avgInjectionPerTick *= (this.AvgLength - 1) / this.AvgLength;
this.avgDrainPerTick += this.tickDrainPerTick / this.AvgLength;
this.avgInjectionPerTick += this.tickInjectionPerTick / this.AvgLength;
this.tickDrainPerTick = 0;
this.tickInjectionPerTick = 0;
// power information.
boolean currentlyHasPower = false;
if ( this.drainPerTick > 0.0001 )
{
double drained = this.extractAEPower( this.getIdlePowerUsage(), Actionable.MODULATE, PowerMultiplier.CONFIG );
currentlyHasPower = drained >= this.drainPerTick - 0.001;
}
else
{
currentlyHasPower = this.extractAEPower( 0.1, Actionable.SIMULATE, PowerMultiplier.CONFIG ) > 0;
}
// ticks since change..
if ( currentlyHasPower == this.hasPower )
this.ticksSinceHasPowerChange++;
else
this.ticksSinceHasPowerChange = 0;
// update status..
this.hasPower = currentlyHasPower;
// update public status, this buffers power ups for 30 ticks.
if ( this.hasPower && this.ticksSinceHasPowerChange > 30 )
this.publicPowerState( true, this.myGrid );
else if ( !this.hasPower )
this.publicPowerState( false, this.myGrid );
this.availableTicksSinceUpdate++;
}
private void publicPowerState(boolean newState, IGrid grid)
{
if ( this.publicHasPower == newState )
return;
this.publicHasPower = newState;
((Grid) this.myGrid).setImportantFlag( 0, this.publicHasPower );
grid.postEvent( new MENetworkPowerStatusChange() );
}
/**
* refresh current stored power.
*/
public void refreshPower()
{
this.availableTicksSinceUpdate = 0;
this.globalAvailablePower = 0;
for (IAEPowerStorage p : this.providers)
this.globalAvailablePower += p.getAECurrentPower();
}
@Override
public double getStoredPower()
{
if ( this.availableTicksSinceUpdate > 90 )
this.refreshPower();
return Math.max( 0.0, this.globalAvailablePower );
}
@Override
public double getMaxStoredPower()
{
return this.globalMaxPower;
}
@Override
public double extractAEPower(double amt, Actionable mode, Set<IEnergyGrid> seen)
{
if ( !seen.add( this ) )
if( !seen.add( this ) )
return 0;
double extractedPower = this.extra;
double required = this.buffer() - this.extra;
if ( mode == Actionable.SIMULATE )
Iterator<IAEPowerStorage> it = this.requesters.iterator();
while( required < maxRequired && it.hasNext() )
{
extractedPower += this.simulateExtract( extractedPower, amt );
if ( extractedPower < amt )
{
Iterator<IEnergyGridProvider> i = this.energyGridProviders.iterator();
while (extractedPower < amt && i.hasNext())
extractedPower += i.next().extractAEPower( amt - extractedPower, mode, seen );
}
return extractedPower;
}
else
{
this.extra = 0;
extractedPower = this.doExtract( extractedPower, amt );
IAEPowerStorage node = it.next();
if( node.getPowerFlow() != AccessRestriction.READ )
required += Math.max( 0.0, node.getAEMaxPower() - node.getAECurrentPower() );
}
// got more then we wanted?
if ( extractedPower > amt )
Iterator<IEnergyGridProvider> ix = this.energyGridProviders.iterator();
while( required < maxRequired && ix.hasNext() )
{
this.extra = extractedPower - amt;
this.globalAvailablePower -= amt;
this.tickDrainPerTick += amt;
return amt;
IEnergyGridProvider node = ix.next();
required += node.getEnergyDemand( maxRequired - required, seen );
}
if ( extractedPower < amt )
{
Iterator<IEnergyGridProvider> i = this.energyGridProviders.iterator();
while (extractedPower < amt && i.hasNext())
extractedPower += i.next().extractAEPower( amt - extractedPower, mode, seen );
}
// go less or the correct amount?
this.globalAvailablePower -= extractedPower;
this.tickDrainPerTick += extractedPower;
return extractedPower;
return required;
}
private double doExtract(double extractedPower, double amt)
{
while (extractedPower < amt && !this.providers.isEmpty())
{
IAEPowerStorage node = this.getFirstProvider();
double req = amt - extractedPower;
double newPower = node.extractAEPower( req, Actionable.MODULATE, PowerMultiplier.ONE );
extractedPower += newPower;
if ( newPower < req )
{
this.providers.remove( node );
this.lastProvider = null;
}
}
// totalDrainPastTicks[0] += extractedPower;
return extractedPower;
}
private double simulateExtract(double extractedPower, double amt)
private double simulateExtract( double extractedPower, double amt )
{
Iterator<IAEPowerStorage> it = this.providers.iterator();
while (extractedPower < amt && it.hasNext())
while( extractedPower < amt && it.hasNext() )
{
IAEPowerStorage node = it.next();
@@ -557,16 +383,36 @@ public class EnergyGridCache implements IEnergyGrid
return extractedPower;
}
@Override
public boolean isNetworkPowered()
private double doExtract( double extractedPower, double amt )
{
return this.publicHasPower;
while( extractedPower < amt && !this.providers.isEmpty() )
{
IAEPowerStorage node = this.getFirstProvider();
double req = amt - extractedPower;
double newPower = node.extractAEPower( req, Actionable.MODULATE, PowerMultiplier.ONE );
extractedPower += newPower;
if( newPower < req )
{
this.providers.remove( node );
this.lastProvider = null;
}
}
// totalDrainPastTicks[0] += extractedPower;
return extractedPower;
}
@Override
public double getIdlePowerUsage()
private IAEPowerStorage getFirstProvider()
{
return this.drainPerTick + this.pgc.channelPowerUsage;
if( this.lastProvider == null )
{
Iterator<IAEPowerStorage> i = this.providers.iterator();
this.lastProvider = i.hasNext() ? i.next() : null;
}
return this.lastProvider;
}
@Override
@@ -582,22 +428,164 @@ public class EnergyGridCache implements IEnergyGrid
}
@Override
public void onSplit(IGridStorage storageB)
public boolean isNetworkPowered()
{
return this.publicHasPower;
}
@Override
public double injectPower( double amt, Actionable mode )
{
this.localSeen.clear();
return this.injectAEPower( amt, mode, this.localSeen );
}
private IAEPowerStorage getFirstRequester()
{
if( this.lastRequester == null )
{
Iterator<IAEPowerStorage> i = this.requesters.iterator();
this.lastRequester = i.hasNext() ? i.next() : null;
}
return this.lastRequester;
}
private double buffer()
{
return this.providers.isEmpty() ? 1000.0 : 0.0;
}
@Override
public double getStoredPower()
{
if( this.availableTicksSinceUpdate > 90 )
this.refreshPower();
return Math.max( 0.0, this.globalAvailablePower );
}
@Override
public double getMaxStoredPower()
{
return this.globalMaxPower;
}
@Override
public double getEnergyDemand( double maxRequired )
{
this.localSeen.clear();
return this.getEnergyDemand( maxRequired, this.localSeen );
}
@Override
public void removeNode( IGridNode node, IGridHost machine )
{
if( machine instanceof IEnergyGridProvider )
this.energyGridProviders.remove( machine );
// idle draw.
GridNode gridNode = (GridNode) node;
this.drainPerTick -= gridNode.previousDraw;
// power storage.
if( machine instanceof IAEPowerStorage )
{
IAEPowerStorage ps = (IAEPowerStorage) machine;
if( ps.isAEPublicPowerStorage() )
{
if( ps.getPowerFlow() != AccessRestriction.WRITE )
{
this.globalMaxPower -= ps.getAEMaxPower();
this.globalAvailablePower -= ps.getAECurrentPower();
}
if( this.lastProvider == machine )
this.lastProvider = null;
if( this.lastRequester == machine )
this.lastRequester = null;
this.providers.remove( machine );
this.requesters.remove( machine );
}
}
if( machine instanceof IStackWatcherHost )
{
IEnergyWatcher myWatcher = this.watchers.get( machine );
if( myWatcher != null )
{
myWatcher.clear();
this.watchers.remove( machine );
}
}
}
@Override
public void addNode( IGridNode node, IGridHost machine )
{
if( machine instanceof IEnergyGridProvider )
this.energyGridProviders.add( (IEnergyGridProvider) machine );
// idle draw...
GridNode gridNode = (GridNode) node;
IGridBlock gb = gridNode.getGridBlock();
gridNode.previousDraw = gb.getIdlePowerUsage();
this.drainPerTick += gridNode.previousDraw;
// power storage
if( machine instanceof IAEPowerStorage )
{
IAEPowerStorage ps = (IAEPowerStorage) machine;
if( ps.isAEPublicPowerStorage() )
{
double max = ps.getAEMaxPower();
double current = ps.getAECurrentPower();
if( ps.getPowerFlow() != AccessRestriction.WRITE )
{
this.globalMaxPower += ps.getAEMaxPower();
}
if( current > 0 && ps.getPowerFlow() != AccessRestriction.WRITE )
{
this.globalAvailablePower += current;
this.providers.add( ps );
}
if( current < max && ps.getPowerFlow() != AccessRestriction.READ )
this.requesters.add( ps );
}
}
if( machine instanceof IEnergyWatcherHost )
{
IEnergyWatcherHost swh = (IEnergyWatcherHost) machine;
EnergyWatcher iw = new EnergyWatcher( this, swh );
this.watchers.put( node, iw );
swh.updateWatcher( iw );
}
this.myGrid.postEventTo( node, new MENetworkPowerStatusChange() );
}
@Override
public void onSplit( IGridStorage storageB )
{
this.extra /= 2;
storageB.dataObject().setDouble( "extraEnergy", this.extra );
}
@Override
public void onJoin(IGridStorage storageB)
public void onJoin( IGridStorage storageB )
{
this.extra += storageB.dataObject().getDouble( "extraEnergy" );
}
@Override
public void populateGridStorage(IGridStorage storage)
public void populateGridStorage( IGridStorage storage )
{
storage.dataObject().setDouble( "extraEnergy", this.extra );
}
}
+162 -163
View File
@@ -18,6 +18,7 @@
package appeng.me.cache;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@@ -53,25 +54,23 @@ import appeng.me.helpers.GenericInterestManager;
import appeng.me.storage.ItemWatcher;
import appeng.me.storage.NetworkInventoryHandler;
public class GridStorageCache implements IStorageGrid
{
final private SetMultimap<IAEStack, ItemWatcher> interests = HashMultimap.create();
final public GenericInterestManager<ItemWatcher> interestManager = new GenericInterestManager<ItemWatcher>( this.interests );
final public IGrid myGrid;
final HashSet<ICellProvider> activeCellProviders = new HashSet<ICellProvider>();
final HashSet<ICellProvider> inactiveCellProviders = new HashSet<ICellProvider>();
final public IGrid myGrid;
private NetworkInventoryHandler<IAEItemStack> myItemNetwork;
final private SetMultimap<IAEStack, ItemWatcher> interests = HashMultimap.create();
final public GenericInterestManager<ItemWatcher> interestManager = new GenericInterestManager<ItemWatcher>( this.interests );
private final NetworkMonitor<IAEItemStack> itemMonitor = new NetworkMonitor<IAEItemStack>( this, StorageChannel.ITEMS );
private NetworkInventoryHandler<IAEFluidStack> myFluidNetwork;
private final NetworkMonitor<IAEFluidStack> fluidMonitor = new NetworkMonitor<IAEFluidStack>( this, StorageChannel.FLUIDS );
private final HashMap<IGridNode, IStackWatcher> watchers = new HashMap<IGridNode, IStackWatcher>();
private NetworkInventoryHandler<IAEItemStack> myItemNetwork;
private NetworkInventoryHandler<IAEFluidStack> myFluidNetwork;
public GridStorageCache(IGrid g) {
public GridStorageCache( IGrid g )
{
this.myGrid = g;
}
@@ -82,82 +81,86 @@ public class GridStorageCache implements IStorageGrid
this.fluidMonitor.onTick();
}
private class CellChangeTrackerRecord
@Override
public void removeNode( IGridNode node, IGridHost machine )
{
if( machine instanceof ICellContainer )
{
ICellContainer cc = (ICellContainer) machine;
final StorageChannel channel;
final int up_or_down;
final IItemList list;
final BaseActionSource src;
public CellChangeTrackerRecord(StorageChannel channel, int i, IMEInventoryHandler<? extends IAEStack> h, BaseActionSource actionSrc) {
this.channel = channel;
this.up_or_down = i;
this.src = actionSrc;
if ( channel == StorageChannel.ITEMS )
this.list = ((IMEInventoryHandler<IAEItemStack>) h).getAvailableItems( AEApi.instance().storage().createItemList() );
else if ( channel == StorageChannel.FLUIDS )
this.list = ((IMEInventoryHandler<IAEFluidStack>) h).getAvailableItems( AEApi.instance().storage().createFluidList() );
else
this.list = null;
this.myGrid.postEvent( new MENetworkCellArrayUpdate() );
this.removeCellProvider( cc, new CellChangeTracker() ).applyChanges();
this.inactiveCellProviders.remove( cc );
}
public void applyChanges()
if( machine instanceof IStackWatcherHost )
{
GridStorageCache.this.postChangesToNetwork( this.channel, this.up_or_down, this.list, this.src );
}
}
private class CellChangeTracker
{
final List<CellChangeTrackerRecord> data = new LinkedList<CellChangeTrackerRecord>();
public void postChanges(StorageChannel channel, int i, IMEInventoryHandler<? extends IAEStack> h, BaseActionSource actionSrc)
{
this.data.add( new CellChangeTrackerRecord( channel, i, h, actionSrc ) );
}
public void applyChanges()
{
for (CellChangeTrackerRecord rec : this.data)
rec.applyChanges();
IStackWatcher myWatcher = this.watchers.get( machine );
if( myWatcher != null )
{
myWatcher.clear();
this.watchers.remove( machine );
}
}
}
@Override
public void registerCellProvider(ICellProvider provider)
public void addNode( IGridNode node, IGridHost machine )
{
this.inactiveCellProviders.add( provider );
this.addCellProvider( provider, new CellChangeTracker() ).applyChanges();
if( machine instanceof ICellContainer )
{
ICellContainer cc = (ICellContainer) machine;
this.inactiveCellProviders.add( cc );
this.myGrid.postEvent( new MENetworkCellArrayUpdate() );
if( node.isActive() )
this.addCellProvider( cc, new CellChangeTracker() ).applyChanges();
}
if( machine instanceof IStackWatcherHost )
{
IStackWatcherHost swh = (IStackWatcherHost) machine;
ItemWatcher iw = new ItemWatcher( this, swh );
this.watchers.put( node, iw );
swh.updateWatcher( iw );
}
}
@Override
public void unregisterCellProvider(ICellProvider provider)
public void onSplit( IGridStorage storageB )
{
this.removeCellProvider( provider, new CellChangeTracker() ).applyChanges();
this.inactiveCellProviders.remove( provider );
}
public CellChangeTracker addCellProvider(ICellProvider cc, CellChangeTracker tracker)
@Override
public void onJoin( IGridStorage storageB )
{
if ( this.inactiveCellProviders.contains( cc ) )
}
@Override
public void populateGridStorage( IGridStorage storage )
{
}
public CellChangeTracker addCellProvider( ICellProvider cc, CellChangeTracker tracker )
{
if( this.inactiveCellProviders.contains( cc ) )
{
this.inactiveCellProviders.remove( cc );
this.activeCellProviders.add( cc );
BaseActionSource actionSrc = new BaseActionSource();
if ( cc instanceof IActionHost )
if( cc instanceof IActionHost )
actionSrc = new MachineSource( (IActionHost) cc );
for (IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( StorageChannel.ITEMS ))
for( IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( StorageChannel.ITEMS ) )
{
tracker.postChanges( StorageChannel.ITEMS, 1, h, actionSrc );
}
for (IMEInventoryHandler<IAEFluidStack> h : cc.getCellArray( StorageChannel.FLUIDS ))
for( IMEInventoryHandler<IAEFluidStack> h : cc.getCellArray( StorageChannel.FLUIDS ) )
{
tracker.postChanges( StorageChannel.FLUIDS, 1, h, actionSrc );
}
@@ -166,23 +169,23 @@ public class GridStorageCache implements IStorageGrid
return tracker;
}
public CellChangeTracker removeCellProvider(ICellProvider cc, CellChangeTracker tracker)
public CellChangeTracker removeCellProvider( ICellProvider cc, CellChangeTracker tracker )
{
if ( this.activeCellProviders.contains( cc ) )
if( this.activeCellProviders.contains( cc ) )
{
this.inactiveCellProviders.add( cc );
this.activeCellProviders.remove( cc );
BaseActionSource actionSrc = new BaseActionSource();
if ( cc instanceof IActionHost )
if( cc instanceof IActionHost )
actionSrc = new MachineSource( (IActionHost) cc );
for (IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( StorageChannel.ITEMS ))
for( IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( StorageChannel.ITEMS ) )
{
tracker.postChanges( StorageChannel.ITEMS, -1, h, actionSrc );
}
for (IMEInventoryHandler<IAEFluidStack> h : cc.getCellArray( StorageChannel.FLUIDS ))
for( IMEInventoryHandler<IAEFluidStack> h : cc.getCellArray( StorageChannel.FLUIDS ) )
{
tracker.postChanges( StorageChannel.FLUIDS, -1, h, actionSrc );
}
@@ -192,7 +195,7 @@ public class GridStorageCache implements IStorageGrid
}
@MENetworkEventSubscribe
public void cellUpdate(MENetworkCellArrayUpdate ev)
public void cellUpdate( MENetworkCellArrayUpdate ev )
{
this.myItemNetwork = null;
this.myFluidNetwork = null;
@@ -203,20 +206,20 @@ public class GridStorageCache implements IStorageGrid
CellChangeTracker tracker = new CellChangeTracker();
for (ICellProvider cc : ll)
for( ICellProvider cc : ll )
{
boolean Active = true;
if ( cc instanceof IActionHost )
if( cc instanceof IActionHost )
{
IGridNode node = ((IActionHost) cc).getActionableNode();
if ( node != null && node.isActive() )
IGridNode node = ( (IActionHost) cc ).getActionableNode();
if( node != null && node.isActive() )
Active = true;
else
Active = false;
}
if ( Active )
if( Active )
this.addCellProvider( cc, tracker );
else
this.removeCellProvider( cc, tracker );
@@ -228,118 +231,81 @@ public class GridStorageCache implements IStorageGrid
tracker.applyChanges();
}
@Override
public void removeNode(IGridNode node, IGridHost machine)
private void postChangesToNetwork( StorageChannel chan, int up_or_down, IItemList availableItems, BaseActionSource src )
{
if ( machine instanceof ICellContainer )
switch( chan )
{
ICellContainer cc = (ICellContainer) machine;
this.myGrid.postEvent( new MENetworkCellArrayUpdate() );
this.removeCellProvider( cc, new CellChangeTracker() ).applyChanges();
this.inactiveCellProviders.remove( cc );
}
if ( machine instanceof IStackWatcherHost )
{
IStackWatcher myWatcher = this.watchers.get( machine );
if ( myWatcher != null )
{
myWatcher.clear();
this.watchers.remove( machine );
}
}
}
@Override
public void addNode(IGridNode node, IGridHost machine)
{
if ( machine instanceof ICellContainer )
{
ICellContainer cc = (ICellContainer) machine;
this.inactiveCellProviders.add( cc );
this.myGrid.postEvent( new MENetworkCellArrayUpdate() );
if ( node.isActive() )
this.addCellProvider( cc, new CellChangeTracker() ).applyChanges();
}
if ( machine instanceof IStackWatcherHost )
{
IStackWatcherHost swh = (IStackWatcherHost) machine;
ItemWatcher iw = new ItemWatcher( this, swh );
this.watchers.put( node, iw );
swh.updateWatcher( iw );
}
}
private void buildNetworkStorage(StorageChannel chan)
{
SecurityCache security = this.myGrid.getCache( ISecurityGrid.class );
switch (chan)
{
case FLUIDS:
this.myFluidNetwork = new NetworkInventoryHandler<IAEFluidStack>( StorageChannel.FLUIDS, security );
for (ICellProvider cc : this.activeCellProviders)
{
for (IMEInventoryHandler<IAEFluidStack> h : cc.getCellArray( chan ))
this.myFluidNetwork.addNewStorage( h );
}
break;
case ITEMS:
this.myItemNetwork = new NetworkInventoryHandler<IAEItemStack>( StorageChannel.ITEMS, security );
for (ICellProvider cc : this.activeCellProviders)
{
for (IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( chan ))
this.myItemNetwork.addNewStorage( h );
}
break;
default:
}
}
private void postChangesToNetwork(StorageChannel chan, int up_or_down, IItemList availableItems, BaseActionSource src)
{
switch (chan)
{
case FLUIDS:
this.fluidMonitor.postChange( up_or_down > 0, availableItems, src );
break;
case ITEMS:
this.itemMonitor.postChange( up_or_down > 0, availableItems, src );
break;
default:
case FLUIDS:
this.fluidMonitor.postChange( up_or_down > 0, availableItems, src );
break;
case ITEMS:
this.itemMonitor.postChange( up_or_down > 0, availableItems, src );
break;
default:
}
}
public IMEInventoryHandler<IAEItemStack> getItemInventoryHandler()
{
if ( this.myItemNetwork == null )
if( this.myItemNetwork == null )
this.buildNetworkStorage( StorageChannel.ITEMS );
return this.myItemNetwork;
}
private void buildNetworkStorage( StorageChannel chan )
{
SecurityCache security = this.myGrid.getCache( ISecurityGrid.class );
switch( chan )
{
case FLUIDS:
this.myFluidNetwork = new NetworkInventoryHandler<IAEFluidStack>( StorageChannel.FLUIDS, security );
for( ICellProvider cc : this.activeCellProviders )
{
for( IMEInventoryHandler<IAEFluidStack> h : cc.getCellArray( chan ) )
this.myFluidNetwork.addNewStorage( h );
}
break;
case ITEMS:
this.myItemNetwork = new NetworkInventoryHandler<IAEItemStack>( StorageChannel.ITEMS, security );
for( ICellProvider cc : this.activeCellProviders )
{
for( IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( chan ) )
this.myItemNetwork.addNewStorage( h );
}
break;
default:
}
}
public IMEInventoryHandler<IAEFluidStack> getFluidInventoryHandler()
{
if ( this.myFluidNetwork == null )
if( this.myFluidNetwork == null )
this.buildNetworkStorage( StorageChannel.FLUIDS );
return this.myFluidNetwork;
}
@Override
public void postAlterationOfStoredItems(StorageChannel chan, Iterable<? extends IAEStack> input, BaseActionSource src)
public void postAlterationOfStoredItems( StorageChannel chan, Iterable<? extends IAEStack> input, BaseActionSource src )
{
if ( chan == StorageChannel.ITEMS )
if( chan == StorageChannel.ITEMS )
this.itemMonitor.postChange( true, (Iterable<IAEItemStack>) input, src );
else if ( chan == StorageChannel.FLUIDS )
else if( chan == StorageChannel.FLUIDS )
this.fluidMonitor.postChange( true, (Iterable<IAEFluidStack>) input, src );
}
@Override
public IMEMonitor<IAEFluidStack> getFluidInventory()
public void registerCellProvider( ICellProvider provider )
{
return this.fluidMonitor;
this.inactiveCellProviders.add( provider );
this.addCellProvider( provider, new CellChangeTracker() ).applyChanges();
}
@Override
public void unregisterCellProvider( ICellProvider provider )
{
this.removeCellProvider( provider, new CellChangeTracker() ).applyChanges();
this.inactiveCellProviders.remove( provider );
}
@Override
@@ -349,21 +315,54 @@ public class GridStorageCache implements IStorageGrid
}
@Override
public void onSplit(IGridStorage storageB)
public IMEMonitor<IAEFluidStack> getFluidInventory()
{
return this.fluidMonitor;
}
@Override
public void onJoin(IGridStorage storageB)
private class CellChangeTrackerRecord
{
final StorageChannel channel;
final int up_or_down;
final IItemList list;
final BaseActionSource src;
public CellChangeTrackerRecord( StorageChannel channel, int i, IMEInventoryHandler<? extends IAEStack> h, BaseActionSource actionSrc )
{
this.channel = channel;
this.up_or_down = i;
this.src = actionSrc;
if( channel == StorageChannel.ITEMS )
this.list = ( (IMEInventoryHandler<IAEItemStack>) h ).getAvailableItems( AEApi.instance().storage().createItemList() );
else if( channel == StorageChannel.FLUIDS )
this.list = ( (IMEInventoryHandler<IAEFluidStack>) h ).getAvailableItems( AEApi.instance().storage().createFluidList() );
else
this.list = null;
}
public void applyChanges()
{
GridStorageCache.this.postChangesToNetwork( this.channel, this.up_or_down, this.list, this.src );
}
}
@Override
public void populateGridStorage(IGridStorage storage)
private class CellChangeTracker
{
}
final List<CellChangeTrackerRecord> data = new LinkedList<CellChangeTrackerRecord>();
public void postChanges( StorageChannel channel, int i, IMEInventoryHandler<? extends IAEStack> h, BaseActionSource actionSrc )
{
this.data.add( new CellChangeTrackerRecord( channel, i, h, actionSrc ) );
}
public void applyChanges()
{
for( CellChangeTrackerRecord rec : this.data )
rec.applyChanges();
}
}
}
+70 -70
View File
@@ -18,6 +18,7 @@
package appeng.me.cache;
import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
@@ -34,94 +35,42 @@ import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.me.storage.ItemWatcher;
public class NetworkMonitor<T extends IAEStack<T>> extends MEMonitorHandler<T>
{
private final static Deque<NetworkMonitor<?>> DEPTH = new LinkedList<NetworkMonitor<?>>();
final private GridStorageCache myGridCache;
final private StorageChannel myChannel;
boolean sendEvent = false;
public NetworkMonitor( GridStorageCache cache, StorageChannel chan )
{
super( null, chan );
this.myGridCache = cache;
this.myChannel = chan;
}
public void forceUpdate()
{
this.hasChanged = true;
Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
while (i.hasNext())
while( i.hasNext() )
{
Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
IMEMonitorHandlerReceiver<T> receiver = o.getKey();
if ( receiver.isValid( o.getValue() ) )
if( receiver.isValid( o.getValue() ) )
receiver.onListUpdate();
else
i.remove();
}
}
public NetworkMonitor(GridStorageCache cache, StorageChannel chan) {
super( null, chan );
this.myGridCache = cache;
this.myChannel = chan;
}
private final static Deque<NetworkMonitor<?>> DEPTH = new LinkedList<NetworkMonitor<?>>();
@Override
protected void postChangesToListeners(Iterable<T> changes, BaseActionSource src)
{
this.postChange( true, changes, src );
}
protected void postChange(boolean Add, Iterable<T> changes, BaseActionSource src)
{
if ( DEPTH.contains( this ) )
return;
DEPTH.push( this );
this.sendEvent = true;
this.notifyListenersOfChange( changes, src );
IItemList<T> myStorageList = this.getStorageList();
for (T changedItem : changes)
{
T difference = changedItem;
if ( !Add && changedItem != null )
(difference = changedItem.copy()).setStackSize( -changedItem.getStackSize() );
if ( this.myGridCache.interestManager.containsKey( changedItem ) )
{
Collection<ItemWatcher> list = this.myGridCache.interestManager.get( changedItem );
if ( !list.isEmpty() )
{
IAEStack fullStack = myStorageList.findPrecise( changedItem );
if ( fullStack == null )
{
fullStack = changedItem.copy();
fullStack.setStackSize( 0 );
}
this.myGridCache.interestManager.enableTransactions();
for (ItemWatcher iw : list)
iw.getHost().onStackChange( myStorageList, fullStack, difference, src, this.getChannel() );
this.myGridCache.interestManager.disableTransactions();
}
}
}
final NetworkMonitor<?> last = DEPTH.pop();
if ( last != this )
throw new RuntimeException( "Invalid Access to Networked Storage API detected." );
}
public void onTick()
{
if ( this.sendEvent )
if( this.sendEvent )
{
this.sendEvent = false;
this.myGridCache.myGrid.postEvent( new MENetworkStorageEvent( this, this.myChannel ) );
@@ -131,15 +80,66 @@ public class NetworkMonitor<T extends IAEStack<T>> extends MEMonitorHandler<T>
@Override
protected IMEInventoryHandler getHandler()
{
switch (this.myChannel)
switch( this.myChannel )
{
case ITEMS:
return this.myGridCache.getItemInventoryHandler();
case FLUIDS:
return this.myGridCache.getFluidInventoryHandler();
default:
case ITEMS:
return this.myGridCache.getItemInventoryHandler();
case FLUIDS:
return this.myGridCache.getFluidInventoryHandler();
default:
}
return null;
}
@Override
protected void postChangesToListeners( Iterable<T> changes, BaseActionSource src )
{
this.postChange( true, changes, src );
}
protected void postChange( boolean Add, Iterable<T> changes, BaseActionSource src )
{
if( DEPTH.contains( this ) )
return;
DEPTH.push( this );
this.sendEvent = true;
this.notifyListenersOfChange( changes, src );
IItemList<T> myStorageList = this.getStorageList();
for( T changedItem : changes )
{
T difference = changedItem;
if( !Add && changedItem != null )
( difference = changedItem.copy() ).setStackSize( -changedItem.getStackSize() );
if( this.myGridCache.interestManager.containsKey( changedItem ) )
{
Collection<ItemWatcher> list = this.myGridCache.interestManager.get( changedItem );
if( !list.isEmpty() )
{
IAEStack fullStack = myStorageList.findPrecise( changedItem );
if( fullStack == null )
{
fullStack = changedItem.copy();
fullStack.setStackSize( 0 );
}
this.myGridCache.interestManager.enableTransactions();
for( ItemWatcher iw : list )
iw.getHost().onStackChange( myStorageList, fullStack, difference, src, this.getChannel() );
this.myGridCache.interestManager.disableTransactions();
}
}
}
final NetworkMonitor<?> last = DEPTH.pop();
if( last != this )
throw new RuntimeException( "Invalid Access to Networked Storage API detected." );
}
}
+103 -102
View File
@@ -18,6 +18,7 @@
package appeng.me.cache;
import java.util.HashMap;
import com.google.common.collect.LinkedHashMultimap;
@@ -37,37 +38,38 @@ import appeng.me.cache.helpers.TunnelCollection;
import appeng.parts.p2p.PartP2PTunnel;
import appeng.parts.p2p.PartP2PTunnelME;
public class P2PCache implements IGridCache
{
final IGrid myGrid;
final private HashMap<Long, PartP2PTunnel> inputs = new HashMap<Long, PartP2PTunnel>();
final private Multimap<Long, PartP2PTunnel> outputs = LinkedHashMultimap.create();
final private TunnelCollection NullColl = new TunnelCollection<PartP2PTunnel>( null, null );
final IGrid myGrid;
public P2PCache(IGrid g) {
public P2PCache( IGrid g )
{
this.myGrid = g;
}
@MENetworkEventSubscribe
public void bootComplete(MENetworkBootingStatusChange bootStatus)
public void bootComplete( MENetworkBootingStatusChange bootStatus )
{
ITickManager tm = this.myGrid.getCache( ITickManager.class );
for (PartP2PTunnel me : this.inputs.values())
for( PartP2PTunnel me : this.inputs.values() )
{
if ( me instanceof PartP2PTunnelME )
if( me instanceof PartP2PTunnelME )
tm.wakeDevice( me.getGridNode() );
}
}
@MENetworkEventSubscribe
public void bootComplete(MENetworkPowerStatusChange power)
public void bootComplete( MENetworkPowerStatusChange power )
{
ITickManager tm = this.myGrid.getCache( ITickManager.class );
for (PartP2PTunnel me : this.inputs.values())
for( PartP2PTunnel me : this.inputs.values() )
{
if ( me instanceof PartP2PTunnelME )
if( me instanceof PartP2PTunnelME )
tm.wakeDevice( me.getGridNode() );
}
}
@@ -78,17 +80,101 @@ public class P2PCache implements IGridCache
}
public void updateFreq(PartP2PTunnel t, long NewFreq)
@Override
public void removeNode( IGridNode node, IGridHost machine )
{
if ( this.outputs.containsValue( t ) )
if( machine instanceof PartP2PTunnel )
{
if( machine instanceof PartP2PTunnelME )
{
if( !node.hasFlag( GridFlags.REQUIRE_CHANNEL ) )
return;
}
PartP2PTunnel t = (PartP2PTunnel) machine;
// AELog.info( "rmv-" + (t.output ? "output: " : "input: ") + t.freq
// );
if( t.output )
this.outputs.remove( t.freq, t );
else
this.inputs.remove( t.freq );
this.updateTunnel( t.freq, !t.output, false );
}
}
@Override
public void addNode( IGridNode node, IGridHost machine )
{
if( machine instanceof PartP2PTunnel )
{
if( machine instanceof PartP2PTunnelME )
{
if( !node.hasFlag( GridFlags.REQUIRE_CHANNEL ) )
return;
}
PartP2PTunnel t = (PartP2PTunnel) machine;
// AELog.info( "add-" + (t.output ? "output: " : "input: ") + t.freq
// );
if( t.output )
this.outputs.put( t.freq, t );
else
this.inputs.put( t.freq, t );
this.updateTunnel( t.freq, !t.output, false );
}
}
@Override
public void onSplit( IGridStorage storageB )
{
}
@Override
public void onJoin( IGridStorage storageB )
{
}
@Override
public void populateGridStorage( IGridStorage storage )
{
}
private void updateTunnel( long freq, boolean updateOutputs, boolean configChange )
{
for( PartP2PTunnel p : this.outputs.get( freq ) )
{
if( configChange )
p.onTunnelConfigChange();
p.onTunnelNetworkChange();
}
PartP2PTunnel in = this.inputs.get( freq );
if( in != null )
{
if( configChange )
in.onTunnelConfigChange();
in.onTunnelNetworkChange();
}
}
public void updateFreq( PartP2PTunnel t, long NewFreq )
{
if( this.outputs.containsValue( t ) )
this.outputs.remove( t.freq, t );
if ( this.inputs.containsValue( t ) )
if( this.inputs.containsValue( t ) )
this.inputs.remove( t.freq );
t.freq = NewFreq;
if ( t.output )
if( t.output )
this.outputs.put( t.freq, t );
else
this.inputs.put( t.freq, t );
@@ -99,106 +185,21 @@ public class P2PCache implements IGridCache
this.updateTunnel( t.freq, !t.output, true );
}
@Override
public void addNode(IGridNode node, IGridHost machine)
{
if ( machine instanceof PartP2PTunnel )
{
if ( machine instanceof PartP2PTunnelME )
{
if ( !node.hasFlag( GridFlags.REQUIRE_CHANNEL ) )
return;
}
PartP2PTunnel t = (PartP2PTunnel) machine;
// AELog.info( "add-" + (t.output ? "output: " : "input: ") + t.freq
// );
if ( t.output )
this.outputs.put( t.freq, t );
else
this.inputs.put( t.freq, t );
this.updateTunnel( t.freq, !t.output, false );
}
}
@Override
public void removeNode(IGridNode node, IGridHost machine)
{
if ( machine instanceof PartP2PTunnel )
{
if ( machine instanceof PartP2PTunnelME )
{
if ( !node.hasFlag( GridFlags.REQUIRE_CHANNEL ) )
return;
}
PartP2PTunnel t = (PartP2PTunnel) machine;
// AELog.info( "rmv-" + (t.output ? "output: " : "input: ") + t.freq
// );
if ( t.output )
this.outputs.remove( t.freq, t );
else
this.inputs.remove( t.freq );
this.updateTunnel( t.freq, !t.output, false );
}
}
private void updateTunnel(long freq, boolean updateOutputs, boolean configChange)
{
for (PartP2PTunnel p : this.outputs.get( freq ))
{
if ( configChange )
p.onTunnelConfigChange();
p.onTunnelNetworkChange();
}
PartP2PTunnel in = this.inputs.get( freq );
if ( in != null )
{
if ( configChange )
in.onTunnelConfigChange();
in.onTunnelNetworkChange();
}
}
public TunnelCollection<PartP2PTunnel> getOutputs(long freq, Class<? extends PartP2PTunnel> c)
public TunnelCollection<PartP2PTunnel> getOutputs( long freq, Class<? extends PartP2PTunnel> c )
{
PartP2PTunnel in = this.inputs.get( freq );
if ( in == null )
if( in == null )
return this.NullColl;
TunnelCollection<PartP2PTunnel> out = this.inputs.get( freq ).getCollection( this.outputs.get( freq ), c );
if ( out == null )
if( out == null )
return this.NullColl;
return out;
}
public PartP2PTunnel getInput(long freq)
public PartP2PTunnel getInput( long freq )
{
return this.inputs.get( freq );
}
@Override
public void onSplit(IGridStorage storageB)
{
}
@Override
public void onJoin(IGridStorage storageB)
{
}
@Override
public void populateGridStorage(IGridStorage storage)
{
}
}
+177 -183
View File
@@ -18,6 +18,7 @@
package appeng.me.cache;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Iterator;
@@ -55,34 +56,28 @@ import appeng.me.pathfinding.PathSegment;
import appeng.tile.networking.TileController;
import appeng.util.Platform;
public class PathGridCache implements IPathingGrid
{
boolean recalculateControllerNextTick = true;
boolean updateNetwork = true;
boolean booting = false;
final LinkedList<PathSegment> active = new LinkedList<PathSegment>();
ControllerState controllerState = ControllerState.NO_CONTROLLER;
int instance = Integer.MIN_VALUE;
int ticksUntilReady = 20;
public int channelsInUse = 0;
int lastChannels = 0;
final Set<TileController> controllers = new HashSet<TileController>();
final Set<IGridNode> requireChannels = new HashSet<IGridNode>();
final Set<IGridNode> blockDense = new HashSet<IGridNode>();
final IGrid myGrid;
private HashSet<IPathItem> semiOpen = new HashSet<IPathItem>();
public int channelsInUse = 0;
public int channelsByBlocks = 0;
public double channelPowerUsage = 0.0;
boolean recalculateControllerNextTick = true;
boolean updateNetwork = true;
boolean booting = false;
ControllerState controllerState = ControllerState.NO_CONTROLLER;
int instance = Integer.MIN_VALUE;
int ticksUntilReady = 20;
int lastChannels = 0;
private HashSet<IPathItem> semiOpen = new HashSet<IPathItem>();
public PathGridCache(IGrid g)
public PathGridCache( IGrid g )
{
this.myGrid = g;
}
@@ -90,14 +85,14 @@ public class PathGridCache implements IPathingGrid
@Override
public void onUpdateTick()
{
if ( this.recalculateControllerNextTick )
if( this.recalculateControllerNextTick )
{
this.recalcController();
}
if ( this.updateNetwork )
if( this.updateNetwork )
{
if ( !this.booting )
if( !this.booting )
this.myGrid.postEvent( new MENetworkBootingStatusChange() );
this.booting = true;
@@ -105,7 +100,7 @@ public class PathGridCache implements IPathingGrid
this.instance++;
this.channelsInUse = 0;
if ( !AEConfig.instance.isFeatureEnabled( AEFeature.Channels ) )
if( !AEConfig.instance.isFeatureEnabled( AEFeature.Channels ) )
{
int used = this.calculateRequiredChannels();
@@ -116,11 +111,11 @@ public class PathGridCache implements IPathingGrid
this.myGrid.getPivot().beginVisit( new AdHocChannelUpdater( used ) );
}
else if ( this.controllerState == ControllerState.NO_CONTROLLER )
else if( this.controllerState == ControllerState.NO_CONTROLLER )
{
int requiredChannels = this.calculateRequiredChannels();
int used = requiredChannels;
if ( requiredChannels > 8 )
if( requiredChannels > 8 )
used = 0;
int nodes = this.myGrid.getNodes().size();
@@ -132,7 +127,7 @@ public class PathGridCache implements IPathingGrid
this.myGrid.getPivot().beginVisit( new AdHocChannelUpdater( used ) );
}
else if ( this.controllerState == ControllerState.CONTROLLER_CONFLICT )
else if( this.controllerState == ControllerState.CONTROLLER_CONFLICT )
{
this.ticksUntilReady = 20;
this.myGrid.getPivot().beginVisit( new AdHocChannelUpdater( 0 ) );
@@ -146,13 +141,13 @@ public class PathGridCache implements IPathingGrid
// myGrid.getPivot().beginVisit( new AdHocChannelUpdater( 0 )
// );
for (IGridNode node : this.myGrid.getMachines( TileController.class ))
for( IGridNode node : this.myGrid.getMachines( TileController.class ) )
{
closedList.add( (IPathItem) node );
for (IGridConnection gcc : node.getConnections())
for( IGridConnection gcc : node.getConnections() )
{
GridConnection gc = (GridConnection) gcc;
if ( !(gc.getOtherSide( node ).getMachine() instanceof TileController) )
if( !( gc.getOtherSide( node ).getMachine() instanceof TileController ) )
{
List<IPathItem> open = new LinkedList<IPathItem>();
closedList.add( gc );
@@ -165,13 +160,13 @@ public class PathGridCache implements IPathingGrid
}
}
if ( !this.active.isEmpty() || this.ticksUntilReady > 0 )
if( !this.active.isEmpty() || this.ticksUntilReady > 0 )
{
Iterator<PathSegment> i = this.active.iterator();
while (i.hasNext())
while( i.hasNext() )
{
PathSegment pat = i.next();
if ( pat.step() )
if( pat.step() )
{
pat.isDead = true;
i.remove();
@@ -180,12 +175,12 @@ public class PathGridCache implements IPathingGrid
this.ticksUntilReady--;
if ( this.active.isEmpty() && this.ticksUntilReady <= 0 )
if( this.active.isEmpty() && this.ticksUntilReady <= 0 )
{
if ( this.controllerState == ControllerState.CONTROLLER_ONLINE )
if( this.controllerState == ControllerState.CONTROLLER_ONLINE )
{
final Iterator<TileController> controllerIterator = this.controllers.iterator();
if (controllerIterator.hasNext())
if( controllerIterator.hasNext() )
{
final TileController controller = controllerIterator.next();
controller.getGridNode( ForgeDirection.UNKNOWN ).beginVisit( new ControllerChannelUpdater() );
@@ -202,19 +197,142 @@ public class PathGridCache implements IPathingGrid
}
}
@Override
public void removeNode( IGridNode gridNode, IGridHost machine )
{
if( machine instanceof TileController )
{
this.controllers.remove( machine );
this.recalculateControllerNextTick = true;
}
EnumSet<GridFlags> flags = gridNode.getGridBlock().getFlags();
if( flags.contains( GridFlags.REQUIRE_CHANNEL ) )
this.requireChannels.remove( gridNode );
if( flags.contains( GridFlags.CANNOT_CARRY_COMPRESSED ) )
this.blockDense.remove( gridNode );
this.repath();
}
@Override
public void addNode( IGridNode gridNode, IGridHost machine )
{
if( machine instanceof TileController )
{
this.controllers.add( (TileController) machine );
this.recalculateControllerNextTick = true;
}
EnumSet<GridFlags> flags = gridNode.getGridBlock().getFlags();
if( flags.contains( GridFlags.REQUIRE_CHANNEL ) )
this.requireChannels.add( gridNode );
if( flags.contains( GridFlags.CANNOT_CARRY_COMPRESSED ) )
this.blockDense.add( gridNode );
this.repath();
}
@Override
public void onSplit( IGridStorage storageB )
{
}
@Override
public void onJoin( IGridStorage storageB )
{
}
@Override
public void populateGridStorage( IGridStorage storage )
{
}
private void recalcController()
{
this.recalculateControllerNextTick = false;
ControllerState old = this.controllerState;
if( this.controllers.isEmpty() )
{
this.controllerState = ControllerState.NO_CONTROLLER;
}
else
{
IGridNode startingNode = this.controllers.iterator().next().getGridNode( ForgeDirection.UNKNOWN );
if( startingNode == null )
{
this.controllerState = ControllerState.CONTROLLER_CONFLICT;
return;
}
DimensionalCoord dc = startingNode.getGridBlock().getLocation();
ControllerValidator cv = new ControllerValidator( dc.x, dc.y, dc.z );
startingNode.beginVisit( cv );
if( cv.isValid && cv.found == this.controllers.size() )
this.controllerState = ControllerState.CONTROLLER_ONLINE;
else
this.controllerState = ControllerState.CONTROLLER_CONFLICT;
}
if( old != this.controllerState )
{
this.myGrid.postEvent( new MENetworkControllerChange() );
}
}
private int calculateRequiredChannels()
{
int depth = 0;
this.semiOpen.clear();
for( IGridNode nodes : this.requireChannels )
{
if( !this.semiOpen.contains( nodes ) )
{
IGridBlock gb = nodes.getGridBlock();
EnumSet<GridFlags> flags = gb.getFlags();
if( flags.contains( GridFlags.COMPRESSED_CHANNEL ) && !this.blockDense.isEmpty() )
return 9;
depth++;
if( flags.contains( GridFlags.MULTIBLOCK ) )
{
IGridMultiblock gmb = (IGridMultiblock) gb;
Iterator<IGridNode> i = gmb.getMultiblockNodes();
while( i.hasNext() )
this.semiOpen.add( (IPathItem) i.next() );
}
}
}
return depth;
}
private void achievementPost()
{
if ( this.lastChannels != this.channelsInUse && AEConfig.instance.isFeatureEnabled( AEFeature.Channels ) )
if( this.lastChannels != this.channelsInUse && AEConfig.instance.isFeatureEnabled( AEFeature.Channels ) )
{
Achievements currentBracket = this.getAchievementBracket( this.channelsInUse );
Achievements lastBracket = this.getAchievementBracket( this.lastChannels );
if ( currentBracket != lastBracket && currentBracket != null )
if( currentBracket != lastBracket && currentBracket != null )
{
Set<Integer> players = new HashSet<Integer>();
for (IGridNode n : this.requireChannels)
for( IGridNode n : this.requireChannels )
players.add( n.getPlayerID() );
for (int id : players)
for( int id : players )
{
Platform.addStat( id, currentBracket.getAchievement() );
}
@@ -223,48 +341,43 @@ public class PathGridCache implements IPathingGrid
this.lastChannels = this.channelsInUse;
}
private Achievements getAchievementBracket(int ch)
private Achievements getAchievementBracket( int ch )
{
if ( ch < 8 )
if( ch < 8 )
return null;
if ( ch < 128 )
if( ch < 128 )
return Achievements.Networking1;
if ( ch < 2048 )
if( ch < 2048 )
return Achievements.Networking2;
return Achievements.Networking3;
}
private int calculateRequiredChannels()
@MENetworkEventSubscribe
void updateNodReq( MENetworkChannelChanged ev )
{
int depth = 0;
this.semiOpen.clear();
IGridNode gridNode = ev.node;
for (IGridNode nodes : this.requireChannels)
{
if ( !this.semiOpen.contains( nodes ) )
{
IGridBlock gb = nodes.getGridBlock();
EnumSet<GridFlags> flags = gb.getFlags();
if( gridNode.getGridBlock().getFlags().contains( GridFlags.REQUIRE_CHANNEL ) )
this.requireChannels.add( gridNode );
else
this.requireChannels.remove( gridNode );
if ( flags.contains( GridFlags.COMPRESSED_CHANNEL ) && !this.blockDense.isEmpty() )
return 9;
this.repath();
}
depth++;
@Override
public boolean isNetworkBooting()
{
return !this.active.isEmpty() && !this.booting;
}
if ( flags.contains( GridFlags.MULTIBLOCK ) )
{
IGridMultiblock gmb = (IGridMultiblock) gb;
Iterator<IGridNode> i = gmb.getMultiblockNodes();
while (i.hasNext())
this.semiOpen.add( (IPathItem) i.next() );
}
}
}
return depth;
@Override
public ControllerState getControllerState()
{
return this.controllerState;
}
@Override
@@ -276,123 +389,4 @@ public class PathGridCache implements IPathingGrid
this.channelsByBlocks = 0;
this.updateNetwork = true;
}
@Override
public void removeNode(IGridNode gridNode, IGridHost machine)
{
if ( machine instanceof TileController )
{
this.controllers.remove( machine );
this.recalculateControllerNextTick = true;
}
EnumSet<GridFlags> flags = gridNode.getGridBlock().getFlags();
if ( flags.contains( GridFlags.REQUIRE_CHANNEL ) )
this.requireChannels.remove( gridNode );
if ( flags.contains( GridFlags.CANNOT_CARRY_COMPRESSED ) )
this.blockDense.remove( gridNode );
this.repath();
}
@Override
public void addNode(IGridNode gridNode, IGridHost machine)
{
if ( machine instanceof TileController )
{
this.controllers.add( (TileController) machine );
this.recalculateControllerNextTick = true;
}
EnumSet<GridFlags> flags = gridNode.getGridBlock().getFlags();
if ( flags.contains( GridFlags.REQUIRE_CHANNEL ) )
this.requireChannels.add( gridNode );
if ( flags.contains( GridFlags.CANNOT_CARRY_COMPRESSED ) )
this.blockDense.add( gridNode );
this.repath();
}
@MENetworkEventSubscribe
void updateNodReq(MENetworkChannelChanged ev)
{
IGridNode gridNode = ev.node;
if ( gridNode.getGridBlock().getFlags().contains( GridFlags.REQUIRE_CHANNEL ) )
this.requireChannels.add( gridNode );
else
this.requireChannels.remove( gridNode );
this.repath();
}
private void recalcController()
{
this.recalculateControllerNextTick = false;
ControllerState old = this.controllerState;
if ( this.controllers.isEmpty() )
{
this.controllerState = ControllerState.NO_CONTROLLER;
}
else
{
IGridNode startingNode = this.controllers.iterator().next().getGridNode( ForgeDirection.UNKNOWN );
if ( startingNode == null )
{
this.controllerState = ControllerState.CONTROLLER_CONFLICT;
return;
}
DimensionalCoord dc = startingNode.getGridBlock().getLocation();
ControllerValidator cv = new ControllerValidator( dc.x, dc.y, dc.z );
startingNode.beginVisit( cv );
if ( cv.isValid && cv.found == this.controllers.size() )
this.controllerState = ControllerState.CONTROLLER_ONLINE;
else
this.controllerState = ControllerState.CONTROLLER_CONFLICT;
}
if ( old != this.controllerState )
{
this.myGrid.postEvent( new MENetworkControllerChange() );
}
}
@Override
public ControllerState getControllerState()
{
return this.controllerState;
}
@Override
public boolean isNetworkBooting()
{
return !this.active.isEmpty() && !this.booting;
}
@Override
public void onSplit(IGridStorage storageB)
{
}
@Override
public void onJoin(IGridStorage storageB)
{
}
@Override
public void populateGridStorage(IGridStorage storage)
{
}
}
+77 -76
View File
@@ -18,6 +18,7 @@
package appeng.me.cache;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
@@ -37,24 +38,25 @@ import appeng.api.networking.security.ISecurityProvider;
import appeng.core.WorldSettings;
import appeng.me.GridNode;
public class SecurityCache implements ISecurityGrid
{
public final IGrid myGrid;
final private List<ISecurityProvider> securityProvider = new ArrayList<ISecurityProvider>();
final private HashMap<Integer, EnumSet<SecurityPermissions>> playerPerms = new HashMap<Integer, EnumSet<SecurityPermissions>>();
private long securityKey = -1;
public SecurityCache(IGrid g) {
public SecurityCache( IGrid g )
{
this.myGrid = g;
}
private long securityKey = -1;
public final IGrid myGrid;
@MENetworkEventSubscribe
public void updatePermissions(MENetworkSecurityChange ev)
public void updatePermissions( MENetworkSecurityChange ev )
{
this.playerPerms.clear();
if ( this.securityProvider.isEmpty() )
if( this.securityProvider.isEmpty() )
return;
this.securityProvider.get( 0 ).readPermissions( this.playerPerms );
@@ -66,27 +68,90 @@ public class SecurityCache implements ISecurityGrid
}
@Override
public void onUpdateTick()
{
}
@Override
public void removeNode( IGridNode gridNode, IGridHost machine )
{
if( machine instanceof ISecurityProvider )
{
this.securityProvider.remove( machine );
this.updateSecurityKey();
}
}
private void updateSecurityKey()
{
long lastCode = this.securityKey;
if( this.securityProvider.size() == 1 )
this.securityKey = this.securityProvider.get( 0 ).getSecurityKey();
else
this.securityKey = -1;
if( lastCode != this.securityKey )
{
this.myGrid.postEvent( new MENetworkSecurityChange() );
for( IGridNode n : this.myGrid.getNodes() )
( (GridNode) n ).lastSecurityKey = this.securityKey;
}
}
@Override
public void addNode( IGridNode gridNode, IGridHost machine )
{
if( machine instanceof ISecurityProvider )
{
this.securityProvider.add( (ISecurityProvider) machine );
this.updateSecurityKey();
}
else
( (GridNode) gridNode ).lastSecurityKey = this.securityKey;
}
@Override
public void onSplit( IGridStorage destinationStorage )
{
}
@Override
public void onJoin( IGridStorage sourceStorage )
{
}
@Override
public void populateGridStorage( IGridStorage destinationStorage )
{
} @Override
public boolean isAvailable()
{
return this.securityProvider.size() == 1 && this.securityProvider.get( 0 ).isSecurityEnabled();
}
@Override
public boolean hasPermission(EntityPlayer player, SecurityPermissions perm)
public boolean hasPermission( EntityPlayer player, SecurityPermissions perm )
{
return this.hasPermission( player == null ? -1 : WorldSettings.getInstance().getPlayerID( player.getGameProfile() ), perm );
}
@Override
public boolean hasPermission(int playerID, SecurityPermissions perm)
public boolean hasPermission( int playerID, SecurityPermissions perm )
{
if ( this.isAvailable() )
if( this.isAvailable() )
{
EnumSet<SecurityPermissions> perms = this.playerPerms.get( playerID );
if ( perms == null )
if( perms == null )
{
if ( playerID == -1 ) // no default?
if( playerID == -1 ) // no default?
return false;
else
return this.hasPermission( -1, perm );
@@ -97,75 +162,11 @@ public class SecurityCache implements ISecurityGrid
return true;
}
private void updateSecurityKey()
{
long lastCode = this.securityKey;
if ( this.securityProvider.size() == 1 )
this.securityKey = this.securityProvider.get( 0 ).getSecurityKey();
else
this.securityKey = -1;
if ( lastCode != this.securityKey )
{
this.myGrid.postEvent( new MENetworkSecurityChange() );
for (IGridNode n : this.myGrid.getNodes())
((GridNode) n).lastSecurityKey = this.securityKey;
}
}
@Override
public void removeNode(IGridNode gridNode, IGridHost machine)
{
if ( machine instanceof ISecurityProvider )
{
this.securityProvider.remove( machine );
this.updateSecurityKey();
}
}
@Override
public void addNode(IGridNode gridNode, IGridHost machine)
{
if ( machine instanceof ISecurityProvider )
{
this.securityProvider.add( (ISecurityProvider) machine );
this.updateSecurityKey();
}
else
((GridNode) gridNode).lastSecurityKey = this.securityKey;
}
@Override
public void onUpdateTick()
{
}
@Override
public void onSplit(IGridStorage destinationStorage)
{
}
@Override
public void onJoin(IGridStorage sourceStorage)
{
}
@Override
public void populateGridStorage(IGridStorage destinationStorage)
{
}
@Override
public int getOwner()
{
if ( this.isAvailable() )
if( this.isAvailable() )
return this.securityProvider.get( 0 ).getOwner();
return -1;
}
}
+125 -130
View File
@@ -18,6 +18,7 @@
package appeng.me.cache;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -36,31 +37,138 @@ import appeng.me.cluster.implementations.SpatialPylonCluster;
import appeng.tile.spatial.TileSpatialIOPort;
import appeng.tile.spatial.TileSpatialPylon;
public class SpatialPylonCache implements ISpatialCache
{
final IGrid myGrid;
long powerRequired = 0;
double efficiency = 0.0;
DimensionalCoord captureMin;
DimensionalCoord captureMax;
boolean isValid = false;
List<TileSpatialIOPort> ioPorts = new LinkedList<TileSpatialIOPort>();
HashMap<SpatialPylonCluster, SpatialPylonCluster> clusters = new HashMap<SpatialPylonCluster, SpatialPylonCluster>();
boolean needsUpdate = false;
final IGrid myGrid;
public SpatialPylonCache(IGrid g) {
public SpatialPylonCache( IGrid g )
{
this.myGrid = g;
}
@Override
public long requiredPower()
@MENetworkEventSubscribe
public void bootingRender( MENetworkBootingStatusChange c )
{
return this.powerRequired;
this.reset( this.myGrid );
}
public void reset( IGrid grid )
{
int reqX = 0;
int reqY = 0;
int reqZ = 0;
int requirePylonBlocks = 1;
double minPower = 0;
double maxPower = 0;
this.clusters = new HashMap<SpatialPylonCluster, SpatialPylonCluster>();
this.ioPorts = new LinkedList<TileSpatialIOPort>();
for( IGridNode gm : grid.getMachines( TileSpatialIOPort.class ) )
{
this.ioPorts.add( (TileSpatialIOPort) gm.getMachine() );
}
IReadOnlyCollection<IGridNode> set = grid.getMachines( TileSpatialPylon.class );
for( IGridNode gm : set )
{
if( gm.meetsChannelRequirements() )
{
SpatialPylonCluster c = ( (TileSpatialPylon) gm.getMachine() ).getCluster();
if( c != null )
this.clusters.put( c, c );
}
}
this.captureMax = null;
this.captureMin = null;
this.isValid = true;
int pylonBlocks = 0;
for( SpatialPylonCluster cl : this.clusters.values() )
{
if( this.captureMax == null )
this.captureMax = cl.max.copy();
if( this.captureMin == null )
this.captureMin = cl.min.copy();
pylonBlocks += cl.tileCount();
this.captureMin.x = Math.min( this.captureMin.x, cl.min.x );
this.captureMin.y = Math.min( this.captureMin.y, cl.min.y );
this.captureMin.z = Math.min( this.captureMin.z, cl.min.z );
this.captureMax.x = Math.max( this.captureMax.x, cl.max.x );
this.captureMax.y = Math.max( this.captureMax.y, cl.max.y );
this.captureMax.z = Math.max( this.captureMax.z, cl.max.z );
}
if( this.hasRegion() )
{
this.isValid = this.captureMax.x - this.captureMin.x > 1 && this.captureMax.y - this.captureMin.y > 1 && this.captureMax.z - this.captureMin.z > 1;
for( SpatialPylonCluster cl : this.clusters.values() )
{
switch( cl.currentAxis )
{
case X:
this.isValid = this.isValid && ( ( this.captureMax.y == cl.min.y || this.captureMin.y == cl.max.y ) || ( this.captureMax.z == cl.min.z || this.captureMin.z == cl.max.z ) ) && ( ( this.captureMax.y == cl.max.y || this.captureMin.y == cl.min.y ) || ( this.captureMax.z == cl.max.z || this.captureMin.z == cl.min.z ) );
break;
case Y:
this.isValid = this.isValid && ( ( this.captureMax.x == cl.min.x || this.captureMin.x == cl.max.x ) || ( this.captureMax.z == cl.min.z || this.captureMin.z == cl.max.z ) ) && ( ( this.captureMax.x == cl.max.x || this.captureMin.x == cl.min.x ) || ( this.captureMax.z == cl.max.z || this.captureMin.z == cl.min.z ) );
break;
case Z:
this.isValid = this.isValid && ( ( this.captureMax.y == cl.min.y || this.captureMin.y == cl.max.y ) || ( this.captureMax.x == cl.min.x || this.captureMin.x == cl.max.x ) ) && ( ( this.captureMax.y == cl.max.y || this.captureMin.y == cl.min.y ) || ( this.captureMax.x == cl.max.x || this.captureMin.x == cl.min.x ) );
break;
case UNFORMED:
this.isValid = false;
break;
}
}
reqX = this.captureMax.x - this.captureMin.x;
reqY = this.captureMax.y - this.captureMin.y;
reqZ = this.captureMax.z - this.captureMin.z;
requirePylonBlocks = Math.max( 6, ( ( reqX * reqZ + reqX * reqY + reqY * reqZ ) * 3 ) / 8 );
this.efficiency = (double) pylonBlocks / (double) requirePylonBlocks;
if( this.efficiency > 1.0 )
this.efficiency = 1.0;
if( this.efficiency < 0.0 )
this.efficiency = 0.0;
minPower = (double) reqX * (double) reqY * reqZ * AEConfig.instance.spatialPowerMultiplier;
maxPower = Math.pow( minPower, AEConfig.instance.spatialPowerExponent );
}
double affective_efficiency = Math.pow( this.efficiency, 0.25 );
this.powerRequired = (long) ( affective_efficiency * minPower + ( 1.0 - affective_efficiency ) * maxPower );
for( SpatialPylonCluster cl : this.clusters.values() )
{
boolean myWasValid = cl.isValid;
cl.isValid = this.isValid;
if( myWasValid != this.isValid )
cl.updateStatus( false );
}
}
@Override
@@ -87,116 +195,10 @@ public class SpatialPylonCache implements ISpatialCache
return this.captureMax;
}
public void reset(IGrid grid)
@Override
public long requiredPower()
{
int reqX = 0;
int reqY = 0;
int reqZ = 0;
int requirePylonBlocks = 1;
double minPower = 0;
double maxPower = 0;
this.clusters = new HashMap<SpatialPylonCluster, SpatialPylonCluster>();
this.ioPorts = new LinkedList<TileSpatialIOPort>();
for (IGridNode gm : grid.getMachines( TileSpatialIOPort.class ))
{
this.ioPorts.add( (TileSpatialIOPort) gm.getMachine() );
}
IReadOnlyCollection<IGridNode> set = grid.getMachines( TileSpatialPylon.class );
for (IGridNode gm : set)
{
if ( gm.meetsChannelRequirements() )
{
SpatialPylonCluster c = ((TileSpatialPylon) gm.getMachine()).getCluster();
if ( c != null )
this.clusters.put( c, c );
}
}
this.captureMax = null;
this.captureMin = null;
this.isValid = true;
int pylonBlocks = 0;
for (SpatialPylonCluster cl : this.clusters.values())
{
if ( this.captureMax == null )
this.captureMax = cl.max.copy();
if ( this.captureMin == null )
this.captureMin = cl.min.copy();
pylonBlocks += cl.tileCount();
this.captureMin.x = Math.min( this.captureMin.x, cl.min.x );
this.captureMin.y = Math.min( this.captureMin.y, cl.min.y );
this.captureMin.z = Math.min( this.captureMin.z, cl.min.z );
this.captureMax.x = Math.max( this.captureMax.x, cl.max.x );
this.captureMax.y = Math.max( this.captureMax.y, cl.max.y );
this.captureMax.z = Math.max( this.captureMax.z, cl.max.z );
}
if ( this.hasRegion() )
{
this.isValid = this.captureMax.x - this.captureMin.x > 1 && this.captureMax.y - this.captureMin.y > 1 && this.captureMax.z - this.captureMin.z > 1;
for (SpatialPylonCluster cl : this.clusters.values())
{
switch (cl.currentAxis)
{
case X:
this.isValid = this.isValid && ((this.captureMax.y == cl.min.y || this.captureMin.y == cl.max.y) || (this.captureMax.z == cl.min.z || this.captureMin.z == cl.max.z))
&& ((this.captureMax.y == cl.max.y || this.captureMin.y == cl.min.y) || (this.captureMax.z == cl.max.z || this.captureMin.z == cl.min.z));
break;
case Y:
this.isValid = this.isValid && ((this.captureMax.x == cl.min.x || this.captureMin.x == cl.max.x) || (this.captureMax.z == cl.min.z || this.captureMin.z == cl.max.z))
&& ((this.captureMax.x == cl.max.x || this.captureMin.x == cl.min.x) || (this.captureMax.z == cl.max.z || this.captureMin.z == cl.min.z));
break;
case Z:
this.isValid = this.isValid && ((this.captureMax.y == cl.min.y || this.captureMin.y == cl.max.y) || (this.captureMax.x == cl.min.x || this.captureMin.x == cl.max.x))
&& ((this.captureMax.y == cl.max.y || this.captureMin.y == cl.min.y) || (this.captureMax.x == cl.max.x || this.captureMin.x == cl.min.x));
break;
case UNFORMED:
this.isValid = false;
break;
}
}
reqX = this.captureMax.x - this.captureMin.x;
reqY = this.captureMax.y - this.captureMin.y;
reqZ = this.captureMax.z - this.captureMin.z;
requirePylonBlocks = Math.max( 6, ((reqX * reqZ + reqX * reqY + reqY * reqZ) * 3) / 8 );
this.efficiency = (double) pylonBlocks / (double) requirePylonBlocks;
if ( this.efficiency > 1.0 )
this.efficiency = 1.0;
if ( this.efficiency < 0.0 )
this.efficiency = 0.0;
minPower = (double) reqX * (double) reqY * reqZ * AEConfig.instance.spatialPowerMultiplier;
maxPower = Math.pow( minPower, AEConfig.instance.spatialPowerExponent );
}
double affective_efficiency = Math.pow( this.efficiency, 0.25 );
this.powerRequired = (long) (affective_efficiency * minPower + (1.0 - affective_efficiency) * maxPower);
for (SpatialPylonCluster cl : this.clusters.values())
{
boolean myWasValid = cl.isValid;
cl.isValid = this.isValid;
if ( myWasValid != this.isValid )
cl.updateStatus( false );
}
return this.powerRequired;
}
@Override
@@ -205,45 +207,38 @@ public class SpatialPylonCache implements ISpatialCache
return (float) this.efficiency * 100;
}
@MENetworkEventSubscribe
public void bootingRender(MENetworkBootingStatusChange c)
{
this.reset( this.myGrid );
}
@Override
public void onUpdateTick()
{
}
@Override
public void addNode(IGridNode node, IGridHost machine)
public void removeNode( IGridNode node, IGridHost machine )
{
}
@Override
public void removeNode(IGridNode node, IGridHost machine)
public void addNode( IGridNode node, IGridHost machine )
{
}
@Override
public void onSplit(IGridStorage storageB)
public void onSplit( IGridStorage storageB )
{
}
@Override
public void onJoin(IGridStorage storageB)
public void onJoin( IGridStorage storageB )
{
}
@Override
public void populateGridStorage(IGridStorage storage)
public void populateGridStorage( IGridStorage storage )
{
}
}
+99 -101
View File
@@ -18,6 +18,7 @@
package appeng.me.cache;
import java.util.HashMap;
import java.util.PriorityQueue;
@@ -35,37 +36,35 @@ import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.me.cache.helpers.TickTracker;
public class TickManagerCache implements ITickManager
{
private long currentTick = 0;
final IGrid myGrid;
public TickManagerCache(IGrid g) {
this.myGrid = g;
}
final HashMap<IGridNode, TickTracker> alertable = new HashMap<IGridNode, TickTracker>();
final HashMap<IGridNode, TickTracker> sleeping = new HashMap<IGridNode, TickTracker>();
final HashMap<IGridNode, TickTracker> awake = new HashMap<IGridNode, TickTracker>();
final PriorityQueue<TickTracker> upcomingTicks = new PriorityQueue<TickTracker>();
private long currentTick = 0;
public TickManagerCache( IGrid g )
{
this.myGrid = g;
}
public long getCurrentTick()
{
return this.currentTick;
}
public long getAvgNanoTime(IGridNode node)
public long getAvgNanoTime( IGridNode node )
{
TickTracker tt = this.awake.get( node );
if ( tt == null )
if( tt == null )
tt = this.sleeping.get( node );
if ( tt == null )
if( tt == null )
return -1;
return tt.getAvgNanos();
@@ -78,40 +77,40 @@ public class TickManagerCache implements ITickManager
try
{
this.currentTick++;
while (!this.upcomingTicks.isEmpty())
while( !this.upcomingTicks.isEmpty() )
{
tt = this.upcomingTicks.peek();
int diff = (int) (this.currentTick - tt.lastTick);
if ( diff >= tt.current_rate )
int diff = (int) ( this.currentTick - tt.lastTick );
if( diff >= tt.current_rate )
{
// remove tt..
this.upcomingTicks.poll();
TickRateModulation mod = tt.gt.tickingRequest( tt.node, diff );
switch (mod)
switch( mod )
{
case FASTER:
tt.setRate( tt.current_rate - 2 );
break;
case IDLE:
tt.setRate( tt.request.maxTickRate );
break;
case SAME:
break;
case SLEEP:
this.sleepDevice( tt.node );
break;
case SLOWER:
tt.setRate( tt.current_rate + 1 );
break;
case URGENT:
tt.setRate( 0 );
break;
default:
break;
case FASTER:
tt.setRate( tt.current_rate - 2 );
break;
case IDLE:
tt.setRate( tt.request.maxTickRate );
break;
case SAME:
break;
case SLEEP:
this.sleepDevice( tt.node );
break;
case SLOWER:
tt.setRate( tt.current_rate + 1 );
break;
case URGENT:
tt.setRate( 0 );
break;
default:
break;
}
if ( this.awake.containsKey( tt.node ) )
if( this.awake.containsKey( tt.node ) )
this.addToQueue( tt );
}
else
@@ -120,24 +119,77 @@ public class TickManagerCache implements ITickManager
}
catch( Throwable t )
{
CrashReport crashreport = CrashReport.makeCrashReport(t, "Ticking GridNode");
CrashReportCategory crashreportcategory = crashreport.makeCategory( tt.gt.getClass().getSimpleName() + " being ticked." );
tt.addEntityCrashInfo(crashreportcategory);
throw new ReportedException(crashreport);
CrashReport crashreport = CrashReport.makeCrashReport( t, "Ticking GridNode" );
CrashReportCategory crashreportcategory = crashreport.makeCategory( tt.gt.getClass().getSimpleName() + " being ticked." );
tt.addEntityCrashInfo( crashreportcategory );
throw new ReportedException( crashreport );
}
}
private void addToQueue(TickTracker tt)
private void addToQueue( TickTracker tt )
{
tt.lastTick = this.currentTick;
this.upcomingTicks.add( tt );
}
@Override
public boolean alertDevice(IGridNode node)
public void removeNode( IGridNode gridNode, IGridHost machine )
{
if( machine instanceof IGridTickable )
{
this.alertable.remove( gridNode );
this.sleeping.remove( gridNode );
this.awake.remove( gridNode );
}
}
@Override
public void addNode( IGridNode gridNode, IGridHost machine )
{
if( machine instanceof IGridTickable )
{
TickingRequest tr = ( (IGridTickable) machine ).getTickingRequest( gridNode );
if( tr != null )
{
TickTracker tt = new TickTracker( tr, gridNode, (IGridTickable) machine, this.currentTick, this );
if( tr.canBeAlerted )
this.alertable.put( gridNode, tt );
if( tr.isSleeping )
this.sleeping.put( gridNode, tt );
else
{
this.awake.put( gridNode, tt );
this.addToQueue( tt );
}
}
}
}
@Override
public void onSplit( IGridStorage storageB )
{
}
@Override
public void onJoin( IGridStorage storageB )
{
}
@Override
public void populateGridStorage( IGridStorage storage )
{
}
@Override
public boolean alertDevice( IGridNode node )
{
TickTracker tt = this.alertable.get( node );
if ( tt == null )
if( tt == null )
return false;
// throw new RuntimeException(
// "Invalid alerted device, this node is not marked as alertable, or part of this grid." );
@@ -158,9 +210,9 @@ public class TickManagerCache implements ITickManager
}
@Override
public boolean sleepDevice(IGridNode node)
public boolean sleepDevice( IGridNode node )
{
if ( this.awake.containsKey( node ) )
if( this.awake.containsKey( node ) )
{
TickTracker gt = this.awake.get( node );
this.awake.remove( node );
@@ -173,9 +225,9 @@ public class TickManagerCache implements ITickManager
}
@Override
public boolean wakeDevice(IGridNode node)
public boolean wakeDevice( IGridNode node )
{
if ( this.sleeping.containsKey( node ) )
if( this.sleeping.containsKey( node ) )
{
TickTracker gt = this.sleeping.get( node );
this.sleeping.remove( node );
@@ -187,58 +239,4 @@ public class TickManagerCache implements ITickManager
return false;
}
@Override
public void removeNode(IGridNode gridNode, IGridHost machine)
{
if ( machine instanceof IGridTickable )
{
this.alertable.remove( gridNode );
this.sleeping.remove( gridNode );
this.awake.remove( gridNode );
}
}
@Override
public void addNode(IGridNode gridNode, IGridHost machine)
{
if ( machine instanceof IGridTickable )
{
TickingRequest tr = ((IGridTickable) machine).getTickingRequest( gridNode );
if ( tr != null )
{
TickTracker tt = new TickTracker( tr, gridNode, (IGridTickable) machine, this.currentTick, this );
if ( tr.canBeAlerted )
this.alertable.put( gridNode, tt );
if ( tr.isSleeping )
this.sleeping.put( gridNode, tt );
else
{
this.awake.put( gridNode, tt );
this.addToQueue( tt );
}
}
}
}
@Override
public void onSplit(IGridStorage storageB)
{
}
@Override
public void onJoin(IGridStorage storageB)
{
}
@Override
public void populateGridStorage(IGridStorage storage)
{
}
}
@@ -18,15 +18,17 @@
package appeng.me.cache.helpers;
import appeng.api.networking.IGridConnection;
public class ConnectionWrapper
{
public IGridConnection connection;
public ConnectionWrapper(IGridConnection gc) {
public ConnectionWrapper( IGridConnection gc )
{
this.connection = gc;
}
}
+5 -4
View File
@@ -18,22 +18,24 @@
package appeng.me.cache.helpers;
import java.util.HashMap;
import java.util.concurrent.Callable;
import appeng.api.networking.IGridNode;
import appeng.parts.p2p.PartP2PTunnelME;
public class Connections implements Callable
{
final private PartP2PTunnelME me;
final public HashMap<IGridNode, TunnelConnection> connections = new HashMap<IGridNode, TunnelConnection>();
final private PartP2PTunnelME me;
public boolean create = false;
public boolean destroy = false;
public Connections(PartP2PTunnelME o) {
public Connections( PartP2PTunnelME o )
{
this.me = o;
}
@@ -56,5 +58,4 @@ public class Connections implements Callable
this.create = true;
this.destroy = false;
}
}
+16 -13
View File
@@ -18,6 +18,7 @@
package appeng.me.cache.helpers;
import net.minecraft.crash.CrashReportCategory;
import appeng.api.networking.IGridNode;
@@ -27,6 +28,7 @@ import appeng.api.util.DimensionalCoord;
import appeng.me.cache.TickManagerCache;
import appeng.parts.AEBasePart;
public class TickTracker implements Comparable<TickTracker>
{
@@ -40,44 +42,45 @@ public class TickTracker implements Comparable<TickTracker>
public long lastTick;
public int current_rate;
public TickTracker(TickingRequest req, IGridNode node, IGridTickable gt, long currentTick, TickManagerCache tickManagerCache) {
public TickTracker( TickingRequest req, IGridNode node, IGridTickable gt, long currentTick, TickManagerCache tickManagerCache )
{
this.request = req;
this.gt = gt;
this.node = node;
this.current_rate = (req.minTickRate + req.maxTickRate) / 2;
this.current_rate = ( req.minTickRate + req.maxTickRate ) / 2;
this.lastTick = currentTick;
this.host = tickManagerCache;
}
public long getAvgNanos()
{
return (this.LastFiveTicksTime / 5);
return ( this.LastFiveTicksTime / 5 );
}
public void setRate(int rate)
public void setRate( int rate )
{
this.current_rate = rate;
if ( this.current_rate < this.request.minTickRate )
if( this.current_rate < this.request.minTickRate )
this.current_rate = this.request.minTickRate;
if ( this.current_rate > this.request.maxTickRate )
if( this.current_rate > this.request.maxTickRate )
this.current_rate = this.request.maxTickRate;
}
@Override
public int compareTo(TickTracker t)
public int compareTo( TickTracker t )
{
int nextTick = (int) ((this.lastTick - this.host.getCurrentTick()) + this.current_rate);
int ts_nextTick = (int) ((t.lastTick - this.host.getCurrentTick()) + t.current_rate);
int nextTick = (int) ( ( this.lastTick - this.host.getCurrentTick() ) + this.current_rate );
int ts_nextTick = (int) ( ( t.lastTick - this.host.getCurrentTick() ) + t.current_rate );
return nextTick - ts_nextTick;
}
public void addEntityCrashInfo(CrashReportCategory crashreportcategory)
public void addEntityCrashInfo( CrashReportCategory crashreportcategory )
{
if ( this.gt instanceof AEBasePart )
if( this.gt instanceof AEBasePart )
{
AEBasePart part = (AEBasePart)this.gt;
AEBasePart part = (AEBasePart) this.gt;
part.addEntityCrashInfo( crashreportcategory );
}
@@ -89,7 +92,7 @@ public class TickTracker implements Comparable<TickTracker>
crashreportcategory.addCrashSection( "ConnectedSides", this.node.getConnectedSides() );
DimensionalCoord dc = this.node.getGridBlock().getLocation();
if ( dc != null )
if( dc != null )
crashreportcategory.addCrashSection( "Location", dc );
}
}
+14 -11
View File
@@ -18,32 +18,27 @@
package appeng.me.cache.helpers;
import java.util.Collection;
import java.util.Iterator;
import appeng.parts.p2p.PartP2PTunnel;
import appeng.util.iterators.NullIterator;
public class TunnelCollection<T extends PartP2PTunnel> implements Iterable<T>
{
final Class clz;
Collection<T> tunnelSources;
public TunnelCollection(Collection<T> src, Class c) {
public TunnelCollection( Collection<T> src, Class c )
{
this.tunnelSources = src;
this.clz = c;
}
@Override
public Iterator<T> iterator()
{
if ( this.tunnelSources == null )
return new NullIterator<T>();
return new TunnelIterator<T>( this.tunnelSources, this.clz );
}
public void setSource(Collection<T> c)
public void setSource( Collection<T> c )
{
this.tunnelSources = c;
}
@@ -53,7 +48,15 @@ public class TunnelCollection<T extends PartP2PTunnel> implements Iterable<T>
return !this.iterator().hasNext();
}
public boolean matches(Class<? extends PartP2PTunnel> c)
@Override
public Iterator<T> iterator()
{
if( this.tunnelSources == null )
return new NullIterator<T>();
return new TunnelIterator<T>( this.tunnelSources, this.clz );
}
public boolean matches( Class<? extends PartP2PTunnel> c )
{
return this.clz == c;
}
@@ -18,16 +18,19 @@
package appeng.me.cache.helpers;
import appeng.api.networking.IGridConnection;
import appeng.parts.p2p.PartP2PTunnelME;
public class TunnelConnection
{
final public PartP2PTunnelME tunnel;
final public IGridConnection c;
public TunnelConnection(PartP2PTunnelME t, IGridConnection con) {
public TunnelConnection( PartP2PTunnelME t, IGridConnection con )
{
this.tunnel = t;
this.c = con;
}
+13 -11
View File
@@ -18,11 +18,13 @@
package appeng.me.cache.helpers;
import java.util.Collection;
import java.util.Iterator;
import appeng.parts.p2p.PartP2PTunnel;
public class TunnelIterator<T extends PartP2PTunnel> implements Iterator<T>
{
@@ -30,22 +32,23 @@ public class TunnelIterator<T extends PartP2PTunnel> implements Iterator<T>
final Class targetType;
T Next;
private void findNext()
public TunnelIterator( Collection<T> tunnelSources, Class clz )
{
while (this.Next == null && this.wrapped.hasNext())
{
this.Next = this.wrapped.next();
if ( !this.targetType.isInstance( this.Next ) )
this.Next = null;
}
}
public TunnelIterator(Collection<T> tunnelSources, Class clz) {
this.wrapped = tunnelSources.iterator();
this.targetType = clz;
this.findNext();
}
private void findNext()
{
while( this.Next == null && this.wrapped.hasNext() )
{
this.Next = this.wrapped.next();
if( !this.targetType.isInstance( this.Next ) )
this.Next = null;
}
}
@Override
public boolean hasNext()
{
@@ -66,5 +69,4 @@ public class TunnelIterator<T extends PartP2PTunnel> implements Iterator<T>
{
// no.
}
}
@@ -18,17 +18,18 @@
package appeng.me.cluster;
import java.util.Iterator;
import appeng.api.networking.IGridHost;
public interface IAECluster
{
void updateStatus(boolean updateGrid);
void updateStatus( boolean updateGrid );
void destroy();
Iterator<IGridHost> getTiles();
}
@@ -18,14 +18,13 @@
package appeng.me.cluster;
public interface IAEMultiBlock
{
void disconnect(boolean b);
void disconnect( boolean b );
IAECluster getCluster();
boolean isValid();
}
+111 -106
View File
@@ -18,6 +18,7 @@
package appeng.me.cluster;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
@@ -26,65 +27,20 @@ import appeng.api.util.WorldCoord;
import appeng.core.AELog;
import appeng.util.Platform;
public abstract class MBCalculator
{
final private IAEMultiBlock target;
public MBCalculator(IAEMultiBlock t) {
public MBCalculator( IAEMultiBlock t )
{
this.target = t;
}
/**
* check if the tile entities are correct for the structure.
*
* @param te to be checked tile entity
* @return true if tile entity is valid for structure
*/
public abstract boolean isValidTile(TileEntity te);
/**
* construct the correct cluster, usually very simple.
*
* @param w world
* @param min min world coord
* @param max max world coord
* @return created cluster
*/
public abstract IAECluster createCluster(World w, WorldCoord min, WorldCoord max);
/**
* configure the multi-block tiles, most of the important stuff is in here.
*
* @param c updated cluster
* @param w in world
* @param min min world coord
* @param max max world coord
*/
public abstract void updateTiles(IAECluster c, World w, WorldCoord min, WorldCoord max);
/**
* disassembles the multi-block.
*/
public abstract void disconnect();
/**
* verify if the structure is the correct dimensions, or size
*
* @param min min world coord
* @param max max world coord
* @return true if structure has correct dimensions or size
*/
public abstract boolean checkMultiblockScale(WorldCoord min, WorldCoord max);
public boolean isValidTileAt(World w, int x, int y, int z)
public void calculateMultiblock( World world, WorldCoord loc )
{
return this.isValidTile( w.getTileEntity( x, y, z ) );
}
public void calculateMultiblock(World world, WorldCoord loc)
{
if ( Platform.isClient() )
if( Platform.isClient() )
return;
try
@@ -93,34 +49,34 @@ public abstract class MBCalculator
WorldCoord max = loc.copy();
// find size of MB structure...
while (this.isValidTileAt( world, min.x - 1, min.y, min.z ))
while( this.isValidTileAt( world, min.x - 1, min.y, min.z ) )
min.x--;
while (this.isValidTileAt( world, min.x, min.y - 1, min.z ))
while( this.isValidTileAt( world, min.x, min.y - 1, min.z ) )
min.y--;
while (this.isValidTileAt( world, min.x, min.y, min.z - 1 ))
while( this.isValidTileAt( world, min.x, min.y, min.z - 1 ) )
min.z--;
while (this.isValidTileAt( world, max.x + 1, max.y, max.z ))
while( this.isValidTileAt( world, max.x + 1, max.y, max.z ) )
max.x++;
while (this.isValidTileAt( world, max.x, max.y + 1, max.z ))
while( this.isValidTileAt( world, max.x, max.y + 1, max.z ) )
max.y++;
while (this.isValidTileAt( world, max.x, max.y, max.z + 1 ))
while( this.isValidTileAt( world, max.x, max.y, max.z + 1 ) )
max.z++;
if ( this.checkMultiblockScale( min, max ) )
if( this.checkMultiblockScale( min, max ) )
{
if ( this.verifyUnownedRegion( world, min, max ) )
if( this.verifyUnownedRegion( world, min, max ) )
{
IAECluster c = this.createCluster( world, min, max );
try
{
if ( !this.verifyInternalStructure( world, min, max ) )
if( !this.verifyInternalStructure( world, min, max ) )
{
this.disconnect();
return;
}
}
catch (Exception err)
catch( Exception err )
{
this.disconnect();
return;
@@ -128,7 +84,7 @@ public abstract class MBCalculator
boolean updateGrid = false;
IAECluster cluster = this.target.getCluster();
if ( cluster == null )
if( cluster == null )
{
this.updateTiles( c, world, min, max );
@@ -142,7 +98,7 @@ public abstract class MBCalculator
}
}
}
catch (Throwable err)
catch( Throwable err )
{
AELog.error( err );
}
@@ -150,48 +106,107 @@ public abstract class MBCalculator
this.disconnect();
}
public abstract boolean verifyInternalStructure(World worldObj, WorldCoord min, WorldCoord max);
public boolean verifyUnownedRegionInner(World w, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, ForgeDirection side)
public boolean isValidTileAt( World w, int x, int y, int z )
{
switch (side)
return this.isValidTile( w.getTileEntity( x, y, z ) );
}
/**
* verify if the structure is the correct dimensions, or size
*
* @param min min world coord
* @param max max world coord
*
* @return true if structure has correct dimensions or size
*/
public abstract boolean checkMultiblockScale( WorldCoord min, WorldCoord max );
public boolean verifyUnownedRegion( World w, WorldCoord min, WorldCoord max )
{
for( ForgeDirection side : ForgeDirection.VALID_DIRECTIONS )
if( this.verifyUnownedRegionInner( w, min.x, min.y, min.z, max.x, max.y, max.z, side ) )
return false;
return true;
}
/**
* construct the correct cluster, usually very simple.
*
* @param w world
* @param min min world coord
* @param max max world coord
*
* @return created cluster
*/
public abstract IAECluster createCluster( World w, WorldCoord min, WorldCoord max );
public abstract boolean verifyInternalStructure( World worldObj, WorldCoord min, WorldCoord max );
/**
* disassembles the multi-block.
*/
public abstract void disconnect();
/**
* configure the multi-block tiles, most of the important stuff is in here.
*
* @param c updated cluster
* @param w in world
* @param min min world coord
* @param max max world coord
*/
public abstract void updateTiles( IAECluster c, World w, WorldCoord min, WorldCoord max );
/**
* check if the tile entities are correct for the structure.
*
* @param te to be checked tile entity
*
* @return true if tile entity is valid for structure
*/
public abstract boolean isValidTile( TileEntity te );
public boolean verifyUnownedRegionInner( World w, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, ForgeDirection side )
{
switch( side )
{
case WEST:
minX -= 1;
maxX = minX;
break;
case EAST:
maxX += 1;
minX = maxX;
break;
case DOWN:
minY -= 1;
maxY = minY;
break;
case NORTH:
maxZ += 1;
minZ = maxZ;
break;
case SOUTH:
minZ -= 1;
maxZ = minZ;
break;
case UP:
maxY += 1;
minY = maxY;
break;
case UNKNOWN:
return false;
case WEST:
minX -= 1;
maxX = minX;
break;
case EAST:
maxX += 1;
minX = maxX;
break;
case DOWN:
minY -= 1;
maxY = minY;
break;
case NORTH:
maxZ += 1;
minZ = maxZ;
break;
case SOUTH:
minZ -= 1;
maxZ = minZ;
break;
case UP:
maxY += 1;
minY = maxY;
break;
case UNKNOWN:
return false;
}
for (int x = minX; x <= maxX; x++)
for( int x = minX; x <= maxX; x++ )
{
for (int y = minY; y <= maxY; y++)
for( int y = minY; y <= maxY; y++ )
{
for (int z = minZ; z <= maxZ; z++)
for( int z = minZ; z <= maxZ; z++ )
{
TileEntity te = w.getTileEntity( x, y, z );
if ( this.isValidTile( te ) )
if( this.isValidTile( te ) )
return true;
}
}
@@ -199,14 +214,4 @@ public abstract class MBCalculator
return false;
}
public boolean verifyUnownedRegion(World w, WorldCoord min, WorldCoord max)
{
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
if ( this.verifyUnownedRegionInner( w, min.x, min.y, min.z, max.x, max.y, max.z, side ) )
return false;
return true;
}
}
@@ -18,6 +18,7 @@
package appeng.me.cluster.implementations;
import java.util.Iterator;
import net.minecraft.tileentity.TileEntity;
@@ -34,47 +35,80 @@ import appeng.me.cluster.IAEMultiBlock;
import appeng.me.cluster.MBCalculator;
import appeng.tile.crafting.TileCraftingTile;
public class CraftingCPUCalculator extends MBCalculator
{
final TileCraftingTile tqb;
public CraftingCPUCalculator(IAEMultiBlock t) {
public CraftingCPUCalculator( IAEMultiBlock t )
{
super( t );
this.tqb = (TileCraftingTile) t;
}
@Override
public boolean isValidTile(TileEntity te)
public boolean checkMultiblockScale( WorldCoord min, WorldCoord max )
{
return te instanceof TileCraftingTile;
}
@Override
public boolean checkMultiblockScale(WorldCoord min, WorldCoord max)
{
if ( max.x - min.x > 16 )
if( max.x - min.x > 16 )
return false;
if ( max.y - min.y > 16 )
if( max.y - min.y > 16 )
return false;
if ( max.z - min.z > 16 )
if( max.z - min.z > 16 )
return false;
return true;
}
@Override
public void updateTiles(IAECluster cl, World w, WorldCoord min, WorldCoord max)
public IAECluster createCluster( World w, WorldCoord min, WorldCoord max )
{
return new CraftingCPUCluster( min, max );
}
@Override
public boolean verifyInternalStructure( World w, WorldCoord min, WorldCoord max )
{
boolean storage = false;
for( int x = min.x; x <= max.x; x++ )
{
for( int y = min.y; y <= max.y; y++ )
{
for( int z = min.z; z <= max.z; z++ )
{
IAEMultiBlock te = (IAEMultiBlock) w.getTileEntity( x, y, z );
if( !te.isValid() )
return false;
if( !storage && te instanceof TileCraftingTile )
storage = ( (TileCraftingTile) te ).getStorageBytes() > 0;
}
}
}
return storage;
}
@Override
public void disconnect()
{
this.tqb.disconnect( true );
}
@Override
public void updateTiles( IAECluster cl, World w, WorldCoord min, WorldCoord max )
{
CraftingCPUCluster c = (CraftingCPUCluster) cl;
for (int x = min.x; x <= max.x; x++)
for( int x = min.x; x <= max.x; x++ )
{
for (int y = min.y; y <= max.y; y++)
for( int y = min.y; y <= max.y; y++ )
{
for (int z = min.z; z <= max.z; z++)
for( int z = min.z; z <= max.z; z++ )
{
TileCraftingTile te = (TileCraftingTile) w.getTileEntity( x, y, z );
te.updateStatus( c );
@@ -86,14 +120,14 @@ public class CraftingCPUCalculator extends MBCalculator
c.done();
Iterator<IGridHost> i = c.getTiles();
while (i.hasNext())
while( i.hasNext() )
{
IGridHost gh = i.next();
IGridNode n = gh.getGridNode( ForgeDirection.UNKNOWN );
if ( n != null )
if( n != null )
{
IGrid g = n.getGrid();
if ( g != null )
if( g != null )
{
g.postEvent( new MENetworkCraftingCpuChange( n ) );
return;
@@ -103,40 +137,8 @@ public class CraftingCPUCalculator extends MBCalculator
}
@Override
public IAECluster createCluster(World w, WorldCoord min, WorldCoord max)
public boolean isValidTile( TileEntity te )
{
return new CraftingCPUCluster( min, max );
return te instanceof TileCraftingTile;
}
@Override
public void disconnect()
{
this.tqb.disconnect( true );
}
@Override
public boolean verifyInternalStructure(World w, WorldCoord min, WorldCoord max)
{
boolean storage = false;
for (int x = min.x; x <= max.x; x++)
{
for (int y = min.y; y <= max.y; y++)
{
for (int z = min.z; z <= max.z; z++)
{
IAEMultiBlock te = (IAEMultiBlock) w.getTileEntity( x, y, z );
if ( !te.isValid() )
return false;
if ( !storage && te instanceof TileCraftingTile )
storage = ((TileCraftingTile) te).getStorageBytes() > 0;
}
}
}
return storage;
}
}
File diff suppressed because it is too large Load Diff
@@ -18,6 +18,7 @@
package appeng.me.cluster.implementations;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.IBlockAccess;
@@ -32,31 +33,27 @@ import appeng.me.cluster.IAEMultiBlock;
import appeng.me.cluster.MBCalculator;
import appeng.tile.qnb.TileQuantumBridge;
public class QuantumCalculator extends MBCalculator
{
final private TileQuantumBridge tqb;
public QuantumCalculator(IAEMultiBlock t) {
public QuantumCalculator( IAEMultiBlock t )
{
super( t );
this.tqb = (TileQuantumBridge) t;
}
@Override
public boolean isValidTile(TileEntity te)
{
return te instanceof TileQuantumBridge;
}
@Override
public boolean checkMultiblockScale(WorldCoord min, WorldCoord max)
public boolean checkMultiblockScale( WorldCoord min, WorldCoord max )
{
if ( (max.x - min.x + 1) * (max.y - min.y + 1) * (max.z - min.z + 1) == 9 )
if( ( max.x - min.x + 1 ) * ( max.y - min.y + 1 ) * ( max.z - min.z + 1 ) == 9 )
{
int ones = ((max.x - min.x) == 0 ? 1 : 0) + ((max.y - min.y) == 0 ? 1 : 0) + ((max.z - min.z) == 0 ? 1 : 0);
int ones = ( ( max.x - min.x ) == 0 ? 1 : 0 ) + ( ( max.y - min.y ) == 0 ? 1 : 0 ) + ( ( max.z - min.z ) == 0 ? 1 : 0 );
int threes = ((max.x - min.x) == 2 ? 1 : 0) + ((max.y - min.y) == 2 ? 1 : 0) + ((max.z - min.z) == 2 ? 1 : 0);
int threes = ( ( max.x - min.x ) == 2 ? 1 : 0 ) + ( ( max.y - min.y ) == 2 ? 1 : 0 ) + ( ( max.z - min.z ) == 2 ? 1 : 0 );
return ones == 1 && threes == 2;
}
@@ -64,86 +61,40 @@ public class QuantumCalculator extends MBCalculator
}
@Override
public void updateTiles(IAECluster cl, World w, WorldCoord min, WorldCoord max)
{
byte num = 0;
byte ringNum = 0;
QuantumCluster c = (QuantumCluster) cl;
for (int x = min.x; x <= max.x; x++)
{
for (int y = min.y; y <= max.y; y++)
{
for (int z = min.z; z <= max.z; z++)
{
TileQuantumBridge te = (TileQuantumBridge) w.getTileEntity( x, y, z );
byte flags;
num++;
if ( num == 5 )
{
flags = num;
c.setCenter( te );
}
else
{
if ( num == 1 || num == 3 || num == 7 || num == 9 )
flags = (byte) (this.tqb.corner | num);
else
flags = num;
c.Ring[ringNum] = te;
ringNum++;
}
te.updateStatus( c, flags, true );
}
}
}
}
@Override
public IAECluster createCluster(World w, WorldCoord min, WorldCoord max)
public IAECluster createCluster( World w, WorldCoord min, WorldCoord max )
{
return new QuantumCluster( min, max );
}
@Override
public void disconnect()
{
this.tqb.disconnect(true);
}
@Override
public boolean verifyInternalStructure(World w, WorldCoord min, WorldCoord max)
public boolean verifyInternalStructure( World w, WorldCoord min, WorldCoord max )
{
byte num = 0;
for (int x = min.x; x <= max.x; x++)
for( int x = min.x; x <= max.x; x++ )
{
for (int y = min.y; y <= max.y; y++)
for( int y = min.y; y <= max.y; y++ )
{
for (int z = min.z; z <= max.z; z++)
for( int z = min.z; z <= max.z; z++ )
{
IAEMultiBlock te = (IAEMultiBlock) w.getTileEntity( x, y, z );
if ( !te.isValid() )
if( !te.isValid() )
return false;
num++;
final IBlocks blocks = AEApi.instance().definitions().blocks();
if ( num == 5 )
if( num == 5 )
{
if ( !this.isBlockAtLocation( w, x, y, z, blocks.quantumLink() ) )
if( !this.isBlockAtLocation( w, x, y, z, blocks.quantumLink() ) )
{
return false;
}
}
else
{
if ( !this.isBlockAtLocation( w, x, y, z, blocks.quantumRing() ) )
if( !this.isBlockAtLocation( w, x, y, z, blocks.quantumRing() ) )
{
return false;
}
@@ -154,9 +105,60 @@ public class QuantumCalculator extends MBCalculator
return true;
}
@Override
public void disconnect()
{
this.tqb.disconnect( true );
}
@Override
public void updateTiles( IAECluster cl, World w, WorldCoord min, WorldCoord max )
{
byte num = 0;
byte ringNum = 0;
QuantumCluster c = (QuantumCluster) cl;
for( int x = min.x; x <= max.x; x++ )
{
for( int y = min.y; y <= max.y; y++ )
{
for( int z = min.z; z <= max.z; z++ )
{
TileQuantumBridge te = (TileQuantumBridge) w.getTileEntity( x, y, z );
byte flags;
num++;
if( num == 5 )
{
flags = num;
c.setCenter( te );
}
else
{
if( num == 1 || num == 3 || num == 7 || num == 9 )
flags = (byte) ( this.tqb.corner | num );
else
flags = num;
c.Ring[ringNum] = te;
ringNum++;
}
te.updateStatus( c, flags, true );
}
}
}
}
@Override
public boolean isValidTile( TileEntity te )
{
return te instanceof TileQuantumBridge;
}
private boolean isBlockAtLocation( IBlockAccess w, int x, int y, int z, IBlockDefinition def )
{
for ( Block block : def.maybeBlock().asSet() )
for( Block block : def.maybeBlock().asSet() )
{
return block == w.getBlock( x, y, z );
}
@@ -18,6 +18,7 @@
package appeng.me.cluster.implementations;
import java.util.Iterator;
import net.minecraft.tileentity.TileEntity;
@@ -43,6 +44,7 @@ import appeng.me.cluster.IAECluster;
import appeng.tile.qnb.TileQuantumBridge;
import appeng.util.iterators.ChainedIterator;
public class QuantumCluster implements ILocatable, IAECluster
{
@@ -50,61 +52,24 @@ public class QuantumCluster implements ILocatable, IAECluster
final public WorldCoord max;
public boolean isDestroyed = false;
public boolean updateStatus = true;
public TileQuantumBridge[] Ring;
boolean registered = false;
ConnectionWrapper connection;
private long thisSide;
private long otherSide;
ConnectionWrapper connection;
public TileQuantumBridge[] Ring;
private TileQuantumBridge center;
@Override
public Iterator<IGridHost> getTiles()
public QuantumCluster( WorldCoord _min, WorldCoord _max )
{
return new ChainedIterator<IGridHost>( this.Ring[0], this.Ring[1], this.Ring[2], this.Ring[3], this.Ring[4], this.Ring[5], this.Ring[6], this.Ring[7], this.center );
}
public void setCenter(TileQuantumBridge c)
{
this.registered = true;
MinecraftForge.EVENT_BUS.register( this );
this.center = c;
}
public QuantumCluster(WorldCoord _min, WorldCoord _max) {
this.min = _min;
this.max = _max;
this.Ring = new TileQuantumBridge[8];
}
public boolean canUseNode(long qe)
{
QuantumCluster qc = (QuantumCluster) AEApi.instance().registries().locatable().getLocatableBy( qe );
if ( qc != null )
{
World theWorld = qc.center.getWorldObj();
if ( !qc.isDestroyed )
{
Chunk c = theWorld.getChunkFromBlockCoords( qc.center.xCoord, qc.center.zCoord );
if ( c.isChunkLoaded )
{
int id = theWorld.provider.dimensionId;
World cur = DimensionManager.getWorld( id );
TileEntity te = theWorld.getTileEntity( qc.center.xCoord, qc.center.yCoord, qc.center.zCoord );
return te != qc.center || theWorld != cur;
}
}
}
return true;
}
@SubscribeEvent
public void onUnload(WorldEvent.Unload e)
public void onUnload( WorldEvent.Unload e )
{
if ( this.center.getWorldObj() == e.world )
if( this.center.getWorldObj() == e.world )
{
this.updateStatus = false;
this.destroy();
@@ -112,25 +77,25 @@ public class QuantumCluster implements ILocatable, IAECluster
}
@Override
public void updateStatus(boolean updateGrid)
public void updateStatus( boolean updateGrid )
{
long qe;
qe = this.center.getQEFrequency();
if ( this.thisSide != qe && this.thisSide != -qe )
if( this.thisSide != qe && this.thisSide != -qe )
{
if ( qe != 0 )
if( qe != 0 )
{
if ( this.thisSide != 0 )
if( this.thisSide != 0 )
MinecraftForge.EVENT_BUS.post( new LocatableEventAnnounce( this, LocatableEvent.Unregister ) );
if ( this.canUseNode( -qe ) )
if( this.canUseNode( -qe ) )
{
this.otherSide = qe;
this.thisSide = -qe;
}
else if ( this.canUseNode( qe ) )
else if( this.canUseNode( qe ) )
{
this.thisSide = qe;
this.otherSide = -qe;
@@ -151,37 +116,37 @@ public class QuantumCluster implements ILocatable, IAECluster
boolean shutdown = false;
if ( myOtherSide instanceof QuantumCluster )
if( myOtherSide instanceof QuantumCluster )
{
QuantumCluster sideA = this;
QuantumCluster sideB = (QuantumCluster) myOtherSide;
if ( sideA.isActive() && sideB.isActive() )
if( sideA.isActive() && sideB.isActive() )
{
if ( this.connection != null && this.connection.connection != null )
if( this.connection != null && this.connection.connection != null )
{
IGridNode a = this.connection.connection.a();
IGridNode b = this.connection.connection.b();
IGridNode sa = sideA.getNode();
IGridNode sb = sideB.getNode();
if ( (a == sa || b == sa) && (a == sb || b == sb) )
if( ( a == sa || b == sa ) && ( a == sb || b == sb ) )
return;
}
try
{
if ( sideA.connection != null )
if( sideA.connection != null )
{
if ( sideA.connection.connection != null )
if( sideA.connection.connection != null )
{
sideA.connection.connection.destroy();
sideA.connection = new ConnectionWrapper( null );
}
}
if ( sideB.connection != null )
if( sideB.connection != null )
{
if ( sideB.connection.connection != null )
if( sideB.connection.connection != null )
{
sideB.connection.connection.destroy();
sideB.connection = new ConnectionWrapper( null );
@@ -190,7 +155,7 @@ public class QuantumCluster implements ILocatable, IAECluster
sideA.connection = sideB.connection = new ConnectionWrapper( AEApi.instance().createGridConnection( sideA.getNode(), sideB.getNode() ) );
}
catch (FailedConnection e)
catch( FailedConnection e )
{
// :(
}
@@ -201,9 +166,9 @@ public class QuantumCluster implements ILocatable, IAECluster
else
shutdown = true;
if ( shutdown && this.connection != null )
if( shutdown && this.connection != null )
{
if ( this.connection.connection != null )
if( this.connection.connection != null )
{
this.connection.connection.destroy();
this.connection.connection = null;
@@ -212,20 +177,60 @@ public class QuantumCluster implements ILocatable, IAECluster
}
}
public boolean canUseNode( long qe )
{
QuantumCluster qc = (QuantumCluster) AEApi.instance().registries().locatable().getLocatableBy( qe );
if( qc != null )
{
World theWorld = qc.center.getWorldObj();
if( !qc.isDestroyed )
{
Chunk c = theWorld.getChunkFromBlockCoords( qc.center.xCoord, qc.center.zCoord );
if( c.isChunkLoaded )
{
int id = theWorld.provider.dimensionId;
World cur = DimensionManager.getWorld( id );
TileEntity te = theWorld.getTileEntity( qc.center.xCoord, qc.center.yCoord, qc.center.zCoord );
return te != qc.center || theWorld != cur;
}
}
}
return true;
}
private boolean isActive()
{
if( this.isDestroyed || !this.registered )
return false;
return this.center.isPowered() && this.hasQES();
}
private IGridNode getNode()
{
return this.center.getGridNode( ForgeDirection.UNKNOWN );
}
public boolean hasQES()
{
return this.thisSide != 0;
}
@Override
public void destroy()
{
if ( this.isDestroyed )
if( this.isDestroyed )
return;
this.isDestroyed = true;
if ( this.registered )
if( this.registered )
{
MinecraftForge.EVENT_BUS.unregister( this );
this.registered = false;
}
if ( this.thisSide != 0 )
if( this.thisSide != 0 )
{
this.updateStatus( true );
MinecraftForge.EVENT_BUS.post( new LocatableEventAnnounce( this, LocatableEvent.Unregister ) );
@@ -233,7 +238,7 @@ public class QuantumCluster implements ILocatable, IAECluster
this.center.updateStatus( null, (byte) -1, this.updateStatus );
for (TileQuantumBridge r : this.Ring)
for( TileQuantumBridge r : this.Ring )
{
r.updateStatus( null, (byte) -1, this.updateStatus );
}
@@ -242,7 +247,13 @@ public class QuantumCluster implements ILocatable, IAECluster
this.Ring = new TileQuantumBridge[8];
}
public boolean isCorner(TileQuantumBridge tileQuantumBridge)
@Override
public Iterator<IGridHost> getTiles()
{
return new ChainedIterator<IGridHost>( this.Ring[0], this.Ring[1], this.Ring[2], this.Ring[3], this.Ring[4], this.Ring[5], this.Ring[6], this.Ring[7], this.center );
}
public boolean isCorner( TileQuantumBridge tileQuantumBridge )
{
return this.Ring[0] == tileQuantumBridge || this.Ring[2] == tileQuantumBridge || this.Ring[4] == tileQuantumBridge || this.Ring[6] == tileQuantumBridge;
}
@@ -258,22 +269,10 @@ public class QuantumCluster implements ILocatable, IAECluster
return this.center;
}
public boolean hasQES()
public void setCenter( TileQuantumBridge c )
{
return this.thisSide != 0;
this.registered = true;
MinecraftForge.EVENT_BUS.register( this );
this.center = c;
}
private IGridNode getNode()
{
return this.center.getGridNode( ForgeDirection.UNKNOWN );
}
private boolean isActive()
{
if ( this.isDestroyed || !this.registered )
return false;
return this.center.isPowered() && this.hasQES();
}
}
@@ -18,6 +18,7 @@
package appeng.me.cluster.implementations;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
@@ -28,75 +29,44 @@ import appeng.me.cluster.IAEMultiBlock;
import appeng.me.cluster.MBCalculator;
import appeng.tile.spatial.TileSpatialPylon;
public class SpatialPylonCalculator extends MBCalculator
{
private final TileSpatialPylon tqb;
public SpatialPylonCalculator(IAEMultiBlock t) {
public SpatialPylonCalculator( IAEMultiBlock t )
{
super( t );
this.tqb = (TileSpatialPylon) t;
}
@Override
public boolean isValidTile(TileEntity te)
public boolean checkMultiblockScale( WorldCoord min, WorldCoord max )
{
return te instanceof TileSpatialPylon;
return ( min.x == max.x && min.y == max.y && min.z != max.z ) || ( min.x == max.x && min.y != max.y && min.z == max.z ) || ( min.x != max.x && min.y == max.y && min.z == max.z );
}
@Override
public boolean checkMultiblockScale(WorldCoord min, WorldCoord max)
{
return (min.x == max.x && min.y == max.y && min.z != max.z) || (min.x == max.x && min.y != max.y && min.z == max.z) || (min.x != max.x && min.y == max.y && min.z == max.z);
}
@Override
public void updateTiles(IAECluster cl, World w, WorldCoord min, WorldCoord max)
{
SpatialPylonCluster c = (SpatialPylonCluster) cl;
for (int x = min.x; x <= max.x; x++)
{
for (int y = min.y; y <= max.y; y++)
{
for (int z = min.z; z <= max.z; z++)
{
TileSpatialPylon te = (TileSpatialPylon) w.getTileEntity( x, y, z );
te.updateStatus( c );
c.line.add( (te) );
}
}
}
}
@Override
public IAECluster createCluster(World w, WorldCoord min, WorldCoord max)
public IAECluster createCluster( World w, WorldCoord min, WorldCoord max )
{
return new SpatialPylonCluster( new DimensionalCoord( w, min.x, min.y, min.z ), new DimensionalCoord( w, max.x, max.y, max.z ) );
}
@Override
public void disconnect()
{
this.tqb.disconnect(true);
}
@Override
public boolean verifyInternalStructure(World w, WorldCoord min, WorldCoord max)
public boolean verifyInternalStructure( World w, WorldCoord min, WorldCoord max )
{
for (int x = min.x; x <= max.x; x++)
for( int x = min.x; x <= max.x; x++ )
{
for (int y = min.y; y <= max.y; y++)
for( int y = min.y; y <= max.y; y++ )
{
for (int z = min.z; z <= max.z; z++)
for( int z = min.z; z <= max.z; z++ )
{
IAEMultiBlock te = (IAEMultiBlock) w.getTileEntity( x, y, z );
if ( !te.isValid() )
if( !te.isValid() )
return false;
}
}
}
@@ -104,4 +74,34 @@ public class SpatialPylonCalculator extends MBCalculator
return true;
}
@Override
public void disconnect()
{
this.tqb.disconnect( true );
}
@Override
public void updateTiles( IAECluster cl, World w, WorldCoord min, WorldCoord max )
{
SpatialPylonCluster c = (SpatialPylonCluster) cl;
for( int x = min.x; x <= max.x; x++ )
{
for( int y = min.y; y <= max.y; y++ )
{
for( int z = min.z; z <= max.z; z++ )
{
TileSpatialPylon te = (TileSpatialPylon) w.getTileEntity( x, y, z );
te.updateStatus( c );
c.line.add( ( te ) );
}
}
}
}
@Override
public boolean isValidTile( TileEntity te )
{
return te instanceof TileSpatialPylon;
}
}
@@ -18,6 +18,7 @@
package appeng.me.cluster.implementations;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -27,43 +28,39 @@ import appeng.api.util.DimensionalCoord;
import appeng.me.cluster.IAECluster;
import appeng.tile.spatial.TileSpatialPylon;
public class SpatialPylonCluster implements IAECluster
{
public enum Axis
{
X, Y, Z, UNFORMED
}
final public DimensionalCoord min;
final public DimensionalCoord max;
final List<TileSpatialPylon> line = new ArrayList<TileSpatialPylon>();
public boolean isDestroyed = false;
public Axis currentAxis = Axis.UNFORMED;
final List<TileSpatialPylon> line = new ArrayList<TileSpatialPylon>();
public boolean isValid;
public boolean hasPower;
public boolean hasChannel;
public SpatialPylonCluster(DimensionalCoord _min, DimensionalCoord _max) {
public SpatialPylonCluster( DimensionalCoord _min, DimensionalCoord _max )
{
this.min = _min.copy();
this.max = _max.copy();
if ( this.min.x != this.max.x )
if( this.min.x != this.max.x )
this.currentAxis = Axis.X;
else if ( this.min.y != this.max.y )
else if( this.min.y != this.max.y )
this.currentAxis = Axis.Y;
else if ( this.min.z != this.max.z )
else if( this.min.z != this.max.z )
this.currentAxis = Axis.Z;
else
this.currentAxis = Axis.UNFORMED;
}
@Override
public void updateStatus(boolean updateGrid)
public void updateStatus( boolean updateGrid )
{
for (TileSpatialPylon r : this.line)
for( TileSpatialPylon r : this.line )
{
r.recalculateDisplay();
}
@@ -73,20 +70,14 @@ public class SpatialPylonCluster implements IAECluster
public void destroy()
{
if ( this.isDestroyed )
if( this.isDestroyed )
return;
this.isDestroyed = true;
for (TileSpatialPylon r : this.line)
for( TileSpatialPylon r : this.line )
{
r.updateStatus( null );
}
}
public int tileCount()
{
return this.line.size();
}
@Override
@@ -95,4 +86,13 @@ public class SpatialPylonCluster implements IAECluster
return (Iterator) this.line.iterator();
}
public int tileCount()
{
return this.line.size();
}
public enum Axis
{
X, Y, Z, UNFORMED
}
}
@@ -18,9 +18,11 @@
package appeng.me.energy;
import appeng.api.networking.energy.IEnergyWatcher;
import appeng.util.ItemSorters;
public class EnergyThreshold implements Comparable<EnergyThreshold>
{
@@ -28,14 +30,15 @@ public class EnergyThreshold implements Comparable<EnergyThreshold>
public final IEnergyWatcher watcher;
final int hash;
public EnergyThreshold(double lim, IEnergyWatcher wat) {
public EnergyThreshold( double lim, IEnergyWatcher wat )
{
this.Limit = lim;
this.watcher = wat;
if ( this.watcher != null )
this.hash = this.watcher.hashCode() ^ ((Double) lim).hashCode();
if( this.watcher != null )
this.hash = this.watcher.hashCode() ^ ( (Double) lim ).hashCode();
else
this.hash = ((Double) lim).hashCode();
this.hash = ( (Double) lim ).hashCode();
}
@Override
@@ -45,9 +48,8 @@ public class EnergyThreshold implements Comparable<EnergyThreshold>
}
@Override
public int compareTo(EnergyThreshold o)
public int compareTo( EnergyThreshold o )
{
return ItemSorters.compareDouble( this.Limit, o.Limit );
}
}
+132 -130
View File
@@ -18,6 +18,7 @@
package appeng.me.energy;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
@@ -26,12 +27,141 @@ import appeng.api.networking.energy.IEnergyWatcher;
import appeng.api.networking.energy.IEnergyWatcherHost;
import appeng.me.cache.EnergyGridCache;
/**
* Maintain my interests, and a global watch list, they should always be fully synchronized.
*/
public class EnergyWatcher implements IEnergyWatcher
{
final EnergyGridCache gsc;
final IEnergyWatcherHost myObject;
final HashSet<EnergyThreshold> myInterests = new HashSet<EnergyThreshold>();
public EnergyWatcher( EnergyGridCache cache, IEnergyWatcherHost host )
{
this.gsc = cache;
this.myObject = host;
}
public void post( EnergyGridCache energyGridCache )
{
this.myObject.onThresholdPass( energyGridCache );
}
public IEnergyWatcherHost getHost()
{
return this.myObject;
}
@Override
public int size()
{
return this.myInterests.size();
}
@Override
public boolean isEmpty()
{
return this.myInterests.isEmpty();
}
@Override
public boolean contains( Object o )
{
return this.myInterests.contains( o );
}
@Override
public Iterator<Double> iterator()
{
return new EnergyWatcherIterator( this, this.myInterests.iterator() );
}
@Override
public Object[] toArray()
{
return this.myInterests.toArray();
}
@Override
public <T> T[] toArray( T[] a )
{
return this.myInterests.toArray( a );
}
@Override
public boolean add( Double e )
{
if( this.myInterests.contains( e ) )
return false;
EnergyThreshold eh = new EnergyThreshold( e, this );
return this.gsc.interests.add( eh ) && this.myInterests.add( eh );
}
@Override
public boolean remove( Object o )
{
EnergyThreshold eh = new EnergyThreshold( (Double) o, this );
return this.myInterests.remove( eh ) && this.gsc.interests.remove( eh );
}
@Override
public boolean containsAll( Collection<?> c )
{
return this.myInterests.containsAll( c );
}
@Override
public boolean addAll( Collection<? extends Double> c )
{
boolean didChange = false;
for( Double o : c )
didChange = this.add( o ) || didChange;
return didChange;
}
@Override
public boolean removeAll( Collection<?> c )
{
boolean didSomething = false;
for( Object o : c )
didSomething = this.remove( o ) || didSomething;
return didSomething;
}
@Override
public boolean retainAll( Collection<?> c )
{
boolean changed = false;
Iterator<Double> i = this.iterator();
while( i.hasNext() )
{
if( !c.contains( i.next() ) )
{
i.remove();
changed = true;
}
}
return changed;
}
@Override
public void clear()
{
Iterator<EnergyThreshold> i = this.myInterests.iterator();
while( i.hasNext() )
{
this.gsc.interests.remove( i.next() );
i.remove();
}
}
class EnergyWatcherIterator implements Iterator<Double>
{
@@ -39,7 +169,8 @@ public class EnergyWatcher implements IEnergyWatcher
final Iterator<EnergyThreshold> interestIterator;
EnergyThreshold myLast;
public EnergyWatcherIterator(EnergyWatcher parent, Iterator<EnergyThreshold> i) {
public EnergyWatcherIterator( EnergyWatcher parent, Iterator<EnergyThreshold> i )
{
this.watcher = parent;
this.interestIterator = i;
}
@@ -63,134 +194,5 @@ public class EnergyWatcher implements IEnergyWatcher
EnergyWatcher.this.gsc.interests.remove( this.myLast );
this.interestIterator.remove();
}
}
final EnergyGridCache gsc;
final IEnergyWatcherHost myObject;
final HashSet<EnergyThreshold> myInterests = new HashSet<EnergyThreshold>();
public void post(EnergyGridCache energyGridCache)
{
this.myObject.onThresholdPass( energyGridCache );
}
public EnergyWatcher(EnergyGridCache cache, IEnergyWatcherHost host) {
this.gsc = cache;
this.myObject = host;
}
public IEnergyWatcherHost getHost()
{
return this.myObject;
}
@Override
public boolean add(Double e)
{
if ( this.myInterests.contains( e ) )
return false;
EnergyThreshold eh = new EnergyThreshold( e, this );
return this.gsc.interests.add( eh ) && this.myInterests.add( eh );
}
@Override
public boolean addAll(Collection<? extends Double> c)
{
boolean didChange = false;
for (Double o : c)
didChange = this.add( o ) || didChange;
return didChange;
}
@Override
public void clear()
{
Iterator<EnergyThreshold> i = this.myInterests.iterator();
while (i.hasNext())
{
this.gsc.interests.remove( i.next() );
i.remove();
}
}
@Override
public boolean contains(Object o)
{
return this.myInterests.contains( o );
}
@Override
public boolean containsAll(Collection<?> c)
{
return this.myInterests.containsAll( c );
}
@Override
public boolean isEmpty()
{
return this.myInterests.isEmpty();
}
@Override
public Iterator<Double> iterator()
{
return new EnergyWatcherIterator( this, this.myInterests.iterator() );
}
@Override
public boolean remove(Object o)
{
EnergyThreshold eh = new EnergyThreshold( (Double) o, this );
return this.myInterests.remove( eh ) && this.gsc.interests.remove( eh );
}
@Override
public boolean removeAll(Collection<?> c)
{
boolean didSomething = false;
for (Object o : c)
didSomething = this.remove( o ) || didSomething;
return didSomething;
}
@Override
public boolean retainAll(Collection<?> c)
{
boolean changed = false;
Iterator<Double> i = this.iterator();
while (i.hasNext())
{
if ( !c.contains( i.next() ) )
{
i.remove();
changed = true;
}
}
return changed;
}
@Override
public int size()
{
return this.myInterests.size();
}
@Override
public Object[] toArray()
{
return this.myInterests.toArray();
}
@Override
public <T> T[] toArray(T[] a)
{
return this.myInterests.toArray( a );
}
}
@@ -18,6 +18,7 @@
package appeng.me.helpers;
import java.util.Collections;
import java.util.EnumSet;
@@ -51,40 +52,25 @@ import appeng.parts.networking.PartCable;
import appeng.tile.AEBaseTile;
import appeng.util.Platform;
public class AENetworkProxy implements IGridBlock
{
final private IGridProxyable gp;
final private boolean worldNode;
final private String nbtName; // name
public AEColor myColor = AEColor.Transparent;
NBTTagCompound data = null; // input
private ItemStack myRepInstance;
private boolean isReady = false;
private IGridNode node = null;
private EnumSet<ForgeDirection> validSides;
public AEColor myColor = AEColor.Transparent;
private EnumSet<GridFlags> flags = EnumSet.noneOf( GridFlags.class );
private double idleDraw = 1.0;
final private String nbtName; // name
NBTTagCompound data = null; // input
private EntityPlayer owner;
@Override
public ItemStack getMachineRepresentation()
public AENetworkProxy( IGridProxyable te, String nbtName, ItemStack visual, boolean inWorld )
{
return this.myRepInstance;
}
public void setVisualRepresentation(ItemStack is)
{
this.myRepInstance = is;
}
public AENetworkProxy(IGridProxyable te, String nbtName, ItemStack visual, boolean inWorld) {
this.gp = te;
this.nbtName = nbtName;
this.worldNode = inWorld;
@@ -92,27 +78,201 @@ public class AENetworkProxy implements IGridBlock
this.validSides = EnumSet.allOf( ForgeDirection.class );
}
public void writeToNBT(NBTTagCompound tag)
public void setVisualRepresentation( ItemStack is )
{
if ( this.node != null )
this.myRepInstance = is;
}
public void writeToNBT( NBTTagCompound tag )
{
if( this.node != null )
this.node.saveToNBT( this.nbtName, tag );
}
public void readFromNBT(NBTTagCompound tag)
public void setValidSides( EnumSet<ForgeDirection> validSides )
{
this.validSides = validSides;
if( this.node != null )
this.node.updateState();
}
public void validate()
{
if( this.gp instanceof AEBaseTile )
TickHandler.INSTANCE.addInit( (AEBaseTile) this.gp );
}
public void onChunkUnload()
{
this.isReady = false;
this.invalidate();
}
public void invalidate()
{
this.isReady = false;
if( this.node != null )
{
this.node.destroy();
this.node = null;
}
}
public void onReady()
{
this.isReady = true;
// send orientation based directionality to the node.
if( this.gp instanceof IOrientable )
{
IOrientable ori = (IOrientable) this.gp;
if( ori.canBeRotated() )
ori.setOrientation( ori.getForward(), ori.getUp() );
}
this.getNode();
}
public IGridNode getNode()
{
if( this.node == null && Platform.isServer() && this.isReady )
{
this.node = AEApi.instance().createGridNode( this );
this.readFromNBT( this.data );
this.node.updateState();
}
return this.node;
}
public void readFromNBT( NBTTagCompound tag )
{
this.data = tag;
if ( this.node != null && this.data != null )
if( this.node != null && this.data != null )
{
this.node.loadFromNBT( this.nbtName, this.data );
this.data = null;
}
else if ( this.node != null && this.owner != null )
else if( this.node != null && this.owner != null )
{
this.node.setPlayerID( WorldSettings.getInstance().getPlayerID( this.owner.getGameProfile() ) );
this.owner = null;
}
}
public IPathingGrid getPath() throws GridAccessException
{
IGrid grid = this.getGrid();
if( grid == null )
throw new GridAccessException();
IPathingGrid pg = grid.getCache( IPathingGrid.class );
if( pg == null )
throw new GridAccessException();
return pg;
}
/**
* short cut!
*
* @return grid of node
*
* @throws GridAccessException of node or grid is null
*/
public IGrid getGrid() throws GridAccessException
{
if( this.node == null )
throw new GridAccessException();
IGrid grid = this.node.getGrid();
if( grid == null )
throw new GridAccessException();
return grid;
}
public ITickManager getTick() throws GridAccessException
{
IGrid grid = this.getGrid();
if( grid == null )
throw new GridAccessException();
ITickManager pg = grid.getCache( ITickManager.class );
if( pg == null )
throw new GridAccessException();
return pg;
}
public IStorageGrid getStorage() throws GridAccessException
{
IGrid grid = this.getGrid();
if( grid == null )
throw new GridAccessException();
IStorageGrid pg = grid.getCache( IStorageGrid.class );
if( pg == null )
throw new GridAccessException();
return pg;
}
public P2PCache getP2P() throws GridAccessException
{
IGrid grid = this.getGrid();
if( grid == null )
throw new GridAccessException();
P2PCache pg = grid.getCache( P2PCache.class );
if( pg == null )
throw new GridAccessException();
return pg;
}
public ISecurityGrid getSecurity() throws GridAccessException
{
IGrid grid = this.getGrid();
if( grid == null )
throw new GridAccessException();
ISecurityGrid sg = grid.getCache( ISecurityGrid.class );
if( sg == null )
throw new GridAccessException();
return sg;
}
public ICraftingGrid getCrafting() throws GridAccessException
{
IGrid grid = this.getGrid();
if( grid == null )
throw new GridAccessException();
ICraftingGrid sg = grid.getCache( ICraftingGrid.class );
if( sg == null )
throw new GridAccessException();
return sg;
}
@Override
public double getIdlePowerUsage()
{
return this.idleDraw;
}
@Override
public EnumSet<GridFlags> getFlags()
{
return this.flags;
}
@Override
public boolean isWorldAccessible()
{
return this.worldNode;
}
@Override
public DimensionalCoord getLocation()
{
@@ -126,14 +286,14 @@ public class AENetworkProxy implements IGridBlock
}
@Override
public void onGridNotification(GridNotification notification)
public void onGridNotification( GridNotification notification )
{
if ( this.gp instanceof PartCable )
((PartCable) this.gp).markForUpdate();
if( this.gp instanceof PartCable )
( (PartCable) this.gp ).markForUpdate();
}
@Override
public void setNetworkStatus(IGrid grid, int channelsInUse)
public void setNetworkStatus( IGrid grid, int channelsInUse )
{
}
@@ -144,186 +304,25 @@ public class AENetworkProxy implements IGridBlock
return this.validSides;
}
public void setValidSides(EnumSet<ForgeDirection> validSides)
{
this.validSides = validSides;
if ( this.node != null )
this.node.updateState();
}
public IGridNode getNode()
{
if ( this.node == null && Platform.isServer() && this.isReady )
{
this.node = AEApi.instance().createGridNode( this );
this.readFromNBT( this.data );
this.node.updateState();
}
return this.node;
}
public void validate()
{
if ( this.gp instanceof AEBaseTile )
TickHandler.INSTANCE.addInit( (AEBaseTile) this.gp );
}
public void onChunkUnload()
{
this.isReady = false;
this.invalidate();
}
public void invalidate()
{
this.isReady = false;
if ( this.node != null )
{
this.node.destroy();
this.node = null;
}
}
public void onReady()
{
this.isReady = true;
// send orientation based directionality to the node.
if ( this.gp instanceof IOrientable )
{
IOrientable ori = (IOrientable) this.gp;
if ( ori.canBeRotated() )
ori.setOrientation( ori.getForward(), ori.getUp() );
}
this.getNode();
}
@Override
public IGridHost getMachine()
{
return this.gp;
}
/**
* short cut!
*
* @return grid of node
* @throws GridAccessException of node or grid is null
*/
public IGrid getGrid() throws GridAccessException
@Override
public void gridChanged()
{
if ( this.node == null )
throw new GridAccessException();
IGrid grid = this.node.getGrid();
if ( grid == null )
throw new GridAccessException();
return grid;
}
public IEnergyGrid getEnergy() throws GridAccessException
{
IGrid grid = this.getGrid();
if ( grid == null )
throw new GridAccessException();
IEnergyGrid eg = grid.getCache( IEnergyGrid.class );
if ( eg == null )
throw new GridAccessException();
return eg;
}
public IPathingGrid getPath() throws GridAccessException
{
IGrid grid = this.getGrid();
if ( grid == null )
throw new GridAccessException();
IPathingGrid pg = grid.getCache( IPathingGrid.class );
if ( pg == null )
throw new GridAccessException();
return pg;
}
public ITickManager getTick() throws GridAccessException
{
IGrid grid = this.getGrid();
if ( grid == null )
throw new GridAccessException();
ITickManager pg = grid.getCache( ITickManager.class );
if ( pg == null )
throw new GridAccessException();
return pg;
}
public IStorageGrid getStorage() throws GridAccessException
{
IGrid grid = this.getGrid();
if ( grid == null )
throw new GridAccessException();
IStorageGrid pg = grid.getCache( IStorageGrid.class );
if ( pg == null )
throw new GridAccessException();
return pg;
}
public P2PCache getP2P() throws GridAccessException
{
IGrid grid = this.getGrid();
if ( grid == null )
throw new GridAccessException();
P2PCache pg = grid.getCache( P2PCache.class );
if ( pg == null )
throw new GridAccessException();
return pg;
}
public ISecurityGrid getSecurity() throws GridAccessException
{
IGrid grid = this.getGrid();
if ( grid == null )
throw new GridAccessException();
ISecurityGrid sg = grid.getCache( ISecurityGrid.class );
if ( sg == null )
throw new GridAccessException();
return sg;
}
public ICraftingGrid getCrafting() throws GridAccessException
{
IGrid grid = this.getGrid();
if ( grid == null )
throw new GridAccessException();
ICraftingGrid sg = grid.getCache( ICraftingGrid.class );
if ( sg == null )
throw new GridAccessException();
return sg;
this.gp.gridChanged();
}
@Override
public boolean isWorldAccessible()
public ItemStack getMachineRepresentation()
{
return this.worldNode;
return this.myRepInstance;
}
@Override
public EnumSet<GridFlags> getFlags()
{
return this.flags;
}
public void setFlags(GridFlags... requireChannel)
public void setFlags( GridFlags... requireChannel )
{
EnumSet<GridFlags> flags = EnumSet.noneOf( GridFlags.class );
@@ -332,24 +331,18 @@ public class AENetworkProxy implements IGridBlock
this.flags = flags;
}
@Override
public double getIdlePowerUsage()
{
return this.idleDraw;
}
public void setIdlePowerUsage(double idle)
public void setIdlePowerUsage( double idle )
{
this.idleDraw = idle;
if ( this.node != null )
if( this.node != null )
{
try
{
IGrid g = this.getGrid();
g.postEvent( new MENetworkPowerIdleChange( this.node ) );
}
catch (GridAccessException e)
catch( GridAccessException e )
{
// not ready for this yet..
}
@@ -363,7 +356,7 @@ public class AENetworkProxy implements IGridBlock
public boolean isActive()
{
if ( this.node == null )
if( this.node == null )
return false;
return this.node.isActive();
@@ -375,21 +368,25 @@ public class AENetworkProxy implements IGridBlock
{
return this.getEnergy().isNetworkPowered();
}
catch (GridAccessException e)
catch( GridAccessException e )
{
return false;
}
}
@Override
public void gridChanged()
public IEnergyGrid getEnergy() throws GridAccessException
{
this.gp.gridChanged();
IGrid grid = this.getGrid();
if( grid == null )
throw new GridAccessException();
IEnergyGrid eg = grid.getCache( IEnergyGrid.class );
if( eg == null )
throw new GridAccessException();
return eg;
}
public void setOwner(EntityPlayer player)
public void setOwner( EntityPlayer player )
{
this.owner = player;
}
}
@@ -18,6 +18,7 @@
package appeng.me.helpers;
import java.util.Iterator;
import net.minecraft.item.ItemStack;
@@ -29,24 +30,26 @@ import appeng.me.cluster.IAEMultiBlock;
import appeng.util.iterators.ChainedIterator;
import appeng.util.iterators.ProxyNodeIterator;
public class AENetworkProxyMultiblock extends AENetworkProxy implements IGridMultiblock
{
IAECluster getCluster()
public AENetworkProxyMultiblock( IGridProxyable te, String nbtName, ItemStack itemStack, boolean inWorld )
{
return ((IAEMultiBlock) this.getMachine()).getCluster();
}
public AENetworkProxyMultiblock(IGridProxyable te, String nbtName, ItemStack itemStack, boolean inWorld) {
super( te, nbtName, itemStack, inWorld );
}
@Override
public Iterator<IGridNode> getMultiblockNodes()
{
if ( this.getCluster() == null )
if( this.getCluster() == null )
return new ChainedIterator<IGridNode>();
return new ProxyNodeIterator( this.getCluster().getTiles() );
}
IAECluster getCluster()
{
return ( (IAEMultiBlock) this.getMachine() ).getCluster();
}
}
@@ -18,28 +18,30 @@
package appeng.me.helpers;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.networking.IGridNode;
import appeng.api.networking.energy.IEnergySource;
public class ChannelPowerSrc implements IEnergySource
{
final IGridNode node;
final IEnergySource realSrc;
public ChannelPowerSrc(IGridNode networkNode, IEnergySource src) {
public ChannelPowerSrc( IGridNode networkNode, IEnergySource src )
{
this.node = networkNode;
this.realSrc = src;
}
@Override
public double extractAEPower(double amt, Actionable mode, PowerMultiplier usePowerMultiplier)
public double extractAEPower( double amt, Actionable mode, PowerMultiplier usePowerMultiplier )
{
if ( this.node.isActive() )
if( this.node.isActive() )
return this.realSrc.extractAEPower( amt, mode, usePowerMultiplier );
return 0.0;
}
}
@@ -18,6 +18,7 @@
package appeng.me.helpers;
import java.util.Collection;
import java.util.LinkedList;
@@ -25,34 +26,22 @@ import com.google.common.collect.Multimap;
import appeng.api.storage.data.IAEStack;
public class GenericInterestManager<T>
{
class SavedTransactions
{
public final boolean put;
public final IAEStack stack;
public final T iw;
public SavedTransactions(boolean putOperation, IAEStack myStack, T watcher) {
this.put = putOperation;
this.stack = myStack;
this.iw = watcher;
}
}
private final Multimap<IAEStack, T> container;
private LinkedList<SavedTransactions> transactions = null;
private int transDepth = 0;
public GenericInterestManager(Multimap<IAEStack, T> interests) {
public GenericInterestManager( Multimap<IAEStack, T> interests )
{
this.container = interests;
}
public void enableTransactions()
{
if ( this.transDepth == 0 )
if( this.transDepth == 0 )
this.transactions = new LinkedList<SavedTransactions>();
this.transDepth++;
@@ -62,14 +51,14 @@ public class GenericInterestManager<T>
{
this.transDepth--;
if ( this.transDepth == 0 )
if( this.transDepth == 0 )
{
LinkedList<SavedTransactions> myActions = this.transactions;
this.transactions = null;
for (SavedTransactions t : myActions)
for( SavedTransactions t : myActions )
{
if ( t.put )
if( t.put )
this.put( t.stack, t.iw );
else
this.remove( t.stack, t.iw );
@@ -77,19 +66,9 @@ public class GenericInterestManager<T>
}
}
public boolean containsKey(IAEStack stack)
public boolean put( IAEStack stack, T iw )
{
return this.container.containsKey( stack );
}
public Collection<T> get(IAEStack stack)
{
return this.container.get( stack );
}
public boolean put(IAEStack stack, T iw)
{
if ( this.transactions != null )
if( this.transactions != null )
{
this.transactions.add( new SavedTransactions( true, stack, iw ) );
return true;
@@ -98,9 +77,9 @@ public class GenericInterestManager<T>
return this.container.put( stack, iw );
}
public boolean remove(IAEStack stack, T iw)
public boolean remove( IAEStack stack, T iw )
{
if ( this.transactions != null )
if( this.transactions != null )
{
this.transactions.add( new SavedTransactions( true, stack, iw ) );
return true;
@@ -109,4 +88,28 @@ public class GenericInterestManager<T>
return this.container.remove( stack, iw );
}
public boolean containsKey( IAEStack stack )
{
return this.container.containsKey( stack );
}
public Collection<T> get( IAEStack stack )
{
return this.container.get( stack );
}
class SavedTransactions
{
public final boolean put;
public final IAEStack stack;
public final T iw;
public SavedTransactions( boolean putOperation, IAEStack myStack, T watcher )
{
this.put = putOperation;
this.stack = myStack;
this.iw = watcher;
}
}
}
@@ -18,9 +18,11 @@
package appeng.me.helpers;
import appeng.api.networking.IGridHost;
import appeng.api.util.DimensionalCoord;
public interface IGridProxyable extends IGridHost
{
@@ -18,23 +18,26 @@
package appeng.me.pathfinding;
import appeng.api.networking.IGridConnection;
import appeng.api.networking.IGridConnectionVisitor;
import appeng.api.networking.IGridNode;
import appeng.me.GridConnection;
import appeng.me.GridNode;
public class AdHocChannelUpdater implements IGridConnectionVisitor
{
final private int usedChannels;
public AdHocChannelUpdater(int used) {
public AdHocChannelUpdater( int used )
{
this.usedChannels = used;
}
@Override
public boolean visitNode(IGridNode n)
public boolean visitNode( IGridNode n )
{
GridNode gn = (GridNode) n;
gn.setControllerRoute( null, true );
@@ -44,7 +47,7 @@ public class AdHocChannelUpdater implements IGridConnectionVisitor
}
@Override
public void visitConnection(IGridConnection gcc)
public void visitConnection( IGridConnection gcc )
{
GridConnection gc = (GridConnection) gcc;
gc.setControllerRoute( null, true );
@@ -18,17 +18,19 @@
package appeng.me.pathfinding;
import appeng.api.networking.IGridConnection;
import appeng.api.networking.IGridConnectionVisitor;
import appeng.api.networking.IGridNode;
import appeng.me.GridConnection;
import appeng.me.GridNode;
public class ControllerChannelUpdater implements IGridConnectionVisitor
{
@Override
public boolean visitNode(IGridNode n)
public boolean visitNode( IGridNode n )
{
GridNode gn = (GridNode) n;
gn.finalizeChannels();
@@ -36,7 +38,7 @@ public class ControllerChannelUpdater implements IGridConnectionVisitor
}
@Override
public void visitConnection(IGridConnection gcc)
public void visitConnection( IGridConnection gcc )
{
GridConnection gc = (GridConnection) gcc;
gc.finalizeChannels();
@@ -18,26 +18,27 @@
package appeng.me.pathfinding;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IGridVisitor;
import appeng.tile.networking.TileController;
public class ControllerValidator implements IGridVisitor
{
public boolean isValid = true;
public int found = 0;
int minX;
int minY;
int minZ;
int maxX;
int maxY;
int maxZ;
public boolean isValid = true;
public int found = 0;
public ControllerValidator(int x, int y, int z) {
public ControllerValidator( int x, int y, int z )
{
this.minX = x;
this.minY = y;
this.minZ = z;
@@ -47,10 +48,10 @@ public class ControllerValidator implements IGridVisitor
}
@Override
public boolean visitNode(IGridNode n)
public boolean visitNode( IGridNode n )
{
IGridHost host = n.getMachine();
if ( this.isValid && host instanceof TileController )
if( this.isValid && host instanceof TileController )
{
TileController c = (TileController) host;
@@ -61,7 +62,7 @@ public class ControllerValidator implements IGridVisitor
this.minZ = Math.min( c.zCoord, this.minZ );
this.maxZ = Math.max( c.zCoord, this.maxZ );
if ( this.maxX - this.minX < 7 && this.maxY - this.minY < 7 && this.maxZ - this.minZ < 7 )
if( this.maxX - this.minX < 7 && this.maxY - this.minY < 7 && this.maxZ - this.minZ < 7 )
{
this.found++;
return true;
@@ -18,17 +18,19 @@
package appeng.me.pathfinding;
import java.util.EnumSet;
import appeng.api.networking.GridFlags;
import appeng.api.util.IReadOnlyCollection;
public interface IPathItem
{
IPathItem getControllerRoute();
void setControllerRoute(IPathItem fast, boolean zeroOut);
void setControllerRoute( IPathItem fast, boolean zeroOut );
/**
* used to determine if the finder can continue.
@@ -43,7 +45,7 @@ public interface IPathItem
/**
* add one to the channel count, this is mostly for cables.
*/
void incrementChannelCount(int usedChannels);
void incrementChannelCount( int usedChannels );
/**
* get the grid flags for this IPathItem.
@@ -56,5 +58,4 @@ public interface IPathItem
* channels are done, wrap it up.
*/
void finalizeChannels();
}
@@ -18,6 +18,7 @@
package appeng.me.pathfinding;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedList;
@@ -29,14 +30,17 @@ import appeng.api.networking.IGridMultiblock;
import appeng.api.networking.IGridNode;
import appeng.me.cache.PathGridCache;
public class PathSegment
{
public boolean isDead;
final PathGridCache pgc;
final Set<IPathItem> semiOpen;
final Set<IPathItem> closed;
public boolean isDead;
List<IPathItem> open;
public PathSegment(PathGridCache myPGC, List<IPathItem> open, Set<IPathItem> semiOpen, Set<IPathItem> closed)
public PathSegment( PathGridCache myPGC, List<IPathItem> open, Set<IPathItem> semiOpen, Set<IPathItem> closed )
{
this.open = open;
this.semiOpen = semiOpen;
@@ -45,44 +49,40 @@ public class PathSegment
this.isDead = false;
}
List<IPathItem> open;
final Set<IPathItem> semiOpen;
final Set<IPathItem> closed;
public boolean step()
{
List<IPathItem> oldOpen = this.open;
this.open = new LinkedList<IPathItem>();
for (IPathItem i : oldOpen)
for( IPathItem i : oldOpen )
{
for (IPathItem pi : i.getPossibleOptions())
for( IPathItem pi : i.getPossibleOptions() )
{
EnumSet<GridFlags> flags = pi.getFlags();
if ( !this.closed.contains( pi ) )
if( !this.closed.contains( pi ) )
{
pi.setControllerRoute( i, true );
if ( flags.contains( GridFlags.REQUIRE_CHANNEL ) )
if( flags.contains( GridFlags.REQUIRE_CHANNEL ) )
{
// close the semi open.
if ( !this.semiOpen.contains( pi ) )
if( !this.semiOpen.contains( pi ) )
{
boolean worked;
if ( flags.contains( GridFlags.COMPRESSED_CHANNEL ) )
if( flags.contains( GridFlags.COMPRESSED_CHANNEL ) )
worked = this.useDenseChannel( pi );
else
worked = this.useChannel( pi );
if ( worked && flags.contains( GridFlags.MULTIBLOCK ) )
if( worked && flags.contains( GridFlags.MULTIBLOCK ) )
{
Iterator<IGridNode> oni = ((IGridMultiblock) ((IGridNode) pi).getGridBlock()).getMultiblockNodes();
while (oni.hasNext())
Iterator<IGridNode> oni = ( (IGridMultiblock) ( (IGridNode) pi ).getGridBlock() ).getMultiblockNodes();
while( oni.hasNext() )
{
IGridNode otherNodes = oni.next();
if ( otherNodes != pi )
if( otherNodes != pi )
this.semiOpen.add( (IPathItem) otherNodes );
}
}
@@ -103,19 +103,19 @@ public class PathSegment
return this.open.isEmpty();
}
private boolean useChannel(IPathItem start)
private boolean useDenseChannel( IPathItem start )
{
IPathItem pi = start;
while (pi != null)
while( pi != null )
{
if ( !pi.canSupportMoreChannels() )
if( !pi.canSupportMoreChannels() || pi.getFlags().contains( GridFlags.CANNOT_CARRY_COMPRESSED ) )
return false;
pi = pi.getControllerRoute();
}
pi = start;
while (pi != null)
while( pi != null )
{
this.pgc.channelsByBlocks++;
pi.incrementChannelCount( 1 );
@@ -126,19 +126,19 @@ public class PathSegment
return true;
}
private boolean useDenseChannel(IPathItem start)
private boolean useChannel( IPathItem start )
{
IPathItem pi = start;
while (pi != null)
while( pi != null )
{
if ( !pi.canSupportMoreChannels() || pi.getFlags().contains( GridFlags.CANNOT_CARRY_COMPRESSED ) )
if( !pi.canSupportMoreChannels() )
return false;
pi = pi.getControllerRoute();
}
pi = start;
while (pi != null)
while( pi != null )
{
this.pgc.channelsByBlocks++;
pi.incrementChannelCount( 1 );
@@ -148,5 +148,4 @@ public class PathSegment
this.pgc.channelsInUse++;
return true;
}
}
@@ -18,6 +18,7 @@
package appeng.me.storage;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
@@ -31,45 +32,46 @@ import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.tile.misc.TileCondenser;
public class AEExternalHandler implements IExternalStorageHandler
{
@Override
public boolean canHandle(TileEntity te, ForgeDirection d, StorageChannel channel, BaseActionSource mySrc)
public boolean canHandle( TileEntity te, ForgeDirection d, StorageChannel channel, BaseActionSource mySrc )
{
if ( channel == StorageChannel.ITEMS && te instanceof ITileStorageMonitorable )
return ((ITileStorageMonitorable) te).getMonitorable( d, mySrc ) != null;
if( channel == StorageChannel.ITEMS && te instanceof ITileStorageMonitorable )
return ( (ITileStorageMonitorable) te ).getMonitorable( d, mySrc ) != null;
return te instanceof TileCondenser;
}
@Override
public IMEInventory getInventory(TileEntity te, ForgeDirection d, StorageChannel channel, BaseActionSource src)
public IMEInventory getInventory( TileEntity te, ForgeDirection d, StorageChannel channel, BaseActionSource src )
{
if ( te instanceof TileCondenser )
if( te instanceof TileCondenser )
{
if ( channel == StorageChannel.ITEMS )
if( channel == StorageChannel.ITEMS )
return new VoidItemInventory( (TileCondenser) te );
else
return new VoidFluidInventory( (TileCondenser) te );
}
if ( te instanceof ITileStorageMonitorable )
if( te instanceof ITileStorageMonitorable )
{
ITileStorageMonitorable iface = (ITileStorageMonitorable) te;
IStorageMonitorable sm = iface.getMonitorable( d, src );
if ( channel == StorageChannel.ITEMS && sm != null )
if( channel == StorageChannel.ITEMS && sm != null )
{
IMEInventory<IAEItemStack> ii = sm.getItemInventory();
if ( ii != null )
if( ii != null )
return ii;
}
if ( channel == StorageChannel.FLUIDS && sm != null )
if( channel == StorageChannel.FLUIDS && sm != null )
{
IMEInventory<IAEFluidStack> fi = sm.getFluidInventory();
if ( fi != null )
if( fi != null )
return fi;
}
}
+364 -366
View File
@@ -18,6 +18,7 @@
package appeng.me.storage;
import java.util.HashSet;
import net.minecraft.inventory.IInventory;
@@ -43,6 +44,7 @@ import appeng.api.storage.data.IItemList;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
public class CellInventory implements ICellInventory
{
@@ -54,50 +56,285 @@ public class CellInventory implements ICellInventory
static final String ITEM_PRE_FORMATTED_SLOT = "PF#";
static final String ITEM_PRE_FORMATTED_NAME = "PN";
static final String ITEM_PRE_FORMATTED_FUZZY = "FP";
private static final HashSet<Integer> BLACK_LIST = new HashSet<Integer>();
static protected String[] ITEM_SLOT_ARR;
static protected String[] ITEM_SLOT_COUNT_ARR;
final protected NBTTagCompound tagCompound;
final protected ISaveProvider container;
protected int MAX_ITEM_TYPES = 63;
protected short storedItems = 0;
protected int storedItemCount = 0;
protected IItemList<IAEItemStack> cellItems;
protected ItemStack i;
protected IStorageCell CellType;
final protected ISaveProvider container;
protected CellInventory(NBTTagCompound data, ISaveProvider container) {
protected CellInventory( NBTTagCompound data, ISaveProvider container )
{
this.tagCompound = data;
this.container = container;
}
protected void loadCellItems()
protected CellInventory( ItemStack o, ISaveProvider container ) throws AppEngException
{
if ( this.cellItems == null )
this.cellItems = AEApi.instance().storage().createItemList();
this.cellItems.resetStatus(); // clears totals and stuff.
int types = (int) this.getStoredItemTypes();
for (int x = 0; x < types; x++)
if( ITEM_SLOT_ARR == null )
{
ItemStack t = ItemStack.loadItemStackFromNBT( this.tagCompound.getCompoundTag( ITEM_SLOT_ARR[x] ) );
if ( t != null )
{
t.stackSize = this.tagCompound.getInteger( ITEM_SLOT_COUNT_ARR[x] );
ITEM_SLOT_ARR = new String[this.MAX_ITEM_TYPES];
ITEM_SLOT_COUNT_ARR = new String[this.MAX_ITEM_TYPES];
if ( t.stackSize > 0 )
for( int x = 0; x < this.MAX_ITEM_TYPES; x++ )
{
ITEM_SLOT_ARR[x] = ITEM_SLOT + x;
ITEM_SLOT_COUNT_ARR[x] = ITEM_SLOT_COUNT + x;
}
}
if( o == null )
{
throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" );
}
this.CellType = null;
this.i = o;
Item type = this.i.getItem();
if( type instanceof IStorageCell )
{
this.CellType = (IStorageCell) this.i.getItem();
this.MAX_ITEM_TYPES = this.CellType.getTotalTypes( this.i );
}
if( this.CellType == null )
{
throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" );
}
if( !this.CellType.isStorageCell( this.i ) )
{
throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" );
}
if( this.MAX_ITEM_TYPES > 63 )
this.MAX_ITEM_TYPES = 63;
if( this.MAX_ITEM_TYPES < 1 )
this.MAX_ITEM_TYPES = 1;
this.container = container;
this.tagCompound = Platform.openNbtData( o );
this.storedItems = this.tagCompound.getShort( ITEM_TYPE_TAG );
this.storedItemCount = this.tagCompound.getInteger( ITEM_COUNT_TAG );
this.cellItems = null;
}
public static IMEInventoryHandler getCell( ItemStack o, ISaveProvider container2 )
{
try
{
return new CellInventoryHandler( new CellInventory( o, container2 ) );
}
catch( AppEngException e )
{
return null;
}
}
private static boolean isStorageCell( ItemStack i )
{
if( i == null )
{
return false;
}
try
{
Item type = i.getItem();
if( type instanceof IStorageCell )
{
return !( (IStorageCell) type ).storableInStorageCell();
}
}
catch( Throwable err )
{
return true;
}
return false;
}
public static boolean isCell( ItemStack i )
{
if( i == null )
{
return false;
}
Item type = i.getItem();
if( type instanceof IStorageCell )
{
return ( (IStorageCell) type ).isStorageCell( i );
}
return false;
}
public static void addBasicBlackList( int itemID, int Meta )
{
BLACK_LIST.add( ( Meta << Platform.DEF_OFFSET ) | itemID );
}
public static boolean isBlackListed( IAEItemStack input )
{
if( BLACK_LIST.contains( ( OreDictionary.WILDCARD_VALUE << Platform.DEF_OFFSET ) | Item.getIdFromItem( input.getItem() ) ) )
return true;
return BLACK_LIST.contains( ( input.getItemDamage() << Platform.DEF_OFFSET ) | Item.getIdFromItem( input.getItem() ) );
}
private boolean isEmpty( IMEInventory meInventory )
{
return meInventory.getAvailableItems( AEApi.instance().storage().createItemList() ).isEmpty();
}
@Override
public IAEItemStack injectItems( IAEItemStack input, Actionable mode, BaseActionSource src )
{
if( input == null )
return null;
if( input.getStackSize() == 0 )
return null;
if( isBlackListed( input ) || this.CellType.isBlackListed( this.i, input ) )
return input;
ItemStack sharedItemStack = input.getItemStack();
if( CellInventory.isStorageCell( sharedItemStack ) )
{
IMEInventory meInventory = getCell( sharedItemStack, null );
if( meInventory != null && !this.isEmpty( meInventory ) )
return input;
}
IAEItemStack l = this.getCellItems().findPrecise( input );
if( l != null )
{
long remainingItemSlots = this.getRemainingItemCount();
if( remainingItemSlots < 0 )
return input;
if( input.getStackSize() > remainingItemSlots )
{
IAEItemStack r = input.copy();
r.setStackSize( r.getStackSize() - remainingItemSlots );
if( mode == Actionable.MODULATE )
{
this.cellItems.add( AEItemStack.create( t ) );
l.setStackSize( l.getStackSize() + remainingItemSlots );
this.updateItemCount( remainingItemSlots );
this.saveChanges();
}
return r;
}
else
{
if( mode == Actionable.MODULATE )
{
l.setStackSize( l.getStackSize() + input.getStackSize() );
this.updateItemCount( input.getStackSize() );
this.saveChanges();
}
return null;
}
}
if( this.canHoldNewItem() ) // room for new type, and for at least one item!
{
int remainingItemCount = (int) this.getRemainingItemCount() - this.getBytesPerType() * 8;
if( remainingItemCount > 0 )
{
if( input.getStackSize() > remainingItemCount )
{
ItemStack toReturn = Platform.cloneItemStack( sharedItemStack );
toReturn.stackSize = sharedItemStack.stackSize - remainingItemCount;
if( mode == Actionable.MODULATE )
{
ItemStack toWrite = Platform.cloneItemStack( sharedItemStack );
toWrite.stackSize = remainingItemCount;
this.cellItems.add( AEItemStack.create( toWrite ) );
this.updateItemCount( toWrite.stackSize );
this.saveChanges();
}
return AEItemStack.create( toReturn );
}
if( mode == Actionable.MODULATE )
{
this.updateItemCount( input.getStackSize() );
this.cellItems.add( input );
this.saveChanges();
}
return null;
}
}
return input;
}
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, BaseActionSource src )
{
if( request == null )
return null;
long size = Math.min( Integer.MAX_VALUE, request.getStackSize() );
IAEItemStack Results = null;
IAEItemStack l = this.getCellItems().findPrecise( request );
if( l != null )
{
Results = l.copy();
if( l.getStackSize() <= size )
{
Results.setStackSize( l.getStackSize() );
if( mode == Actionable.MODULATE )
{
this.updateItemCount( -l.getStackSize() );
l.setStackSize( 0 );
this.saveChanges();
}
}
else
{
Results.setStackSize( size );
if( mode == Actionable.MODULATE )
{
l.setStackSize( l.getStackSize() - size );
this.updateItemCount( -size );
this.saveChanges();
}
}
}
// cellItems.clean();
return Results;
}
IItemList<IAEItemStack> getCellItems()
{
if( this.cellItems == null )
{
this.cellItems = AEApi.instance().storage().createItemList();
this.loadCellItems();
}
return this.cellItems;
}
private void updateItemCount( long delta )
{
this.storedItemCount += delta;
this.tagCompound.setInteger( ITEM_COUNT_TAG, this.storedItemCount );
}
void saveChanges()
@@ -107,12 +344,12 @@ public class CellInventory implements ICellInventory
// add new pretty stuff...
int x = 0;
for (IAEItemStack v : this.cellItems)
for( IAEItemStack v : this.cellItems )
{
itemCount += v.getStackSize();
NBTBase c = this.tagCompound.getTag( ITEM_SLOT_ARR[x] );
if ( c instanceof NBTTagCompound )
if( c instanceof NBTTagCompound )
{
v.writeToNBT( (NBTTagCompound) c );
}
@@ -140,20 +377,20 @@ public class CellInventory implements ICellInventory
* if ( tagType instanceof NBTTagShort ) ((NBTTagShort) tagType).data = storedItems = (short) cellItems.size();
* else
*/
if ( this.cellItems.isEmpty() )
if( this.cellItems.isEmpty() )
{
this.tagCompound.removeTag( ITEM_TYPE_TAG );
}
else
{
this.storedItems = ( short ) this.cellItems.size();
this.storedItems = (short) this.cellItems.size();
this.tagCompound.setShort( ITEM_TYPE_TAG, this.storedItems );
}
/*
* if ( tagCount instanceof NBTTagInt ) ((NBTTagInt) tagCount).data = storedItemCount = itemCount; else
*/
if ( itemCount == 0 )
if( itemCount == 0 )
{
this.tagCompound.removeTag( ITEM_COUNT_TAG );
}
@@ -164,362 +401,46 @@ public class CellInventory implements ICellInventory
}
// clean any old crusty stuff...
for (; x < oldStoredItems && x < this.MAX_ITEM_TYPES; x++)
for(; x < oldStoredItems && x < this.MAX_ITEM_TYPES; x++ )
{
this.tagCompound.removeTag( ITEM_SLOT_ARR[x] );
this.tagCompound.removeTag( ITEM_SLOT_COUNT_ARR[x] );
}
if ( this.container != null )
if( this.container != null )
this.container.saveChanges( this );
}
protected CellInventory(ItemStack o, ISaveProvider container) throws AppEngException {
if ( ITEM_SLOT_ARR == null )
{
ITEM_SLOT_ARR = new String[this.MAX_ITEM_TYPES];
ITEM_SLOT_COUNT_ARR = new String[this.MAX_ITEM_TYPES];
for (int x = 0; x < this.MAX_ITEM_TYPES; x++)
{
ITEM_SLOT_ARR[x] = ITEM_SLOT + x;
ITEM_SLOT_COUNT_ARR[x] = ITEM_SLOT_COUNT + x;
}
}
if ( o == null )
{
throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" );
}
this.CellType = null;
this.i = o;
Item type = this.i.getItem();
if ( type instanceof IStorageCell )
{
this.CellType = (IStorageCell) this.i.getItem();
this.MAX_ITEM_TYPES = this.CellType.getTotalTypes( this.i );
}
if ( this.CellType == null )
{
throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" );
}
if ( !this.CellType.isStorageCell( this.i ) )
{
throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" );
}
if ( this.MAX_ITEM_TYPES > 63 )
this.MAX_ITEM_TYPES = 63;
if ( this.MAX_ITEM_TYPES < 1 )
this.MAX_ITEM_TYPES = 1;
this.container = container;
this.tagCompound = Platform.openNbtData( o );
this.storedItems = this.tagCompound.getShort( ITEM_TYPE_TAG );
this.storedItemCount = this.tagCompound.getInteger( ITEM_COUNT_TAG );
this.cellItems = null;
}
IItemList<IAEItemStack> getCellItems()
protected void loadCellItems()
{
if ( this.cellItems == null )
{
if( this.cellItems == null )
this.cellItems = AEApi.instance().storage().createItemList();
this.loadCellItems();
}
return this.cellItems;
}
this.cellItems.resetStatus(); // clears totals and stuff.
@Override
public int getBytesPerType()
{
return this.CellType.BytePerType( this.i );
}
int types = (int) this.getStoredItemTypes();
@Override
public boolean canHoldNewItem()
{
long bytesFree = this.getFreeBytes();
return (bytesFree > this.getBytesPerType() || (bytesFree == this.getBytesPerType() && this.getUnusedItemCount() > 0)) && this.getRemainingItemTypes() > 0;
}
public static IMEInventoryHandler getCell(ItemStack o, ISaveProvider container2)
{
try
for( int x = 0; x < types; x++ )
{
return new CellInventoryHandler( new CellInventory( o, container2 ) );
}
catch (AppEngException e)
{
return null;
}
}
private static boolean isStorageCell(ItemStack i)
{
if ( i == null )
{
return false;
}
try
{
Item type = i.getItem();
if ( type instanceof IStorageCell )
ItemStack t = ItemStack.loadItemStackFromNBT( this.tagCompound.getCompoundTag( ITEM_SLOT_ARR[x] ) );
if( t != null )
{
return !((IStorageCell) type).storableInStorageCell();
}
}
catch (Throwable err)
{
return true;
}
t.stackSize = this.tagCompound.getInteger( ITEM_SLOT_COUNT_ARR[x] );
return false;
}
public static boolean isCell(ItemStack i)
{
if ( i == null )
{
return false;
}
Item type = i.getItem();
if ( type instanceof IStorageCell )
{
return ((IStorageCell) type).isStorageCell( i );
}
return false;
}
@Override
public long getTotalBytes()
{
return this.CellType.getBytes( this.i );
}
@Override
public long getFreeBytes()
{
return this.getTotalBytes() - this.getUsedBytes();
}
@Override
public long getUsedBytes()
{
long bytesForItemCount = (this.getStoredItemCount() + this.getUnusedItemCount()) / 8;
return this.getStoredItemTypes() * this.getBytesPerType() + bytesForItemCount;
}
@Override
public long getTotalItemTypes()
{
return this.MAX_ITEM_TYPES;
}
@Override
public long getStoredItemTypes()
{
return this.storedItems;
}
@Override
public long getStoredItemCount()
{
return this.storedItemCount;
}
private void updateItemCount(long delta)
{
this.storedItemCount += delta;
this.tagCompound.setInteger( ITEM_COUNT_TAG, this.storedItemCount );
}
@Override
public long getRemainingItemTypes()
{
long basedOnStorage = this.getFreeBytes() / this.getBytesPerType();
long baseOnTotal = this.getTotalItemTypes() - this.getStoredItemTypes();
return basedOnStorage > baseOnTotal ? baseOnTotal : basedOnStorage;
}
@Override
public long getRemainingItemCount()
{
long remaining = this.getFreeBytes() * 8 + this.getUnusedItemCount();
return remaining > 0 ? remaining : 0;
}
@Override
public int getUnusedItemCount()
{
int div = (int) (this.getStoredItemCount() % 8);
if ( div == 0 )
{
return 0;
}
return 8 - div;
}
private static final HashSet<Integer> BLACK_LIST = new HashSet<Integer>();
public static void addBasicBlackList(int itemID, int Meta)
{
BLACK_LIST.add( ( Meta << Platform.DEF_OFFSET ) | itemID );
}
public static boolean isBlackListed(IAEItemStack input)
{
if ( BLACK_LIST.contains( (OreDictionary.WILDCARD_VALUE << Platform.DEF_OFFSET) | Item.getIdFromItem( input.getItem() ) ) )
return true;
return BLACK_LIST.contains( (input.getItemDamage() << Platform.DEF_OFFSET) | Item.getIdFromItem( input.getItem() ) );
}
private boolean isEmpty(IMEInventory meInventory)
{
return meInventory.getAvailableItems( AEApi.instance().storage().createItemList() ).isEmpty();
}
@Override
public IAEItemStack injectItems(IAEItemStack input, Actionable mode, BaseActionSource src)
{
if ( input == null )
return null;
if ( input.getStackSize() == 0 )
return null;
if ( isBlackListed( input ) || this.CellType.isBlackListed( this.i, input ) )
return input;
ItemStack sharedItemStack = input.getItemStack();
if ( CellInventory.isStorageCell( sharedItemStack ) )
{
IMEInventory meInventory = getCell( sharedItemStack, null );
if ( meInventory != null && !this.isEmpty( meInventory ) )
return input;
}
IAEItemStack l = this.getCellItems().findPrecise( input );
if ( l != null )
{
long remainingItemSlots = this.getRemainingItemCount();
if ( remainingItemSlots < 0 )
return input;
if ( input.getStackSize() > remainingItemSlots )
{
IAEItemStack r = input.copy();
r.setStackSize( r.getStackSize() - remainingItemSlots );
if ( mode == Actionable.MODULATE )
if( t.stackSize > 0 )
{
l.setStackSize( l.getStackSize() + remainingItemSlots );
this.updateItemCount( remainingItemSlots );
this.saveChanges();
}
return r;
}
else
{
if ( mode == Actionable.MODULATE )
{
l.setStackSize( l.getStackSize() + input.getStackSize() );
this.updateItemCount( input.getStackSize() );
this.saveChanges();
}
return null;
}
}
if ( this.canHoldNewItem() ) // room for new type, and for at least one item!
{
int remainingItemCount = (int) this.getRemainingItemCount() - this.getBytesPerType() * 8;
if ( remainingItemCount > 0 )
{
if ( input.getStackSize() > remainingItemCount )
{
ItemStack toReturn = Platform.cloneItemStack( sharedItemStack );
toReturn.stackSize = sharedItemStack.stackSize - remainingItemCount;
if ( mode == Actionable.MODULATE )
{
ItemStack toWrite = Platform.cloneItemStack( sharedItemStack );
toWrite.stackSize = remainingItemCount;
this.cellItems.add( AEItemStack.create( toWrite ) );
this.updateItemCount( toWrite.stackSize );
this.saveChanges();
}
return AEItemStack.create( toReturn );
}
if ( mode == Actionable.MODULATE )
{
this.updateItemCount( input.getStackSize() );
this.cellItems.add( input );
this.saveChanges();
}
return null;
}
}
return input;
}
@Override
public IAEItemStack extractItems(IAEItemStack request, Actionable mode, BaseActionSource src)
{
if ( request == null )
return null;
long size = Math.min( Integer.MAX_VALUE, request.getStackSize() );
IAEItemStack Results = null;
IAEItemStack l = this.getCellItems().findPrecise( request );
if ( l != null )
{
Results = l.copy();
if ( l.getStackSize() <= size )
{
Results.setStackSize( l.getStackSize() );
if ( mode == Actionable.MODULATE )
{
this.updateItemCount( -l.getStackSize() );
l.setStackSize( 0 );
this.saveChanges();
}
}
else
{
Results.setStackSize( size );
if ( mode == Actionable.MODULATE )
{
l.setStackSize( l.getStackSize() - size );
this.updateItemCount( -size );
this.saveChanges();
this.cellItems.add( AEItemStack.create( t ) );
}
}
}
return Results;
// cellItems.clean();
}
@Override
public IItemList getAvailableItems(IItemList out)
public IItemList getAvailableItems( IItemList out )
{
for (IAEItemStack i : this.getCellItems())
for( IAEItemStack i : this.getCellItems() )
out.add( i );
return out;
@@ -531,6 +452,12 @@ public class CellInventory implements ICellInventory
return StorageChannel.ITEMS;
}
@Override
public ItemStack getItemStack()
{
return this.i;
}
@Override
public double getIdleDrain()
{
@@ -556,19 +483,90 @@ public class CellInventory implements ICellInventory
}
@Override
public int getStatusForCell()
public int getBytesPerType()
{
if ( this.canHoldNewItem() )
return 1;
if ( this.getRemainingItemCount() > 0 )
return 2;
return 3;
return this.CellType.BytePerType( this.i );
}
@Override
public ItemStack getItemStack()
public boolean canHoldNewItem()
{
return this.i;
long bytesFree = this.getFreeBytes();
return ( bytesFree > this.getBytesPerType() || ( bytesFree == this.getBytesPerType() && this.getUnusedItemCount() > 0 ) ) && this.getRemainingItemTypes() > 0;
}
@Override
public long getTotalBytes()
{
return this.CellType.getBytes( this.i );
}
@Override
public long getFreeBytes()
{
return this.getTotalBytes() - this.getUsedBytes();
}
@Override
public long getUsedBytes()
{
long bytesForItemCount = ( this.getStoredItemCount() + this.getUnusedItemCount() ) / 8;
return this.getStoredItemTypes() * this.getBytesPerType() + bytesForItemCount;
}
@Override
public long getTotalItemTypes()
{
return this.MAX_ITEM_TYPES;
}
@Override
public long getStoredItemCount()
{
return this.storedItemCount;
}
@Override
public long getStoredItemTypes()
{
return this.storedItems;
}
@Override
public long getRemainingItemTypes()
{
long basedOnStorage = this.getFreeBytes() / this.getBytesPerType();
long baseOnTotal = this.getTotalItemTypes() - this.getStoredItemTypes();
return basedOnStorage > baseOnTotal ? baseOnTotal : basedOnStorage;
}
@Override
public long getRemainingItemCount()
{
long remaining = this.getFreeBytes() * 8 + this.getUnusedItemCount();
return remaining > 0 ? remaining : 0;
}
@Override
public int getUnusedItemCount()
{
int div = (int) ( this.getStoredItemCount() % 8 );
if( div == 0 )
{
return 0;
}
return 8 - div;
}
@Override
public int getStatusForCell()
{
if( this.canHoldNewItem() )
return 1;
if( this.getRemainingItemCount() > 0 )
return 2;
return 3;
}
}
@@ -18,6 +18,7 @@
package appeng.me.storage;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -38,30 +39,16 @@ import appeng.util.item.AEItemStack;
import appeng.util.prioitylist.FuzzyPriorityList;
import appeng.util.prioitylist.PrecisePriorityList;
public class CellInventoryHandler extends MEInventoryHandler<IAEItemStack> implements ICellInventoryHandler
{
NBTTagCompound openNbtData()
CellInventoryHandler( IMEInventory c )
{
return Platform.openNbtData( this.getCellInv().getItemStack() );
}
@Override
public ICellInventory getCellInv()
{
Object o = this.internal;
if ( o instanceof MEPassThrough )
o = ((MEPassThrough) o).getInternal();
return (ICellInventory) (o instanceof ICellInventory ? o : null);
}
CellInventoryHandler(IMEInventory c) {
super( c, StorageChannel.ITEMS );
ICellInventory ci = this.getCellInv();
if ( ci != null )
if( ci != null )
{
IItemList<IAEItemStack> priorityList = AEApi.instance().storage().createItemList();
@@ -72,40 +59,40 @@ public class CellInventoryHandler extends MEInventoryHandler<IAEItemStack> imple
boolean hasInverter = false;
boolean hasFuzzy = false;
for (int x = 0; x < upgrades.getSizeInventory(); x++)
for( int x = 0; x < upgrades.getSizeInventory(); x++ )
{
ItemStack is = upgrades.getStackInSlot( x );
if ( is != null && is.getItem() instanceof IUpgradeModule )
if( is != null && is.getItem() instanceof IUpgradeModule )
{
Upgrades u = ((IUpgradeModule) is.getItem()).getType( is );
if ( u != null )
Upgrades u = ( (IUpgradeModule) is.getItem() ).getType( is );
if( u != null )
{
switch (u)
switch( u )
{
case FUZZY:
hasFuzzy = true;
break;
case INVERTER:
hasInverter = true;
break;
default:
case FUZZY:
hasFuzzy = true;
break;
case INVERTER:
hasInverter = true;
break;
default:
}
}
}
}
for (int x = 0; x < config.getSizeInventory(); x++)
for( int x = 0; x < config.getSizeInventory(); x++ )
{
ItemStack is = config.getStackInSlot( x );
if ( is != null )
if( is != null )
priorityList.add( AEItemStack.create( is ) );
}
this.setWhitelist( hasInverter ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST );
if ( !priorityList.isEmpty() )
if( !priorityList.isEmpty() )
{
if ( hasFuzzy )
if( hasFuzzy )
this.setPartitionList( new FuzzyPriorityList<IAEItemStack>( priorityList, fzMode ) );
else
this.setPartitionList( new PrecisePriorityList<IAEItemStack>( priorityList ) );
@@ -113,10 +100,21 @@ public class CellInventoryHandler extends MEInventoryHandler<IAEItemStack> imple
}
}
@Override
public ICellInventory getCellInv()
{
Object o = this.internal;
if( o instanceof MEPassThrough )
o = ( (MEPassThrough) o ).getInternal();
return (ICellInventory) ( o instanceof ICellInventory ? o : null );
}
@Override
public boolean isPreformatted()
{
return ! this.getPartitionList().isEmpty();
return !this.getPartitionList().isEmpty();
}
@Override
@@ -131,14 +129,18 @@ public class CellInventoryHandler extends MEInventoryHandler<IAEItemStack> imple
return this.getWhitelist();
}
public int getStatusForCell()
NBTTagCompound openNbtData()
{
int val = this.getCellInv().getStatusForCell();
if ( val == 1 && this.isPreformatted() )
val = 2;
return val;
return Platform.openNbtData( this.getCellInv().getItemStack() );
}
public int getStatusForCell()
{
int val = this.getCellInv().getStatusForCell();
if( val == 1 && this.isPreformatted() )
val = 2;
return val;
}
}
@@ -18,6 +18,7 @@
package appeng.me.storage;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
@@ -31,21 +32,17 @@ import appeng.api.storage.data.IItemList;
import appeng.items.contents.CellConfig;
import appeng.util.item.AEItemStack;
public class CreativeCellInventory implements IMEInventoryHandler<IAEItemStack>
{
final IItemList<IAEItemStack> itemListCache = AEApi.instance().storage().createItemList();
public static IMEInventoryHandler getCell(ItemStack o)
{
return new CellInventoryHandler( new CreativeCellInventory( o ) );
}
protected CreativeCellInventory(ItemStack o)
protected CreativeCellInventory( ItemStack o )
{
CellConfig cc = new CellConfig( o );
for (ItemStack is : cc)
if ( is != null )
for( ItemStack is : cc )
if( is != null )
{
IAEItemStack i = AEItemStack.create( is );
i.setStackSize( Integer.MAX_VALUE );
@@ -53,30 +50,35 @@ public class CreativeCellInventory implements IMEInventoryHandler<IAEItemStack>
}
}
public static IMEInventoryHandler getCell( ItemStack o )
{
return new CellInventoryHandler( new CreativeCellInventory( o ) );
}
@Override
public IAEItemStack injectItems(IAEItemStack input, Actionable mode, BaseActionSource src)
public IAEItemStack injectItems( IAEItemStack input, Actionable mode, BaseActionSource src )
{
IAEItemStack local = this.itemListCache.findPrecise( input );
if ( local == null )
if( local == null )
return input;
return null;
}
@Override
public IAEItemStack extractItems(IAEItemStack request, Actionable mode, BaseActionSource src)
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, BaseActionSource src )
{
IAEItemStack local = this.itemListCache.findPrecise( request );
if ( local == null )
if( local == null )
return null;
return request.copy();
}
@Override
public IItemList<IAEItemStack> getAvailableItems(IItemList out)
public IItemList<IAEItemStack> getAvailableItems( IItemList out )
{
for (IAEItemStack ais : this.itemListCache)
for( IAEItemStack ais : this.itemListCache )
out.add( ais );
return out;
}
@@ -94,13 +96,13 @@ public class CreativeCellInventory implements IMEInventoryHandler<IAEItemStack>
}
@Override
public boolean isPrioritized(IAEItemStack input)
public boolean isPrioritized( IAEItemStack input )
{
return this.itemListCache.findPrecise( input ) != null;
}
@Override
public boolean canAccept(IAEItemStack input)
public boolean canAccept( IAEItemStack input )
{
return this.itemListCache.findPrecise( input ) != null;
}
@@ -118,9 +120,8 @@ public class CreativeCellInventory implements IMEInventoryHandler<IAEItemStack>
}
@Override
public boolean validForPass(int i)
public boolean validForPass( int i )
{
return true;
}
}
@@ -18,6 +18,7 @@
package appeng.me.storage;
import net.minecraft.item.ItemStack;
import appeng.api.config.Actionable;
@@ -27,6 +28,7 @@ import appeng.api.storage.ICellHandler;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.data.IAEStack;
public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
{
@@ -35,7 +37,8 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
final ICellHandler handler;
final IChestOrDrive cord;
public DriveWatcher(IMEInventory<T> i, ItemStack is, ICellHandler han, IChestOrDrive cod) {
public DriveWatcher( IMEInventory<T> i, ItemStack is, ICellHandler han, IChestOrDrive cod )
{
super( i, i.getChannel() );
this.is = is;
this.handler = han;
@@ -43,17 +46,17 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
}
@Override
public T injectItems(T input, Actionable type, BaseActionSource src)
public T injectItems( T input, Actionable type, BaseActionSource src )
{
long size = input.getStackSize();
T a = super.injectItems( input, type, src );
if ( a == null || a.getStackSize() != size )
if( a == null || a.getStackSize() != size )
{
int newStatus = this.handler.getStatusForCell( this.is, this.getInternal() );
if ( newStatus != this.oldStatus )
if( newStatus != this.oldStatus )
{
this.cord.blinkCell( this.getSlot() );
}
@@ -63,15 +66,15 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
}
@Override
public T extractItems(T request, Actionable type, BaseActionSource src)
public T extractItems( T request, Actionable type, BaseActionSource src )
{
T a = super.extractItems( request, type, src );
if ( a != null )
if( a != null )
{
int newStatus = this.handler.getStatusForCell( this.is, this.getInternal() );
if ( newStatus != this.oldStatus )
if( newStatus != this.oldStatus )
{
this.cord.blinkCell( this.getSlot() );
}
+125 -123
View File
@@ -18,6 +18,7 @@
package appeng.me.storage;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
@@ -27,12 +28,134 @@ import appeng.api.networking.storage.IStackWatcherHost;
import appeng.api.storage.data.IAEStack;
import appeng.me.cache.GridStorageCache;
/**
* Maintain my interests, and a global watch list, they should always be fully synchronized.
*/
public class ItemWatcher implements IStackWatcher
{
final GridStorageCache gsc;
final IStackWatcherHost myObject;
final HashSet<IAEStack> myInterests = new HashSet<IAEStack>();
public ItemWatcher( GridStorageCache cache, IStackWatcherHost host )
{
this.gsc = cache;
this.myObject = host;
}
public IStackWatcherHost getHost()
{
return this.myObject;
}
@Override
public int size()
{
return this.myInterests.size();
}
@Override
public boolean isEmpty()
{
return this.myInterests.isEmpty();
}
@Override
public boolean contains( Object o )
{
return this.myInterests.contains( o );
}
@Override
public Iterator<IAEStack> iterator()
{
return new ItemWatcherIterator( this, this.myInterests.iterator() );
}
@Override
public Object[] toArray()
{
return this.myInterests.toArray();
}
@Override
public <T> T[] toArray( T[] a )
{
return this.myInterests.toArray( a );
}
@Override
public boolean add( IAEStack e )
{
if( this.myInterests.contains( e ) )
return false;
return this.myInterests.add( e.copy() ) && this.gsc.interestManager.put( e, this );
}
@Override
public boolean remove( Object o )
{
return this.myInterests.remove( o ) && this.gsc.interestManager.remove( (IAEStack) o, this );
}
@Override
public boolean containsAll( Collection<?> c )
{
return this.myInterests.containsAll( c );
}
@Override
public boolean addAll( Collection<? extends IAEStack> c )
{
boolean didChange = false;
for( IAEStack o : c )
didChange = this.add( o ) || didChange;
return didChange;
}
@Override
public boolean removeAll( Collection<?> c )
{
boolean didSomething = false;
for( Object o : c )
didSomething = this.remove( o ) || didSomething;
return didSomething;
}
@Override
public boolean retainAll( Collection<?> c )
{
boolean changed = false;
Iterator<IAEStack> i = this.iterator();
while( i.hasNext() )
{
if( !c.contains( i.next() ) )
{
i.remove();
changed = true;
}
}
return changed;
}
@Override
public void clear()
{
Iterator<IAEStack> i = this.myInterests.iterator();
while( i.hasNext() )
{
this.gsc.interestManager.remove( i.next(), this );
i.remove();
}
}
class ItemWatcherIterator implements Iterator<IAEStack>
{
@@ -40,7 +163,8 @@ public class ItemWatcher implements IStackWatcher
final Iterator<IAEStack> interestIterator;
IAEStack myLast;
public ItemWatcherIterator(ItemWatcher parent, Iterator<IAEStack> i) {
public ItemWatcherIterator( ItemWatcher parent, Iterator<IAEStack> i )
{
this.watcher = parent;
this.interestIterator = i;
}
@@ -63,127 +187,5 @@ public class ItemWatcher implements IStackWatcher
ItemWatcher.this.gsc.interestManager.remove( this.myLast, this.watcher );
this.interestIterator.remove();
}
}
final GridStorageCache gsc;
final IStackWatcherHost myObject;
final HashSet<IAEStack> myInterests = new HashSet<IAEStack>();
public ItemWatcher(GridStorageCache cache, IStackWatcherHost host) {
this.gsc = cache;
this.myObject = host;
}
public IStackWatcherHost getHost()
{
return this.myObject;
}
@Override
public boolean add(IAEStack e)
{
if ( this.myInterests.contains( e ) )
return false;
return this.myInterests.add( e.copy() ) && this.gsc.interestManager.put( e, this );
}
@Override
public boolean addAll(Collection<? extends IAEStack> c)
{
boolean didChange = false;
for (IAEStack o : c)
didChange = this.add( o ) || didChange;
return didChange;
}
@Override
public void clear()
{
Iterator<IAEStack> i = this.myInterests.iterator();
while (i.hasNext())
{
this.gsc.interestManager.remove( i.next(), this );
i.remove();
}
}
@Override
public boolean contains(Object o)
{
return this.myInterests.contains( o );
}
@Override
public boolean containsAll(Collection<?> c)
{
return this.myInterests.containsAll( c );
}
@Override
public boolean isEmpty()
{
return this.myInterests.isEmpty();
}
@Override
public Iterator<IAEStack> iterator()
{
return new ItemWatcherIterator( this, this.myInterests.iterator() );
}
@Override
public boolean remove(Object o)
{
return this.myInterests.remove( o ) && this.gsc.interestManager.remove( (IAEStack)o, this );
}
@Override
public boolean removeAll(Collection<?> c)
{
boolean didSomething = false;
for (Object o : c)
didSomething = this.remove( o ) || didSomething;
return didSomething;
}
@Override
public boolean retainAll(Collection<?> c)
{
boolean changed = false;
Iterator<IAEStack> i = this.iterator();
while (i.hasNext())
{
if ( !c.contains( i.next() ) )
{
i.remove();
changed = true;
}
}
return changed;
}
@Override
public int size()
{
return this.myInterests.size();
}
@Override
public Object[] toArray()
{
return this.myInterests.toArray();
}
@Override
public <T> T[] toArray(T[] a)
{
return this.myInterests.toArray( a );
}
}
@@ -18,6 +18,7 @@
package appeng.me.storage;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
@@ -31,64 +32,60 @@ import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
public class MEIInventoryWrapper implements IMEInventory<IAEItemStack>
{
protected final IInventory target;
protected final InventoryAdaptor adaptor;
public MEIInventoryWrapper(IInventory m, InventoryAdaptor ia) {
public MEIInventoryWrapper( IInventory m, InventoryAdaptor ia )
{
this.target = m;
this.adaptor = ia;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
@Override
public IAEItemStack injectItems(IAEItemStack iox, Actionable mode, BaseActionSource src)
public IAEItemStack injectItems( IAEItemStack iox, Actionable mode, BaseActionSource src )
{
ItemStack input = iox.getItemStack();
if ( this.adaptor != null )
if( this.adaptor != null )
{
ItemStack is = mode == Actionable.SIMULATE ? this.adaptor.simulateAdd( input ) : this.adaptor.addItems( input );
if ( is == null )
if( is == null )
return null;
return AEItemStack.create( is );
}
ItemStack out = Platform.cloneItemStack( input );
if ( mode == Actionable.MODULATE ) // absolutely no need for a first run in simulate mode.
if( mode == Actionable.MODULATE ) // absolutely no need for a first run in simulate mode.
{
for (int x = 0; x < this.target.getSizeInventory(); x++)
for( int x = 0; x < this.target.getSizeInventory(); x++ )
{
ItemStack t = this.target.getStackInSlot( x );
if ( Platform.isSameItem( t, input ) )
if( Platform.isSameItem( t, input ) )
{
int oriStack = t.stackSize;
t.stackSize += out.stackSize;
this.target.setInventorySlotContents( x, t );
if ( t.stackSize > this.target.getInventoryStackLimit() )
if( t.stackSize > this.target.getInventoryStackLimit() )
{
t.stackSize = this.target.getInventoryStackLimit();
}
if ( t.stackSize > t.getMaxStackSize() )
if( t.stackSize > t.getMaxStackSize() )
{
t.stackSize = t.getMaxStackSize();
}
out.stackSize -= t.stackSize - oriStack;
if ( out.stackSize <= 0 )
if( out.stackSize <= 0 )
{
return null;
}
@@ -96,25 +93,25 @@ public class MEIInventoryWrapper implements IMEInventory<IAEItemStack>
}
}
for (int x = 0; x < this.target.getSizeInventory(); x++)
for( int x = 0; x < this.target.getSizeInventory(); x++ )
{
ItemStack t = this.target.getStackInSlot( x );
if ( t == null )
if( t == null )
{
t = Platform.cloneItemStack( input );
t.stackSize = out.stackSize;
if ( t.stackSize > this.target.getInventoryStackLimit() )
if( t.stackSize > this.target.getInventoryStackLimit() )
{
t.stackSize = this.target.getInventoryStackLimit();
}
out.stackSize -= t.stackSize;
if ( mode == Actionable.MODULATE )
if( mode == Actionable.MODULATE )
this.target.setInventorySlotContents( x, t );
if ( out.stackSize <= 0 )
if( out.stackSize <= 0 )
{
return null;
}
@@ -125,21 +122,21 @@ public class MEIInventoryWrapper implements IMEInventory<IAEItemStack>
}
@Override
public IAEItemStack extractItems(IAEItemStack request, Actionable mode, BaseActionSource src)
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, BaseActionSource src )
{
ItemStack Gathered = null;
ItemStack Req = request.getItemStack();
int request_stackSize = Req.stackSize;
if ( request_stackSize > Req.getMaxStackSize() )
if( request_stackSize > Req.getMaxStackSize() )
{
request_stackSize = Req.getMaxStackSize();
}
Req.stackSize = request_stackSize;
if ( this.adaptor != null )
if( this.adaptor != null )
{
Gathered = this.adaptor.removeItems( Req.stackSize, Req, null );
}
@@ -149,22 +146,22 @@ public class MEIInventoryWrapper implements IMEInventory<IAEItemStack>
Gathered.stackSize = 0;
// try to find matching inventories that already have it...
for (int x = 0; x < this.target.getSizeInventory(); x++)
for( int x = 0; x < this.target.getSizeInventory(); x++ )
{
ItemStack sub = this.target.getStackInSlot( x );
if ( Platform.isSameItem( sub, Req ) )
if( Platform.isSameItem( sub, Req ) )
{
int reqNum = Req.stackSize;
if ( reqNum > sub.stackSize )
if( reqNum > sub.stackSize )
{
reqNum = Req.stackSize;
}
ItemStack retrieved = null;
if ( sub.stackSize < Req.stackSize )
if( sub.stackSize < Req.stackSize )
{
retrieved = Platform.cloneItemStack( sub );
sub.stackSize = 0;
@@ -174,38 +171,37 @@ public class MEIInventoryWrapper implements IMEInventory<IAEItemStack>
retrieved = sub.splitStack( Req.stackSize );
}
if ( sub.stackSize <= 0 )
if( sub.stackSize <= 0 )
this.target.setInventorySlotContents( x, null );
else
this.target.setInventorySlotContents( x, sub );
if ( retrieved != null )
if( retrieved != null )
{
Gathered.stackSize += retrieved.stackSize;
Req.stackSize -= retrieved.stackSize;
}
if ( request_stackSize == Gathered.stackSize )
if( request_stackSize == Gathered.stackSize )
{
return AEItemStack.create( Gathered );
}
}
}
if ( Gathered.stackSize == 0 )
if( Gathered.stackSize == 0 )
{
return null;
}
}
return AEItemStack.create( Gathered );
}
@Override
public IItemList<IAEItemStack> getAvailableItems(IItemList<IAEItemStack> out)
public IItemList<IAEItemStack> getAvailableItems( IItemList<IAEItemStack> out )
{
for (int x = 0; x < this.target.getSizeInventory(); x++)
for( int x = 0; x < this.target.getSizeInventory(); x++ )
{
out.addStorage( AEItemStack.create( this.target.getStackInSlot( x ) ) );
}
@@ -213,4 +209,9 @@ public class MEIInventoryWrapper implements IMEInventory<IAEItemStack>
return out;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
}
@@ -36,10 +36,9 @@ import appeng.util.prioitylist.IPartitionList;
public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHandler<T>
{
final StorageChannel channel;
final protected IMEMonitor<T> monitor;
final protected IMEInventoryHandler<T> internal;
final StorageChannel channel;
private int myPriority;
private IncludeExclude myWhitelist;
private AccessRestriction myAccess;
@@ -53,12 +52,12 @@ public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHa
{
this.channel = channel;
if ( i instanceof IMEInventoryHandler )
this.internal = ( IMEInventoryHandler<T> ) i;
if( i instanceof IMEInventoryHandler )
this.internal = (IMEInventoryHandler<T>) i;
else
this.internal = new MEPassThrough<T>( i, channel );
this.monitor = this.internal instanceof IMEMonitor ? ( IMEMonitor<T> ) this.internal : null;
this.monitor = this.internal instanceof IMEMonitor ? (IMEMonitor<T>) this.internal : null;
this.myPriority = 0;
this.myWhitelist = IncludeExclude.WHITELIST;
@@ -66,17 +65,6 @@ public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHa
this.myPartitionList = new DefaultPriorityList<T>();
}
@Override
public int getPriority()
{
return this.myPriority;
}
public void setPriority( int myPriority )
{
this.myPriority = myPriority;
}
public IncludeExclude getWhitelist()
{
return this.myWhitelist;
@@ -113,7 +101,7 @@ public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHa
@Override
public T injectItems( T input, Actionable type, BaseActionSource src )
{
if ( !this.canAccept( input ) )
if( !this.canAccept( input ) )
return input;
return this.internal.injectItems( input, type, src );
@@ -122,7 +110,7 @@ public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHa
@Override
public T extractItems( T request, Actionable type, BaseActionSource src )
{
if ( !this.hasReadAccess )
if( !this.hasReadAccess )
return null;
return this.internal.extractItems( request, type, src );
@@ -131,7 +119,7 @@ public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHa
@Override
public IItemList<T> getAvailableItems( IItemList<T> out )
{
if ( !this.hasReadAccess )
if( !this.hasReadAccess )
return out;
return this.internal.getAvailableItems( out );
@@ -152,7 +140,7 @@ public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHa
@Override
public boolean isPrioritized( T input )
{
if ( this.myWhitelist == IncludeExclude.WHITELIST )
if( this.myWhitelist == IncludeExclude.WHITELIST )
return this.myPartitionList.isListed( input ) || this.internal.isPrioritized( input );
return false;
}
@@ -160,31 +148,41 @@ public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHa
@Override
public boolean canAccept( T input )
{
if ( !this.hasWriteAccess )
if( !this.hasWriteAccess )
return false;
if ( this.myWhitelist == IncludeExclude.BLACKLIST && this.myPartitionList.isListed( input ) )
if( this.myWhitelist == IncludeExclude.BLACKLIST && this.myPartitionList.isListed( input ) )
return false;
if ( this.myPartitionList.isEmpty() || this.myWhitelist == IncludeExclude.BLACKLIST )
if( this.myPartitionList.isEmpty() || this.myWhitelist == IncludeExclude.BLACKLIST )
return this.internal.canAccept( input );
return this.myPartitionList.isListed( input ) && this.internal.canAccept( input );
}
@Override
public int getPriority()
{
return this.myPriority;
}
public void setPriority( int myPriority )
{
this.myPriority = myPriority;
}
@Override
public int getSlot()
{
return this.internal.getSlot();
}
public IMEInventory<T> getInternal()
{
return this.internal;
}
@Override
public boolean validForPass( int i )
{
return true;
}
public IMEInventory<T> getInternal()
{
return this.internal;
}
}
@@ -18,6 +18,7 @@
package appeng.me.storage;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
@@ -42,70 +43,48 @@ import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.ItemSlot;
public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>
{
static class CachedItemStack
{
public CachedItemStack(ItemStack is)
{
if ( is == null )
{
this.itemStack = null;
this.aeStack = null;
}
else
{
this.itemStack = is.copy();
this.aeStack = AEApi.instance().storage().createItemStack( is );
}
}
final ItemStack itemStack;
final IAEItemStack aeStack;
}
final InventoryAdaptor adaptor;
private final NavigableMap<Integer, CachedItemStack> memory;
final IItemList<IAEItemStack> list = AEApi.instance().storage().createItemList();
final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object>();
private final NavigableMap<Integer, CachedItemStack> memory;
public BaseActionSource mySource;
public StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
@Override
public void addListener(IMEMonitorHandlerReceiver<IAEItemStack> l, Object verificationToken)
{
this.listeners.put( l, verificationToken );
}
@Override
public void removeListener(IMEMonitorHandlerReceiver<IAEItemStack> l)
{
this.listeners.remove( l );
}
public MEMonitorIInventory(InventoryAdaptor adaptor)
public MEMonitorIInventory( InventoryAdaptor adaptor )
{
this.adaptor = adaptor;
this.memory = new ConcurrentSkipListMap<Integer, CachedItemStack>();
}
@Override
public IAEItemStack injectItems(IAEItemStack input, Actionable type, BaseActionSource src)
public void addListener( IMEMonitorHandlerReceiver<IAEItemStack> l, Object verificationToken )
{
this.listeners.put( l, verificationToken );
}
@Override
public void removeListener( IMEMonitorHandlerReceiver<IAEItemStack> l )
{
this.listeners.remove( l );
}
@Override
public IAEItemStack injectItems( IAEItemStack input, Actionable type, BaseActionSource src )
{
ItemStack out = null;
if ( type == Actionable.SIMULATE )
if( type == Actionable.SIMULATE )
out = this.adaptor.simulateAdd( input.getItemStack() );
else
out = this.adaptor.addItems( input.getItemStack() );
this.onTick();
if ( out == null )
if( out == null )
return null;
// better then doing construction from scratch :3
@@ -114,6 +93,146 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>
return o;
}
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable type, BaseActionSource src )
{
ItemStack out = null;
if( type == Actionable.SIMULATE )
out = this.adaptor.simulateRemove( (int) request.getStackSize(), request.getItemStack(), null );
else
out = this.adaptor.removeItems( (int) request.getStackSize(), request.getItemStack(), null );
if( out == null )
return null;
// better then doing construction from scratch :3
IAEItemStack o = request.copy();
o.setStackSize( out.stackSize );
this.onTick();
return o;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
public TickRateModulation onTick()
{
boolean changed = false;
LinkedList<IAEItemStack> changes = new LinkedList<IAEItemStack>();
int high = 0;
this.list.resetStatus();
for( ItemSlot is : this.adaptor )
{
CachedItemStack old = this.memory.get( is.slot );
high = Math.max( high, is.slot );
ItemStack newIS = !is.isExtractable && this.mode == StorageFilter.EXTRACTABLE_ONLY ? null : is.getItemStack();
ItemStack oldIS = old == null ? null : old.itemStack;
if( this.isDifferent( newIS, oldIS ) )
{
CachedItemStack cis = new CachedItemStack( is.getItemStack() );
this.memory.put( is.slot, cis );
if( old != null && old.aeStack != null )
{
old.aeStack.setStackSize( -old.aeStack.getStackSize() );
changes.add( old.aeStack );
}
if( cis.aeStack != null )
{
changes.add( cis.aeStack );
this.list.add( cis.aeStack );
}
changed = true;
}
else
{
int newSize = ( newIS == null ? 0 : newIS.stackSize );
int diff = newSize - ( oldIS == null ? 0 : oldIS.stackSize );
IAEItemStack stack = ( old == null || old.aeStack == null ? AEApi.instance().storage().createItemStack( newIS ) : old.aeStack.copy() );
if( stack != null )
{
stack.setStackSize( newSize );
this.list.add( stack );
}
if( diff != 0 && stack != null )
{
CachedItemStack cis = new CachedItemStack( is.getItemStack() );
this.memory.put( is.slot, cis );
IAEItemStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
changed = true;
}
}
}
// detect dropped items; should fix non IISided Inventory Changes.
NavigableMap<Integer, CachedItemStack> end = this.memory.tailMap( high, false );
if( !end.isEmpty() )
{
for( CachedItemStack cis : end.values() )
{
if( cis != null && cis.aeStack != null )
{
IAEItemStack a = cis.aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
changed = true;
}
}
end.clear();
}
if( !changes.isEmpty() )
this.postDifference( changes );
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
}
private boolean isDifferent( ItemStack a, ItemStack b )
{
if( a == b && b == null )
return false;
if( ( a == null && b != null ) || ( a != null && b == null ) )
return true;
return !Platform.isSameItemPrecise( a, b );
}
private void postDifference( Iterable<IAEItemStack> a )
{
// AELog.info( a.getItemStack().getUnlocalizedName() + " @ " + a.getStackSize() );
if( a != null )
{
Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
while( i.hasNext() )
{
Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
if( key.isValid( l.getValue() ) )
key.postChange( this, a, this.mySource );
else
i.remove();
}
}
}
@Override
public AccessRestriction getAccess()
{
@@ -121,13 +240,13 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>
}
@Override
public boolean isPrioritized(IAEItemStack input)
public boolean isPrioritized( IAEItemStack input )
{
return false;
}
@Override
public boolean canAccept(IAEItemStack input)
public boolean canAccept( IAEItemStack input )
{
return true;
}
@@ -145,164 +264,44 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>
}
@Override
public IItemList<IAEItemStack> getStorageList()
public boolean validForPass( int i )
{
return this.list;
return true;
}
@Override
public IItemList<IAEItemStack> getAvailableItems(IItemList out)
public IItemList<IAEItemStack> getAvailableItems( IItemList out )
{
for (CachedItemStack is : this.memory.values())
for( CachedItemStack is : this.memory.values() )
out.addStorage( is.aeStack );
return out;
}
@Override
public IAEItemStack extractItems(IAEItemStack request, Actionable type, BaseActionSource src)
public IItemList<IAEItemStack> getStorageList()
{
ItemStack out = null;
if ( type == Actionable.SIMULATE )
out = this.adaptor.simulateRemove( (int) request.getStackSize(), request.getItemStack(), null );
else
out = this.adaptor.removeItems( (int) request.getStackSize(), request.getItemStack(), null );
if ( out == null )
return null;
// better then doing construction from scratch :3
IAEItemStack o = request.copy();
o.setStackSize( out.stackSize );
this.onTick();
return o;
return this.list;
}
public TickRateModulation onTick()
static class CachedItemStack
{
boolean changed = false;
LinkedList<IAEItemStack> changes = new LinkedList<IAEItemStack>();
final ItemStack itemStack;
final IAEItemStack aeStack;
int high = 0;
this.list.resetStatus();
for (ItemSlot is : this.adaptor)
public CachedItemStack( ItemStack is )
{
CachedItemStack old = this.memory.get( is.slot );
high = Math.max( high, is.slot );
ItemStack newIS = !is.isExtractable && this.mode == StorageFilter.EXTRACTABLE_ONLY ? null : is.getItemStack();
ItemStack oldIS = old == null ? null : old.itemStack;
if ( this.isDifferent( newIS, oldIS ) )
if( is == null )
{
CachedItemStack cis = new CachedItemStack( is.getItemStack() );
this.memory.put( is.slot, cis );
if ( old != null && old.aeStack != null )
{
old.aeStack.setStackSize( -old.aeStack.getStackSize() );
changes.add( old.aeStack );
}
if ( cis.aeStack != null )
{
changes.add( cis.aeStack );
this.list.add( cis.aeStack );
}
changed = true;
this.itemStack = null;
this.aeStack = null;
}
else
{
int newSize = (newIS == null ? 0 : newIS.stackSize);
int diff = newSize - (oldIS == null ? 0 : oldIS.stackSize);
IAEItemStack stack = (old == null || old.aeStack == null ? AEApi.instance().storage().createItemStack( newIS ) : old.aeStack.copy());
if ( stack != null )
{
stack.setStackSize( newSize );
this.list.add( stack );
}
if ( diff != 0 && stack != null )
{
CachedItemStack cis = new CachedItemStack( is.getItemStack() );
this.memory.put( is.slot, cis );
IAEItemStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
changed = true;
}
}
}
// detect dropped items; should fix non IISided Inventory Changes.
NavigableMap<Integer, CachedItemStack> end = this.memory.tailMap( high, false );
if ( !end.isEmpty() )
{
for (CachedItemStack cis : end.values())
{
if ( cis != null && cis.aeStack != null )
{
IAEItemStack a = cis.aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
changed = true;
}
}
end.clear();
}
if ( !changes.isEmpty() )
this.postDifference( changes );
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
}
private boolean isDifferent(ItemStack a, ItemStack b)
{
if ( a == b && b == null )
return false;
if ( (a == null && b != null) || (a != null && b == null) )
return true;
return !Platform.isSameItemPrecise( a, b );
}
private void postDifference(Iterable<IAEItemStack> a)
{
// AELog.info( a.getItemStack().getUnlocalizedName() + " @ " + a.getStackSize() );
if ( a != null )
{
Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
while (i.hasNext())
{
Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
if ( key.isValid( l.getValue() ) )
key.postChange( this, a, this.mySource );
else
i.remove();
this.itemStack = is.copy();
this.aeStack = AEApi.instance().storage().createItemStack( is );
}
}
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
@Override
public boolean validForPass(int i)
{
return true;
}
}
@@ -18,6 +18,7 @@
package appeng.me.storage;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
@@ -33,58 +34,57 @@ import appeng.api.storage.data.IItemList;
import appeng.util.Platform;
import appeng.util.inv.ItemListIgnoreCrafting;
public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T> implements IMEMonitor<T>, IMEMonitorHandlerReceiver<T>
{
final HashMap<IMEMonitorHandlerReceiver<T>, Object> listeners = new HashMap<IMEMonitorHandlerReceiver<T>, Object>();
public BaseActionSource changeSource;
IMEMonitor<T> monitor;
public BaseActionSource changeSource;
public MEMonitorPassThrough(IMEInventory<T> i, StorageChannel channel) {
public MEMonitorPassThrough( IMEInventory<T> i, StorageChannel channel )
{
super( i, channel );
if ( i instanceof IMEMonitor )
if( i instanceof IMEMonitor )
this.monitor = (IMEMonitor<T>) i;
}
@Override
public void setInternal(IMEInventory<T> i)
public void setInternal( IMEInventory<T> i )
{
if ( this.monitor != null )
if( this.monitor != null )
this.monitor.removeListener( this );
this.monitor = null;
IItemList<T> before = this.getInternal() == null ? this.channel.createList() : this.getInternal()
.getAvailableItems( new ItemListIgnoreCrafting( this.channel.createList() ) );
IItemList<T> before = this.getInternal() == null ? this.channel.createList() : this.getInternal().getAvailableItems( new ItemListIgnoreCrafting( this.channel.createList() ) );
super.setInternal( i );
if ( i instanceof IMEMonitor )
if( i instanceof IMEMonitor )
this.monitor = (IMEMonitor<T>) i;
IItemList<T> after = this.getInternal() == null ? this.channel.createList() : this.getInternal()
.getAvailableItems( new ItemListIgnoreCrafting( this.channel.createList() ) );
IItemList<T> after = this.getInternal() == null ? this.channel.createList() : this.getInternal().getAvailableItems( new ItemListIgnoreCrafting( this.channel.createList() ) );
if ( this.monitor != null )
if( this.monitor != null )
this.monitor.addListener( this, this.monitor );
Platform.postListChanges( before, after, this, this.changeSource );
}
@Override
public IItemList<T> getAvailableItems(IItemList out)
public IItemList<T> getAvailableItems( IItemList out )
{
super.getAvailableItems( new ItemListIgnoreCrafting( out ) );
return out;
}
@Override
public void addListener(IMEMonitorHandlerReceiver<T> l, Object verificationToken)
public void addListener( IMEMonitorHandlerReceiver<T> l, Object verificationToken )
{
this.listeners.put( l, verificationToken );
}
@Override
public void removeListener(IMEMonitorHandlerReceiver<T> l)
public void removeListener( IMEMonitorHandlerReceiver<T> l )
{
this.listeners.remove( l );
}
@@ -92,7 +92,7 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
@Override
public IItemList<T> getStorageList()
{
if ( this.monitor == null )
if( this.monitor == null )
{
IItemList<T> out = this.channel.createList();
this.getInternal().getAvailableItems( new ItemListIgnoreCrafting( out ) );
@@ -102,20 +102,20 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
}
@Override
public boolean isValid(Object verificationToken)
public boolean isValid( Object verificationToken )
{
return verificationToken == this.monitor;
}
@Override
public void postChange(IBaseMonitor<T> monitor, Iterable<T> change, BaseActionSource source)
public void postChange( IBaseMonitor<T> monitor, Iterable<T> change, BaseActionSource source )
{
Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.listeners.entrySet().iterator();
while (i.hasNext())
while( i.hasNext() )
{
Entry<IMEMonitorHandlerReceiver<T>, Object> e = i.next();
IMEMonitorHandlerReceiver<T> receiver = e.getKey();
if ( receiver.isValid( e.getValue() ) )
if( receiver.isValid( e.getValue() ) )
receiver.postChange( this, change, source );
else
i.remove();
@@ -126,11 +126,11 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
public void onListUpdate()
{
Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.listeners.entrySet().iterator();
while (i.hasNext())
while( i.hasNext() )
{
Entry<IMEMonitorHandlerReceiver<T>, Object> e = i.next();
IMEMonitorHandlerReceiver<T> receiver = e.getKey();
if ( receiver.isValid( e.getValue() ) )
if( receiver.isValid( e.getValue() ) )
receiver.onListUpdate();
else
i.remove();
@@ -18,6 +18,7 @@
package appeng.me.storage;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.networking.security.BaseActionSource;
@@ -27,41 +28,43 @@ import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
public class MEPassThrough<T extends IAEStack<T>> implements IMEInventoryHandler<T>
{
private IMEInventory<T> internal;
final protected StorageChannel channel;
private IMEInventory<T> internal;
public MEPassThrough( IMEInventory<T> i, StorageChannel channel )
{
this.channel = channel;
this.setInternal( i );
}
protected IMEInventory<T> getInternal()
{
return this.internal;
}
public MEPassThrough(IMEInventory<T> i, StorageChannel channel) {
this.channel = channel;
this.setInternal( i );
}
public void setInternal(IMEInventory<T> i)
public void setInternal( IMEInventory<T> i )
{
this.internal = i;
}
@Override
public T injectItems(T input, Actionable type, BaseActionSource src)
public T injectItems( T input, Actionable type, BaseActionSource src )
{
return this.internal.injectItems( input, type, src );
}
@Override
public T extractItems(T request, Actionable type, BaseActionSource src)
public T extractItems( T request, Actionable type, BaseActionSource src )
{
return this.internal.extractItems( request, type, src );
}
@Override
public IItemList<T> getAvailableItems(IItemList out)
public IItemList<T> getAvailableItems( IItemList out )
{
return this.internal.getAvailableItems( out );
}
@@ -79,13 +82,13 @@ public class MEPassThrough<T extends IAEStack<T>> implements IMEInventoryHandler
}
@Override
public boolean isPrioritized(T input)
public boolean isPrioritized( T input )
{
return false;
}
@Override
public boolean canAccept(T input)
public boolean canAccept( T input )
{
return true;
}
@@ -103,9 +106,8 @@ public class MEPassThrough<T extends IAEStack<T>> implements IMEInventoryHandler
}
@Override
public boolean validForPass(int i)
public boolean validForPass( int i )
{
return true;
}
}
@@ -18,6 +18,7 @@
package appeng.me.storage;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
@@ -42,157 +43,75 @@ import appeng.api.storage.data.IItemList;
import appeng.me.cache.SecurityCache;
import appeng.util.ItemSorters;
public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHandler<T>
{
private final static Comparator<Integer> PRIORITY_SORTER = new Comparator<Integer>() {
static final ThreadLocal<LinkedList> DEPTH_MOD = new ThreadLocal<LinkedList>();
static final ThreadLocal<LinkedList> DEPTH_SIM = new ThreadLocal<LinkedList>();
private final static Comparator<Integer> PRIORITY_SORTER = new Comparator<Integer>()
{
@Override
public int compare(Integer o1, Integer o2)
public int compare( Integer o1, Integer o2 )
{
return ItemSorters.compareInt( o2, o1 );
}
};
static int currentPass = 0;
final StorageChannel myChannel;
final SecurityCache security;
// final TreeMultimap<Integer, IMEInventoryHandler<T>> priorityInventory;
private final NavigableMap<Integer, List<IMEInventoryHandler<T>>> priorityInventory;
int myPass = 0;
public NetworkInventoryHandler(StorageChannel chan, SecurityCache security) {
public NetworkInventoryHandler( StorageChannel chan, SecurityCache security )
{
this.myChannel = chan;
this.security = security;
this.priorityInventory = new TreeMap<Integer, List<IMEInventoryHandler<T>>>( PRIORITY_SORTER ); // TreeMultimap.create( prioritySorter, hashSorter );
}
public void addNewStorage(IMEInventoryHandler<T> h)
public void addNewStorage( IMEInventoryHandler<T> h )
{
int priority = h.getPriority();
List<IMEInventoryHandler<T>> list = this.priorityInventory.get( priority );
if ( list == null )
if( list == null )
this.priorityInventory.put( priority, list = new ArrayList<IMEInventoryHandler<T>>() );
list.add( h );
}
static int currentPass = 0;
int myPass = 0;
static final ThreadLocal<LinkedList> DEPTH_MOD = new ThreadLocal<LinkedList>();
static final ThreadLocal<LinkedList> DEPTH_SIM = new ThreadLocal<LinkedList>();
private LinkedList getDepth(Actionable type)
{
ThreadLocal<LinkedList> depth = type == Actionable.MODULATE ? DEPTH_MOD : DEPTH_SIM;
LinkedList s = depth.get();
if ( s == null )
depth.set( s = new LinkedList() );
return s;
}
private boolean diveList(NetworkInventoryHandler<T> networkInventoryHandler, Actionable type)
{
LinkedList cDepth = this.getDepth( type );
if ( cDepth.contains( networkInventoryHandler ) )
return true;
cDepth.push( this );
return false;
}
private boolean diveIteration(NetworkInventoryHandler<T> networkInventoryHandler, Actionable type)
{
LinkedList cDepth = this.getDepth( type );
if ( cDepth.isEmpty() )
{
currentPass++;
this.myPass = currentPass;
}
else
{
if ( currentPass == this.myPass )
return true;
else
this.myPass = currentPass;
}
cDepth.push( this );
return false;
}
private void surface(NetworkInventoryHandler<T> networkInventoryHandler, Actionable type)
{
if ( this.getDepth( type ).pop() != this )
throw new RuntimeException( "Invalid Access to Networked Storage API detected." );
}
private boolean testPermission(BaseActionSource src, SecurityPermissions permission)
{
if ( src.isPlayer() )
{
if ( !this.security.hasPermission( ((PlayerSource) src).player, permission ) )
return true;
}
else if ( src.isMachine() )
{
if ( this.security.isAvailable() )
{
IGridNode n = ((MachineSource) src).via.getActionableNode();
if ( n == null )
return true;
IGrid gn = n.getGrid();
if ( gn != this.security.myGrid )
{
int playerID = -1;
ISecurityGrid sg = gn.getCache( ISecurityGrid.class );
playerID = sg.getOwner();
if ( !this.security.hasPermission( playerID, permission ) )
return true;
}
}
}
return false;
}
@Override
public T injectItems(T input, Actionable type, BaseActionSource src)
public T injectItems( T input, Actionable type, BaseActionSource src )
{
if ( this.diveList( this, type ) )
if( this.diveList( this, type ) )
return input;
if ( this.testPermission( src, SecurityPermissions.INJECT ) )
if( this.testPermission( src, SecurityPermissions.INJECT ) )
{
this.surface( this, type );
return input;
}
for (List<IMEInventoryHandler<T>> invList : this.priorityInventory.values())
for( List<IMEInventoryHandler<T>> invList : this.priorityInventory.values() )
{
Iterator<IMEInventoryHandler<T>> ii = invList.iterator();
while (ii.hasNext() && input != null)
while( ii.hasNext() && input != null )
{
IMEInventoryHandler<T> inv = ii.next();
if ( inv.validForPass( 1 ) && inv.canAccept( input )
&& (inv.isPrioritized( input ) || inv.extractItems( input, Actionable.SIMULATE, src ) != null) )
if( inv.validForPass( 1 ) && inv.canAccept( input ) && ( inv.isPrioritized( input ) || inv.extractItems( input, Actionable.SIMULATE, src ) != null ) )
{
input = inv.injectItems( input, type, src );
}
}
ii = invList.iterator();
while (ii.hasNext() && input != null)
while( ii.hasNext() && input != null )
{
IMEInventoryHandler<T> inv = ii.next();
if ( inv.validForPass( 2 ) && inv.canAccept( input ) )// ignore crafting on the second pass.
if( inv.validForPass( 2 ) && inv.canAccept( input ) )// ignore crafting on the second pass.
{
input = inv.injectItems( input, type, src );
}
@@ -204,13 +123,73 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
return input;
}
@Override
public T extractItems(T request, Actionable mode, BaseActionSource src)
private boolean diveList( NetworkInventoryHandler<T> networkInventoryHandler, Actionable type )
{
if ( this.diveList( this, mode ) )
LinkedList cDepth = this.getDepth( type );
if( cDepth.contains( networkInventoryHandler ) )
return true;
cDepth.push( this );
return false;
}
private boolean testPermission( BaseActionSource src, SecurityPermissions permission )
{
if( src.isPlayer() )
{
if( !this.security.hasPermission( ( (PlayerSource) src ).player, permission ) )
return true;
}
else if( src.isMachine() )
{
if( this.security.isAvailable() )
{
IGridNode n = ( (MachineSource) src ).via.getActionableNode();
if( n == null )
return true;
IGrid gn = n.getGrid();
if( gn != this.security.myGrid )
{
int playerID = -1;
ISecurityGrid sg = gn.getCache( ISecurityGrid.class );
playerID = sg.getOwner();
if( !this.security.hasPermission( playerID, permission ) )
return true;
}
}
}
return false;
}
private void surface( NetworkInventoryHandler<T> networkInventoryHandler, Actionable type )
{
if( this.getDepth( type ).pop() != this )
throw new RuntimeException( "Invalid Access to Networked Storage API detected." );
}
private LinkedList getDepth( Actionable type )
{
ThreadLocal<LinkedList> depth = type == Actionable.MODULATE ? DEPTH_MOD : DEPTH_SIM;
LinkedList s = depth.get();
if( s == null )
depth.set( s = new LinkedList() );
return s;
}
@Override
public T extractItems( T request, Actionable mode, BaseActionSource src )
{
if( this.diveList( this, mode ) )
return null;
if ( this.testPermission( src, SecurityPermissions.EXTRACT ) )
if( this.testPermission( src, SecurityPermissions.EXTRACT ) )
{
this.surface( this, mode );
return null;
@@ -223,12 +202,12 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
output.setStackSize( 0 );
long req = request.getStackSize();
while (i.hasNext())
while( i.hasNext() )
{
List<IMEInventoryHandler<T>> invList = i.next();
Iterator<IMEInventoryHandler<T>> ii = invList.iterator();
while (ii.hasNext() && output.getStackSize() < req)
while( ii.hasNext() && output.getStackSize() < req )
{
IMEInventoryHandler<T> inv = ii.next();
@@ -239,21 +218,21 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
this.surface( this, mode );
if ( output.getStackSize() <= 0 )
if( output.getStackSize() <= 0 )
return null;
return output;
}
@Override
public IItemList<T> getAvailableItems(IItemList out)
public IItemList<T> getAvailableItems( IItemList out )
{
if ( this.diveIteration( this, Actionable.SIMULATE ) )
if( this.diveIteration( this, Actionable.SIMULATE ) )
return out;
// for (Entry<Integer, IMEInventoryHandler<T>> h : priorityInventory.entries())
for (List<IMEInventoryHandler<T>> i : this.priorityInventory.values())
for (IMEInventoryHandler<T> j : i)
for( List<IMEInventoryHandler<T>> i : this.priorityInventory.values() )
for( IMEInventoryHandler<T> j : i )
out = j.getAvailableItems( out );
this.surface( this, Actionable.SIMULATE );
@@ -261,6 +240,26 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
return out;
}
private boolean diveIteration( NetworkInventoryHandler<T> networkInventoryHandler, Actionable type )
{
LinkedList cDepth = this.getDepth( type );
if( cDepth.isEmpty() )
{
currentPass++;
this.myPass = currentPass;
}
else
{
if( currentPass == this.myPass )
return true;
else
this.myPass = currentPass;
}
cDepth.push( this );
return false;
}
@Override
public StorageChannel getChannel()
{
@@ -274,13 +273,13 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
}
@Override
public boolean isPrioritized(T input)
public boolean isPrioritized( T input )
{
return false;
}
@Override
public boolean canAccept(T input)
public boolean canAccept( T input )
{
return true;
}
@@ -298,9 +297,8 @@ public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInvent
}
@Override
public boolean validForPass(int i)
public boolean validForPass( int i )
{
return true;
}
}
@@ -18,6 +18,7 @@
package appeng.me.storage;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.networking.security.BaseActionSource;
@@ -26,33 +27,34 @@ import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
public class NullInventory<T extends IAEStack<T>> implements IMEInventoryHandler<T>
{
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
@Override
public T injectItems(T input, Actionable mode, BaseActionSource src)
public T injectItems( T input, Actionable mode, BaseActionSource src )
{
return input;
}
@Override
public T extractItems(T request, Actionable mode, BaseActionSource src)
public T extractItems( T request, Actionable mode, BaseActionSource src )
{
return null;
}
@Override
public IItemList<T> getAvailableItems(IItemList out)
public IItemList<T> getAvailableItems( IItemList out )
{
return out;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
@Override
public AccessRestriction getAccess()
{
@@ -60,13 +62,13 @@ public class NullInventory<T extends IAEStack<T>> implements IMEInventoryHandler
}
@Override
public boolean isPrioritized(T input)
public boolean isPrioritized( T input )
{
return false;
}
@Override
public boolean canAccept(T input)
public boolean canAccept( T input )
{
return false;
}
@@ -84,9 +86,8 @@ public class NullInventory<T extends IAEStack<T>> implements IMEInventoryHandler
}
@Override
public boolean validForPass(int i)
public boolean validForPass( int i )
{
return i == 2;
}
}
@@ -18,6 +18,7 @@
package appeng.me.storage;
import com.mojang.authlib.GameProfile;
import appeng.api.AEApi;
@@ -34,42 +35,28 @@ import appeng.api.storage.data.IItemList;
import appeng.me.GridAccessException;
import appeng.tile.misc.TileSecurity;
public class SecurityInventory implements IMEInventoryHandler<IAEItemStack>
{
final TileSecurity securityTile;
final public IItemList<IAEItemStack> storedItems = AEApi.instance().storage().createItemList();
final TileSecurity securityTile;
public SecurityInventory(TileSecurity ts) {
public SecurityInventory( TileSecurity ts )
{
this.securityTile = ts;
}
private boolean hasPermission(BaseActionSource src)
{
if ( src.isPlayer() )
{
try
{
return this.securityTile.getProxy().getSecurity().hasPermission( ((PlayerSource) src).player, SecurityPermissions.SECURITY );
}
catch (GridAccessException e)
{
// :P
}
}
return false;
}
@Override
public IAEItemStack injectItems(IAEItemStack input, Actionable type, BaseActionSource src)
public IAEItemStack injectItems( IAEItemStack input, Actionable type, BaseActionSource src )
{
if ( this.hasPermission( src ) )
if( this.hasPermission( src ) )
{
if ( AEApi.instance().definitions().items().biometricCard().isSameAs( input.getItemStack() ) )
if( AEApi.instance().definitions().items().biometricCard().isSameAs( input.getItemStack() ) )
{
if ( this.canAccept( input ) )
if( this.canAccept( input ) )
{
if ( type == Actionable.SIMULATE )
if( type == Actionable.SIMULATE )
return null;
this.storedItems.add( input );
@@ -81,17 +68,33 @@ public class SecurityInventory implements IMEInventoryHandler<IAEItemStack>
return input;
}
@Override
public IAEItemStack extractItems(IAEItemStack request, Actionable mode, BaseActionSource src)
private boolean hasPermission( BaseActionSource src )
{
if ( this.hasPermission( src ) )
if( src.isPlayer() )
{
try
{
return this.securityTile.getProxy().getSecurity().hasPermission( ( (PlayerSource) src ).player, SecurityPermissions.SECURITY );
}
catch( GridAccessException e )
{
// :P
}
}
return false;
}
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, BaseActionSource src )
{
if( this.hasPermission( src ) )
{
IAEItemStack target = this.storedItems.findPrecise( request );
if ( target != null )
if( target != null )
{
IAEItemStack output = target.copy();
if ( mode == Actionable.SIMULATE )
if( mode == Actionable.SIMULATE )
return output;
target.setStackSize( 0 );
@@ -103,9 +106,9 @@ public class SecurityInventory implements IMEInventoryHandler<IAEItemStack>
}
@Override
public IItemList<IAEItemStack> getAvailableItems(IItemList out)
public IItemList<IAEItemStack> getAvailableItems( IItemList out )
{
for (IAEItemStack ais : this.storedItems)
for( IAEItemStack ais : this.storedItems )
out.add( ais );
return out;
@@ -124,32 +127,32 @@ public class SecurityInventory implements IMEInventoryHandler<IAEItemStack>
}
@Override
public boolean isPrioritized(IAEItemStack input)
public boolean isPrioritized( IAEItemStack input )
{
return false;
}
@Override
public boolean canAccept(IAEItemStack input)
public boolean canAccept( IAEItemStack input )
{
if ( input.getItem() instanceof IBiometricCard )
if( input.getItem() instanceof IBiometricCard )
{
IBiometricCard tbc = (IBiometricCard) input.getItem();
GameProfile newUser = tbc.getProfile( input.getItemStack() );
int PlayerID = AEApi.instance().registries().players().getID( newUser );
if ( this.securityTile.getOwner() == PlayerID )
if( this.securityTile.getOwner() == PlayerID )
return false;
for (IAEItemStack ais : this.storedItems)
for( IAEItemStack ais : this.storedItems )
{
if ( ais.isMeaningful() )
if( ais.isMeaningful() )
{
GameProfile thisUser = tbc.getProfile( ais.getItemStack() );
if ( thisUser == newUser )
if( thisUser == newUser )
return false;
if ( thisUser != null && thisUser.equals( newUser ) )
if( thisUser != null && thisUser.equals( newUser ) )
return false;
}
}
@@ -172,9 +175,8 @@ public class SecurityInventory implements IMEInventoryHandler<IAEItemStack>
}
@Override
public boolean validForPass(int i)
public boolean validForPass( int i )
{
return true;
}
}
@@ -42,20 +42,14 @@ public class VoidFluidInventory implements IMEInventoryHandler<IAEFluidStack>
@Override
public IAEFluidStack injectItems( IAEFluidStack input, Actionable mode, BaseActionSource src )
{
if ( mode == Actionable.SIMULATE )
if( mode == Actionable.SIMULATE )
return null;
if ( input != null )
if( input != null )
this.target.addPower( input.getStackSize() / 1000.0 );
return null;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.FLUIDS;
}
@Override
public IAEFluidStack extractItems( IAEFluidStack request, Actionable mode, BaseActionSource src )
{
@@ -68,6 +62,12 @@ public class VoidFluidInventory implements IMEInventoryHandler<IAEFluidStack>
return out;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.FLUIDS;
}
@Override
public AccessRestriction getAccess()
{
@@ -103,5 +103,4 @@ public class VoidFluidInventory implements IMEInventoryHandler<IAEFluidStack>
{
return i == 2;
}
}
@@ -42,20 +42,14 @@ public class VoidItemInventory implements IMEInventoryHandler<IAEItemStack>
@Override
public IAEItemStack injectItems( IAEItemStack input, Actionable mode, BaseActionSource src )
{
if ( mode == Actionable.SIMULATE )
if( mode == Actionable.SIMULATE )
return null;
if ( input != null )
if( input != null )
this.target.addPower( input.getStackSize() );
return null;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, BaseActionSource src )
{
@@ -68,6 +62,12 @@ public class VoidItemInventory implements IMEInventoryHandler<IAEItemStack>
return out;
}
@Override
public StorageChannel getChannel()
{
return StorageChannel.ITEMS;
}
@Override
public AccessRestriction getAccess()
{
@@ -103,5 +103,4 @@ public class VoidItemInventory implements IMEInventoryHandler<IAEItemStack>
{
return i == 2;
}
}