reformatted all src files (#141)
This commit is contained in:
+174
-226
@@ -19,278 +19,226 @@
|
||||
package appeng.me;
|
||||
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridCache;
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.IGridStorage;
|
||||
import appeng.api.networking.IMachineSet;
|
||||
import appeng.api.networking.*;
|
||||
import appeng.api.networking.events.MENetworkEvent;
|
||||
import appeng.api.networking.events.MENetworkPostCacheConstruction;
|
||||
import appeng.api.util.IReadOnlyCollection;
|
||||
import appeng.core.worlddata.WorldData;
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.util.ReadOnlyCollection;
|
||||
import appeng.me.cache.CraftingGridCache;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
public class Grid implements IGrid
|
||||
{
|
||||
private final NetworkEventBus eventBus = new NetworkEventBus();
|
||||
private final Map<Class<? extends IGridHost>, MachineSet> machines = new HashMap<>();
|
||||
private final Map<Class<? extends IGridCache>, GridCacheWrapper> caches = new HashMap<>();
|
||||
private GridNode pivot;
|
||||
private int priority; // how import is this network?
|
||||
private GridStorage myStorage;
|
||||
public class Grid implements IGrid {
|
||||
private final NetworkEventBus eventBus = new NetworkEventBus();
|
||||
private final Map<Class<? extends IGridHost>, MachineSet> machines = new HashMap<>();
|
||||
private final Map<Class<? extends IGridCache>, GridCacheWrapper> caches = new HashMap<>();
|
||||
private GridNode pivot;
|
||||
private int priority; // how import is this network?
|
||||
private GridStorage myStorage;
|
||||
|
||||
public Grid( final GridNode center )
|
||||
{
|
||||
this.pivot = center;
|
||||
public Grid(final GridNode center) {
|
||||
this.pivot = center;
|
||||
|
||||
final Map<Class<? extends IGridCache>, IGridCache> myCaches = AEApi.instance().registries().gridCache().createCacheInstance( this );
|
||||
for( final Entry<Class<? extends IGridCache>, IGridCache> c : myCaches.entrySet() )
|
||||
{
|
||||
final Class<? extends IGridCache> key = c.getKey();
|
||||
final IGridCache value = c.getValue();
|
||||
final Class<? extends IGridCache> valueClass = value.getClass();
|
||||
final Map<Class<? extends IGridCache>, IGridCache> myCaches = AEApi.instance().registries().gridCache().createCacheInstance(this);
|
||||
for (final Entry<Class<? extends IGridCache>, IGridCache> c : myCaches.entrySet()) {
|
||||
final Class<? extends IGridCache> key = c.getKey();
|
||||
final IGridCache value = c.getValue();
|
||||
final Class<? extends IGridCache> valueClass = value.getClass();
|
||||
|
||||
this.eventBus.readClass( key, valueClass );
|
||||
this.caches.put( key, new GridCacheWrapper( value ) );
|
||||
}
|
||||
this.eventBus.readClass(key, valueClass);
|
||||
this.caches.put(key, new GridCacheWrapper(value));
|
||||
}
|
||||
|
||||
this.postEvent( new MENetworkPostCacheConstruction() );
|
||||
this.postEvent(new MENetworkPostCacheConstruction());
|
||||
|
||||
TickHandler.INSTANCE.addNetwork( this );
|
||||
center.setGrid( this );
|
||||
}
|
||||
TickHandler.INSTANCE.addNetwork(this);
|
||||
center.setGrid(this);
|
||||
}
|
||||
|
||||
int getPriority()
|
||||
{
|
||||
return this.priority;
|
||||
}
|
||||
int getPriority() {
|
||||
return this.priority;
|
||||
}
|
||||
|
||||
IGridStorage getMyStorage()
|
||||
{
|
||||
return this.myStorage;
|
||||
}
|
||||
IGridStorage getMyStorage() {
|
||||
return this.myStorage;
|
||||
}
|
||||
|
||||
Map<Class<? extends IGridCache>, GridCacheWrapper> getCaches()
|
||||
{
|
||||
return this.caches;
|
||||
}
|
||||
Map<Class<? extends IGridCache>, GridCacheWrapper> getCaches() {
|
||||
return this.caches;
|
||||
}
|
||||
|
||||
public Iterable<Class<? extends IGridHost>> getMachineClasses()
|
||||
{
|
||||
return this.machines.keySet();
|
||||
}
|
||||
public Iterable<Class<? extends IGridHost>> getMachineClasses() {
|
||||
return this.machines.keySet();
|
||||
}
|
||||
|
||||
int size()
|
||||
{
|
||||
int out = 0;
|
||||
for( final Collection<?> x : this.machines.values() )
|
||||
{
|
||||
out += x.size();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
int size() {
|
||||
int out = 0;
|
||||
for (final Collection<?> x : this.machines.values()) {
|
||||
out += x.size();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void remove( final GridNode gridNode )
|
||||
{
|
||||
for( final IGridCache c : this.caches.values() )
|
||||
{
|
||||
final IGridHost machine = gridNode.getMachine();
|
||||
c.removeNode( gridNode, machine );
|
||||
}
|
||||
void remove(final GridNode gridNode) {
|
||||
for (final IGridCache c : this.caches.values()) {
|
||||
final IGridHost machine = gridNode.getMachine();
|
||||
c.removeNode(gridNode, machine);
|
||||
}
|
||||
|
||||
final Class<? extends IGridHost> machineClass = gridNode.getMachineClass();
|
||||
final Set<IGridNode> nodes = this.machines.get( machineClass );
|
||||
if( nodes != null )
|
||||
{
|
||||
nodes.remove( gridNode );
|
||||
}
|
||||
final Class<? extends IGridHost> machineClass = gridNode.getMachineClass();
|
||||
final Set<IGridNode> nodes = this.machines.get(machineClass);
|
||||
if (nodes != null) {
|
||||
nodes.remove(gridNode);
|
||||
}
|
||||
|
||||
gridNode.setGridStorage( null );
|
||||
gridNode.setGridStorage(null);
|
||||
|
||||
if( this.pivot == gridNode )
|
||||
{
|
||||
final Iterator<IGridNode> n = this.getNodes().iterator();
|
||||
if( n.hasNext() )
|
||||
{
|
||||
this.pivot = (GridNode) n.next();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.pivot = null;
|
||||
TickHandler.INSTANCE.removeNetwork( this );
|
||||
this.myStorage.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.pivot == gridNode) {
|
||||
final Iterator<IGridNode> n = this.getNodes().iterator();
|
||||
if (n.hasNext()) {
|
||||
this.pivot = (GridNode) n.next();
|
||||
} else {
|
||||
this.pivot = null;
|
||||
TickHandler.INSTANCE.removeNetwork(this);
|
||||
this.myStorage.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void add( final GridNode gridNode )
|
||||
{
|
||||
final Class<? extends IGridHost> mClass = gridNode.getMachineClass();
|
||||
void add(final GridNode gridNode) {
|
||||
final Class<? extends IGridHost> mClass = gridNode.getMachineClass();
|
||||
|
||||
MachineSet nodes = this.machines.get( mClass );
|
||||
if( nodes == null )
|
||||
{
|
||||
nodes = new MachineSet( mClass );
|
||||
this.machines.put( mClass, nodes );
|
||||
this.eventBus.readClass( mClass, mClass );
|
||||
}
|
||||
MachineSet nodes = this.machines.get(mClass);
|
||||
if (nodes == null) {
|
||||
nodes = new MachineSet(mClass);
|
||||
this.machines.put(mClass, nodes);
|
||||
this.eventBus.readClass(mClass, mClass);
|
||||
}
|
||||
|
||||
// handle loading grid storages.
|
||||
if( gridNode.getGridStorage() != null )
|
||||
{
|
||||
final GridStorage gs = gridNode.getGridStorage();
|
||||
final IGrid grid = gs.getGrid();
|
||||
// handle loading grid storages.
|
||||
if (gridNode.getGridStorage() != null) {
|
||||
final GridStorage gs = gridNode.getGridStorage();
|
||||
final IGrid grid = gs.getGrid();
|
||||
|
||||
if( grid == null )
|
||||
{
|
||||
this.myStorage = gs;
|
||||
this.myStorage.setGrid( this );
|
||||
if (grid == null) {
|
||||
this.myStorage = gs;
|
||||
this.myStorage.setGrid(this);
|
||||
|
||||
for( final IGridCache gc : this.caches.values() )
|
||||
{
|
||||
gc.onJoin( this.myStorage );
|
||||
}
|
||||
}
|
||||
else if( grid != this )
|
||||
{
|
||||
if( this.myStorage == null )
|
||||
{
|
||||
this.myStorage = WorldData.instance().storageData().getNewGridStorage();
|
||||
this.myStorage.setGrid( this );
|
||||
}
|
||||
for (final IGridCache gc : this.caches.values()) {
|
||||
gc.onJoin(this.myStorage);
|
||||
}
|
||||
} else if (grid != this) {
|
||||
if (this.myStorage == null) {
|
||||
this.myStorage = WorldData.instance().storageData().getNewGridStorage();
|
||||
this.myStorage.setGrid(this);
|
||||
}
|
||||
|
||||
final IGridStorage tmp = new GridStorage();
|
||||
if( !gs.hasDivided( this.myStorage ) )
|
||||
{
|
||||
gs.addDivided( this.myStorage );
|
||||
final IGridStorage tmp = new GridStorage();
|
||||
if (!gs.hasDivided(this.myStorage)) {
|
||||
gs.addDivided(this.myStorage);
|
||||
|
||||
for( final IGridCache gc : ( (Grid) grid ).caches.values() )
|
||||
{
|
||||
gc.onSplit( tmp );
|
||||
}
|
||||
for (final IGridCache gc : ((Grid) grid).caches.values()) {
|
||||
gc.onSplit(tmp);
|
||||
}
|
||||
|
||||
for( final IGridCache gc : this.caches.values() )
|
||||
{
|
||||
gc.onJoin( tmp );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( this.myStorage == null )
|
||||
{
|
||||
this.myStorage = WorldData.instance().storageData().getNewGridStorage();
|
||||
this.myStorage.setGrid( this );
|
||||
}
|
||||
for (final IGridCache gc : this.caches.values()) {
|
||||
gc.onJoin(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (this.myStorage == null) {
|
||||
this.myStorage = WorldData.instance().storageData().getNewGridStorage();
|
||||
this.myStorage.setGrid(this);
|
||||
}
|
||||
|
||||
// update grid node...
|
||||
gridNode.setGridStorage( this.myStorage );
|
||||
// update grid node...
|
||||
gridNode.setGridStorage(this.myStorage);
|
||||
|
||||
// track node.
|
||||
nodes.add( gridNode );
|
||||
// track node.
|
||||
nodes.add(gridNode);
|
||||
|
||||
for( final IGridCache cache : this.caches.values() )
|
||||
{
|
||||
final IGridHost machine = gridNode.getMachine();
|
||||
cache.addNode( gridNode, machine );
|
||||
}
|
||||
for (final IGridCache cache : this.caches.values()) {
|
||||
final IGridHost machine = gridNode.getMachine();
|
||||
cache.addNode(gridNode, machine);
|
||||
}
|
||||
|
||||
gridNode.getGridProxy().gridChanged();
|
||||
// postEventTo( gridNode, networkChanged );
|
||||
}
|
||||
gridNode.getGridProxy().gridChanged();
|
||||
// postEventTo( gridNode, networkChanged );
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( "unchecked" )
|
||||
public <C extends IGridCache> C getCache( final Class<? extends IGridCache> iface )
|
||||
{
|
||||
return (C) this.caches.get( iface ).getCache();
|
||||
}
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <C extends IGridCache> C getCache(final Class<? extends IGridCache> iface) {
|
||||
return (C) this.caches.get(iface).getCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MENetworkEvent postEvent( final MENetworkEvent ev )
|
||||
{
|
||||
final MENetworkEvent ret = this.eventBus.postEvent( this, ev );
|
||||
return ret;
|
||||
}
|
||||
@Override
|
||||
public MENetworkEvent postEvent(final MENetworkEvent ev) {
|
||||
final MENetworkEvent ret = this.eventBus.postEvent(this, ev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MENetworkEvent postEventTo( final IGridNode node, final MENetworkEvent ev )
|
||||
{
|
||||
return this.eventBus.postEventTo( this, (GridNode) node, ev );
|
||||
}
|
||||
@Override
|
||||
public MENetworkEvent postEventTo(final IGridNode node, final MENetworkEvent ev) {
|
||||
return this.eventBus.postEventTo(this, (GridNode) node, ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IReadOnlyCollection<Class<? extends IGridHost>> getMachinesClasses()
|
||||
{
|
||||
final Set<Class<? extends IGridHost>> machineKeys = this.machines.keySet();
|
||||
@Override
|
||||
public IReadOnlyCollection<Class<? extends IGridHost>> getMachinesClasses() {
|
||||
final Set<Class<? extends IGridHost>> machineKeys = this.machines.keySet();
|
||||
|
||||
return new ReadOnlyCollection<>( machineKeys );
|
||||
}
|
||||
return new ReadOnlyCollection<>(machineKeys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMachineSet getMachines( final Class<? extends IGridHost> c )
|
||||
{
|
||||
final MachineSet s = this.machines.get( c );
|
||||
if( s == null )
|
||||
{
|
||||
return new MachineSet( c );
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@Override
|
||||
public IMachineSet getMachines(final Class<? extends IGridHost> c) {
|
||||
final MachineSet s = this.machines.get(c);
|
||||
if (s == null) {
|
||||
return new MachineSet(c);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IReadOnlyCollection<IGridNode> getNodes()
|
||||
{
|
||||
return new GridNodeCollection( this.machines );
|
||||
}
|
||||
@Override
|
||||
public IReadOnlyCollection<IGridNode> getNodes() {
|
||||
return new GridNodeCollection(this.machines);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return this.pivot == null;
|
||||
}
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return this.pivot == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGridNode getPivot()
|
||||
{
|
||||
return this.pivot;
|
||||
}
|
||||
@Override
|
||||
public IGridNode getPivot() {
|
||||
return this.pivot;
|
||||
}
|
||||
|
||||
void setPivot( final GridNode pivot )
|
||||
{
|
||||
this.pivot = pivot;
|
||||
}
|
||||
void setPivot(final GridNode pivot) {
|
||||
this.pivot = pivot;
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
for( final IGridCache gc : this.caches.values() )
|
||||
{
|
||||
// are there any nodes left?
|
||||
if( this.pivot != null )
|
||||
{
|
||||
gc.onUpdateTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void update() {
|
||||
for (final IGridCache gc : this.caches.values()) {
|
||||
// are there any nodes left?
|
||||
if (this.pivot != null) {
|
||||
gc.onUpdateTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void saveState()
|
||||
{
|
||||
for( final IGridCache c : this.caches.values() )
|
||||
{
|
||||
c.populateGridStorage( this.myStorage );
|
||||
}
|
||||
}
|
||||
void saveState() {
|
||||
for (final IGridCache c : this.caches.values()) {
|
||||
c.populateGridStorage(this.myStorage);
|
||||
}
|
||||
}
|
||||
|
||||
public void setImportantFlag( final int i, final boolean publicHasPower )
|
||||
{
|
||||
final int flag = 1 << i;
|
||||
this.priority = ( this.priority & ~flag ) | ( publicHasPower ? flag : 0 );
|
||||
}
|
||||
public void setImportantFlag(final int i, final boolean publicHasPower) {
|
||||
final int flag = 1 << i;
|
||||
this.priority = (this.priority & ~flag) | (publicHasPower ? flag : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
package appeng.me;
|
||||
|
||||
|
||||
public class GridAccessException extends Exception
|
||||
{
|
||||
public class GridAccessException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 3914554394866375300L;
|
||||
private static final long serialVersionUID = 3914554394866375300L;
|
||||
}
|
||||
|
||||
@@ -25,61 +25,51 @@ import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.IGridStorage;
|
||||
|
||||
|
||||
public class GridCacheWrapper implements IGridCache
|
||||
{
|
||||
public class GridCacheWrapper implements IGridCache {
|
||||
|
||||
private final IGridCache myCache;
|
||||
private final String name;
|
||||
private final IGridCache myCache;
|
||||
private final String name;
|
||||
|
||||
public GridCacheWrapper( final IGridCache gc )
|
||||
{
|
||||
this.myCache = gc;
|
||||
this.name = this.getCache().getClass().getName();
|
||||
}
|
||||
public GridCacheWrapper(final IGridCache gc) {
|
||||
this.myCache = gc;
|
||||
this.name = this.getCache().getClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateTick()
|
||||
{
|
||||
this.getCache().onUpdateTick();
|
||||
}
|
||||
@Override
|
||||
public void onUpdateTick() {
|
||||
this.getCache().onUpdateTick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode( final IGridNode gridNode, final IGridHost machine )
|
||||
{
|
||||
this.getCache().removeNode( gridNode, machine );
|
||||
}
|
||||
@Override
|
||||
public void removeNode(final IGridNode gridNode, final IGridHost machine) {
|
||||
this.getCache().removeNode(gridNode, machine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNode( final IGridNode gridNode, final IGridHost machine )
|
||||
{
|
||||
this.getCache().addNode( gridNode, machine );
|
||||
}
|
||||
@Override
|
||||
public void addNode(final IGridNode gridNode, final IGridHost machine) {
|
||||
this.getCache().addNode(gridNode, machine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplit( final IGridStorage storageB )
|
||||
{
|
||||
this.getCache().onSplit( storageB );
|
||||
}
|
||||
@Override
|
||||
public void onSplit(final IGridStorage storageB) {
|
||||
this.getCache().onSplit(storageB);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJoin( final IGridStorage storageB )
|
||||
{
|
||||
this.getCache().onJoin( storageB );
|
||||
}
|
||||
@Override
|
||||
public void onJoin(final IGridStorage storageB) {
|
||||
this.getCache().onJoin(storageB);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateGridStorage( final IGridStorage storage )
|
||||
{
|
||||
this.getCache().populateGridStorage( storage );
|
||||
}
|
||||
@Override
|
||||
public void populateGridStorage(final IGridStorage storage) {
|
||||
this.getCache().populateGridStorage(storage);
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
IGridCache getCache()
|
||||
{
|
||||
return this.myCache;
|
||||
}
|
||||
IGridCache getCache() {
|
||||
return this.myCache;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,6 @@
|
||||
package appeng.me;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import appeng.api.exceptions.ExistingConnectionException;
|
||||
import appeng.api.exceptions.FailedConnectionException;
|
||||
import appeng.api.exceptions.NullNodeConnectionException;
|
||||
@@ -41,262 +38,218 @@ import appeng.me.pathfinding.IPathItem;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.ReadOnlyCollection;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class GridConnection implements IGridConnection, IPathItem
|
||||
{
|
||||
|
||||
private static final String EXISTING_CONNECTION_MESSAGE = "Connection between node [machine=%s, %s] and [machine=%s, %s] on [%s] already exists.";
|
||||
public class GridConnection implements IGridConnection, IPathItem {
|
||||
|
||||
private static final MENetworkChannelsChanged EVENT = new MENetworkChannelsChanged();
|
||||
private int channelData = 0;
|
||||
private Object visitorIterationNumber = null;
|
||||
private GridNode sideA;
|
||||
private AEPartLocation fromAtoB;
|
||||
private GridNode sideB;
|
||||
private static final String EXISTING_CONNECTION_MESSAGE = "Connection between node [machine=%s, %s] and [machine=%s, %s] on [%s] already exists.";
|
||||
|
||||
private GridConnection( final GridNode aNode, final GridNode bNode, final AEPartLocation fromAtoB )
|
||||
{
|
||||
this.sideA = aNode;
|
||||
this.fromAtoB = fromAtoB;
|
||||
this.sideB = bNode;
|
||||
}
|
||||
private static final MENetworkChannelsChanged EVENT = new MENetworkChannelsChanged();
|
||||
private int channelData = 0;
|
||||
private Object visitorIterationNumber = null;
|
||||
private GridNode sideA;
|
||||
private AEPartLocation fromAtoB;
|
||||
private GridNode sideB;
|
||||
|
||||
private boolean isNetworkABetter( final GridNode a, final GridNode b )
|
||||
{
|
||||
return a.getMyGrid().getPriority() > b.getMyGrid().getPriority() || a.getMyGrid().size() > b.getMyGrid().size();
|
||||
}
|
||||
private GridConnection(final GridNode aNode, final GridNode bNode, final AEPartLocation fromAtoB) {
|
||||
this.sideA = aNode;
|
||||
this.fromAtoB = fromAtoB;
|
||||
this.sideB = bNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGridNode getOtherSide( final IGridNode gridNode )
|
||||
{
|
||||
if( gridNode == this.sideA )
|
||||
{
|
||||
return this.sideB;
|
||||
}
|
||||
if( gridNode == this.sideB )
|
||||
{
|
||||
return this.sideA;
|
||||
}
|
||||
private boolean isNetworkABetter(final GridNode a, final GridNode b) {
|
||||
return a.getMyGrid().getPriority() > b.getMyGrid().getPriority() || a.getMyGrid().size() > b.getMyGrid().size();
|
||||
}
|
||||
|
||||
throw new GridException( "Invalid Side of Connection" );
|
||||
}
|
||||
@Override
|
||||
public IGridNode getOtherSide(final IGridNode gridNode) {
|
||||
if (gridNode == this.sideA) {
|
||||
return this.sideB;
|
||||
}
|
||||
if (gridNode == this.sideB) {
|
||||
return this.sideA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AEPartLocation getDirection( final IGridNode side )
|
||||
{
|
||||
if( this.fromAtoB == AEPartLocation.INTERNAL )
|
||||
{
|
||||
return this.fromAtoB;
|
||||
}
|
||||
throw new GridException("Invalid Side of Connection");
|
||||
}
|
||||
|
||||
if( this.sideA == side )
|
||||
{
|
||||
return this.fromAtoB;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.fromAtoB.getOpposite();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public AEPartLocation getDirection(final IGridNode side) {
|
||||
if (this.fromAtoB == AEPartLocation.INTERNAL) {
|
||||
return this.fromAtoB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
// a connection was destroyed RE-PATH!!
|
||||
final IPathingGrid p = this.sideA.getInternalGrid().getCache( IPathingGrid.class );
|
||||
p.repath();
|
||||
if (this.sideA == side) {
|
||||
return this.fromAtoB;
|
||||
} else {
|
||||
return this.fromAtoB.getOpposite();
|
||||
}
|
||||
}
|
||||
|
||||
this.sideA.removeConnection( this );
|
||||
this.sideB.removeConnection( this );
|
||||
@Override
|
||||
public void destroy() {
|
||||
// a connection was destroyed RE-PATH!!
|
||||
final IPathingGrid p = this.sideA.getInternalGrid().getCache(IPathingGrid.class);
|
||||
p.repath();
|
||||
|
||||
this.sideA.validateGrid();
|
||||
this.sideB.validateGrid();
|
||||
}
|
||||
this.sideA.removeConnection(this);
|
||||
this.sideB.removeConnection(this);
|
||||
|
||||
@Override
|
||||
public IGridNode a()
|
||||
{
|
||||
return this.sideA;
|
||||
}
|
||||
this.sideA.validateGrid();
|
||||
this.sideB.validateGrid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGridNode b()
|
||||
{
|
||||
return this.sideB;
|
||||
}
|
||||
@Override
|
||||
public IGridNode a() {
|
||||
return this.sideA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDirection()
|
||||
{
|
||||
return this.fromAtoB != AEPartLocation.INTERNAL;
|
||||
}
|
||||
@Override
|
||||
public IGridNode b() {
|
||||
return this.sideB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUsedChannels()
|
||||
{
|
||||
return ( this.channelData >> 8 ) & 0xff;
|
||||
}
|
||||
@Override
|
||||
public boolean hasDirection() {
|
||||
return this.fromAtoB != AEPartLocation.INTERNAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPathItem getControllerRoute()
|
||||
{
|
||||
if( this.sideA.getFlags().contains( GridFlags.CANNOT_CARRY ) )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return this.sideA;
|
||||
}
|
||||
@Override
|
||||
public int getUsedChannels() {
|
||||
return (this.channelData >> 8) & 0xff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControllerRoute( final IPathItem fast, final boolean zeroOut )
|
||||
{
|
||||
if( zeroOut )
|
||||
{
|
||||
this.channelData &= ~0xff;
|
||||
}
|
||||
@Override
|
||||
public IPathItem getControllerRoute() {
|
||||
if (this.sideA.getFlags().contains(GridFlags.CANNOT_CARRY)) {
|
||||
return null;
|
||||
}
|
||||
return this.sideA;
|
||||
}
|
||||
|
||||
if( this.sideB == fast )
|
||||
{
|
||||
final GridNode tmp = this.sideA;
|
||||
this.sideA = this.sideB;
|
||||
this.sideB = tmp;
|
||||
this.fromAtoB = this.fromAtoB.getOpposite();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void setControllerRoute(final IPathItem fast, final boolean zeroOut) {
|
||||
if (zeroOut) {
|
||||
this.channelData &= ~0xff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSupportMoreChannels()
|
||||
{
|
||||
return this.getLastUsedChannels() < 32; // max, PERIOD.
|
||||
}
|
||||
if (this.sideB == fast) {
|
||||
final GridNode tmp = this.sideA;
|
||||
this.sideA = this.sideB;
|
||||
this.sideB = tmp;
|
||||
this.fromAtoB = this.fromAtoB.getOpposite();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IReadOnlyCollection<IPathItem> getPossibleOptions()
|
||||
{
|
||||
return new ReadOnlyCollection<>( Arrays.asList( (IPathItem) this.a(), (IPathItem) this.b() ) );
|
||||
}
|
||||
@Override
|
||||
public boolean canSupportMoreChannels() {
|
||||
return this.getLastUsedChannels() < 32; // max, PERIOD.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementChannelCount( final int usedChannels )
|
||||
{
|
||||
this.channelData += usedChannels;
|
||||
}
|
||||
@Override
|
||||
public IReadOnlyCollection<IPathItem> getPossibleOptions() {
|
||||
return new ReadOnlyCollection<>(Arrays.asList((IPathItem) this.a(), (IPathItem) this.b()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<GridFlags> getFlags()
|
||||
{
|
||||
return EnumSet.noneOf( GridFlags.class );
|
||||
}
|
||||
@Override
|
||||
public void incrementChannelCount(final int usedChannels) {
|
||||
this.channelData += usedChannels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalizeChannels()
|
||||
{
|
||||
if( this.getUsedChannels() != this.getLastUsedChannels() )
|
||||
{
|
||||
this.channelData &= 0xff;
|
||||
this.channelData |= this.channelData << 8;
|
||||
@Override
|
||||
public EnumSet<GridFlags> getFlags() {
|
||||
return EnumSet.noneOf(GridFlags.class);
|
||||
}
|
||||
|
||||
if( this.sideA.getInternalGrid() != null )
|
||||
{
|
||||
this.sideA.getInternalGrid().postEventTo( this.sideA, EVENT );
|
||||
}
|
||||
@Override
|
||||
public void finalizeChannels() {
|
||||
if (this.getUsedChannels() != this.getLastUsedChannels()) {
|
||||
this.channelData &= 0xff;
|
||||
this.channelData |= this.channelData << 8;
|
||||
|
||||
if( this.sideB.getInternalGrid() != null )
|
||||
{
|
||||
this.sideB.getInternalGrid().postEventTo( this.sideB, EVENT );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.sideA.getInternalGrid() != null) {
|
||||
this.sideA.getInternalGrid().postEventTo(this.sideA, EVENT);
|
||||
}
|
||||
|
||||
private int getLastUsedChannels()
|
||||
{
|
||||
return this.channelData & 0xff;
|
||||
}
|
||||
if (this.sideB.getInternalGrid() != null) {
|
||||
this.sideB.getInternalGrid().postEventTo(this.sideB, EVENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object getVisitorIterationNumber()
|
||||
{
|
||||
return this.visitorIterationNumber;
|
||||
}
|
||||
private int getLastUsedChannels() {
|
||||
return this.channelData & 0xff;
|
||||
}
|
||||
|
||||
void setVisitorIterationNumber( final Object visitorIterationNumber )
|
||||
{
|
||||
this.visitorIterationNumber = visitorIterationNumber;
|
||||
}
|
||||
Object getVisitorIterationNumber() {
|
||||
return this.visitorIterationNumber;
|
||||
}
|
||||
|
||||
public static GridConnection create( final IGridNode aNode, final IGridNode bNode, final AEPartLocation fromAtoB ) throws FailedConnectionException
|
||||
{
|
||||
if( aNode == null || bNode == null )
|
||||
{
|
||||
throw new NullNodeConnectionException();
|
||||
}
|
||||
void setVisitorIterationNumber(final Object visitorIterationNumber) {
|
||||
this.visitorIterationNumber = visitorIterationNumber;
|
||||
}
|
||||
|
||||
final GridNode a = (GridNode) aNode;
|
||||
final GridNode b = (GridNode) bNode;
|
||||
public static GridConnection create(final IGridNode aNode, final IGridNode bNode, final AEPartLocation fromAtoB) throws FailedConnectionException {
|
||||
if (aNode == null || bNode == null) {
|
||||
throw new NullNodeConnectionException();
|
||||
}
|
||||
|
||||
if( a.hasConnection( b ) || b.hasConnection( a ) )
|
||||
{
|
||||
final String aMachineClass = a.getGridBlock().getMachine().getClass().getSimpleName();
|
||||
final String bMachineClass = b.getGridBlock().getMachine().getClass().getSimpleName();
|
||||
final String aCoordinates = a.getGridBlock().getLocation().toString();
|
||||
final String bCoordinates = b.getGridBlock().getLocation().toString();
|
||||
final GridNode a = (GridNode) aNode;
|
||||
final GridNode b = (GridNode) bNode;
|
||||
|
||||
throw new ExistingConnectionException( String.format( EXISTING_CONNECTION_MESSAGE, aMachineClass, aCoordinates, bMachineClass, bCoordinates,
|
||||
fromAtoB ) );
|
||||
}
|
||||
if (a.hasConnection(b) || b.hasConnection(a)) {
|
||||
final String aMachineClass = a.getGridBlock().getMachine().getClass().getSimpleName();
|
||||
final String bMachineClass = b.getGridBlock().getMachine().getClass().getSimpleName();
|
||||
final String aCoordinates = a.getGridBlock().getLocation().toString();
|
||||
final String bCoordinates = b.getGridBlock().getLocation().toString();
|
||||
|
||||
if( !Platform.securityCheck( a, b ) )
|
||||
{
|
||||
if( AEConfig.instance().isFeatureEnabled( AEFeature.LOG_SECURITY_AUDITS ) )
|
||||
{
|
||||
final DimensionalCoord aCoordinates = a.getGridBlock().getLocation();
|
||||
final DimensionalCoord bCoordinates = b.getGridBlock().getLocation();
|
||||
throw new ExistingConnectionException(String.format(EXISTING_CONNECTION_MESSAGE, aMachineClass, aCoordinates, bMachineClass, bCoordinates,
|
||||
fromAtoB));
|
||||
}
|
||||
|
||||
AELog.info( "Security audit 1 failed at [%s] belonging to player [id=%d]", aCoordinates.toString(), a.getPlayerID() );
|
||||
AELog.info( "Security audit 2 failed at [%s] belonging to player [id=%d]", bCoordinates.toString(), b.getPlayerID() );
|
||||
}
|
||||
if (!Platform.securityCheck(a, b)) {
|
||||
if (AEConfig.instance().isFeatureEnabled(AEFeature.LOG_SECURITY_AUDITS)) {
|
||||
final DimensionalCoord aCoordinates = a.getGridBlock().getLocation();
|
||||
final DimensionalCoord bCoordinates = b.getGridBlock().getLocation();
|
||||
|
||||
throw new SecurityConnectionException();
|
||||
}
|
||||
AELog.info("Security audit 1 failed at [%s] belonging to player [id=%d]", aCoordinates.toString(), a.getPlayerID());
|
||||
AELog.info("Security audit 2 failed at [%s] belonging to player [id=%d]", bCoordinates.toString(), b.getPlayerID());
|
||||
}
|
||||
|
||||
// Create the actual connection
|
||||
final GridConnection connection = new GridConnection( a, b, fromAtoB );
|
||||
throw new SecurityConnectionException();
|
||||
}
|
||||
|
||||
// Update both nodes with the new connection.
|
||||
if( a.getMyGrid() == null )
|
||||
{
|
||||
b.setGrid( a.getInternalGrid() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( a.getMyGrid() == null )
|
||||
{
|
||||
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
|
||||
aNode.beginVisit( gp );
|
||||
}
|
||||
else if( b.getMyGrid() == null )
|
||||
{
|
||||
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
|
||||
bNode.beginVisit( gp );
|
||||
}
|
||||
else if( connection.isNetworkABetter( a, b ) )
|
||||
{
|
||||
final GridPropagator gp = new GridPropagator( a.getInternalGrid() );
|
||||
b.beginVisit( gp );
|
||||
}
|
||||
else
|
||||
{
|
||||
final GridPropagator gp = new GridPropagator( b.getInternalGrid() );
|
||||
a.beginVisit( gp );
|
||||
}
|
||||
}
|
||||
// Create the actual connection
|
||||
final GridConnection connection = new GridConnection(a, b, fromAtoB);
|
||||
|
||||
// a connection was destroyed RE-PATH!!
|
||||
final IPathingGrid p = connection.sideA.getInternalGrid().getCache( IPathingGrid.class );
|
||||
p.repath();
|
||||
// Update both nodes with the new connection.
|
||||
if (a.getMyGrid() == null) {
|
||||
b.setGrid(a.getInternalGrid());
|
||||
} else {
|
||||
if (a.getMyGrid() == null) {
|
||||
final GridPropagator gp = new GridPropagator(b.getInternalGrid());
|
||||
aNode.beginVisit(gp);
|
||||
} else if (b.getMyGrid() == null) {
|
||||
final GridPropagator gp = new GridPropagator(a.getInternalGrid());
|
||||
bNode.beginVisit(gp);
|
||||
} else if (connection.isNetworkABetter(a, b)) {
|
||||
final GridPropagator gp = new GridPropagator(a.getInternalGrid());
|
||||
b.beginVisit(gp);
|
||||
} else {
|
||||
final GridPropagator gp = new GridPropagator(b.getInternalGrid());
|
||||
a.beginVisit(gp);
|
||||
}
|
||||
}
|
||||
|
||||
connection.sideA.addConnection( connection );
|
||||
connection.sideB.addConnection( connection );
|
||||
// a connection was destroyed RE-PATH!!
|
||||
final IPathingGrid p = connection.sideA.getInternalGrid().getCache(IPathingGrid.class);
|
||||
p.repath();
|
||||
|
||||
return connection;
|
||||
}
|
||||
connection.sideA.addConnection(connection);
|
||||
connection.sideB.addConnection(connection);
|
||||
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,12 @@
|
||||
package appeng.me;
|
||||
|
||||
|
||||
public class GridException extends RuntimeException
|
||||
{
|
||||
public class GridException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -8110077032108243076L;
|
||||
private static final long serialVersionUID = -8110077032108243076L;
|
||||
|
||||
public GridException( final String s )
|
||||
{
|
||||
public GridException(final String s) {
|
||||
|
||||
super( s );
|
||||
}
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,77 +19,65 @@
|
||||
package appeng.me;
|
||||
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.util.IReadOnlyCollection;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class GridNodeCollection implements IReadOnlyCollection<IGridNode>
|
||||
{
|
||||
private final Map<Class<? extends IGridHost>, MachineSet> machines;
|
||||
|
||||
public GridNodeCollection( final Map<Class<? extends IGridHost>, MachineSet> machines )
|
||||
{
|
||||
this.machines = machines;
|
||||
}
|
||||
public class GridNodeCollection implements IReadOnlyCollection<IGridNode> {
|
||||
private final Map<Class<? extends IGridHost>, MachineSet> machines;
|
||||
|
||||
@Override
|
||||
public Iterator<IGridNode> iterator()
|
||||
{
|
||||
return new GridNodeIterator( this.machines );
|
||||
}
|
||||
public GridNodeCollection(final Map<Class<? extends IGridHost>, MachineSet> machines) {
|
||||
this.machines = machines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size()
|
||||
{
|
||||
int size = 0;
|
||||
@Override
|
||||
public Iterator<IGridNode> iterator() {
|
||||
return new GridNodeIterator(this.machines);
|
||||
}
|
||||
|
||||
for( final Set<IGridNode> o : this.machines.values() )
|
||||
{
|
||||
size += o.size();
|
||||
}
|
||||
@Override
|
||||
public int size() {
|
||||
int size = 0;
|
||||
|
||||
return size;
|
||||
}
|
||||
for (final Set<IGridNode> o : this.machines.values()) {
|
||||
size += o.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty()
|
||||
{
|
||||
for( final Set<IGridNode> o : this.machines.values() )
|
||||
{
|
||||
if( !o.isEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
for (final Set<IGridNode> o : this.machines.values()) {
|
||||
if (!o.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains( final Object maybeGridNode )
|
||||
{
|
||||
final boolean doesContainNode;
|
||||
return true;
|
||||
}
|
||||
|
||||
if( maybeGridNode instanceof IGridNode )
|
||||
{
|
||||
final IGridNode node = (IGridNode) maybeGridNode;
|
||||
final IGridHost machine = node.getMachine();
|
||||
final Class<? extends IGridHost> machineClass = machine.getClass();
|
||||
@Override
|
||||
public boolean contains(final Object maybeGridNode) {
|
||||
final boolean doesContainNode;
|
||||
|
||||
final MachineSet machineSet = this.machines.get( machineClass );
|
||||
if (maybeGridNode instanceof IGridNode) {
|
||||
final IGridNode node = (IGridNode) maybeGridNode;
|
||||
final IGridHost machine = node.getMachine();
|
||||
final Class<? extends IGridHost> machineClass = machine.getClass();
|
||||
|
||||
doesContainNode = machineSet != null && machineSet.contains( maybeGridNode );
|
||||
}
|
||||
else
|
||||
{
|
||||
doesContainNode = false;
|
||||
}
|
||||
final MachineSet machineSet = this.machines.get(machineClass);
|
||||
|
||||
return doesContainNode;
|
||||
}
|
||||
doesContainNode = machineSet != null && machineSet.contains(maybeGridNode);
|
||||
} else {
|
||||
doesContainNode = false;
|
||||
}
|
||||
|
||||
return doesContainNode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,68 +19,57 @@
|
||||
package appeng.me;
|
||||
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Nested iterator for {@link appeng.me.MachineSet}
|
||||
*
|
||||
* <p>
|
||||
* Traverses first over the {@link appeng.me.MachineSet} and then over every containing
|
||||
* {@link appeng.api.networking.IGridNode}
|
||||
*/
|
||||
public class GridNodeIterator implements Iterator<IGridNode>
|
||||
{
|
||||
private final Iterator<MachineSet> outerIterator;
|
||||
private Iterator<IGridNode> innerIterator;
|
||||
public class GridNodeIterator implements Iterator<IGridNode> {
|
||||
private final Iterator<MachineSet> outerIterator;
|
||||
private Iterator<IGridNode> innerIterator;
|
||||
|
||||
public GridNodeIterator( final Map<Class<? extends IGridHost>, MachineSet> machines )
|
||||
{
|
||||
this.outerIterator = machines.values().iterator();
|
||||
this.innerHasNext();
|
||||
}
|
||||
public GridNodeIterator(final Map<Class<? extends IGridHost>, MachineSet> machines) {
|
||||
this.outerIterator = machines.values().iterator();
|
||||
this.innerHasNext();
|
||||
}
|
||||
|
||||
private boolean innerHasNext()
|
||||
{
|
||||
final boolean hasNext = this.outerIterator.hasNext();
|
||||
private boolean innerHasNext() {
|
||||
final boolean hasNext = this.outerIterator.hasNext();
|
||||
|
||||
if( hasNext )
|
||||
{
|
||||
final MachineSet nextElem = this.outerIterator.next();
|
||||
this.innerIterator = nextElem.iterator();
|
||||
}
|
||||
if (hasNext) {
|
||||
final MachineSet nextElem = this.outerIterator.next();
|
||||
this.innerIterator = nextElem.iterator();
|
||||
}
|
||||
|
||||
return hasNext;
|
||||
}
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext()
|
||||
{
|
||||
while( true )
|
||||
{
|
||||
if( this.innerIterator.hasNext() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if( !this.innerHasNext() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
while (true) {
|
||||
if (this.innerIterator.hasNext()) {
|
||||
return true;
|
||||
} else if (!this.innerHasNext()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGridNode next()
|
||||
{
|
||||
return this.innerIterator.next();
|
||||
}
|
||||
@Override
|
||||
public IGridNode next() {
|
||||
return this.innerIterator.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove()
|
||||
{
|
||||
this.innerIterator.remove();
|
||||
}
|
||||
@Override
|
||||
public void remove() {
|
||||
this.innerIterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,25 +23,21 @@ import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.IGridVisitor;
|
||||
|
||||
|
||||
public class GridPropagator implements IGridVisitor
|
||||
{
|
||||
private final Grid g;
|
||||
public class GridPropagator implements IGridVisitor {
|
||||
private final Grid g;
|
||||
|
||||
public GridPropagator( final Grid g )
|
||||
{
|
||||
this.g = g;
|
||||
}
|
||||
public GridPropagator(final Grid g) {
|
||||
this.g = g;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitNode( final IGridNode n )
|
||||
{
|
||||
final GridNode gn = (GridNode) n;
|
||||
if( gn.getMyGrid() != this.g || this.g.getPivot() == n )
|
||||
{
|
||||
gn.setGrid( this.g );
|
||||
@Override
|
||||
public boolean visitNode(final IGridNode n) {
|
||||
final GridNode gn = (GridNode) n;
|
||||
if (gn.getMyGrid() != this.g || this.g.getPivot() == n) {
|
||||
gn.setGrid(this.g);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,35 +23,29 @@ import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.IGridVisitor;
|
||||
|
||||
|
||||
class GridSplitDetector implements IGridVisitor
|
||||
{
|
||||
class GridSplitDetector implements IGridVisitor {
|
||||
|
||||
private final IGridNode pivot;
|
||||
private boolean pivotFound;
|
||||
private final IGridNode pivot;
|
||||
private boolean pivotFound;
|
||||
|
||||
public GridSplitDetector( final IGridNode pivot )
|
||||
{
|
||||
this.pivot = pivot;
|
||||
}
|
||||
public GridSplitDetector(final IGridNode pivot) {
|
||||
this.pivot = pivot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitNode( final IGridNode n )
|
||||
{
|
||||
if( n == this.pivot )
|
||||
{
|
||||
this.setPivotFound( true );
|
||||
}
|
||||
@Override
|
||||
public boolean visitNode(final IGridNode n) {
|
||||
if (n == this.pivot) {
|
||||
this.setPivotFound(true);
|
||||
}
|
||||
|
||||
return !this.isPivotFound();
|
||||
}
|
||||
return !this.isPivotFound();
|
||||
}
|
||||
|
||||
public boolean isPivotFound()
|
||||
{
|
||||
return this.pivotFound;
|
||||
}
|
||||
public boolean isPivotFound() {
|
||||
return this.pivotFound;
|
||||
}
|
||||
|
||||
private void setPivotFound( final boolean pivotFound )
|
||||
{
|
||||
this.pivotFound = pivotFound;
|
||||
}
|
||||
private void setPivotFound(final boolean pivotFound) {
|
||||
this.pivotFound = pivotFound;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,137 +19,117 @@
|
||||
package appeng.me;
|
||||
|
||||
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridStorage;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.worlddata.WorldData;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridStorage;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.worlddata.WorldData;
|
||||
public class GridStorage implements IGridStorage {
|
||||
|
||||
private final long myID;
|
||||
private final NBTTagCompound data;
|
||||
private final GridStorageSearch mySearchEntry; // keep myself in the list until I'm
|
||||
private final WeakHashMap<GridStorage, Boolean> divided = new WeakHashMap<>();
|
||||
private WeakReference<IGrid> internalGrid = null;
|
||||
|
||||
public class GridStorage implements IGridStorage
|
||||
{
|
||||
// lost...
|
||||
|
||||
private final long myID;
|
||||
private final NBTTagCompound data;
|
||||
private final GridStorageSearch mySearchEntry; // keep myself in the list until I'm
|
||||
private final WeakHashMap<GridStorage, Boolean> divided = new WeakHashMap<>();
|
||||
private WeakReference<IGrid> internalGrid = null;
|
||||
/**
|
||||
* for use with world settings
|
||||
*
|
||||
* @param id ID of grid storage
|
||||
* @param gss grid storage search
|
||||
*/
|
||||
public GridStorage(final long id, final GridStorageSearch gss) {
|
||||
this.myID = id;
|
||||
this.mySearchEntry = gss;
|
||||
this.data = new NBTTagCompound();
|
||||
}
|
||||
|
||||
// lost...
|
||||
/**
|
||||
* for use with world settings
|
||||
*
|
||||
* @param input array of bytes string
|
||||
* @param id ID of grid storage
|
||||
* @param gss grid storage search
|
||||
*/
|
||||
public GridStorage(final String input, final long id, final GridStorageSearch gss) {
|
||||
this.myID = id;
|
||||
this.mySearchEntry = gss;
|
||||
NBTTagCompound myTag = null;
|
||||
|
||||
/**
|
||||
* for use with world settings
|
||||
*
|
||||
* @param id ID of grid storage
|
||||
* @param gss grid storage search
|
||||
*/
|
||||
public GridStorage( final long id, final GridStorageSearch gss )
|
||||
{
|
||||
this.myID = id;
|
||||
this.mySearchEntry = gss;
|
||||
this.data = new NBTTagCompound();
|
||||
}
|
||||
try {
|
||||
final byte[] byteData = javax.xml.bind.DatatypeConverter.parseBase64Binary(input);
|
||||
myTag = CompressedStreamTools.readCompressed(new ByteArrayInputStream(byteData));
|
||||
} catch (final Throwable t) {
|
||||
myTag = new NBTTagCompound();
|
||||
}
|
||||
|
||||
/**
|
||||
* for use with world settings
|
||||
*
|
||||
* @param input array of bytes string
|
||||
* @param id ID of grid storage
|
||||
* @param gss grid storage search
|
||||
*/
|
||||
public GridStorage( final String input, final long id, final GridStorageSearch gss )
|
||||
{
|
||||
this.myID = id;
|
||||
this.mySearchEntry = gss;
|
||||
NBTTagCompound myTag = null;
|
||||
this.data = myTag;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final byte[] byteData = javax.xml.bind.DatatypeConverter.parseBase64Binary( input );
|
||||
myTag = CompressedStreamTools.readCompressed( new ByteArrayInputStream( byteData ) );
|
||||
}
|
||||
catch( final Throwable t )
|
||||
{
|
||||
myTag = new NBTTagCompound();
|
||||
}
|
||||
/**
|
||||
* fake storage.
|
||||
*/
|
||||
public GridStorage() {
|
||||
this.myID = 0;
|
||||
this.mySearchEntry = null;
|
||||
this.data = new NBTTagCompound();
|
||||
}
|
||||
|
||||
this.data = myTag;
|
||||
}
|
||||
public String getValue() {
|
||||
final Grid currentGrid = (Grid) this.getGrid();
|
||||
if (currentGrid != null) {
|
||||
currentGrid.saveState();
|
||||
}
|
||||
|
||||
/**
|
||||
* fake storage.
|
||||
*/
|
||||
public GridStorage()
|
||||
{
|
||||
this.myID = 0;
|
||||
this.mySearchEntry = null;
|
||||
this.data = new NBTTagCompound();
|
||||
}
|
||||
try {
|
||||
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
CompressedStreamTools.writeCompressed(this.data, out);
|
||||
return javax.xml.bind.DatatypeConverter.printBase64Binary(out.toByteArray());
|
||||
} catch (final IOException e) {
|
||||
AELog.debug(e);
|
||||
}
|
||||
|
||||
public String getValue()
|
||||
{
|
||||
final Grid currentGrid = (Grid) this.getGrid();
|
||||
if( currentGrid != null )
|
||||
{
|
||||
currentGrid.saveState();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
CompressedStreamTools.writeCompressed( this.data, out );
|
||||
return javax.xml.bind.DatatypeConverter.printBase64Binary( out.toByteArray() );
|
||||
}
|
||||
catch( final IOException e )
|
||||
{
|
||||
AELog.debug( e );
|
||||
}
|
||||
public IGrid getGrid() {
|
||||
return this.internalGrid == null ? null : this.internalGrid.get();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
void setGrid(final Grid grid) {
|
||||
this.internalGrid = new WeakReference<>(grid);
|
||||
}
|
||||
|
||||
public IGrid getGrid()
|
||||
{
|
||||
return this.internalGrid == null ? null : this.internalGrid.get();
|
||||
}
|
||||
@Override
|
||||
public NBTTagCompound dataObject() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
void setGrid( final Grid grid )
|
||||
{
|
||||
this.internalGrid = new WeakReference<>( grid );
|
||||
}
|
||||
@Override
|
||||
public long getID() {
|
||||
return this.myID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound dataObject()
|
||||
{
|
||||
return this.data;
|
||||
}
|
||||
void addDivided(final GridStorage gs) {
|
||||
this.divided.put(gs, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getID()
|
||||
{
|
||||
return this.myID;
|
||||
}
|
||||
boolean hasDivided(final GridStorage myStorage) {
|
||||
return this.divided.containsKey(myStorage);
|
||||
}
|
||||
|
||||
void addDivided( final GridStorage gs )
|
||||
{
|
||||
this.divided.put( gs, true );
|
||||
}
|
||||
|
||||
boolean hasDivided( final GridStorage myStorage )
|
||||
{
|
||||
return this.divided.containsKey( myStorage );
|
||||
}
|
||||
|
||||
void remove()
|
||||
{
|
||||
WorldData.instance().storageData().destroyGridStorage( this.myID );
|
||||
}
|
||||
void remove() {
|
||||
WorldData.instance().storageData().destroyGridStorage(this.myID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,56 +22,43 @@ package appeng.me;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
|
||||
public class GridStorageSearch
|
||||
{
|
||||
public class GridStorageSearch {
|
||||
|
||||
private final long id;
|
||||
private WeakReference<GridStorage> gridStorage;
|
||||
private final long id;
|
||||
private WeakReference<GridStorage> gridStorage;
|
||||
|
||||
/**
|
||||
* for use with the world settings
|
||||
*
|
||||
* @param id ID of grid storage search
|
||||
*/
|
||||
public GridStorageSearch( final long id )
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
/**
|
||||
* for use with the world settings
|
||||
*
|
||||
* @param id ID of grid storage search
|
||||
*/
|
||||
public GridStorageSearch(final long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return ( (Long) this.id ).hashCode();
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ((Long) this.id).hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( final Object obj )
|
||||
{
|
||||
if( obj == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if( this.getClass() != obj.getClass() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (this.getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final GridStorageSearch other = (GridStorageSearch) obj;
|
||||
if( this.id == other.id )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
final GridStorageSearch other = (GridStorageSearch) obj;
|
||||
return this.id == other.id;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public WeakReference<GridStorage> getGridStorage() {
|
||||
return this.gridStorage;
|
||||
}
|
||||
|
||||
public WeakReference<GridStorage> getGridStorage()
|
||||
{
|
||||
return this.gridStorage;
|
||||
}
|
||||
|
||||
public void setGridStorage( final WeakReference<GridStorage> gridStorage )
|
||||
{
|
||||
this.gridStorage = gridStorage;
|
||||
}
|
||||
public void setGridStorage(final WeakReference<GridStorage> gridStorage) {
|
||||
this.gridStorage = gridStorage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,28 +19,25 @@
|
||||
package appeng.me;
|
||||
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.IMachineSet;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
public class MachineSet extends HashSet<IGridNode> implements IMachineSet
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 3224660708327386933L;
|
||||
public class MachineSet extends HashSet<IGridNode> implements IMachineSet {
|
||||
|
||||
private final Class<? extends IGridHost> machine;
|
||||
private static final long serialVersionUID = 3224660708327386933L;
|
||||
|
||||
MachineSet( final Class<? extends IGridHost> m )
|
||||
{
|
||||
this.machine = m;
|
||||
}
|
||||
private final Class<? extends IGridHost> machine;
|
||||
|
||||
@Override
|
||||
public Class<? extends IGridHost> getMachineClass()
|
||||
{
|
||||
return this.machine;
|
||||
}
|
||||
MachineSet(final Class<? extends IGridHost> m) {
|
||||
this.machine = m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IGridHost> getMachineClass() {
|
||||
return this.machine;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,211 +19,163 @@
|
||||
package appeng.me;
|
||||
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.IMachineSet;
|
||||
import appeng.api.networking.events.MENetworkEvent;
|
||||
import appeng.api.networking.events.MENetworkEventSubscribe;
|
||||
import appeng.core.AELog;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class NetworkEventBus
|
||||
{
|
||||
private static final Collection<Class> READ_CLASSES = new HashSet<>();
|
||||
private static final Map<Class<? extends MENetworkEvent>, Map<Class, MENetworkEventInfo>> EVENTS = new HashMap<>();
|
||||
|
||||
void readClass( final Class listAs, final Class c )
|
||||
{
|
||||
if( READ_CLASSES.contains( c ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
READ_CLASSES.add( c );
|
||||
public class NetworkEventBus {
|
||||
private static final Collection<Class> READ_CLASSES = new HashSet<>();
|
||||
private static final Map<Class<? extends MENetworkEvent>, Map<Class, MENetworkEventInfo>> EVENTS = new HashMap<>();
|
||||
|
||||
try
|
||||
{
|
||||
for( final Method m : c.getMethods() )
|
||||
{
|
||||
final MENetworkEventSubscribe s = m.getAnnotation( MENetworkEventSubscribe.class );
|
||||
if( s != null )
|
||||
{
|
||||
final Class[] types = m.getParameterTypes();
|
||||
if( types.length == 1 )
|
||||
{
|
||||
if( MENetworkEvent.class.isAssignableFrom( types[0] ) )
|
||||
{
|
||||
void readClass(final Class listAs, final Class c) {
|
||||
if (READ_CLASSES.contains(c)) {
|
||||
return;
|
||||
}
|
||||
READ_CLASSES.add(c);
|
||||
|
||||
Map<Class, MENetworkEventInfo> classEvents = EVENTS.get( types[0] );
|
||||
if( classEvents == null )
|
||||
{
|
||||
EVENTS.put( types[0], classEvents = new HashMap<>() );
|
||||
}
|
||||
try {
|
||||
for (final Method m : c.getMethods()) {
|
||||
final MENetworkEventSubscribe s = m.getAnnotation(MENetworkEventSubscribe.class);
|
||||
if (s != null) {
|
||||
final Class[] types = m.getParameterTypes();
|
||||
if (types.length == 1) {
|
||||
if (MENetworkEvent.class.isAssignableFrom(types[0])) {
|
||||
|
||||
MENetworkEventInfo thisEvent = classEvents.get( listAs );
|
||||
if( thisEvent == null )
|
||||
{
|
||||
thisEvent = new MENetworkEventInfo();
|
||||
}
|
||||
Map<Class, MENetworkEventInfo> classEvents = EVENTS.get(types[0]);
|
||||
if (classEvents == null) {
|
||||
EVENTS.put(types[0], classEvents = new HashMap<>());
|
||||
}
|
||||
|
||||
thisEvent.Add( types[0], c, m );
|
||||
MENetworkEventInfo thisEvent = classEvents.get(listAs);
|
||||
if (thisEvent == null) {
|
||||
thisEvent = new MENetworkEventInfo();
|
||||
}
|
||||
|
||||
classEvents.put( listAs, thisEvent );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException( "Invalid ME Network Event Subscriber, " + m
|
||||
.getName() + "s Parameter must extend MENetworkEvent." );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException( "Invalid ME Network Event Subscriber, " + m.getName() + " must have exactly 1 parameter." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( final Throwable t )
|
||||
{
|
||||
throw new IllegalStateException( "Error while adding " + c.getName() + " to event bus", t );
|
||||
}
|
||||
}
|
||||
thisEvent.Add(types[0], c, m);
|
||||
|
||||
MENetworkEvent postEvent( final Grid g, final MENetworkEvent e )
|
||||
{
|
||||
final Map<Class, MENetworkEventInfo> subscribers = EVENTS.get( e.getClass() );
|
||||
int x = 0;
|
||||
classEvents.put(listAs, thisEvent);
|
||||
} else {
|
||||
throw new IllegalStateException("Invalid ME Network Event Subscriber, " + m
|
||||
.getName() + "s Parameter must extend MENetworkEvent.");
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Invalid ME Network Event Subscriber, " + m.getName() + " must have exactly 1 parameter.");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (final Throwable t) {
|
||||
throw new IllegalStateException("Error while adding " + c.getName() + " to event bus", t);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if( subscribers != null )
|
||||
{
|
||||
for( final Entry<Class, MENetworkEventInfo> subscriber : subscribers.entrySet() )
|
||||
{
|
||||
final MENetworkEventInfo target = subscriber.getValue();
|
||||
final GridCacheWrapper cache = g.getCaches().get( subscriber.getKey() );
|
||||
if( cache != null )
|
||||
{
|
||||
x++;
|
||||
target.invoke( cache.getCache(), e );
|
||||
}
|
||||
MENetworkEvent postEvent(final Grid g, final MENetworkEvent e) {
|
||||
final Map<Class, MENetworkEventInfo> subscribers = EVENTS.get(e.getClass());
|
||||
int x = 0;
|
||||
|
||||
// events may create or remove grid nodes in rare cases
|
||||
final IMachineSet machines = g.getMachines( subscriber.getKey() );
|
||||
final List<IGridNode> work = new ArrayList<>( machines.size() );
|
||||
machines.forEach( work::add );
|
||||
try {
|
||||
if (subscribers != null) {
|
||||
for (final Entry<Class, MENetworkEventInfo> subscriber : subscribers.entrySet()) {
|
||||
final MENetworkEventInfo target = subscriber.getValue();
|
||||
final GridCacheWrapper cache = g.getCaches().get(subscriber.getKey());
|
||||
if (cache != null) {
|
||||
x++;
|
||||
target.invoke(cache.getCache(), e);
|
||||
}
|
||||
|
||||
for( final IGridNode obj : work )
|
||||
{
|
||||
// stil part of grid?
|
||||
if( machines.contains( obj ) )
|
||||
{
|
||||
x++;
|
||||
target.invoke( obj.getMachine(), e );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( final NetworkEventDone done )
|
||||
{
|
||||
// Early out.
|
||||
}
|
||||
// events may create or remove grid nodes in rare cases
|
||||
final IMachineSet machines = g.getMachines(subscriber.getKey());
|
||||
final List<IGridNode> work = new ArrayList<>(machines.size());
|
||||
machines.forEach(work::add);
|
||||
|
||||
e.setVisitedObjects( x );
|
||||
return e;
|
||||
}
|
||||
for (final IGridNode obj : work) {
|
||||
// stil part of grid?
|
||||
if (machines.contains(obj)) {
|
||||
x++;
|
||||
target.invoke(obj.getMachine(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (final NetworkEventDone done) {
|
||||
// Early out.
|
||||
}
|
||||
|
||||
MENetworkEvent postEventTo( final Grid grid, final GridNode node, final MENetworkEvent e )
|
||||
{
|
||||
final Map<Class, MENetworkEventInfo> subscribers = EVENTS.get( e.getClass() );
|
||||
int x = 0;
|
||||
e.setVisitedObjects(x);
|
||||
return e;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if( subscribers != null )
|
||||
{
|
||||
final MENetworkEventInfo target = subscribers.get( node.getMachineClass() );
|
||||
if( target != null )
|
||||
{
|
||||
x++;
|
||||
target.invoke( node.getMachine(), e );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( final NetworkEventDone done )
|
||||
{
|
||||
// Early out.
|
||||
}
|
||||
MENetworkEvent postEventTo(final Grid grid, final GridNode node, final MENetworkEvent e) {
|
||||
final Map<Class, MENetworkEventInfo> subscribers = EVENTS.get(e.getClass());
|
||||
int x = 0;
|
||||
|
||||
e.setVisitedObjects( x );
|
||||
return e;
|
||||
}
|
||||
try {
|
||||
if (subscribers != null) {
|
||||
final MENetworkEventInfo target = subscribers.get(node.getMachineClass());
|
||||
if (target != null) {
|
||||
x++;
|
||||
target.invoke(node.getMachine(), e);
|
||||
}
|
||||
}
|
||||
} catch (final NetworkEventDone done) {
|
||||
// Early out.
|
||||
}
|
||||
|
||||
private static class NetworkEventDone extends Throwable
|
||||
{
|
||||
e.setVisitedObjects(x);
|
||||
return e;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = -3079021487019171205L;
|
||||
}
|
||||
private static class NetworkEventDone extends Throwable {
|
||||
|
||||
private class EventMethod
|
||||
{
|
||||
private static final long serialVersionUID = -3079021487019171205L;
|
||||
}
|
||||
|
||||
private final Class objClass;
|
||||
private final Method objMethod;
|
||||
private final Class objEvent;
|
||||
private class EventMethod {
|
||||
|
||||
public EventMethod( final Class Event, final Class ObjClass, final Method ObjMethod )
|
||||
{
|
||||
this.objClass = ObjClass;
|
||||
this.objMethod = ObjMethod;
|
||||
this.objEvent = Event;
|
||||
}
|
||||
private final Class objClass;
|
||||
private final Method objMethod;
|
||||
private final Class objEvent;
|
||||
|
||||
private void invoke( final Object obj, final MENetworkEvent e ) throws NetworkEventDone
|
||||
{
|
||||
try
|
||||
{
|
||||
this.objMethod.invoke( obj, e );
|
||||
}
|
||||
catch( final Throwable e1 )
|
||||
{
|
||||
AELog.error( "[AppEng] Network Event caused exception:" );
|
||||
AELog.error( "Class: %1s, Object: %2s", obj.getClass().getName(), obj.toString() );
|
||||
AELog.info( e1 );
|
||||
throw new IllegalStateException( e1 );
|
||||
}
|
||||
public EventMethod(final Class Event, final Class ObjClass, final Method ObjMethod) {
|
||||
this.objClass = ObjClass;
|
||||
this.objMethod = ObjMethod;
|
||||
this.objEvent = Event;
|
||||
}
|
||||
|
||||
if( e.isCanceled() )
|
||||
{
|
||||
throw new NetworkEventDone();
|
||||
}
|
||||
}
|
||||
}
|
||||
private void invoke(final Object obj, final MENetworkEvent e) throws NetworkEventDone {
|
||||
try {
|
||||
this.objMethod.invoke(obj, e);
|
||||
} catch (final Throwable e1) {
|
||||
AELog.error("[AppEng] Network Event caused exception:");
|
||||
AELog.error("Class: %1s, Object: %2s", obj.getClass().getName(), obj.toString());
|
||||
AELog.info(e1);
|
||||
throw new IllegalStateException(e1);
|
||||
}
|
||||
|
||||
private class MENetworkEventInfo
|
||||
{
|
||||
if (e.isCanceled()) {
|
||||
throw new NetworkEventDone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final List<EventMethod> methods = new ArrayList<>();
|
||||
private class MENetworkEventInfo {
|
||||
|
||||
private void Add( final Class Event, final Class ObjClass, final Method ObjMethod )
|
||||
{
|
||||
this.methods.add( new EventMethod( Event, ObjClass, ObjMethod ) );
|
||||
}
|
||||
private final List<EventMethod> methods = new ArrayList<>();
|
||||
|
||||
private void invoke( final Object obj, final MENetworkEvent e ) throws NetworkEventDone
|
||||
{
|
||||
for( final EventMethod em : this.methods )
|
||||
{
|
||||
em.invoke( obj, e );
|
||||
}
|
||||
}
|
||||
}
|
||||
private void Add(final Class Event, final Class ObjClass, final Method ObjMethod) {
|
||||
this.methods.add(new EventMethod(Event, ObjClass, ObjMethod));
|
||||
}
|
||||
|
||||
private void invoke(final Object obj, final MENetworkEvent e) throws NetworkEventDone {
|
||||
for (final EventMethod em : this.methods) {
|
||||
em.invoke(obj, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+527
-657
File diff suppressed because it is too large
Load Diff
+641
-794
File diff suppressed because it is too large
Load Diff
+198
-263
@@ -19,15 +19,6 @@
|
||||
package appeng.me.cache;
|
||||
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.crafting.MECraftingInventory;
|
||||
import appeng.helpers.IInterfaceHost;
|
||||
import appeng.helpers.IPriorityHost;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridHost;
|
||||
@@ -41,11 +32,7 @@ import appeng.api.networking.security.ISecurityGrid;
|
||||
import appeng.api.networking.storage.IStackWatcher;
|
||||
import appeng.api.networking.storage.IStackWatcherHost;
|
||||
import appeng.api.networking.storage.IStorageGrid;
|
||||
import appeng.api.storage.ICellContainer;
|
||||
import appeng.api.storage.ICellProvider;
|
||||
import appeng.api.storage.IMEInventoryHandler;
|
||||
import appeng.api.storage.IMEMonitor;
|
||||
import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.*;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
@@ -54,311 +41,259 @@ import appeng.me.helpers.GenericInterestManager;
|
||||
import appeng.me.helpers.MachineSource;
|
||||
import appeng.me.storage.ItemWatcher;
|
||||
import appeng.me.storage.NetworkInventoryHandler;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class GridStorageCache implements IStorageGrid
|
||||
{
|
||||
public class GridStorageCache implements IStorageGrid {
|
||||
|
||||
private final IGrid myGrid;
|
||||
private final HashSet<ICellProvider> activeCellProviders = new HashSet<>();
|
||||
private final HashSet<ICellProvider> inactiveCellProviders = new HashSet<>();
|
||||
private final SetMultimap<IAEStack, ItemWatcher> interests = HashMultimap.create();
|
||||
private final GenericInterestManager<ItemWatcher> interestManager = new GenericInterestManager<>( this.interests );
|
||||
private final HashMap<IGridNode, IStackWatcher> watchers = new HashMap<>();
|
||||
private final Map<IStorageChannel<? extends IAEStack>, NetworkInventoryHandler<?>> storageNetworks;
|
||||
private final Map<IStorageChannel<? extends IAEStack>, NetworkMonitor<?>> storageMonitors;
|
||||
private int localDepth;
|
||||
private final IGrid myGrid;
|
||||
private final HashSet<ICellProvider> activeCellProviders = new HashSet<>();
|
||||
private final HashSet<ICellProvider> inactiveCellProviders = new HashSet<>();
|
||||
private final SetMultimap<IAEStack, ItemWatcher> interests = HashMultimap.create();
|
||||
private final GenericInterestManager<ItemWatcher> interestManager = new GenericInterestManager<>(this.interests);
|
||||
private final HashMap<IGridNode, IStackWatcher> watchers = new HashMap<>();
|
||||
private final Map<IStorageChannel<? extends IAEStack>, NetworkInventoryHandler<?>> storageNetworks;
|
||||
private final Map<IStorageChannel<? extends IAEStack>, NetworkMonitor<?>> storageMonitors;
|
||||
private int localDepth;
|
||||
|
||||
public GridStorageCache( final IGrid g )
|
||||
{
|
||||
this.myGrid = g;
|
||||
this.storageNetworks = new IdentityHashMap<>();
|
||||
this.storageMonitors = new IdentityHashMap<>();
|
||||
public GridStorageCache(final IGrid g) {
|
||||
this.myGrid = g;
|
||||
this.storageNetworks = new IdentityHashMap<>();
|
||||
this.storageMonitors = new IdentityHashMap<>();
|
||||
|
||||
AEApi.instance().storage().storageChannels().forEach( channel -> this.storageMonitors.put( channel, new NetworkMonitor<>( this, channel ) ) );
|
||||
}
|
||||
AEApi.instance().storage().storageChannels().forEach(channel -> this.storageMonitors.put(channel, new NetworkMonitor<>(this, channel)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateTick()
|
||||
{
|
||||
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.onTick() );
|
||||
}
|
||||
@Override
|
||||
public void onUpdateTick() {
|
||||
this.storageMonitors.forEach((channel, monitor) -> monitor.onTick());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode( final IGridNode node, final IGridHost machine )
|
||||
{
|
||||
if( machine instanceof ICellContainer )
|
||||
{
|
||||
final ICellContainer cc = (ICellContainer) machine;
|
||||
final CellChangeTracker tracker = new CellChangeTracker();
|
||||
@Override
|
||||
public void removeNode(final IGridNode node, final IGridHost machine) {
|
||||
if (machine instanceof ICellContainer) {
|
||||
final ICellContainer cc = (ICellContainer) machine;
|
||||
final CellChangeTracker tracker = new CellChangeTracker();
|
||||
|
||||
this.removeCellProvider( cc, tracker );
|
||||
this.inactiveCellProviders.remove( cc );
|
||||
cellUpdate( null );
|
||||
this.removeCellProvider(cc, tracker);
|
||||
this.inactiveCellProviders.remove(cc);
|
||||
cellUpdate(null);
|
||||
|
||||
tracker.applyChanges();
|
||||
}
|
||||
tracker.applyChanges();
|
||||
}
|
||||
|
||||
if( machine instanceof IStackWatcherHost )
|
||||
{
|
||||
final IStackWatcher myWatcher = this.watchers.get( node );
|
||||
if (machine instanceof IStackWatcherHost) {
|
||||
final IStackWatcher myWatcher = this.watchers.get(node);
|
||||
|
||||
if( myWatcher != null )
|
||||
{
|
||||
myWatcher.reset();
|
||||
this.watchers.remove( node );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (myWatcher != null) {
|
||||
myWatcher.reset();
|
||||
this.watchers.remove(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNode( final IGridNode node, final IGridHost machine )
|
||||
{
|
||||
if( machine instanceof ICellContainer )
|
||||
{
|
||||
final ICellContainer cc = (ICellContainer) machine;
|
||||
this.inactiveCellProviders.add( cc );
|
||||
@Override
|
||||
public void addNode(final IGridNode node, final IGridHost machine) {
|
||||
if (machine instanceof ICellContainer) {
|
||||
final ICellContainer cc = (ICellContainer) machine;
|
||||
this.inactiveCellProviders.add(cc);
|
||||
|
||||
cellUpdate( null );
|
||||
cellUpdate(null);
|
||||
|
||||
if( node.isActive() )
|
||||
{
|
||||
final CellChangeTracker tracker = new CellChangeTracker();
|
||||
if (node.isActive()) {
|
||||
final CellChangeTracker tracker = new CellChangeTracker();
|
||||
|
||||
this.addCellProvider( cc, tracker );
|
||||
tracker.applyChanges();
|
||||
}
|
||||
}
|
||||
this.addCellProvider(cc, tracker);
|
||||
tracker.applyChanges();
|
||||
}
|
||||
}
|
||||
|
||||
if( machine instanceof IStackWatcherHost )
|
||||
{
|
||||
final IStackWatcherHost swh = (IStackWatcherHost) machine;
|
||||
final ItemWatcher iw = new ItemWatcher( this, swh );
|
||||
this.watchers.put( node, iw );
|
||||
swh.updateWatcher( iw );
|
||||
}
|
||||
}
|
||||
if (machine instanceof IStackWatcherHost) {
|
||||
final IStackWatcherHost swh = (IStackWatcherHost) machine;
|
||||
final ItemWatcher iw = new ItemWatcher(this, swh);
|
||||
this.watchers.put(node, iw);
|
||||
swh.updateWatcher(iw);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplit( final IGridStorage storageB )
|
||||
{
|
||||
@Override
|
||||
public void onSplit(final IGridStorage storageB) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJoin( final IGridStorage storageB )
|
||||
{
|
||||
@Override
|
||||
public void onJoin(final IGridStorage storageB) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateGridStorage( final IGridStorage storage )
|
||||
{
|
||||
@Override
|
||||
public void populateGridStorage(final IGridStorage storage) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends IAEStack<T>> IMEInventoryHandler<T> getInventoryHandler( IStorageChannel<T> channel )
|
||||
{
|
||||
return (IMEInventoryHandler<T>) this.storageNetworks.computeIfAbsent( channel, this::buildNetworkStorage );
|
||||
}
|
||||
public <T extends IAEStack<T>> IMEInventoryHandler<T> getInventoryHandler(IStorageChannel<T> channel) {
|
||||
return (IMEInventoryHandler<T>) this.storageNetworks.computeIfAbsent(channel, this::buildNetworkStorage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IAEStack<T>> IMEMonitor<T> getInventory( IStorageChannel<T> channel )
|
||||
{
|
||||
return (IMEMonitor<T>) this.storageMonitors.get( channel );
|
||||
}
|
||||
@Override
|
||||
public <T extends IAEStack<T>> IMEMonitor<T> getInventory(IStorageChannel<T> channel) {
|
||||
return (IMEMonitor<T>) this.storageMonitors.get(channel);
|
||||
}
|
||||
|
||||
private CellChangeTracker addCellProvider( final ICellProvider cc, final CellChangeTracker tracker )
|
||||
{
|
||||
if( this.inactiveCellProviders.contains( cc ) )
|
||||
{
|
||||
this.inactiveCellProviders.remove( cc );
|
||||
this.activeCellProviders.add( cc );
|
||||
private CellChangeTracker addCellProvider(final ICellProvider cc, final CellChangeTracker tracker) {
|
||||
if (this.inactiveCellProviders.contains(cc)) {
|
||||
this.inactiveCellProviders.remove(cc);
|
||||
this.activeCellProviders.add(cc);
|
||||
|
||||
final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource( (IActionHost) cc ) : new BaseActionSource();
|
||||
final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource((IActionHost) cc) : new BaseActionSource();
|
||||
|
||||
this.storageMonitors.forEach( ( channel, monitor ) ->
|
||||
{
|
||||
for( final IMEInventoryHandler<?> h : cc.getCellArray( channel ) )
|
||||
{
|
||||
tracker.postChanges( channel, 1, h, actionSrc );
|
||||
}
|
||||
} );
|
||||
}
|
||||
this.storageMonitors.forEach((channel, monitor) ->
|
||||
{
|
||||
for (final IMEInventoryHandler<?> h : cc.getCellArray(channel)) {
|
||||
tracker.postChanges(channel, 1, h, actionSrc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return tracker;
|
||||
}
|
||||
return tracker;
|
||||
}
|
||||
|
||||
private CellChangeTracker removeCellProvider( final ICellProvider cc, final CellChangeTracker tracker )
|
||||
{
|
||||
if( this.activeCellProviders.contains( cc ) )
|
||||
{
|
||||
this.activeCellProviders.remove( cc );
|
||||
this.inactiveCellProviders.add( cc );
|
||||
private CellChangeTracker removeCellProvider(final ICellProvider cc, final CellChangeTracker tracker) {
|
||||
if (this.activeCellProviders.contains(cc)) {
|
||||
this.activeCellProviders.remove(cc);
|
||||
this.inactiveCellProviders.add(cc);
|
||||
|
||||
final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource( (IActionHost) cc ) : new BaseActionSource();
|
||||
final IActionSource actionSrc = cc instanceof IActionHost ? new MachineSource((IActionHost) cc) : new BaseActionSource();
|
||||
|
||||
this.storageMonitors.forEach( ( channel, monitor ) ->
|
||||
{
|
||||
for( final IMEInventoryHandler<IAEItemStack> h : cc.getCellArray( channel ) )
|
||||
{
|
||||
tracker.postChanges( channel, -1, h, actionSrc );
|
||||
}
|
||||
} );
|
||||
}
|
||||
this.storageMonitors.forEach((channel, monitor) ->
|
||||
{
|
||||
for (final IMEInventoryHandler<IAEItemStack> h : cc.getCellArray(channel)) {
|
||||
tracker.postChanges(channel, -1, h, actionSrc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return tracker;
|
||||
}
|
||||
return tracker;
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void cellUpdate( final MENetworkCellArrayUpdate ev )
|
||||
{
|
||||
if( localDepth > 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
localDepth++;
|
||||
this.storageNetworks.clear();
|
||||
@MENetworkEventSubscribe
|
||||
public void cellUpdate(final MENetworkCellArrayUpdate ev) {
|
||||
if (localDepth > 0) {
|
||||
return;
|
||||
}
|
||||
localDepth++;
|
||||
this.storageNetworks.clear();
|
||||
|
||||
final List<ICellProvider> ll = new ArrayList<ICellProvider>();
|
||||
ll.addAll( this.inactiveCellProviders );
|
||||
ll.addAll( this.activeCellProviders );
|
||||
final List<ICellProvider> ll = new ArrayList<ICellProvider>();
|
||||
ll.addAll(this.inactiveCellProviders);
|
||||
ll.addAll(this.activeCellProviders);
|
||||
|
||||
final CellChangeTracker tracker = new CellChangeTracker();
|
||||
final CellChangeTracker tracker = new CellChangeTracker();
|
||||
|
||||
for( final ICellProvider cc : ll )
|
||||
{
|
||||
boolean active = true;
|
||||
for (final ICellProvider cc : ll) {
|
||||
boolean active = true;
|
||||
|
||||
if( cc instanceof IActionHost )
|
||||
{
|
||||
final IGridNode node = ( (IActionHost) cc ).getActionableNode();
|
||||
if( node != null && node.isActive() )
|
||||
{
|
||||
active = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
active = false;
|
||||
}
|
||||
}
|
||||
if (cc instanceof IActionHost) {
|
||||
final IGridNode node = ((IActionHost) cc).getActionableNode();
|
||||
active = node != null && node.isActive();
|
||||
}
|
||||
|
||||
if( active )
|
||||
{
|
||||
this.addCellProvider( cc, tracker );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.removeCellProvider( cc, tracker );
|
||||
}
|
||||
}
|
||||
tracker.applyChanges();
|
||||
localDepth--;
|
||||
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.setForceUpdate( true ) );
|
||||
}
|
||||
if (active) {
|
||||
this.addCellProvider(cc, tracker);
|
||||
} else {
|
||||
this.removeCellProvider(cc, tracker);
|
||||
}
|
||||
}
|
||||
tracker.applyChanges();
|
||||
localDepth--;
|
||||
this.storageMonitors.forEach((channel, monitor) -> monitor.setForceUpdate(true));
|
||||
}
|
||||
|
||||
private <T extends IAEStack<T>, C extends IStorageChannel<T>> void postChangesToNetwork( final C chan, final int upOrDown, final IItemList<T> availableItems, final IActionSource src )
|
||||
{
|
||||
this.storageMonitors.get( chan ).postChange( upOrDown > 0, (Iterable) availableItems, src );
|
||||
}
|
||||
private <T extends IAEStack<T>, C extends IStorageChannel<T>> void postChangesToNetwork(final C chan, final int upOrDown, final IItemList<T> availableItems, final IActionSource src) {
|
||||
this.storageMonitors.get(chan).postChange(upOrDown > 0, (Iterable) availableItems, src);
|
||||
}
|
||||
|
||||
private <T extends IAEStack<T>, C extends IStorageChannel<T>> NetworkInventoryHandler<T> buildNetworkStorage( final C chan )
|
||||
{
|
||||
final SecurityCache security = this.getGrid().getCache( ISecurityGrid.class );
|
||||
private <T extends IAEStack<T>, C extends IStorageChannel<T>> NetworkInventoryHandler<T> buildNetworkStorage(final C chan) {
|
||||
final SecurityCache security = this.getGrid().getCache(ISecurityGrid.class);
|
||||
|
||||
final NetworkInventoryHandler<T> storageNetwork = new NetworkInventoryHandler<>( chan, security );
|
||||
final NetworkInventoryHandler<T> storageNetwork = new NetworkInventoryHandler<>(chan, security);
|
||||
|
||||
for( final ICellProvider cc : this.activeCellProviders )
|
||||
{
|
||||
for( final IMEInventoryHandler<T> h : cc.getCellArray( chan ) )
|
||||
{
|
||||
storageNetwork.addNewStorage( h );
|
||||
}
|
||||
}
|
||||
for (final ICellProvider cc : this.activeCellProviders) {
|
||||
for (final IMEInventoryHandler<T> h : cc.getCellArray(chan)) {
|
||||
storageNetwork.addNewStorage(h);
|
||||
}
|
||||
}
|
||||
|
||||
return storageNetwork;
|
||||
}
|
||||
return storageNetwork;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postAlterationOfStoredItems( final IStorageChannel<?> chan, final Iterable<? extends IAEStack<?>> input, final IActionSource src )
|
||||
{
|
||||
this.storageMonitors.get( chan ).postChange( true, (Iterable) input, src );
|
||||
}
|
||||
@Override
|
||||
public void postAlterationOfStoredItems(final IStorageChannel<?> chan, final Iterable<? extends IAEStack<?>> input, final IActionSource src) {
|
||||
this.storageMonitors.get(chan).postChange(true, (Iterable) input, src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postCraftablesChanges( IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src )
|
||||
{
|
||||
this.storageMonitors.get( chan ).updateCraftables( (Iterable) input, src );
|
||||
}
|
||||
@Override
|
||||
public void postCraftablesChanges(IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src) {
|
||||
this.storageMonitors.get(chan).updateCraftables((Iterable) input, src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCellProvider( final ICellProvider provider )
|
||||
{
|
||||
this.inactiveCellProviders.add( provider );
|
||||
this.addCellProvider( provider, new CellChangeTracker() ).applyChanges();
|
||||
}
|
||||
@Override
|
||||
public void registerCellProvider(final ICellProvider provider) {
|
||||
this.inactiveCellProviders.add(provider);
|
||||
this.addCellProvider(provider, new CellChangeTracker()).applyChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterCellProvider( final ICellProvider provider )
|
||||
{
|
||||
this.removeCellProvider( provider, new CellChangeTracker() ).applyChanges();
|
||||
this.inactiveCellProviders.remove( provider );
|
||||
}
|
||||
@Override
|
||||
public void unregisterCellProvider(final ICellProvider provider) {
|
||||
this.removeCellProvider(provider, new CellChangeTracker()).applyChanges();
|
||||
this.inactiveCellProviders.remove(provider);
|
||||
}
|
||||
|
||||
public GenericInterestManager<ItemWatcher> getInterestManager()
|
||||
{
|
||||
return this.interestManager;
|
||||
}
|
||||
public GenericInterestManager<ItemWatcher> getInterestManager() {
|
||||
return this.interestManager;
|
||||
}
|
||||
|
||||
IGrid getGrid()
|
||||
{
|
||||
return this.myGrid;
|
||||
}
|
||||
IGrid getGrid() {
|
||||
return this.myGrid;
|
||||
}
|
||||
|
||||
private class CellChangeTrackerRecord<T extends IAEStack<T>>
|
||||
{
|
||||
private class CellChangeTrackerRecord<T extends IAEStack<T>> {
|
||||
|
||||
final IStorageChannel<T> channel;
|
||||
final int up_or_down;
|
||||
final IItemList<T> list;
|
||||
final IActionSource src;
|
||||
final IStorageChannel<T> channel;
|
||||
final int up_or_down;
|
||||
final IItemList<T> list;
|
||||
final IActionSource src;
|
||||
|
||||
public CellChangeTrackerRecord( final IStorageChannel<T> channel, final int i, final IMEInventoryHandler<T> h, final IActionSource actionSrc )
|
||||
{
|
||||
this.channel = channel;
|
||||
this.up_or_down = i;
|
||||
this.src = actionSrc;
|
||||
public CellChangeTrackerRecord(final IStorageChannel<T> channel, final int i, final IMEInventoryHandler<T> h, final IActionSource actionSrc) {
|
||||
this.channel = channel;
|
||||
this.up_or_down = i;
|
||||
this.src = actionSrc;
|
||||
|
||||
this.list = h.getAvailableItems( channel.createList() );
|
||||
}
|
||||
this.list = h.getAvailableItems(channel.createList());
|
||||
}
|
||||
|
||||
public void applyChanges()
|
||||
{
|
||||
if( !this.list.isEmpty() )
|
||||
{
|
||||
GridStorageCache.this.postChangesToNetwork( this.channel, this.up_or_down, this.list, this.src );
|
||||
}
|
||||
}
|
||||
}
|
||||
public void applyChanges() {
|
||||
if (!this.list.isEmpty()) {
|
||||
GridStorageCache.this.postChangesToNetwork(this.channel, this.up_or_down, this.list, this.src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CellChangeTracker<T extends IAEStack<T>>
|
||||
{
|
||||
private class CellChangeTracker<T extends IAEStack<T>> {
|
||||
|
||||
final List<CellChangeTrackerRecord<T>> data = new ArrayList<>();
|
||||
final List<CellChangeTrackerRecord<T>> data = new ArrayList<>();
|
||||
|
||||
public void postChanges( final IStorageChannel<T> channel, final int i, final IMEInventoryHandler<T> h, final IActionSource actionSrc )
|
||||
{
|
||||
this.data.add( new CellChangeTrackerRecord<T>( channel, i, h, actionSrc ) );
|
||||
}
|
||||
public void postChanges(final IStorageChannel<T> channel, final int i, final IMEInventoryHandler<T> h, final IActionSource actionSrc) {
|
||||
this.data.add(new CellChangeTrackerRecord<T>(channel, i, h, actionSrc));
|
||||
}
|
||||
|
||||
public void applyChanges()
|
||||
{
|
||||
for( final CellChangeTrackerRecord<T> rec : this.data )
|
||||
{
|
||||
rec.applyChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void applyChanges() {
|
||||
for (final CellChangeTrackerRecord<T> rec : this.data) {
|
||||
rec.applyChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+221
-282
@@ -19,8 +19,6 @@
|
||||
package appeng.me.cache;
|
||||
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Actionable;
|
||||
@@ -38,339 +36,280 @@ import appeng.me.storage.ItemWatcher;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
|
||||
{
|
||||
@Nonnull
|
||||
private static final HashMap<IActionSource, LinkedList<NetworkMonitor<?>>> src2MonitorsMap = new HashMap<>();
|
||||
private static final Set<IActionSource> nestingSources = new HashSet<>();
|
||||
public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T> {
|
||||
@Nonnull
|
||||
private static final HashMap<IActionSource, LinkedList<NetworkMonitor<?>>> src2MonitorsMap = new HashMap<>();
|
||||
private static final Set<IActionSource> nestingSources = new HashSet<>();
|
||||
|
||||
protected boolean wasNested = false;
|
||||
protected boolean isNested = false;
|
||||
protected boolean wasNested = false;
|
||||
protected boolean isNested = false;
|
||||
|
||||
@Nonnull
|
||||
private final GridStorageCache myGridCache;
|
||||
@Nonnull
|
||||
private final IStorageChannel<T> myChannel;
|
||||
@Nonnull
|
||||
private final IItemList<T> cachedList;
|
||||
@Nonnull
|
||||
private final Object2ObjectMap<IMEMonitorHandlerReceiver<T>, Object> listeners;
|
||||
@Nonnull
|
||||
private final GridStorageCache myGridCache;
|
||||
@Nonnull
|
||||
private final IStorageChannel<T> myChannel;
|
||||
@Nonnull
|
||||
private final IItemList<T> cachedList;
|
||||
@Nonnull
|
||||
private final Object2ObjectMap<IMEMonitorHandlerReceiver<T>, Object> listeners;
|
||||
|
||||
private boolean sendEvent = false;
|
||||
private long gridItemCount;
|
||||
private long gridFluidCount;
|
||||
public boolean forceUpdate;
|
||||
private boolean sendEvent = false;
|
||||
private long gridItemCount;
|
||||
private long gridFluidCount;
|
||||
public boolean forceUpdate;
|
||||
|
||||
public NetworkMonitor( final GridStorageCache cache, final IStorageChannel<T> chan )
|
||||
{
|
||||
this.myGridCache = cache;
|
||||
this.myChannel = chan;
|
||||
this.cachedList = chan.createList();
|
||||
this.listeners = new Object2ObjectOpenHashMap<>();
|
||||
}
|
||||
public NetworkMonitor(final GridStorageCache cache, final IStorageChannel<T> chan) {
|
||||
this.myGridCache = cache;
|
||||
this.myChannel = chan;
|
||||
this.cachedList = chan.createList();
|
||||
this.listeners = new Object2ObjectOpenHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener( final IMEMonitorHandlerReceiver<T> l, final Object verificationToken )
|
||||
{
|
||||
this.listeners.put( l, verificationToken );
|
||||
}
|
||||
@Override
|
||||
public void addListener(final IMEMonitorHandlerReceiver<T> l, final Object verificationToken) {
|
||||
this.listeners.put(l, verificationToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccept( final T input )
|
||||
{
|
||||
return this.getHandler().canAccept( input );
|
||||
}
|
||||
@Override
|
||||
public boolean canAccept(final T input) {
|
||||
return this.getHandler().canAccept(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T extractItems( final T request, final Actionable mode, final IActionSource src )
|
||||
{
|
||||
return this.getHandler().extractItems( request, mode, src );
|
||||
}
|
||||
@Override
|
||||
public T extractItems(final T request, final Actionable mode, final IActionSource src) {
|
||||
return this.getHandler().extractItems(request, mode, src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessRestriction getAccess()
|
||||
{
|
||||
return this.getHandler().getAccess();
|
||||
}
|
||||
@Override
|
||||
public AccessRestriction getAccess() {
|
||||
return this.getHandler().getAccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems( final IItemList<T> out )
|
||||
{
|
||||
return this.getHandler().getAvailableItems( out );
|
||||
}
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems(final IItemList<T> out) {
|
||||
return this.getHandler().getAvailableItems(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel<T> getChannel()
|
||||
{
|
||||
return this.getHandler().getChannel();
|
||||
}
|
||||
@Override
|
||||
public IStorageChannel<T> getChannel() {
|
||||
return this.getHandler().getChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority()
|
||||
{
|
||||
return this.getHandler().getPriority();
|
||||
}
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return this.getHandler().getPriority();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlot()
|
||||
{
|
||||
return this.getHandler().getSlot();
|
||||
}
|
||||
@Override
|
||||
public int getSlot() {
|
||||
return this.getHandler().getSlot();
|
||||
}
|
||||
|
||||
public long getGridCurrentCount()
|
||||
{
|
||||
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
||||
{
|
||||
return gridItemCount;
|
||||
}
|
||||
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
||||
{
|
||||
return gridFluidCount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public long getGridCurrentCount() {
|
||||
if (myChannel == AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)) {
|
||||
return gridItemCount;
|
||||
} else if (myChannel == AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class)) {
|
||||
return gridFluidCount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void incGridCurrentCount( long count )
|
||||
{
|
||||
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
||||
{
|
||||
gridItemCount += count;
|
||||
}
|
||||
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
||||
{
|
||||
gridFluidCount += count;
|
||||
}
|
||||
}
|
||||
public void incGridCurrentCount(long count) {
|
||||
if (myChannel == AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)) {
|
||||
gridItemCount += count;
|
||||
} else if (myChannel == AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class)) {
|
||||
gridFluidCount += count;
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IItemList<T> getStorageList()
|
||||
{
|
||||
return this.cachedList;
|
||||
}
|
||||
@Nonnull
|
||||
@Override
|
||||
public IItemList<T> getStorageList() {
|
||||
return this.cachedList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T injectItems( final T input, final Actionable mode, final IActionSource src )
|
||||
{
|
||||
return this.getHandler().injectItems( input, mode, src );
|
||||
}
|
||||
@Override
|
||||
public T injectItems(final T input, final Actionable mode, final IActionSource src) {
|
||||
return this.getHandler().injectItems(input, mode, src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrioritized( final T input )
|
||||
{
|
||||
return this.getHandler().isPrioritized( input );
|
||||
}
|
||||
@Override
|
||||
public boolean isPrioritized(final T input) {
|
||||
return this.getHandler().isPrioritized(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener( final IMEMonitorHandlerReceiver<T> l )
|
||||
{
|
||||
this.listeners.remove( l );
|
||||
}
|
||||
@Override
|
||||
public void removeListener(final IMEMonitorHandlerReceiver<T> l) {
|
||||
this.listeners.remove(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validForPass( final int i )
|
||||
{
|
||||
return this.getHandler().validForPass( i );
|
||||
}
|
||||
@Override
|
||||
public boolean validForPass(final int i) {
|
||||
return this.getHandler().validForPass(i);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private IMEInventoryHandler<T> getHandler()
|
||||
{
|
||||
return this.myGridCache.getInventoryHandler( this.myChannel );
|
||||
}
|
||||
@Nullable
|
||||
private IMEInventoryHandler<T> getHandler() {
|
||||
return this.myGridCache.getInventoryHandler(this.myChannel);
|
||||
}
|
||||
|
||||
private Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> getListeners()
|
||||
{
|
||||
return this.listeners.entrySet().iterator();
|
||||
}
|
||||
private Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> getListeners() {
|
||||
return this.listeners.entrySet().iterator();
|
||||
}
|
||||
|
||||
private void notifyListenersOfChange( final Iterable<T> diff, final IActionSource src )
|
||||
{
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
|
||||
private void notifyListenersOfChange(final Iterable<T> diff, final IActionSource src) {
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
|
||||
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
|
||||
final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
|
||||
while (i.hasNext()) {
|
||||
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
|
||||
final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
|
||||
|
||||
if( receiver.isValid( o.getValue() ) )
|
||||
{
|
||||
receiver.postChange( this, diff, src );
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (receiver.isValid(o.getValue())) {
|
||||
receiver.postChange(this, diff, src);
|
||||
} else {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateCraftables( Iterable<T> input, IActionSource src )
|
||||
{
|
||||
for( final T changedItem : input )
|
||||
{
|
||||
if (changedItem.isCraftable()) {
|
||||
this.cachedList.add( changedItem );
|
||||
}
|
||||
else
|
||||
{
|
||||
T i = this.cachedList.findPrecise( changedItem );
|
||||
if (i != null)
|
||||
i.setCraftable( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
protected void updateCraftables(Iterable<T> input, IActionSource src) {
|
||||
for (final T changedItem : input) {
|
||||
if (changedItem.isCraftable()) {
|
||||
this.cachedList.add(changedItem);
|
||||
} else {
|
||||
T i = this.cachedList.findPrecise(changedItem);
|
||||
if (i != null)
|
||||
i.setCraftable(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void postChange( final boolean add, final Iterable<T> changes, final IActionSource src )
|
||||
{
|
||||
src2MonitorsMap.putIfAbsent( src, new LinkedList<>() );
|
||||
if( src2MonitorsMap.get( src ).contains( this ) )
|
||||
{
|
||||
nestingSources.add( src );
|
||||
return;
|
||||
}
|
||||
src2MonitorsMap.get( src ).add( this );
|
||||
protected void postChange(final boolean add, final Iterable<T> changes, final IActionSource src) {
|
||||
src2MonitorsMap.putIfAbsent(src, new LinkedList<>());
|
||||
if (src2MonitorsMap.get(src).contains(this)) {
|
||||
nestingSources.add(src);
|
||||
return;
|
||||
}
|
||||
src2MonitorsMap.get(src).add(this);
|
||||
|
||||
this.sendEvent = true;
|
||||
this.sendEvent = true;
|
||||
|
||||
for( final T change : changes )
|
||||
{
|
||||
//T change = changed;
|
||||
if( !add && change != null )
|
||||
{
|
||||
//change = changed.copy();
|
||||
change.setStackSize( -change.getStackSize() );
|
||||
}
|
||||
for (final T change : changes) {
|
||||
//T change = changed;
|
||||
if (!add && change != null) {
|
||||
//change = changed.copy();
|
||||
change.setStackSize(-change.getStackSize());
|
||||
}
|
||||
|
||||
incGridCurrentCount( change.getStackSize() );
|
||||
this.cachedList.addStorage( change );
|
||||
incGridCurrentCount(change.getStackSize());
|
||||
this.cachedList.addStorage(change);
|
||||
|
||||
if( this.myGridCache.getInterestManager().containsKey( change ) )
|
||||
{
|
||||
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( change );
|
||||
if (this.myGridCache.getInterestManager().containsKey(change)) {
|
||||
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get(change);
|
||||
|
||||
if( !list.isEmpty() )
|
||||
{
|
||||
IAEStack<T> fullStack = this.getStorageList().findPrecise( change );
|
||||
if (!list.isEmpty()) {
|
||||
IAEStack<T> fullStack = this.getStorageList().findPrecise(change);
|
||||
|
||||
if( fullStack == null )
|
||||
{
|
||||
fullStack = change.copy();
|
||||
fullStack.setStackSize( 0 );
|
||||
}
|
||||
if (fullStack == null) {
|
||||
fullStack = change.copy();
|
||||
fullStack.setStackSize(0);
|
||||
}
|
||||
|
||||
this.myGridCache.getInterestManager().enableTransactions();
|
||||
this.myGridCache.getInterestManager().enableTransactions();
|
||||
|
||||
for( final ItemWatcher iw : list )
|
||||
{
|
||||
iw.getHost().onStackChange( this.getStorageList(), fullStack, change, src, this.getChannel() );
|
||||
}
|
||||
for (final ItemWatcher iw : list) {
|
||||
iw.getHost().onStackChange(this.getStorageList(), fullStack, change, src, this.getChannel());
|
||||
}
|
||||
|
||||
this.myGridCache.getInterestManager().disableTransactions();
|
||||
}
|
||||
}
|
||||
}
|
||||
this.myGridCache.getInterestManager().disableTransactions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.notifyListenersOfChange( changes, src );
|
||||
this.notifyListenersOfChange(changes, src);
|
||||
|
||||
if( src2MonitorsMap.get( src ).getFirst() == this )
|
||||
{
|
||||
boolean nested = nestingSources.contains( src );
|
||||
src2MonitorsMap.get( src ).forEach( networkMonitor -> networkMonitor.isNested = nested );
|
||||
if (src2MonitorsMap.get(src).getFirst() == this) {
|
||||
boolean nested = nestingSources.contains(src);
|
||||
src2MonitorsMap.get(src).forEach(networkMonitor -> networkMonitor.isNested = nested);
|
||||
|
||||
src2MonitorsMap.get( src ).forEach( networkMonitor -> {
|
||||
if( networkMonitor.isNested != networkMonitor.wasNested )
|
||||
{
|
||||
networkMonitor.wasNested = networkMonitor.isNested;
|
||||
networkMonitor.setForceUpdate( true );
|
||||
}
|
||||
} );
|
||||
src2MonitorsMap.remove( src );
|
||||
nestingSources.remove( src );
|
||||
}
|
||||
}
|
||||
src2MonitorsMap.get(src).forEach(networkMonitor -> {
|
||||
if (networkMonitor.isNested != networkMonitor.wasNested) {
|
||||
networkMonitor.wasNested = networkMonitor.isNested;
|
||||
networkMonitor.setForceUpdate(true);
|
||||
}
|
||||
});
|
||||
src2MonitorsMap.remove(src);
|
||||
nestingSources.remove(src);
|
||||
}
|
||||
}
|
||||
|
||||
public void setForceUpdate( boolean forceUpdate )
|
||||
{
|
||||
this.forceUpdate = forceUpdate;
|
||||
}
|
||||
public void setForceUpdate(boolean forceUpdate) {
|
||||
this.forceUpdate = forceUpdate;
|
||||
}
|
||||
|
||||
void forceUpdate()
|
||||
{
|
||||
forceUpdate = false;
|
||||
this.cachedList.resetStatus();
|
||||
this.getAvailableItems( this.cachedList );
|
||||
void forceUpdate() {
|
||||
forceUpdate = false;
|
||||
this.cachedList.resetStatus();
|
||||
this.getAvailableItems(this.cachedList);
|
||||
|
||||
long count = 0;
|
||||
for( T stack : this.cachedList )
|
||||
{
|
||||
count += stack.getStackSize();
|
||||
long count = 0;
|
||||
for (T stack : this.cachedList) {
|
||||
count += stack.getStackSize();
|
||||
|
||||
if( this.myGridCache.getInterestManager().containsKey( stack ) )
|
||||
{
|
||||
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( stack );
|
||||
if (this.myGridCache.getInterestManager().containsKey(stack)) {
|
||||
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get(stack);
|
||||
|
||||
if( !list.isEmpty() )
|
||||
{
|
||||
IAEStack<T> fullStack = this.getStorageList().findPrecise( stack );
|
||||
if (!list.isEmpty()) {
|
||||
IAEStack<T> fullStack = this.getStorageList().findPrecise(stack);
|
||||
|
||||
if( fullStack == null )
|
||||
{
|
||||
fullStack = stack.copy();
|
||||
fullStack.setStackSize( 0 );
|
||||
}
|
||||
if (fullStack == null) {
|
||||
fullStack = stack.copy();
|
||||
fullStack.setStackSize(0);
|
||||
}
|
||||
|
||||
this.myGridCache.getInterestManager().enableTransactions();
|
||||
this.myGridCache.getInterestManager().enableTransactions();
|
||||
|
||||
for ( final ItemWatcher iw : list )
|
||||
{
|
||||
iw.getHost().onStackChange( this.getStorageList(), fullStack, stack, null, this.getChannel() );
|
||||
}
|
||||
for (final ItemWatcher iw : list) {
|
||||
iw.getHost().onStackChange(this.getStorageList(), fullStack, stack, null, this.getChannel());
|
||||
}
|
||||
|
||||
this.myGridCache.getInterestManager().disableTransactions();
|
||||
}
|
||||
}
|
||||
}
|
||||
this.myGridCache.getInterestManager().disableTransactions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
|
||||
{
|
||||
gridItemCount = count;
|
||||
}
|
||||
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
|
||||
{
|
||||
gridFluidCount = count;
|
||||
}
|
||||
if (myChannel == AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)) {
|
||||
gridItemCount = count;
|
||||
} else if (myChannel == AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class)) {
|
||||
gridFluidCount = count;
|
||||
}
|
||||
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
|
||||
final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
|
||||
while (i.hasNext()) {
|
||||
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
|
||||
final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
|
||||
|
||||
if( receiver.isValid( o.getValue() ) )
|
||||
{
|
||||
receiver.onListUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (receiver.isValid(o.getValue())) {
|
||||
receiver.onListUpdate();
|
||||
} else {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onTick()
|
||||
{
|
||||
if( forceUpdate )
|
||||
{
|
||||
forceUpdate();
|
||||
}
|
||||
if( this.sendEvent )
|
||||
{
|
||||
this.sendEvent = false;
|
||||
this.myGridCache.getGrid().postEvent( new MENetworkStorageEvent( this, this.myChannel ) );
|
||||
}
|
||||
}
|
||||
void onTick() {
|
||||
if (forceUpdate) {
|
||||
forceUpdate();
|
||||
}
|
||||
if (this.sendEvent) {
|
||||
this.sendEvent = false;
|
||||
this.myGridCache.getGrid().postEvent(new MENetworkStorageEvent(this, this.myChannel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+169
-228
@@ -19,18 +19,7 @@
|
||||
package appeng.me.cache;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import appeng.api.networking.GridFlags;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridCache;
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.IGridStorage;
|
||||
import appeng.api.networking.*;
|
||||
import appeng.api.networking.events.MENetworkBootingStatusChange;
|
||||
import appeng.api.networking.events.MENetworkEventSubscribe;
|
||||
import appeng.api.networking.events.MENetworkPowerStatusChange;
|
||||
@@ -39,261 +28,213 @@ import appeng.core.AELog;
|
||||
import appeng.me.cache.helpers.TunnelCollection;
|
||||
import appeng.parts.p2p.PartP2PTunnel;
|
||||
import appeng.parts.p2p.PartP2PTunnelME;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public class P2PCache implements IGridCache
|
||||
{
|
||||
private static final TunnelCollection<PartP2PTunnel> NULL_COLLECTION = new TunnelCollection<PartP2PTunnel>( null, null );
|
||||
public class P2PCache implements IGridCache {
|
||||
private static final TunnelCollection<PartP2PTunnel> NULL_COLLECTION = new TunnelCollection<PartP2PTunnel>(null, null);
|
||||
|
||||
private final IGrid myGrid;
|
||||
private final Multimap<Short, PartP2PTunnel> inputs = LinkedHashMultimap.create();
|
||||
private final Multimap<Short, PartP2PTunnel> outputs = LinkedHashMultimap.create();
|
||||
private final Random frequencyGenerator;
|
||||
private final IGrid myGrid;
|
||||
private final Multimap<Short, PartP2PTunnel> inputs = LinkedHashMultimap.create();
|
||||
private final Multimap<Short, PartP2PTunnel> outputs = LinkedHashMultimap.create();
|
||||
private final Random frequencyGenerator;
|
||||
|
||||
public P2PCache( final IGrid g )
|
||||
{
|
||||
this.myGrid = g;
|
||||
this.frequencyGenerator = new Random( g.hashCode() );
|
||||
}
|
||||
public P2PCache(final IGrid g) {
|
||||
this.myGrid = g;
|
||||
this.frequencyGenerator = new Random(g.hashCode());
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void bootComplete( final MENetworkBootingStatusChange bootStatus )
|
||||
{
|
||||
final ITickManager tm = this.myGrid.getCache( ITickManager.class );
|
||||
for( final PartP2PTunnel me : this.inputs.values() )
|
||||
{
|
||||
if( me instanceof PartP2PTunnelME )
|
||||
{
|
||||
tm.wakeDevice( me.getGridNode() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@MENetworkEventSubscribe
|
||||
public void bootComplete(final MENetworkBootingStatusChange bootStatus) {
|
||||
final ITickManager tm = this.myGrid.getCache(ITickManager.class);
|
||||
for (final PartP2PTunnel me : this.inputs.values()) {
|
||||
if (me instanceof PartP2PTunnelME) {
|
||||
tm.wakeDevice(me.getGridNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void bootComplete( final MENetworkPowerStatusChange power )
|
||||
{
|
||||
final ITickManager tm = this.myGrid.getCache( ITickManager.class );
|
||||
for( final PartP2PTunnel me : this.inputs.values() )
|
||||
{
|
||||
if( me instanceof PartP2PTunnelME )
|
||||
{
|
||||
tm.wakeDevice( me.getGridNode() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@MENetworkEventSubscribe
|
||||
public void bootComplete(final MENetworkPowerStatusChange power) {
|
||||
final ITickManager tm = this.myGrid.getCache(ITickManager.class);
|
||||
for (final PartP2PTunnel me : this.inputs.values()) {
|
||||
if (me instanceof PartP2PTunnelME) {
|
||||
tm.wakeDevice(me.getGridNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateTick()
|
||||
{
|
||||
@Override
|
||||
public void onUpdateTick() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode( final IGridNode node, final IGridHost machine )
|
||||
{
|
||||
if( machine instanceof PartP2PTunnel )
|
||||
{
|
||||
if( machine instanceof PartP2PTunnelME )
|
||||
{
|
||||
if( !node.hasFlag( GridFlags.REQUIRE_CHANNEL ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void removeNode(final IGridNode node, final IGridHost machine) {
|
||||
if (machine instanceof PartP2PTunnel) {
|
||||
if (machine instanceof PartP2PTunnelME) {
|
||||
if (!node.hasFlag(GridFlags.REQUIRE_CHANNEL)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final PartP2PTunnel t = (PartP2PTunnel) machine;
|
||||
// AELog.info( "rmv-" + (t.output ? "output: " : "input: ") + t.freq );
|
||||
final PartP2PTunnel t = (PartP2PTunnel) machine;
|
||||
// AELog.info( "rmv-" + (t.output ? "output: " : "input: ") + t.freq );
|
||||
|
||||
if( t.isOutput() )
|
||||
{
|
||||
this.outputs.remove( t.getFrequency(), t );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.inputs.remove( t.getFrequency(), t );
|
||||
}
|
||||
if (t.isOutput()) {
|
||||
this.outputs.remove(t.getFrequency(), t);
|
||||
} else {
|
||||
this.inputs.remove(t.getFrequency(), t);
|
||||
}
|
||||
|
||||
if( this.inputs.get( t.getFrequency() ).isEmpty() )
|
||||
{
|
||||
this.inputs.removeAll( t.getFrequency() );
|
||||
}
|
||||
if( this.outputs.get( t.getFrequency() ).isEmpty() )
|
||||
{
|
||||
this.outputs.removeAll( t.getFrequency() );
|
||||
}
|
||||
if (this.inputs.get(t.getFrequency()).isEmpty()) {
|
||||
this.inputs.removeAll(t.getFrequency());
|
||||
}
|
||||
if (this.outputs.get(t.getFrequency()).isEmpty()) {
|
||||
this.outputs.removeAll(t.getFrequency());
|
||||
}
|
||||
|
||||
this.updateTunnel( t.getFrequency(), t.isOutput(), false );
|
||||
}
|
||||
}
|
||||
this.updateTunnel(t.getFrequency(), t.isOutput(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNode( final IGridNode node, final IGridHost machine )
|
||||
{
|
||||
if( machine instanceof PartP2PTunnel )
|
||||
{
|
||||
if( machine instanceof PartP2PTunnelME )
|
||||
{
|
||||
if( !node.hasFlag( GridFlags.REQUIRE_CHANNEL ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void addNode(final IGridNode node, final IGridHost machine) {
|
||||
if (machine instanceof PartP2PTunnel) {
|
||||
if (machine instanceof PartP2PTunnelME) {
|
||||
if (!node.hasFlag(GridFlags.REQUIRE_CHANNEL)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final PartP2PTunnel t = (PartP2PTunnel) machine;
|
||||
// AELog.info( "add-" + (t.output ? "output: " : "input: ") + t.freq );
|
||||
final PartP2PTunnel t = (PartP2PTunnel) machine;
|
||||
// AELog.info( "add-" + (t.output ? "output: " : "input: ") + t.freq );
|
||||
|
||||
if( t.isOutput() )
|
||||
{
|
||||
this.outputs.put( t.getFrequency(), t );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.inputs.put( t.getFrequency(), t );
|
||||
}
|
||||
if (t.isOutput()) {
|
||||
this.outputs.put(t.getFrequency(), t);
|
||||
} else {
|
||||
this.inputs.put(t.getFrequency(), t);
|
||||
}
|
||||
|
||||
this.updateTunnel( t.getFrequency(), t.isOutput(), false );
|
||||
}
|
||||
}
|
||||
this.updateTunnel(t.getFrequency(), t.isOutput(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplit( final IGridStorage storageB )
|
||||
{
|
||||
@Override
|
||||
public void onSplit(final IGridStorage storageB) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJoin( final IGridStorage storageB )
|
||||
{
|
||||
@Override
|
||||
public void onJoin(final IGridStorage storageB) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateGridStorage( final IGridStorage storage )
|
||||
{
|
||||
@Override
|
||||
public void populateGridStorage(final IGridStorage storage) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void removeTunnel( final PartP2PTunnel t, short freq )
|
||||
{
|
||||
this.outputs.remove( freq, t );
|
||||
this.inputs.remove( freq, t );
|
||||
if( this.inputs.get( t.getFrequency() ).isEmpty() )
|
||||
{
|
||||
this.inputs.removeAll( t.getFrequency() );
|
||||
}
|
||||
if( this.outputs.get( t.getFrequency() ).isEmpty() )
|
||||
{
|
||||
this.outputs.removeAll( t.getFrequency() );
|
||||
}
|
||||
}
|
||||
public void removeTunnel(final PartP2PTunnel t, short freq) {
|
||||
this.outputs.remove(freq, t);
|
||||
this.inputs.remove(freq, t);
|
||||
if (this.inputs.get(t.getFrequency()).isEmpty()) {
|
||||
this.inputs.removeAll(t.getFrequency());
|
||||
}
|
||||
if (this.outputs.get(t.getFrequency()).isEmpty()) {
|
||||
this.outputs.removeAll(t.getFrequency());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTunnel( final short freq, final boolean updateOutputs, final boolean configChange )
|
||||
{
|
||||
for( final PartP2PTunnel p : this.outputs.get( freq ) )
|
||||
{
|
||||
if( configChange )
|
||||
{
|
||||
p.onTunnelConfigChange();
|
||||
}
|
||||
p.onTunnelNetworkChange();
|
||||
}
|
||||
private void updateTunnel(final short freq, final boolean updateOutputs, final boolean configChange) {
|
||||
for (final PartP2PTunnel p : this.outputs.get(freq)) {
|
||||
if (configChange) {
|
||||
p.onTunnelConfigChange();
|
||||
}
|
||||
p.onTunnelNetworkChange();
|
||||
}
|
||||
|
||||
for( final PartP2PTunnel in : this.inputs.get( freq ) )
|
||||
{
|
||||
if( configChange )
|
||||
{
|
||||
in.onTunnelConfigChange();
|
||||
}
|
||||
in.onTunnelNetworkChange();
|
||||
}
|
||||
}
|
||||
for (final PartP2PTunnel in : this.inputs.get(freq)) {
|
||||
if (configChange) {
|
||||
in.onTunnelConfigChange();
|
||||
}
|
||||
in.onTunnelNetworkChange();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateFreq( final PartP2PTunnel t, final short newFrequency )
|
||||
{
|
||||
if( this.outputs.containsValue( t ) )
|
||||
{
|
||||
this.outputs.remove( t.getFrequency(), t );
|
||||
}
|
||||
public void updateFreq(final PartP2PTunnel t, final short newFrequency) {
|
||||
if (this.outputs.containsValue(t)) {
|
||||
this.outputs.remove(t.getFrequency(), t);
|
||||
}
|
||||
|
||||
if( this.inputs.containsValue( t ) )
|
||||
{
|
||||
this.inputs.remove( t.getFrequency(), t );
|
||||
}
|
||||
if (this.inputs.containsValue(t)) {
|
||||
this.inputs.remove(t.getFrequency(), t);
|
||||
}
|
||||
|
||||
t.setFrequency( newFrequency );
|
||||
t.setFrequency(newFrequency);
|
||||
|
||||
if( t.isOutput() )
|
||||
{
|
||||
this.outputs.put( t.getFrequency(), t );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.inputs.put( t.getFrequency(), t );
|
||||
}
|
||||
if (t.isOutput()) {
|
||||
this.outputs.put(t.getFrequency(), t);
|
||||
} else {
|
||||
this.inputs.put(t.getFrequency(), t);
|
||||
}
|
||||
|
||||
// AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq );
|
||||
this.updateTunnel( t.getFrequency(), t.isOutput(), true );
|
||||
}
|
||||
// AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq );
|
||||
this.updateTunnel(t.getFrequency(), t.isOutput(), true);
|
||||
}
|
||||
|
||||
public short newFrequency()
|
||||
{
|
||||
short newFrequency;
|
||||
int cycles = 0;
|
||||
public short newFrequency() {
|
||||
short newFrequency;
|
||||
int cycles = 0;
|
||||
|
||||
do
|
||||
{
|
||||
newFrequency = (short) this.frequencyGenerator.nextInt( 1 << 16 );
|
||||
cycles++;
|
||||
}
|
||||
while( newFrequency == 0 || this.inputs.containsKey( newFrequency ) );
|
||||
do {
|
||||
newFrequency = (short) this.frequencyGenerator.nextInt(1 << 16);
|
||||
cycles++;
|
||||
}
|
||||
while (newFrequency == 0 || this.inputs.containsKey(newFrequency));
|
||||
|
||||
if( cycles > 25 )
|
||||
{
|
||||
AELog.debug( "Generating a new P2P frequency '%1$d' took %2$d cycles", newFrequency, cycles );
|
||||
}
|
||||
if (cycles > 25) {
|
||||
AELog.debug("Generating a new P2P frequency '%1$d' took %2$d cycles", newFrequency, cycles);
|
||||
}
|
||||
|
||||
return newFrequency;
|
||||
}
|
||||
return newFrequency;
|
||||
}
|
||||
|
||||
public TunnelCollection<PartP2PTunnel> getOutputs( final short freq, final Class<? extends PartP2PTunnel> c )
|
||||
{
|
||||
Collection<PartP2PTunnel> in = this.inputs.get( freq );
|
||||
public TunnelCollection<PartP2PTunnel> getOutputs(final short freq, final Class<? extends PartP2PTunnel> c) {
|
||||
Collection<PartP2PTunnel> in = this.inputs.get(freq);
|
||||
|
||||
if( in == null )
|
||||
{
|
||||
return NULL_COLLECTION;
|
||||
}
|
||||
if (in == null) {
|
||||
return NULL_COLLECTION;
|
||||
}
|
||||
|
||||
TunnelCollection<PartP2PTunnel> out;
|
||||
for( PartP2PTunnel part : this.inputs.get( freq ) )
|
||||
{
|
||||
out = part.getCollection( this.outputs.get( freq ), c );
|
||||
if( out != null )
|
||||
{
|
||||
return out;
|
||||
}
|
||||
}
|
||||
return NULL_COLLECTION;
|
||||
}
|
||||
TunnelCollection<PartP2PTunnel> out;
|
||||
for (PartP2PTunnel part : this.inputs.get(freq)) {
|
||||
out = part.getCollection(this.outputs.get(freq), c);
|
||||
if (out != null) {
|
||||
return out;
|
||||
}
|
||||
}
|
||||
return NULL_COLLECTION;
|
||||
}
|
||||
|
||||
public TunnelCollection<PartP2PTunnel> getInputs( final short freq, final Class<? extends PartP2PTunnel> c )
|
||||
{
|
||||
Collection<PartP2PTunnel> out = this.outputs.get( freq );
|
||||
public TunnelCollection<PartP2PTunnel> getInputs(final short freq, final Class<? extends PartP2PTunnel> c) {
|
||||
Collection<PartP2PTunnel> out = this.outputs.get(freq);
|
||||
|
||||
if( out == null )
|
||||
{
|
||||
return NULL_COLLECTION;
|
||||
}
|
||||
if (out == null) {
|
||||
return NULL_COLLECTION;
|
||||
}
|
||||
|
||||
TunnelCollection<PartP2PTunnel> in;
|
||||
for( PartP2PTunnel part : this.outputs.get( freq ) )
|
||||
{
|
||||
in = part.getCollection( this.inputs.get( freq ), c );
|
||||
if( in != null )
|
||||
{
|
||||
return in;
|
||||
}
|
||||
}
|
||||
return NULL_COLLECTION;
|
||||
}
|
||||
TunnelCollection<PartP2PTunnel> in;
|
||||
for (PartP2PTunnel part : this.outputs.get(freq)) {
|
||||
in = part.getCollection(this.inputs.get(freq), c);
|
||||
if (in != null) {
|
||||
return in;
|
||||
}
|
||||
}
|
||||
return NULL_COLLECTION;
|
||||
}
|
||||
}
|
||||
|
||||
+255
-341
@@ -19,25 +19,8 @@
|
||||
package appeng.me.cache;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.networking.GridFlags;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridBlock;
|
||||
import appeng.api.networking.IGridConnection;
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridMultiblock;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.IGridStorage;
|
||||
import appeng.api.networking.*;
|
||||
import appeng.api.networking.events.MENetworkBootingStatusChange;
|
||||
import appeng.api.networking.events.MENetworkChannelChanged;
|
||||
import appeng.api.networking.events.MENetworkControllerChange;
|
||||
@@ -52,391 +35,322 @@ import appeng.core.features.AEFeature;
|
||||
import appeng.core.stats.IAdvancementTrigger;
|
||||
import appeng.me.GridConnection;
|
||||
import appeng.me.GridNode;
|
||||
import appeng.me.pathfinding.AdHocChannelUpdater;
|
||||
import appeng.me.pathfinding.ControllerChannelUpdater;
|
||||
import appeng.me.pathfinding.ControllerValidator;
|
||||
import appeng.me.pathfinding.IPathItem;
|
||||
import appeng.me.pathfinding.PathSegment;
|
||||
import appeng.me.pathfinding.*;
|
||||
import appeng.tile.networking.TileController;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class PathGridCache implements IPathingGrid
|
||||
{
|
||||
public class PathGridCache implements IPathingGrid {
|
||||
|
||||
private final List<PathSegment> active = new ArrayList<>();
|
||||
private final Set<TileController> controllers = new HashSet<>();
|
||||
private final Set<IGridNode> requireChannels = new HashSet<>();
|
||||
private final Set<IGridNode> blockDense = new HashSet<>();
|
||||
private final IGrid myGrid;
|
||||
private int channelsInUse = 0;
|
||||
private int channelsByBlocks = 0;
|
||||
private double channelPowerUsage = 0.0;
|
||||
private boolean recalculateControllerNextTick = true;
|
||||
private boolean updateNetwork = true;
|
||||
private boolean booting = false;
|
||||
private ControllerState controllerState = ControllerState.NO_CONTROLLER;
|
||||
private int ticksUntilReady = 20;
|
||||
private int lastChannels = 0;
|
||||
private HashSet<IPathItem> semiOpen = new HashSet<>();
|
||||
private final List<PathSegment> active = new ArrayList<>();
|
||||
private final Set<TileController> controllers = new HashSet<>();
|
||||
private final Set<IGridNode> requireChannels = new HashSet<>();
|
||||
private final Set<IGridNode> blockDense = new HashSet<>();
|
||||
private final IGrid myGrid;
|
||||
private int channelsInUse = 0;
|
||||
private int channelsByBlocks = 0;
|
||||
private double channelPowerUsage = 0.0;
|
||||
private boolean recalculateControllerNextTick = true;
|
||||
private boolean updateNetwork = true;
|
||||
private boolean booting = false;
|
||||
private ControllerState controllerState = ControllerState.NO_CONTROLLER;
|
||||
private int ticksUntilReady = 20;
|
||||
private int lastChannels = 0;
|
||||
private HashSet<IPathItem> semiOpen = new HashSet<>();
|
||||
|
||||
public PathGridCache( final IGrid g )
|
||||
{
|
||||
this.myGrid = g;
|
||||
}
|
||||
public PathGridCache(final IGrid g) {
|
||||
this.myGrid = g;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateTick()
|
||||
{
|
||||
if( this.recalculateControllerNextTick )
|
||||
{
|
||||
this.recalcController();
|
||||
}
|
||||
@Override
|
||||
public void onUpdateTick() {
|
||||
if (this.recalculateControllerNextTick) {
|
||||
this.recalcController();
|
||||
}
|
||||
|
||||
if( this.updateNetwork )
|
||||
{
|
||||
if( !this.booting )
|
||||
{
|
||||
this.myGrid.postEvent( new MENetworkBootingStatusChange() );
|
||||
}
|
||||
if (this.updateNetwork) {
|
||||
if (!this.booting) {
|
||||
this.myGrid.postEvent(new MENetworkBootingStatusChange());
|
||||
}
|
||||
|
||||
this.booting = true;
|
||||
this.updateNetwork = false;
|
||||
this.setChannelsInUse( 0 );
|
||||
this.booting = true;
|
||||
this.updateNetwork = false;
|
||||
this.setChannelsInUse(0);
|
||||
|
||||
if( this.controllerState == ControllerState.NO_CONTROLLER )
|
||||
{
|
||||
final int requiredChannels = this.calculateRequiredChannels();
|
||||
int used = requiredChannels;
|
||||
if( AEConfig.instance().isFeatureEnabled( AEFeature.CHANNELS ) && requiredChannels > 8 )
|
||||
{
|
||||
used = 0;
|
||||
}
|
||||
if (this.controllerState == ControllerState.NO_CONTROLLER) {
|
||||
final int requiredChannels = this.calculateRequiredChannels();
|
||||
int used = requiredChannels;
|
||||
if (AEConfig.instance().isFeatureEnabled(AEFeature.CHANNELS) && requiredChannels > 8) {
|
||||
used = 0;
|
||||
}
|
||||
|
||||
final int nodes = this.myGrid.getNodes().size();
|
||||
this.setChannelsInUse( used );
|
||||
final int nodes = this.myGrid.getNodes().size();
|
||||
this.setChannelsInUse(used);
|
||||
|
||||
this.ticksUntilReady = 20 + Math.max( 0, nodes / 100 - 20 );
|
||||
this.setChannelsByBlocks( nodes * used );
|
||||
this.setChannelPowerUsage( this.getChannelsByBlocks() / 128.0 );
|
||||
this.ticksUntilReady = 20 + Math.max(0, nodes / 100 - 20);
|
||||
this.setChannelsByBlocks(nodes * used);
|
||||
this.setChannelPowerUsage(this.getChannelsByBlocks() / 128.0);
|
||||
|
||||
this.myGrid.getPivot().beginVisit( new AdHocChannelUpdater( used ) );
|
||||
}
|
||||
else if( this.controllerState == ControllerState.CONTROLLER_CONFLICT )
|
||||
{
|
||||
this.ticksUntilReady = 20;
|
||||
this.myGrid.getPivot().beginVisit( new AdHocChannelUpdater( 0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
final int nodes = this.myGrid.getNodes().size();
|
||||
this.ticksUntilReady = 20 + Math.max( 0, nodes / 100 - 20 );
|
||||
final HashSet<IPathItem> closedList = new HashSet<>();
|
||||
this.semiOpen = new HashSet<>();
|
||||
this.myGrid.getPivot().beginVisit(new AdHocChannelUpdater(used));
|
||||
} else if (this.controllerState == ControllerState.CONTROLLER_CONFLICT) {
|
||||
this.ticksUntilReady = 20;
|
||||
this.myGrid.getPivot().beginVisit(new AdHocChannelUpdater(0));
|
||||
} else {
|
||||
final int nodes = this.myGrid.getNodes().size();
|
||||
this.ticksUntilReady = 20 + Math.max(0, nodes / 100 - 20);
|
||||
final HashSet<IPathItem> closedList = new HashSet<>();
|
||||
this.semiOpen = new HashSet<>();
|
||||
|
||||
// myGrid.getPivot().beginVisit( new AdHocChannelUpdater( 0 )
|
||||
// );
|
||||
for( final IGridNode node : this.myGrid.getMachines( TileController.class ) )
|
||||
{
|
||||
closedList.add( (IPathItem) node );
|
||||
for( final IGridConnection gcc : node.getConnections() )
|
||||
{
|
||||
final GridConnection gc = (GridConnection) gcc;
|
||||
if( !( gc.getOtherSide( node ).getMachine() instanceof TileController ) )
|
||||
{
|
||||
final List<IPathItem> open = new ArrayList<>();
|
||||
closedList.add( gc );
|
||||
open.add( gc );
|
||||
gc.setControllerRoute( (GridNode) node, true );
|
||||
this.active.add( new PathSegment( this, open, this.semiOpen, closedList ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// myGrid.getPivot().beginVisit( new AdHocChannelUpdater( 0 )
|
||||
// );
|
||||
for (final IGridNode node : this.myGrid.getMachines(TileController.class)) {
|
||||
closedList.add((IPathItem) node);
|
||||
for (final IGridConnection gcc : node.getConnections()) {
|
||||
final GridConnection gc = (GridConnection) gcc;
|
||||
if (!(gc.getOtherSide(node).getMachine() instanceof TileController)) {
|
||||
final List<IPathItem> open = new ArrayList<>();
|
||||
closedList.add(gc);
|
||||
open.add(gc);
|
||||
gc.setControllerRoute((GridNode) node, true);
|
||||
this.active.add(new PathSegment(this, open, this.semiOpen, closedList));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !this.active.isEmpty() || this.ticksUntilReady > 0 )
|
||||
{
|
||||
final Iterator<PathSegment> i = this.active.iterator();
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
final PathSegment pat = i.next();
|
||||
if( pat.step() )
|
||||
{
|
||||
pat.setDead( true );
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
if (!this.active.isEmpty() || this.ticksUntilReady > 0) {
|
||||
final Iterator<PathSegment> i = this.active.iterator();
|
||||
while (i.hasNext()) {
|
||||
final PathSegment pat = i.next();
|
||||
if (pat.step()) {
|
||||
pat.setDead(true);
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
|
||||
this.ticksUntilReady--;
|
||||
this.ticksUntilReady--;
|
||||
|
||||
if( this.active.isEmpty() && this.ticksUntilReady <= 0 )
|
||||
{
|
||||
if( this.controllerState == ControllerState.CONTROLLER_ONLINE )
|
||||
{
|
||||
final Iterator<TileController> controllerIterator = this.controllers.iterator();
|
||||
if( controllerIterator.hasNext() )
|
||||
{
|
||||
final TileController controller = controllerIterator.next();
|
||||
controller.getGridNode( AEPartLocation.INTERNAL ).beginVisit( new ControllerChannelUpdater() );
|
||||
}
|
||||
}
|
||||
if (this.active.isEmpty() && this.ticksUntilReady <= 0) {
|
||||
if (this.controllerState == ControllerState.CONTROLLER_ONLINE) {
|
||||
final Iterator<TileController> controllerIterator = this.controllers.iterator();
|
||||
if (controllerIterator.hasNext()) {
|
||||
final TileController controller = controllerIterator.next();
|
||||
controller.getGridNode(AEPartLocation.INTERNAL).beginVisit(new ControllerChannelUpdater());
|
||||
}
|
||||
}
|
||||
|
||||
// check for achievements
|
||||
this.achievementPost();
|
||||
// check for achievements
|
||||
this.achievementPost();
|
||||
|
||||
this.booting = false;
|
||||
this.setChannelPowerUsage( this.getChannelsByBlocks() / 128.0 );
|
||||
this.myGrid.postEvent( new MENetworkBootingStatusChange() );
|
||||
}
|
||||
}
|
||||
}
|
||||
this.booting = false;
|
||||
this.setChannelPowerUsage(this.getChannelsByBlocks() / 128.0);
|
||||
this.myGrid.postEvent(new MENetworkBootingStatusChange());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode( final IGridNode gridNode, final IGridHost machine )
|
||||
{
|
||||
if( machine instanceof TileController )
|
||||
{
|
||||
this.controllers.remove( machine );
|
||||
this.recalculateControllerNextTick = true;
|
||||
}
|
||||
@Override
|
||||
public void removeNode(final IGridNode gridNode, final IGridHost machine) {
|
||||
if (machine instanceof TileController) {
|
||||
this.controllers.remove(machine);
|
||||
this.recalculateControllerNextTick = true;
|
||||
}
|
||||
|
||||
final EnumSet<GridFlags> flags = gridNode.getGridBlock().getFlags();
|
||||
final EnumSet<GridFlags> flags = gridNode.getGridBlock().getFlags();
|
||||
|
||||
if( flags.contains( GridFlags.REQUIRE_CHANNEL ) )
|
||||
{
|
||||
this.requireChannels.remove( gridNode );
|
||||
}
|
||||
if (flags.contains(GridFlags.REQUIRE_CHANNEL)) {
|
||||
this.requireChannels.remove(gridNode);
|
||||
}
|
||||
|
||||
if( flags.contains( GridFlags.CANNOT_CARRY_COMPRESSED ) )
|
||||
{
|
||||
this.blockDense.remove( gridNode );
|
||||
}
|
||||
if (flags.contains(GridFlags.CANNOT_CARRY_COMPRESSED)) {
|
||||
this.blockDense.remove(gridNode);
|
||||
}
|
||||
|
||||
this.repath();
|
||||
}
|
||||
this.repath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNode( final IGridNode gridNode, final IGridHost machine )
|
||||
{
|
||||
if( machine instanceof TileController )
|
||||
{
|
||||
this.controllers.add( (TileController) machine );
|
||||
this.recalculateControllerNextTick = true;
|
||||
}
|
||||
@Override
|
||||
public void addNode(final IGridNode gridNode, final IGridHost machine) {
|
||||
if (machine instanceof TileController) {
|
||||
this.controllers.add((TileController) machine);
|
||||
this.recalculateControllerNextTick = true;
|
||||
}
|
||||
|
||||
final EnumSet<GridFlags> flags = gridNode.getGridBlock().getFlags();
|
||||
final EnumSet<GridFlags> flags = gridNode.getGridBlock().getFlags();
|
||||
|
||||
if( flags.contains( GridFlags.REQUIRE_CHANNEL ) )
|
||||
{
|
||||
this.requireChannels.add( gridNode );
|
||||
}
|
||||
if (flags.contains(GridFlags.REQUIRE_CHANNEL)) {
|
||||
this.requireChannels.add(gridNode);
|
||||
}
|
||||
|
||||
if( flags.contains( GridFlags.CANNOT_CARRY_COMPRESSED ) )
|
||||
{
|
||||
this.blockDense.add( gridNode );
|
||||
}
|
||||
if (flags.contains(GridFlags.CANNOT_CARRY_COMPRESSED)) {
|
||||
this.blockDense.add(gridNode);
|
||||
}
|
||||
|
||||
this.repath();
|
||||
}
|
||||
this.repath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplit( final IGridStorage storageB )
|
||||
{
|
||||
@Override
|
||||
public void onSplit(final IGridStorage storageB) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJoin( final IGridStorage storageB )
|
||||
{
|
||||
@Override
|
||||
public void onJoin(final IGridStorage storageB) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateGridStorage( final IGridStorage storage )
|
||||
{
|
||||
@Override
|
||||
public void populateGridStorage(final IGridStorage storage) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void recalcController()
|
||||
{
|
||||
this.recalculateControllerNextTick = false;
|
||||
final ControllerState old = this.controllerState;
|
||||
private void recalcController() {
|
||||
this.recalculateControllerNextTick = false;
|
||||
final ControllerState old = this.controllerState;
|
||||
|
||||
if( this.controllers.isEmpty() )
|
||||
{
|
||||
this.controllerState = ControllerState.NO_CONTROLLER;
|
||||
}
|
||||
else
|
||||
{
|
||||
final IGridNode startingNode = this.controllers.iterator().next().getGridNode( AEPartLocation.INTERNAL );
|
||||
if( startingNode == null )
|
||||
{
|
||||
this.controllerState = ControllerState.CONTROLLER_CONFLICT;
|
||||
return;
|
||||
}
|
||||
if (this.controllers.isEmpty()) {
|
||||
this.controllerState = ControllerState.NO_CONTROLLER;
|
||||
} else {
|
||||
final IGridNode startingNode = this.controllers.iterator().next().getGridNode(AEPartLocation.INTERNAL);
|
||||
if (startingNode == null) {
|
||||
this.controllerState = ControllerState.CONTROLLER_CONFLICT;
|
||||
return;
|
||||
}
|
||||
|
||||
final DimensionalCoord dc = startingNode.getGridBlock().getLocation();
|
||||
final ControllerValidator cv = new ControllerValidator( dc.x, dc.y, dc.z );
|
||||
final DimensionalCoord dc = startingNode.getGridBlock().getLocation();
|
||||
final ControllerValidator cv = new ControllerValidator(dc.x, dc.y, dc.z);
|
||||
|
||||
startingNode.beginVisit( cv );
|
||||
startingNode.beginVisit(cv);
|
||||
|
||||
if( cv.isValid() && cv.getFound() == this.controllers.size() )
|
||||
{
|
||||
this.controllerState = ControllerState.CONTROLLER_ONLINE;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.controllerState = ControllerState.CONTROLLER_CONFLICT;
|
||||
}
|
||||
}
|
||||
if (cv.isValid() && cv.getFound() == this.controllers.size()) {
|
||||
this.controllerState = ControllerState.CONTROLLER_ONLINE;
|
||||
} else {
|
||||
this.controllerState = ControllerState.CONTROLLER_CONFLICT;
|
||||
}
|
||||
}
|
||||
|
||||
if( old != this.controllerState )
|
||||
{
|
||||
this.myGrid.postEvent( new MENetworkControllerChange() );
|
||||
}
|
||||
}
|
||||
if (old != this.controllerState) {
|
||||
this.myGrid.postEvent(new MENetworkControllerChange());
|
||||
}
|
||||
}
|
||||
|
||||
private int calculateRequiredChannels()
|
||||
{
|
||||
this.semiOpen.clear();
|
||||
private int calculateRequiredChannels() {
|
||||
this.semiOpen.clear();
|
||||
|
||||
int depth = 0;
|
||||
for( final IGridNode nodes : this.requireChannels )
|
||||
{
|
||||
if( !this.semiOpen.contains( (IPathItem) nodes ) )
|
||||
{
|
||||
final IGridBlock gb = nodes.getGridBlock();
|
||||
final EnumSet<GridFlags> flags = gb.getFlags();
|
||||
int depth = 0;
|
||||
for (final IGridNode nodes : this.requireChannels) {
|
||||
if (!this.semiOpen.contains((IPathItem) nodes)) {
|
||||
final IGridBlock gb = nodes.getGridBlock();
|
||||
final EnumSet<GridFlags> flags = gb.getFlags();
|
||||
|
||||
if( flags.contains( GridFlags.COMPRESSED_CHANNEL ) && !this.blockDense.isEmpty() )
|
||||
{
|
||||
return 9;
|
||||
}
|
||||
if (flags.contains(GridFlags.COMPRESSED_CHANNEL) && !this.blockDense.isEmpty()) {
|
||||
return 9;
|
||||
}
|
||||
|
||||
depth++;
|
||||
depth++;
|
||||
|
||||
if( flags.contains( GridFlags.MULTIBLOCK ) )
|
||||
{
|
||||
final IGridMultiblock gmb = (IGridMultiblock) gb;
|
||||
final Iterator<IGridNode> i = gmb.getMultiblockNodes();
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
this.semiOpen.add( (IPathItem) i.next() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flags.contains(GridFlags.MULTIBLOCK)) {
|
||||
final IGridMultiblock gmb = (IGridMultiblock) gb;
|
||||
final Iterator<IGridNode> i = gmb.getMultiblockNodes();
|
||||
while (i.hasNext()) {
|
||||
this.semiOpen.add((IPathItem) i.next());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return depth;
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
|
||||
private void achievementPost()
|
||||
{
|
||||
if( this.lastChannels != this.getChannelsInUse() && AEConfig.instance().isFeatureEnabled( AEFeature.CHANNELS ) )
|
||||
{
|
||||
final IAdvancementTrigger currentBracket = this.getAchievementBracket( this.getChannelsInUse() );
|
||||
final IAdvancementTrigger lastBracket = this.getAchievementBracket( this.lastChannels );
|
||||
if( currentBracket != lastBracket && currentBracket != null )
|
||||
{
|
||||
for( final IGridNode n : this.requireChannels )
|
||||
{
|
||||
EntityPlayer player = AEApi.instance().registries().players().findPlayer( n.getPlayerID() );
|
||||
if( player instanceof EntityPlayerMP )
|
||||
{
|
||||
currentBracket.trigger( (EntityPlayerMP) player );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.lastChannels = this.getChannelsInUse();
|
||||
}
|
||||
private void achievementPost() {
|
||||
if (this.lastChannels != this.getChannelsInUse() && AEConfig.instance().isFeatureEnabled(AEFeature.CHANNELS)) {
|
||||
final IAdvancementTrigger currentBracket = this.getAchievementBracket(this.getChannelsInUse());
|
||||
final IAdvancementTrigger lastBracket = this.getAchievementBracket(this.lastChannels);
|
||||
if (currentBracket != lastBracket && currentBracket != null) {
|
||||
for (final IGridNode n : this.requireChannels) {
|
||||
EntityPlayer player = AEApi.instance().registries().players().findPlayer(n.getPlayerID());
|
||||
if (player instanceof EntityPlayerMP) {
|
||||
currentBracket.trigger((EntityPlayerMP) player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.lastChannels = this.getChannelsInUse();
|
||||
}
|
||||
|
||||
private IAdvancementTrigger getAchievementBracket( final int ch )
|
||||
{
|
||||
if( ch < 8 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
private IAdvancementTrigger getAchievementBracket(final int ch) {
|
||||
if (ch < 8) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if( ch < 128 )
|
||||
{
|
||||
return AppEng.instance().getAdvancementTriggers().getNetworkApprentice();
|
||||
}
|
||||
if (ch < 128) {
|
||||
return AppEng.instance().getAdvancementTriggers().getNetworkApprentice();
|
||||
}
|
||||
|
||||
if( ch < 2048 )
|
||||
{
|
||||
return AppEng.instance().getAdvancementTriggers().getNetworkEngineer();
|
||||
}
|
||||
if (ch < 2048) {
|
||||
return AppEng.instance().getAdvancementTriggers().getNetworkEngineer();
|
||||
}
|
||||
|
||||
return AppEng.instance().getAdvancementTriggers().getNetworkAdmin();
|
||||
}
|
||||
return AppEng.instance().getAdvancementTriggers().getNetworkAdmin();
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
void updateNodReq( final MENetworkChannelChanged ev )
|
||||
{
|
||||
final IGridNode gridNode = ev.node;
|
||||
@MENetworkEventSubscribe
|
||||
void updateNodReq(final MENetworkChannelChanged ev) {
|
||||
final IGridNode gridNode = ev.node;
|
||||
|
||||
if( gridNode.getGridBlock().getFlags().contains( GridFlags.REQUIRE_CHANNEL ) )
|
||||
{
|
||||
this.requireChannels.add( gridNode );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.requireChannels.remove( gridNode );
|
||||
}
|
||||
if (gridNode.getGridBlock().getFlags().contains(GridFlags.REQUIRE_CHANNEL)) {
|
||||
this.requireChannels.add(gridNode);
|
||||
} else {
|
||||
this.requireChannels.remove(gridNode);
|
||||
}
|
||||
|
||||
this.repath();
|
||||
}
|
||||
this.repath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNetworkBooting()
|
||||
{
|
||||
return !this.booting && !this.active.isEmpty();
|
||||
}
|
||||
@Override
|
||||
public boolean isNetworkBooting() {
|
||||
return !this.booting && !this.active.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ControllerState getControllerState()
|
||||
{
|
||||
return this.controllerState;
|
||||
}
|
||||
@Override
|
||||
public ControllerState getControllerState() {
|
||||
return this.controllerState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void repath()
|
||||
{
|
||||
// clean up...
|
||||
this.active.clear();
|
||||
@Override
|
||||
public void repath() {
|
||||
// clean up...
|
||||
this.active.clear();
|
||||
|
||||
this.setChannelsByBlocks( 0 );
|
||||
this.updateNetwork = true;
|
||||
}
|
||||
this.setChannelsByBlocks(0);
|
||||
this.updateNetwork = true;
|
||||
}
|
||||
|
||||
double getChannelPowerUsage()
|
||||
{
|
||||
return this.channelPowerUsage;
|
||||
}
|
||||
double getChannelPowerUsage() {
|
||||
return this.channelPowerUsage;
|
||||
}
|
||||
|
||||
private void setChannelPowerUsage( final double channelPowerUsage )
|
||||
{
|
||||
this.channelPowerUsage = channelPowerUsage;
|
||||
}
|
||||
private void setChannelPowerUsage(final double channelPowerUsage) {
|
||||
this.channelPowerUsage = channelPowerUsage;
|
||||
}
|
||||
|
||||
public int getChannelsByBlocks()
|
||||
{
|
||||
return this.channelsByBlocks;
|
||||
}
|
||||
public int getChannelsByBlocks() {
|
||||
return this.channelsByBlocks;
|
||||
}
|
||||
|
||||
public void setChannelsByBlocks( final int channelsByBlocks )
|
||||
{
|
||||
this.channelsByBlocks = channelsByBlocks;
|
||||
}
|
||||
public void setChannelsByBlocks(final int channelsByBlocks) {
|
||||
this.channelsByBlocks = channelsByBlocks;
|
||||
}
|
||||
|
||||
public int getChannelsInUse()
|
||||
{
|
||||
return this.channelsInUse;
|
||||
}
|
||||
public int getChannelsInUse() {
|
||||
return this.channelsInUse;
|
||||
}
|
||||
|
||||
public void setChannelsInUse( final int channelsInUse )
|
||||
{
|
||||
this.channelsInUse = channelsInUse;
|
||||
}
|
||||
public void setChannelsInUse(final int channelsInUse) {
|
||||
this.channelsInUse = channelsInUse;
|
||||
}
|
||||
}
|
||||
|
||||
+107
-140
@@ -19,16 +19,6 @@
|
||||
package appeng.me.cache;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridHost;
|
||||
@@ -40,163 +30,140 @@ import appeng.api.networking.security.ISecurityGrid;
|
||||
import appeng.api.networking.security.ISecurityProvider;
|
||||
import appeng.core.worlddata.WorldData;
|
||||
import appeng.me.GridNode;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class SecurityCache implements ISecurityGrid
|
||||
{
|
||||
public class SecurityCache implements ISecurityGrid {
|
||||
|
||||
private final IGrid myGrid;
|
||||
private final List<ISecurityProvider> securityProvider = new ArrayList<>();
|
||||
private final HashMap<Integer, EnumSet<SecurityPermissions>> playerPerms = new HashMap<>();
|
||||
private long securityKey = -1;
|
||||
private final IGrid myGrid;
|
||||
private final List<ISecurityProvider> securityProvider = new ArrayList<>();
|
||||
private final HashMap<Integer, EnumSet<SecurityPermissions>> playerPerms = new HashMap<>();
|
||||
private long securityKey = -1;
|
||||
|
||||
public SecurityCache( final IGrid g )
|
||||
{
|
||||
this.myGrid = g;
|
||||
}
|
||||
public SecurityCache(final IGrid g) {
|
||||
this.myGrid = g;
|
||||
}
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void updatePermissions( final MENetworkSecurityChange ev )
|
||||
{
|
||||
this.playerPerms.clear();
|
||||
if( this.securityProvider.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@MENetworkEventSubscribe
|
||||
public void updatePermissions(final MENetworkSecurityChange ev) {
|
||||
this.playerPerms.clear();
|
||||
if (this.securityProvider.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.securityProvider.get( 0 ).readPermissions( this.playerPerms );
|
||||
}
|
||||
this.securityProvider.get(0).readPermissions(this.playerPerms);
|
||||
}
|
||||
|
||||
public long getSecurityKey()
|
||||
{
|
||||
return this.securityKey;
|
||||
}
|
||||
public long getSecurityKey() {
|
||||
return this.securityKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateTick()
|
||||
{
|
||||
@Override
|
||||
public void onUpdateTick() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode( final IGridNode gridNode, final IGridHost machine )
|
||||
{
|
||||
if( machine instanceof ISecurityProvider )
|
||||
{
|
||||
this.securityProvider.remove( machine );
|
||||
this.updateSecurityKey();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void removeNode(final IGridNode gridNode, final IGridHost machine) {
|
||||
if (machine instanceof ISecurityProvider) {
|
||||
this.securityProvider.remove(machine);
|
||||
this.updateSecurityKey();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSecurityKey()
|
||||
{
|
||||
final long lastCode = this.securityKey;
|
||||
private void updateSecurityKey() {
|
||||
final long lastCode = this.securityKey;
|
||||
|
||||
if( this.securityProvider.size() == 1 )
|
||||
{
|
||||
this.securityKey = this.securityProvider.get( 0 ).getSecurityKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.securityKey = -1;
|
||||
}
|
||||
if (this.securityProvider.size() == 1) {
|
||||
this.securityKey = this.securityProvider.get(0).getSecurityKey();
|
||||
} else {
|
||||
this.securityKey = -1;
|
||||
}
|
||||
|
||||
if( lastCode != this.securityKey )
|
||||
{
|
||||
this.getGrid().postEvent( new MENetworkSecurityChange() );
|
||||
for( final IGridNode n : this.getGrid().getNodes() )
|
||||
{
|
||||
( (GridNode) n ).setLastSecurityKey( this.securityKey );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastCode != this.securityKey) {
|
||||
this.getGrid().postEvent(new MENetworkSecurityChange());
|
||||
for (final IGridNode n : this.getGrid().getNodes()) {
|
||||
((GridNode) n).setLastSecurityKey(this.securityKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNode( final IGridNode gridNode, final IGridHost machine )
|
||||
{
|
||||
if( machine instanceof ISecurityProvider )
|
||||
{
|
||||
this.securityProvider.add( (ISecurityProvider) machine );
|
||||
this.updateSecurityKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
( (GridNode) gridNode ).setLastSecurityKey( this.securityKey );
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void addNode(final IGridNode gridNode, final IGridHost machine) {
|
||||
if (machine instanceof ISecurityProvider) {
|
||||
this.securityProvider.add((ISecurityProvider) machine);
|
||||
this.updateSecurityKey();
|
||||
} else {
|
||||
((GridNode) gridNode).setLastSecurityKey(this.securityKey);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplit( final IGridStorage destinationStorage )
|
||||
{
|
||||
@Override
|
||||
public void onSplit(final IGridStorage destinationStorage) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJoin( final IGridStorage sourceStorage )
|
||||
{
|
||||
@Override
|
||||
public void onJoin(final IGridStorage sourceStorage) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateGridStorage( final IGridStorage destinationStorage )
|
||||
{
|
||||
@Override
|
||||
public void populateGridStorage(final IGridStorage destinationStorage) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable()
|
||||
{
|
||||
return this.securityProvider.size() == 1 && this.securityProvider.get( 0 ).isSecurityEnabled();
|
||||
}
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return this.securityProvider.size() == 1 && this.securityProvider.get(0).isSecurityEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission( final EntityPlayer player, final SecurityPermissions perm )
|
||||
{
|
||||
Preconditions.checkNotNull( player );
|
||||
Preconditions.checkNotNull( perm );
|
||||
@Override
|
||||
public boolean hasPermission(final EntityPlayer player, final SecurityPermissions perm) {
|
||||
Preconditions.checkNotNull(player);
|
||||
Preconditions.checkNotNull(perm);
|
||||
|
||||
final GameProfile profile = player.getGameProfile();
|
||||
final int playerID = WorldData.instance().playerData().getPlayerID( profile );
|
||||
final GameProfile profile = player.getGameProfile();
|
||||
final int playerID = WorldData.instance().playerData().getPlayerID(profile);
|
||||
|
||||
return this.hasPermission( playerID, perm );
|
||||
}
|
||||
return this.hasPermission(playerID, perm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission( final int playerID, final SecurityPermissions perm )
|
||||
{
|
||||
if( this.isAvailable() )
|
||||
{
|
||||
final EnumSet<SecurityPermissions> perms = this.playerPerms.get( playerID );
|
||||
@Override
|
||||
public boolean hasPermission(final int playerID, final SecurityPermissions perm) {
|
||||
if (this.isAvailable()) {
|
||||
final EnumSet<SecurityPermissions> perms = this.playerPerms.get(playerID);
|
||||
|
||||
if( perms == null )
|
||||
{
|
||||
if( playerID == -1 ) // no default?
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.hasPermission( -1, perm );
|
||||
}
|
||||
}
|
||||
if (perms == null) {
|
||||
if (playerID == -1) // no default?
|
||||
{
|
||||
return false;
|
||||
} else {
|
||||
return this.hasPermission(-1, perm);
|
||||
}
|
||||
}
|
||||
|
||||
return perms.contains( perm );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return perms.contains(perm);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOwner()
|
||||
{
|
||||
if( this.isAvailable() )
|
||||
{
|
||||
return this.securityProvider.get( 0 ).getOwner();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@Override
|
||||
public int getOwner() {
|
||||
if (this.isAvailable()) {
|
||||
return this.securityProvider.get(0).getOwner();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public IGrid getGrid()
|
||||
{
|
||||
return this.myGrid;
|
||||
}
|
||||
public IGrid getGrid() {
|
||||
return this.myGrid;
|
||||
}
|
||||
}
|
||||
|
||||
+149
-179
@@ -19,10 +19,6 @@
|
||||
package appeng.me.cache;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
@@ -37,223 +33,197 @@ import appeng.me.cluster.implementations.SpatialPylonCluster;
|
||||
import appeng.tile.spatial.TileSpatialIOPort;
|
||||
import appeng.tile.spatial.TileSpatialPylon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class SpatialPylonCache implements ISpatialCache
|
||||
{
|
||||
|
||||
private final IGrid myGrid;
|
||||
private long powerRequired = 0;
|
||||
private double efficiency = 0.0;
|
||||
private DimensionalCoord captureMin;
|
||||
private DimensionalCoord captureMax;
|
||||
private boolean isValid = false;
|
||||
private List<TileSpatialIOPort> ioPorts = new ArrayList<>();
|
||||
private HashMap<SpatialPylonCluster, SpatialPylonCluster> clusters = new HashMap<>();
|
||||
public class SpatialPylonCache implements ISpatialCache {
|
||||
|
||||
public SpatialPylonCache( final IGrid g )
|
||||
{
|
||||
this.myGrid = g;
|
||||
}
|
||||
private final IGrid myGrid;
|
||||
private long powerRequired = 0;
|
||||
private double efficiency = 0.0;
|
||||
private DimensionalCoord captureMin;
|
||||
private DimensionalCoord captureMax;
|
||||
private boolean isValid = false;
|
||||
private List<TileSpatialIOPort> ioPorts = new ArrayList<>();
|
||||
private HashMap<SpatialPylonCluster, SpatialPylonCluster> clusters = new HashMap<>();
|
||||
|
||||
@MENetworkEventSubscribe
|
||||
public void bootingRender( final MENetworkBootingStatusChange c )
|
||||
{
|
||||
this.reset( this.myGrid );
|
||||
}
|
||||
public SpatialPylonCache(final IGrid g) {
|
||||
this.myGrid = g;
|
||||
}
|
||||
|
||||
private void reset( final IGrid grid )
|
||||
{
|
||||
@MENetworkEventSubscribe
|
||||
public void bootingRender(final MENetworkBootingStatusChange c) {
|
||||
this.reset(this.myGrid);
|
||||
}
|
||||
|
||||
this.clusters = new HashMap<>();
|
||||
this.ioPorts = new ArrayList<>();
|
||||
private void reset(final IGrid grid) {
|
||||
|
||||
for( final IGridNode gm : grid.getMachines( TileSpatialIOPort.class ) )
|
||||
{
|
||||
this.ioPorts.add( (TileSpatialIOPort) gm.getMachine() );
|
||||
}
|
||||
this.clusters = new HashMap<>();
|
||||
this.ioPorts = new ArrayList<>();
|
||||
|
||||
final IReadOnlyCollection<IGridNode> set = grid.getMachines( TileSpatialPylon.class );
|
||||
for( final IGridNode gm : set )
|
||||
{
|
||||
if( gm.meetsChannelRequirements() )
|
||||
{
|
||||
final SpatialPylonCluster c = ( (TileSpatialPylon) gm.getMachine() ).getCluster();
|
||||
if( c != null )
|
||||
{
|
||||
this.clusters.put( c, c );
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final IGridNode gm : grid.getMachines(TileSpatialIOPort.class)) {
|
||||
this.ioPorts.add((TileSpatialIOPort) gm.getMachine());
|
||||
}
|
||||
|
||||
this.captureMax = null;
|
||||
this.captureMin = null;
|
||||
this.isValid = true;
|
||||
final IReadOnlyCollection<IGridNode> set = grid.getMachines(TileSpatialPylon.class);
|
||||
for (final IGridNode gm : set) {
|
||||
if (gm.meetsChannelRequirements()) {
|
||||
final SpatialPylonCluster c = ((TileSpatialPylon) gm.getMachine()).getCluster();
|
||||
if (c != null) {
|
||||
this.clusters.put(c, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int pylonBlocks = 0;
|
||||
for( final SpatialPylonCluster cl : this.clusters.values() )
|
||||
{
|
||||
if( this.captureMax == null )
|
||||
{
|
||||
this.captureMax = cl.getMax().copy();
|
||||
}
|
||||
if( this.captureMin == null )
|
||||
{
|
||||
this.captureMin = cl.getMin().copy();
|
||||
}
|
||||
this.captureMax = null;
|
||||
this.captureMin = null;
|
||||
this.isValid = true;
|
||||
|
||||
pylonBlocks += cl.tileCount();
|
||||
int pylonBlocks = 0;
|
||||
for (final SpatialPylonCluster cl : this.clusters.values()) {
|
||||
if (this.captureMax == null) {
|
||||
this.captureMax = cl.getMax().copy();
|
||||
}
|
||||
if (this.captureMin == null) {
|
||||
this.captureMin = cl.getMin().copy();
|
||||
}
|
||||
|
||||
this.captureMin.x = Math.min( this.captureMin.x, cl.getMin().x );
|
||||
this.captureMin.y = Math.min( this.captureMin.y, cl.getMin().y );
|
||||
this.captureMin.z = Math.min( this.captureMin.z, cl.getMin().z );
|
||||
pylonBlocks += cl.tileCount();
|
||||
|
||||
this.captureMax.x = Math.max( this.captureMax.x, cl.getMax().x );
|
||||
this.captureMax.y = Math.max( this.captureMax.y, cl.getMax().y );
|
||||
this.captureMax.z = Math.max( this.captureMax.z, cl.getMax().z );
|
||||
}
|
||||
this.captureMin.x = Math.min(this.captureMin.x, cl.getMin().x);
|
||||
this.captureMin.y = Math.min(this.captureMin.y, cl.getMin().y);
|
||||
this.captureMin.z = Math.min(this.captureMin.z, cl.getMin().z);
|
||||
|
||||
double maxPower = 0;
|
||||
double minPower = 0;
|
||||
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;
|
||||
this.captureMax.x = Math.max(this.captureMax.x, cl.getMax().x);
|
||||
this.captureMax.y = Math.max(this.captureMax.y, cl.getMax().y);
|
||||
this.captureMax.z = Math.max(this.captureMax.z, cl.getMax().z);
|
||||
}
|
||||
|
||||
for( final SpatialPylonCluster cl : this.clusters.values() )
|
||||
{
|
||||
switch( cl.getCurrentAxis() )
|
||||
{
|
||||
case X:
|
||||
double maxPower = 0;
|
||||
double minPower = 0;
|
||||
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;
|
||||
|
||||
this.isValid = this.isValid && ( ( this.captureMax.y == cl.getMin().y || this.captureMin.y == cl
|
||||
.getMax().y ) || ( this.captureMax.z == cl.getMin().z || this.captureMin.z == cl.getMax().z ) ) && ( ( this.captureMax.y == cl
|
||||
.getMax().y || this.captureMin.y == cl
|
||||
.getMin().y ) || ( this.captureMax.z == cl.getMax().z || this.captureMin.z == cl.getMin().z ) );
|
||||
for (final SpatialPylonCluster cl : this.clusters.values()) {
|
||||
switch (cl.getCurrentAxis()) {
|
||||
case X:
|
||||
|
||||
break;
|
||||
case Y:
|
||||
this.isValid = this.isValid && ((this.captureMax.y == cl.getMin().y || this.captureMin.y == cl
|
||||
.getMax().y) || (this.captureMax.z == cl.getMin().z || this.captureMin.z == cl.getMax().z)) && ((this.captureMax.y == cl
|
||||
.getMax().y || this.captureMin.y == cl
|
||||
.getMin().y) || (this.captureMax.z == cl.getMax().z || this.captureMin.z == cl.getMin().z));
|
||||
|
||||
this.isValid = this.isValid && ( ( this.captureMax.x == cl.getMin().x || this.captureMin.x == cl
|
||||
.getMax().x ) || ( this.captureMax.z == cl.getMin().z || this.captureMin.z == cl.getMax().z ) ) && ( ( this.captureMax.x == cl
|
||||
.getMax().x || this.captureMin.x == cl
|
||||
.getMin().x ) || ( this.captureMax.z == cl.getMax().z || this.captureMin.z == cl.getMin().z ) );
|
||||
break;
|
||||
case Y:
|
||||
|
||||
break;
|
||||
case Z:
|
||||
this.isValid = this.isValid && ((this.captureMax.x == cl.getMin().x || this.captureMin.x == cl
|
||||
.getMax().x) || (this.captureMax.z == cl.getMin().z || this.captureMin.z == cl.getMax().z)) && ((this.captureMax.x == cl
|
||||
.getMax().x || this.captureMin.x == cl
|
||||
.getMin().x) || (this.captureMax.z == cl.getMax().z || this.captureMin.z == cl.getMin().z));
|
||||
|
||||
this.isValid = this.isValid && ( ( this.captureMax.y == cl.getMin().y || this.captureMin.y == cl
|
||||
.getMax().y ) || ( this.captureMax.x == cl.getMin().x || this.captureMin.x == cl.getMax().x ) ) && ( ( this.captureMax.y == cl
|
||||
.getMax().y || this.captureMin.y == cl
|
||||
.getMin().y ) || ( this.captureMax.x == cl.getMax().x || this.captureMin.x == cl.getMin().x ) );
|
||||
break;
|
||||
case Z:
|
||||
|
||||
break;
|
||||
case UNFORMED:
|
||||
this.isValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.isValid = this.isValid && ((this.captureMax.y == cl.getMin().y || this.captureMin.y == cl
|
||||
.getMax().y) || (this.captureMax.x == cl.getMin().x || this.captureMin.x == cl.getMax().x)) && ((this.captureMax.y == cl
|
||||
.getMax().y || this.captureMin.y == cl
|
||||
.getMin().y) || (this.captureMax.x == cl.getMax().x || this.captureMin.x == cl.getMin().x));
|
||||
|
||||
final int reqX = this.captureMax.x - this.captureMin.x;
|
||||
final int reqY = this.captureMax.y - this.captureMin.y;
|
||||
final int reqZ = this.captureMax.z - this.captureMin.z;
|
||||
final int requirePylonBlocks = Math.max( 6, ( ( reqX * reqZ + reqX * reqY + reqY * reqZ ) * 3 ) / 8 );
|
||||
break;
|
||||
case UNFORMED:
|
||||
this.isValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.efficiency = (double) pylonBlocks / (double) requirePylonBlocks;
|
||||
final int reqX = this.captureMax.x - this.captureMin.x;
|
||||
final int reqY = this.captureMax.y - this.captureMin.y;
|
||||
final int reqZ = this.captureMax.z - this.captureMin.z;
|
||||
final int requirePylonBlocks = Math.max(6, ((reqX * reqZ + reqX * reqY + reqY * reqZ) * 3) / 8);
|
||||
|
||||
if( this.efficiency > 1.0 )
|
||||
{
|
||||
this.efficiency = 1.0;
|
||||
}
|
||||
if( this.efficiency < 0.0 )
|
||||
{
|
||||
this.efficiency = 0.0;
|
||||
}
|
||||
this.efficiency = (double) pylonBlocks / (double) requirePylonBlocks;
|
||||
|
||||
minPower = (double) reqX * (double) reqY * reqZ * AEConfig.instance().getSpatialPowerMultiplier();
|
||||
maxPower = Math.pow( minPower, AEConfig.instance().getSpatialPowerExponent() );
|
||||
}
|
||||
if (this.efficiency > 1.0) {
|
||||
this.efficiency = 1.0;
|
||||
}
|
||||
if (this.efficiency < 0.0) {
|
||||
this.efficiency = 0.0;
|
||||
}
|
||||
|
||||
final double affective_efficiency = Math.pow( this.efficiency, 0.25 );
|
||||
this.powerRequired = (long) ( affective_efficiency * minPower + ( 1.0 - affective_efficiency ) * maxPower );
|
||||
minPower = (double) reqX * (double) reqY * reqZ * AEConfig.instance().getSpatialPowerMultiplier();
|
||||
maxPower = Math.pow(minPower, AEConfig.instance().getSpatialPowerExponent());
|
||||
}
|
||||
|
||||
for( final SpatialPylonCluster cl : this.clusters.values() )
|
||||
{
|
||||
final boolean myWasValid = cl.isValid();
|
||||
cl.setValid( this.isValid );
|
||||
if( myWasValid != this.isValid )
|
||||
{
|
||||
cl.updateStatus( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
final double affective_efficiency = Math.pow(this.efficiency, 0.25);
|
||||
this.powerRequired = (long) (affective_efficiency * minPower + (1.0 - affective_efficiency) * maxPower);
|
||||
|
||||
@Override
|
||||
public boolean hasRegion()
|
||||
{
|
||||
return this.captureMin != null;
|
||||
}
|
||||
for (final SpatialPylonCluster cl : this.clusters.values()) {
|
||||
final boolean myWasValid = cl.isValid();
|
||||
cl.setValid(this.isValid);
|
||||
if (myWasValid != this.isValid) {
|
||||
cl.updateStatus(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidRegion()
|
||||
{
|
||||
return this.hasRegion() && this.isValid;
|
||||
}
|
||||
@Override
|
||||
public boolean hasRegion() {
|
||||
return this.captureMin != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DimensionalCoord getMin()
|
||||
{
|
||||
return this.captureMin;
|
||||
}
|
||||
@Override
|
||||
public boolean isValidRegion() {
|
||||
return this.hasRegion() && this.isValid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DimensionalCoord getMax()
|
||||
{
|
||||
return this.captureMax;
|
||||
}
|
||||
@Override
|
||||
public DimensionalCoord getMin() {
|
||||
return this.captureMin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long requiredPower()
|
||||
{
|
||||
return this.powerRequired;
|
||||
}
|
||||
@Override
|
||||
public DimensionalCoord getMax() {
|
||||
return this.captureMax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float currentEfficiency()
|
||||
{
|
||||
return (float) this.efficiency * 100;
|
||||
}
|
||||
@Override
|
||||
public long requiredPower() {
|
||||
return this.powerRequired;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateTick()
|
||||
{
|
||||
}
|
||||
@Override
|
||||
public float currentEfficiency() {
|
||||
return (float) this.efficiency * 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode( final IGridNode node, final IGridHost machine )
|
||||
{
|
||||
@Override
|
||||
public void onUpdateTick() {
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void removeNode(final IGridNode node, final IGridHost machine) {
|
||||
|
||||
@Override
|
||||
public void addNode( final IGridNode node, final IGridHost machine )
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void addNode(final IGridNode node, final IGridHost machine) {
|
||||
|
||||
@Override
|
||||
public void onSplit( final IGridStorage storageB )
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void onSplit(final IGridStorage storageB) {
|
||||
|
||||
@Override
|
||||
public void onJoin( final IGridStorage storageB )
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void onJoin(final IGridStorage storageB) {
|
||||
|
||||
@Override
|
||||
public void populateGridStorage( final IGridStorage storage )
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public void populateGridStorage(final IGridStorage storage) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+160
-194
@@ -19,15 +19,6 @@
|
||||
package appeng.me.cache;
|
||||
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import appeng.parts.automation.PartLevelEmitter;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraft.crash.CrashReport;
|
||||
import net.minecraft.crash.CrashReportCategory;
|
||||
import net.minecraft.util.ReportedException;
|
||||
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
@@ -37,234 +28,209 @@ import appeng.api.networking.ticking.ITickManager;
|
||||
import appeng.api.networking.ticking.TickRateModulation;
|
||||
import appeng.api.networking.ticking.TickingRequest;
|
||||
import appeng.me.cache.helpers.TickTracker;
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.crash.CrashReport;
|
||||
import net.minecraft.crash.CrashReportCategory;
|
||||
import net.minecraft.util.ReportedException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
|
||||
public class TickManagerCache implements ITickManager
|
||||
{
|
||||
public class TickManagerCache implements ITickManager {
|
||||
|
||||
private final IGrid myGrid;
|
||||
private final HashMap<IGridNode, TickTracker> alertable = new HashMap<>();
|
||||
private final HashMap<IGridNode, TickTracker> sleeping = new HashMap<>();
|
||||
private final HashMap<IGridNode, TickTracker> awake = new HashMap<>();
|
||||
private final HashMap<IGridNode, TickTracker> laterTicker = new HashMap<>();
|
||||
private final PriorityQueue<TickTracker> upcomingTicks = new PriorityQueue<>();
|
||||
private final IGrid myGrid;
|
||||
private final HashMap<IGridNode, TickTracker> alertable = new HashMap<>();
|
||||
private final HashMap<IGridNode, TickTracker> sleeping = new HashMap<>();
|
||||
private final HashMap<IGridNode, TickTracker> awake = new HashMap<>();
|
||||
private final HashMap<IGridNode, TickTracker> laterTicker = new HashMap<>();
|
||||
private final PriorityQueue<TickTracker> upcomingTicks = new PriorityQueue<>();
|
||||
|
||||
private long currentTick = 0;
|
||||
private long currentTick = 0;
|
||||
|
||||
public TickManagerCache( final IGrid g )
|
||||
{
|
||||
this.myGrid = g;
|
||||
}
|
||||
public TickManagerCache(final IGrid g) {
|
||||
this.myGrid = g;
|
||||
}
|
||||
|
||||
public long getCurrentTick()
|
||||
{
|
||||
return this.currentTick;
|
||||
}
|
||||
public long getCurrentTick() {
|
||||
return this.currentTick;
|
||||
}
|
||||
|
||||
public long getAvgNanoTime( final IGridNode node )
|
||||
{
|
||||
TickTracker tt = this.awake.get( node );
|
||||
public long getAvgNanoTime(final IGridNode node) {
|
||||
TickTracker tt = this.awake.get(node);
|
||||
|
||||
if( tt == null )
|
||||
{
|
||||
tt = this.sleeping.get( node );
|
||||
}
|
||||
if (tt == null) {
|
||||
tt = this.sleeping.get(node);
|
||||
}
|
||||
|
||||
if( tt == null )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (tt == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return tt.getAvgNanos();
|
||||
}
|
||||
return tt.getAvgNanos();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateTick()
|
||||
{
|
||||
TickTracker tt = null;
|
||||
@Override
|
||||
public void onUpdateTick() {
|
||||
TickTracker tt = null;
|
||||
|
||||
try
|
||||
{
|
||||
this.currentTick++;
|
||||
try {
|
||||
this.currentTick++;
|
||||
|
||||
while ( !this.upcomingTicks.isEmpty() )
|
||||
{
|
||||
tt = this.upcomingTicks.peek();
|
||||
while (!this.upcomingTicks.isEmpty()) {
|
||||
tt = this.upcomingTicks.peek();
|
||||
|
||||
// Stop once it reaches a TickTracker running at a later tick
|
||||
if( tt.getNextTick() > this.currentTick )
|
||||
{
|
||||
break;
|
||||
}
|
||||
// Stop once it reaches a TickTracker running at a later tick
|
||||
if (tt.getNextTick() > this.currentTick) {
|
||||
break;
|
||||
}
|
||||
|
||||
this.upcomingTicks.poll();
|
||||
this.upcomingTicks.poll();
|
||||
|
||||
final int diff = (int) ( this.currentTick - tt.getLastTick() );
|
||||
final TickRateModulation mod = tt.getGridTickable().tickingRequest( tt.getNode(), diff );
|
||||
final int diff = (int) (this.currentTick - tt.getLastTick());
|
||||
final TickRateModulation mod = tt.getGridTickable().tickingRequest(tt.getNode(), diff);
|
||||
|
||||
switch ( mod )
|
||||
{
|
||||
case FASTER:
|
||||
tt.setCurrentRate( tt.getCurrentRate() - 2 );
|
||||
break;
|
||||
case IDLE:
|
||||
tt.setCurrentRate( tt.getRequest().maxTickRate );
|
||||
break;
|
||||
case SAME:
|
||||
break;
|
||||
case SLEEP:
|
||||
this.sleepDevice( tt.getNode() );
|
||||
break;
|
||||
case SLOWER:
|
||||
tt.setCurrentRate( tt.getCurrentRate() + 1 );
|
||||
break;
|
||||
case URGENT:
|
||||
tt.setCurrentRate( 0 );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (mod) {
|
||||
case FASTER:
|
||||
tt.setCurrentRate(tt.getCurrentRate() - 2);
|
||||
break;
|
||||
case IDLE:
|
||||
tt.setCurrentRate(tt.getRequest().maxTickRate);
|
||||
break;
|
||||
case SAME:
|
||||
break;
|
||||
case SLEEP:
|
||||
this.sleepDevice(tt.getNode());
|
||||
break;
|
||||
case SLOWER:
|
||||
tt.setCurrentRate(tt.getCurrentRate() + 1);
|
||||
break;
|
||||
case URGENT:
|
||||
tt.setCurrentRate(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( this.awake.containsKey( tt.getNode() ) )
|
||||
{
|
||||
this.addToQueue( tt );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( final Throwable t )
|
||||
{
|
||||
final CrashReport crashreport = CrashReport.makeCrashReport( t, "Ticking GridNode" );
|
||||
final CrashReportCategory crashreportcategory = crashreport.makeCategory( tt.getGridTickable().getClass().getSimpleName() + " being ticked." );
|
||||
tt.addEntityCrashInfo( crashreportcategory );
|
||||
throw new ReportedException( crashreport );
|
||||
}
|
||||
}
|
||||
if (this.awake.containsKey(tt.getNode())) {
|
||||
this.addToQueue(tt);
|
||||
}
|
||||
}
|
||||
} catch (final Throwable t) {
|
||||
final CrashReport crashreport = CrashReport.makeCrashReport(t, "Ticking GridNode");
|
||||
final CrashReportCategory crashreportcategory = crashreport.makeCategory(tt.getGridTickable().getClass().getSimpleName() + " being ticked.");
|
||||
tt.addEntityCrashInfo(crashreportcategory);
|
||||
throw new ReportedException(crashreport);
|
||||
}
|
||||
}
|
||||
|
||||
private void addToQueue( final TickTracker tt )
|
||||
{
|
||||
tt.setLastTick( this.currentTick );
|
||||
this.upcomingTicks.add( tt );
|
||||
}
|
||||
private void addToQueue(final TickTracker tt) {
|
||||
tt.setLastTick(this.currentTick);
|
||||
this.upcomingTicks.add(tt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode( final IGridNode gridNode, final IGridHost machine )
|
||||
{
|
||||
if( machine instanceof IGridTickable )
|
||||
{
|
||||
this.alertable.remove( gridNode );
|
||||
this.sleeping.remove( gridNode );
|
||||
this.awake.remove( gridNode );
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void removeNode(final IGridNode gridNode, final IGridHost machine) {
|
||||
if (machine instanceof IGridTickable) {
|
||||
this.alertable.remove(gridNode);
|
||||
this.sleeping.remove(gridNode);
|
||||
this.awake.remove(gridNode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNode( final IGridNode gridNode, final IGridHost machine )
|
||||
{
|
||||
if( machine instanceof IGridTickable )
|
||||
{
|
||||
final IGridTickable tickable = ( (IGridTickable) machine );
|
||||
final TickingRequest tr = tickable.getTickingRequest( gridNode );
|
||||
@Override
|
||||
public void addNode(final IGridNode gridNode, final IGridHost machine) {
|
||||
if (machine instanceof IGridTickable) {
|
||||
final IGridTickable tickable = ((IGridTickable) machine);
|
||||
final TickingRequest tr = tickable.getTickingRequest(gridNode);
|
||||
|
||||
Preconditions.checkNotNull( tr );
|
||||
Preconditions.checkNotNull(tr);
|
||||
|
||||
final TickTracker tt = new TickTracker( tr, gridNode, (IGridTickable) machine, this.currentTick, this );
|
||||
final TickTracker tt = new TickTracker(tr, gridNode, (IGridTickable) machine, this.currentTick, this);
|
||||
|
||||
if( tr.canBeAlerted )
|
||||
{
|
||||
this.alertable.put( gridNode, tt );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tr.isSleeping) {
|
||||
this.sleeping.put(gridNode, tt);
|
||||
} else {
|
||||
this.awake.put(gridNode, tt);
|
||||
this.addToQueue(tt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSplit( final IGridStorage storageB )
|
||||
{
|
||||
@Override
|
||||
public void onSplit(final IGridStorage storageB) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJoin( final IGridStorage storageB )
|
||||
{
|
||||
@Override
|
||||
public void onJoin(final IGridStorage storageB) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populateGridStorage( final IGridStorage storage )
|
||||
{
|
||||
@Override
|
||||
public void populateGridStorage(final IGridStorage storage) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alertDevice( final IGridNode node )
|
||||
{
|
||||
Preconditions.checkNotNull( node );
|
||||
@Override
|
||||
public boolean alertDevice(final IGridNode node) {
|
||||
Preconditions.checkNotNull(node);
|
||||
|
||||
final TickTracker tt = this.alertable.get( node );
|
||||
if( tt == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// throw new RuntimeException(
|
||||
// "Invalid alerted device, this node is not marked as alertable, or part of this grid." );
|
||||
final TickTracker tt = this.alertable.get(node);
|
||||
if (tt == null) {
|
||||
return false;
|
||||
}
|
||||
// throw new RuntimeException(
|
||||
// "Invalid alerted device, this node is not marked as alertable, or part of this grid." );
|
||||
|
||||
// set to awake, this is for sanity.
|
||||
this.sleeping.remove( node );
|
||||
this.awake.put( node, tt );
|
||||
// set to awake, this is for sanity.
|
||||
this.sleeping.remove(node);
|
||||
this.awake.put(node, tt);
|
||||
|
||||
// configure sort.
|
||||
tt.setLastTick( tt.getLastTick() - tt.getRequest().maxTickRate );
|
||||
tt.setCurrentRate( tt.getRequest().minTickRate );
|
||||
// configure sort.
|
||||
tt.setLastTick(tt.getLastTick() - tt.getRequest().maxTickRate);
|
||||
tt.setCurrentRate(tt.getRequest().minTickRate);
|
||||
|
||||
// prevent dupes and tick build up.
|
||||
this.upcomingTicks.remove( tt );
|
||||
this.upcomingTicks.add( tt );
|
||||
// prevent dupes and tick build up.
|
||||
this.upcomingTicks.remove(tt);
|
||||
this.upcomingTicks.add(tt);
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sleepDevice( final IGridNode node )
|
||||
{
|
||||
Preconditions.checkNotNull( node );
|
||||
@Override
|
||||
public boolean sleepDevice(final IGridNode node) {
|
||||
Preconditions.checkNotNull(node);
|
||||
|
||||
if( this.awake.containsKey( node ) )
|
||||
{
|
||||
final TickTracker gt = this.awake.get( node );
|
||||
this.awake.remove( node );
|
||||
this.sleeping.put( node, gt );
|
||||
if (this.awake.containsKey(node)) {
|
||||
final TickTracker gt = this.awake.get(node);
|
||||
this.awake.remove(node);
|
||||
this.sleeping.put(node, gt);
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wakeDevice( final IGridNode node )
|
||||
{
|
||||
Preconditions.checkNotNull( node );
|
||||
@Override
|
||||
public boolean wakeDevice(final IGridNode node) {
|
||||
Preconditions.checkNotNull(node);
|
||||
|
||||
if( this.sleeping.containsKey( node ) )
|
||||
{
|
||||
final TickTracker gt = this.sleeping.get( node );
|
||||
this.sleeping.remove( node );
|
||||
this.awake.put( node, gt );
|
||||
this.upcomingTicks.remove( gt );
|
||||
this.addToQueue( gt );
|
||||
if (this.sleeping.containsKey(node)) {
|
||||
final TickTracker gt = this.sleeping.get(node);
|
||||
this.sleeping.remove(node);
|
||||
this.awake.put(node, gt);
|
||||
this.upcomingTicks.remove(gt);
|
||||
this.addToQueue(gt);
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-15
@@ -22,23 +22,19 @@ package appeng.me.cache.helpers;
|
||||
import appeng.api.networking.IGridConnection;
|
||||
|
||||
|
||||
public class ConnectionWrapper
|
||||
{
|
||||
public class ConnectionWrapper {
|
||||
|
||||
private IGridConnection connection;
|
||||
private IGridConnection connection;
|
||||
|
||||
public ConnectionWrapper( final IGridConnection gc )
|
||||
{
|
||||
this.setConnection( gc );
|
||||
}
|
||||
public ConnectionWrapper(final IGridConnection gc) {
|
||||
this.setConnection(gc);
|
||||
}
|
||||
|
||||
public IGridConnection getConnection()
|
||||
{
|
||||
return this.connection;
|
||||
}
|
||||
public IGridConnection getConnection() {
|
||||
return this.connection;
|
||||
}
|
||||
|
||||
public void setConnection( final IGridConnection connection )
|
||||
{
|
||||
this.connection = connection;
|
||||
}
|
||||
public void setConnection(final IGridConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
}
|
||||
+39
-50
@@ -19,70 +19,59 @@
|
||||
package appeng.me.cache.helpers;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.parts.p2p.PartP2PTunnelME;
|
||||
import appeng.util.IWorldCallable;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
public class Connections implements IWorldCallable<Void>
|
||||
{
|
||||
public class Connections implements IWorldCallable<Void> {
|
||||
|
||||
private final HashMap<IGridNode, TunnelConnection> connections = new HashMap<>();
|
||||
private final PartP2PTunnelME me;
|
||||
private boolean create = false;
|
||||
private boolean destroy = false;
|
||||
private final HashMap<IGridNode, TunnelConnection> connections = new HashMap<>();
|
||||
private final PartP2PTunnelME me;
|
||||
private boolean create = false;
|
||||
private boolean destroy = false;
|
||||
|
||||
public Connections( final PartP2PTunnelME o )
|
||||
{
|
||||
this.me = o;
|
||||
}
|
||||
public Connections(final PartP2PTunnelME o) {
|
||||
this.me = o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void call( final World world ) throws Exception
|
||||
{
|
||||
this.me.updateConnections( this );
|
||||
@Override
|
||||
public Void call(final World world) throws Exception {
|
||||
this.me.updateConnections(this);
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void markDestroy()
|
||||
{
|
||||
this.setCreate( false );
|
||||
this.setDestroy( true );
|
||||
}
|
||||
public void markDestroy() {
|
||||
this.setCreate(false);
|
||||
this.setDestroy(true);
|
||||
}
|
||||
|
||||
public void markCreate()
|
||||
{
|
||||
this.setCreate( true );
|
||||
this.setDestroy( false );
|
||||
}
|
||||
public void markCreate() {
|
||||
this.setCreate(true);
|
||||
this.setDestroy(false);
|
||||
}
|
||||
|
||||
public HashMap<IGridNode, TunnelConnection> getConnections()
|
||||
{
|
||||
return this.connections;
|
||||
}
|
||||
public HashMap<IGridNode, TunnelConnection> getConnections() {
|
||||
return this.connections;
|
||||
}
|
||||
|
||||
public boolean isCreate()
|
||||
{
|
||||
return this.create;
|
||||
}
|
||||
public boolean isCreate() {
|
||||
return this.create;
|
||||
}
|
||||
|
||||
private void setCreate( final boolean create )
|
||||
{
|
||||
this.create = create;
|
||||
}
|
||||
private void setCreate(final boolean create) {
|
||||
this.create = create;
|
||||
}
|
||||
|
||||
public boolean isDestroy()
|
||||
{
|
||||
return this.destroy;
|
||||
}
|
||||
public boolean isDestroy() {
|
||||
return this.destroy;
|
||||
}
|
||||
|
||||
private void setDestroy( final boolean destroy )
|
||||
{
|
||||
this.destroy = destroy;
|
||||
}
|
||||
private void setDestroy(final boolean destroy) {
|
||||
this.destroy = destroy;
|
||||
}
|
||||
}
|
||||
|
||||
+72
-90
@@ -19,124 +19,106 @@
|
||||
package appeng.me.cache.helpers;
|
||||
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.crash.CrashReportCategory;
|
||||
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.ticking.IGridTickable;
|
||||
import appeng.api.networking.ticking.TickingRequest;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.me.cache.TickManagerCache;
|
||||
import appeng.parts.AEBasePart;
|
||||
import net.minecraft.crash.CrashReportCategory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
|
||||
public class TickTracker implements Comparable<TickTracker>
|
||||
{
|
||||
public class TickTracker implements Comparable<TickTracker> {
|
||||
|
||||
private final TickingRequest request;
|
||||
private final IGridTickable gt;
|
||||
private final IGridNode node;
|
||||
private final TickingRequest request;
|
||||
private final IGridTickable gt;
|
||||
private final IGridNode node;
|
||||
|
||||
private final long LastFiveTicksTime = 0;
|
||||
private final long LastFiveTicksTime = 0;
|
||||
|
||||
private long lastTick;
|
||||
private int currentRate;
|
||||
private long lastTick;
|
||||
private int currentRate;
|
||||
|
||||
public TickTracker( final TickingRequest req, final IGridNode node, final IGridTickable gt, final long currentTick, final TickManagerCache tickManagerCache )
|
||||
{
|
||||
this.request = req;
|
||||
this.gt = gt;
|
||||
this.node = node;
|
||||
this.setCurrentRate( ( req.minTickRate + req.maxTickRate ) / 2 );
|
||||
this.setLastTick( currentTick );
|
||||
}
|
||||
public TickTracker(final TickingRequest req, final IGridNode node, final IGridTickable gt, final long currentTick, final TickManagerCache tickManagerCache) {
|
||||
this.request = req;
|
||||
this.gt = gt;
|
||||
this.node = node;
|
||||
this.setCurrentRate((req.minTickRate + req.maxTickRate) / 2);
|
||||
this.setLastTick(currentTick);
|
||||
}
|
||||
|
||||
public long getAvgNanos()
|
||||
{
|
||||
return( this.LastFiveTicksTime / 5 );
|
||||
}
|
||||
public long getAvgNanos() {
|
||||
return (this.LastFiveTicksTime / 5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo( @Nonnull final TickTracker t )
|
||||
{
|
||||
int next = Long.compare( this.getNextTick(), t.getNextTick() );
|
||||
@Override
|
||||
public int compareTo(@Nonnull final TickTracker t) {
|
||||
int next = Long.compare(this.getNextTick(), t.getNextTick());
|
||||
|
||||
if( next != 0 )
|
||||
{
|
||||
return next;
|
||||
}
|
||||
if (next != 0) {
|
||||
return next;
|
||||
}
|
||||
|
||||
int last = Long.compare( this.getLastTick(), t.getLastTick() );
|
||||
int last = Long.compare(this.getLastTick(), t.getLastTick());
|
||||
|
||||
if( last != 0 )
|
||||
{
|
||||
return last;
|
||||
}
|
||||
if (last != 0) {
|
||||
return last;
|
||||
}
|
||||
|
||||
return Integer.compare( this.getCurrentRate(), t.getCurrentRate() );
|
||||
return Integer.compare(this.getCurrentRate(), t.getCurrentRate());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void addEntityCrashInfo( final CrashReportCategory crashreportcategory )
|
||||
{
|
||||
if( this.getGridTickable() instanceof AEBasePart )
|
||||
{
|
||||
final AEBasePart part = (AEBasePart) this.getGridTickable();
|
||||
part.addEntityCrashInfo( crashreportcategory );
|
||||
}
|
||||
public void addEntityCrashInfo(final CrashReportCategory crashreportcategory) {
|
||||
if (this.getGridTickable() instanceof AEBasePart) {
|
||||
final AEBasePart part = (AEBasePart) this.getGridTickable();
|
||||
part.addEntityCrashInfo(crashreportcategory);
|
||||
}
|
||||
|
||||
crashreportcategory.addCrashSection( "CurrentTickRate", this.getCurrentRate() );
|
||||
crashreportcategory.addCrashSection( "MinTickRate", this.getRequest().minTickRate );
|
||||
crashreportcategory.addCrashSection( "MaxTickRate", this.getRequest().maxTickRate );
|
||||
crashreportcategory.addCrashSection( "MachineType", this.getGridTickable().getClass().getName() );
|
||||
crashreportcategory.addCrashSection( "GridBlockType", this.getNode().getGridBlock().getClass().getName() );
|
||||
crashreportcategory.addCrashSection( "ConnectedSides", this.getNode().getConnectedSides() );
|
||||
crashreportcategory.addCrashSection("CurrentTickRate", this.getCurrentRate());
|
||||
crashreportcategory.addCrashSection("MinTickRate", this.getRequest().minTickRate);
|
||||
crashreportcategory.addCrashSection("MaxTickRate", this.getRequest().maxTickRate);
|
||||
crashreportcategory.addCrashSection("MachineType", this.getGridTickable().getClass().getName());
|
||||
crashreportcategory.addCrashSection("GridBlockType", this.getNode().getGridBlock().getClass().getName());
|
||||
crashreportcategory.addCrashSection("ConnectedSides", this.getNode().getConnectedSides());
|
||||
|
||||
final DimensionalCoord dc = this.getNode().getGridBlock().getLocation();
|
||||
if( dc != null )
|
||||
{
|
||||
crashreportcategory.addCrashSection( "Location", dc );
|
||||
}
|
||||
}
|
||||
final DimensionalCoord dc = this.getNode().getGridBlock().getLocation();
|
||||
if (dc != null) {
|
||||
crashreportcategory.addCrashSection("Location", dc);
|
||||
}
|
||||
}
|
||||
|
||||
public int getCurrentRate()
|
||||
{
|
||||
return this.currentRate;
|
||||
}
|
||||
public int getCurrentRate() {
|
||||
return this.currentRate;
|
||||
}
|
||||
|
||||
public void setCurrentRate( final int currentRate )
|
||||
{
|
||||
this.currentRate = Math.min( this.getRequest().maxTickRate, Math.max( this.getRequest().minTickRate, currentRate ) );
|
||||
}
|
||||
public void setCurrentRate(final int currentRate) {
|
||||
this.currentRate = Math.min(this.getRequest().maxTickRate, Math.max(this.getRequest().minTickRate, currentRate));
|
||||
}
|
||||
|
||||
public long getNextTick()
|
||||
{
|
||||
return this.lastTick + this.currentRate;
|
||||
}
|
||||
public long getNextTick() {
|
||||
return this.lastTick + this.currentRate;
|
||||
}
|
||||
|
||||
public long getLastTick()
|
||||
{
|
||||
return this.lastTick;
|
||||
}
|
||||
public long getLastTick() {
|
||||
return this.lastTick;
|
||||
}
|
||||
|
||||
public void setLastTick( final long lastTick )
|
||||
{
|
||||
this.lastTick = lastTick;
|
||||
}
|
||||
public void setLastTick(final long lastTick) {
|
||||
this.lastTick = lastTick;
|
||||
}
|
||||
|
||||
public IGridNode getNode()
|
||||
{
|
||||
return this.node;
|
||||
}
|
||||
public IGridNode getNode() {
|
||||
return this.node;
|
||||
}
|
||||
|
||||
public IGridTickable getGridTickable()
|
||||
{
|
||||
return this.gt;
|
||||
}
|
||||
public IGridTickable getGridTickable() {
|
||||
return this.gt;
|
||||
}
|
||||
|
||||
public TickingRequest getRequest()
|
||||
{
|
||||
return this.request;
|
||||
}
|
||||
public TickingRequest getRequest() {
|
||||
return this.request;
|
||||
}
|
||||
}
|
||||
|
||||
+32
-41
@@ -19,58 +19,49 @@
|
||||
package appeng.me.cache.helpers;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import appeng.parts.p2p.PartP2PTunnel;
|
||||
import appeng.util.iterators.NullIterator;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class TunnelCollection<T extends PartP2PTunnel> implements Iterable<T>
|
||||
{
|
||||
|
||||
private final Class clz;
|
||||
private Collection<T> tunnelSources;
|
||||
public class TunnelCollection<T extends PartP2PTunnel> implements Iterable<T> {
|
||||
|
||||
public TunnelCollection( final Collection<T> src, final Class c )
|
||||
{
|
||||
this.tunnelSources = src;
|
||||
this.clz = c;
|
||||
}
|
||||
private final Class clz;
|
||||
private Collection<T> tunnelSources;
|
||||
|
||||
public void setSource( final Collection<T> c )
|
||||
{
|
||||
this.tunnelSources = c;
|
||||
}
|
||||
public TunnelCollection(final Collection<T> src, final Class c) {
|
||||
this.tunnelSources = src;
|
||||
this.clz = c;
|
||||
}
|
||||
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return !this.iterator().hasNext();
|
||||
}
|
||||
public void setSource(final Collection<T> c) {
|
||||
this.tunnelSources = c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator()
|
||||
{
|
||||
if( this.tunnelSources == null )
|
||||
{
|
||||
return new NullIterator<>();
|
||||
}
|
||||
return new TunnelIterator<>( this.tunnelSources, this.clz );
|
||||
}
|
||||
public boolean isEmpty() {
|
||||
return !this.iterator().hasNext();
|
||||
}
|
||||
|
||||
public boolean matches( final Class<? extends PartP2PTunnel> c )
|
||||
{
|
||||
return this.clz == c;
|
||||
}
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
if (this.tunnelSources == null) {
|
||||
return new NullIterator<>();
|
||||
}
|
||||
return new TunnelIterator<>(this.tunnelSources, this.clz);
|
||||
}
|
||||
|
||||
public Class<? extends PartP2PTunnel> getClz()
|
||||
{
|
||||
return this.clz;
|
||||
}
|
||||
public boolean matches(final Class<? extends PartP2PTunnel> c) {
|
||||
return this.clz == c;
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return this.tunnelSources == null ? 0 : this.tunnelSources.size();
|
||||
}
|
||||
public Class<? extends PartP2PTunnel> getClz() {
|
||||
return this.clz;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.tunnelSources == null ? 0 : this.tunnelSources.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+13
-17
@@ -23,25 +23,21 @@ import appeng.api.networking.IGridConnection;
|
||||
import appeng.parts.p2p.PartP2PTunnelME;
|
||||
|
||||
|
||||
public class TunnelConnection
|
||||
{
|
||||
public class TunnelConnection {
|
||||
|
||||
private final PartP2PTunnelME tunnel;
|
||||
private final IGridConnection c;
|
||||
private final PartP2PTunnelME tunnel;
|
||||
private final IGridConnection c;
|
||||
|
||||
public TunnelConnection( final PartP2PTunnelME t, final IGridConnection con )
|
||||
{
|
||||
this.tunnel = t;
|
||||
this.c = con;
|
||||
}
|
||||
public TunnelConnection(final PartP2PTunnelME t, final IGridConnection con) {
|
||||
this.tunnel = t;
|
||||
this.c = con;
|
||||
}
|
||||
|
||||
public IGridConnection getConnection()
|
||||
{
|
||||
return this.c;
|
||||
}
|
||||
public IGridConnection getConnection() {
|
||||
return this.c;
|
||||
}
|
||||
|
||||
public PartP2PTunnelME getTunnel()
|
||||
{
|
||||
return this.tunnel;
|
||||
}
|
||||
public PartP2PTunnelME getTunnel() {
|
||||
return this.tunnel;
|
||||
}
|
||||
}
|
||||
+34
-42
@@ -19,56 +19,48 @@
|
||||
package appeng.me.cache.helpers;
|
||||
|
||||
|
||||
import appeng.parts.p2p.PartP2PTunnel;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import appeng.parts.p2p.PartP2PTunnel;
|
||||
|
||||
public class TunnelIterator<T extends PartP2PTunnel> implements Iterator<T> {
|
||||
|
||||
public class TunnelIterator<T extends PartP2PTunnel> implements Iterator<T>
|
||||
{
|
||||
private final Iterator<T> wrapped;
|
||||
private final Class targetType;
|
||||
private T Next;
|
||||
|
||||
private final Iterator<T> wrapped;
|
||||
private final Class targetType;
|
||||
private T Next;
|
||||
public TunnelIterator(final Collection<T> tunnelSources, final Class clz) {
|
||||
this.wrapped = tunnelSources.iterator();
|
||||
this.targetType = clz;
|
||||
this.findNext();
|
||||
}
|
||||
|
||||
public TunnelIterator( final Collection<T> tunnelSources, final 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
this.findNext();
|
||||
return this.Next != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext()
|
||||
{
|
||||
this.findNext();
|
||||
return this.Next != null;
|
||||
}
|
||||
@Override
|
||||
public T next() {
|
||||
final T tmp = this.Next;
|
||||
this.Next = null;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next()
|
||||
{
|
||||
final T tmp = this.Next;
|
||||
this.Next = null;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove()
|
||||
{
|
||||
// no.
|
||||
}
|
||||
@Override
|
||||
public void remove() {
|
||||
// no.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,17 +19,16 @@
|
||||
package appeng.me.cluster;
|
||||
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import appeng.api.networking.IGridHost;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public interface IAECluster
|
||||
{
|
||||
|
||||
void updateStatus( boolean updateGrid );
|
||||
public interface IAECluster {
|
||||
|
||||
void destroy();
|
||||
void updateStatus(boolean updateGrid);
|
||||
|
||||
Iterator<IGridHost> getTiles();
|
||||
void destroy();
|
||||
|
||||
Iterator<IGridHost> getTiles();
|
||||
}
|
||||
|
||||
@@ -19,12 +19,11 @@
|
||||
package appeng.me.cluster;
|
||||
|
||||
|
||||
public interface IAEMultiBlock
|
||||
{
|
||||
public interface IAEMultiBlock {
|
||||
|
||||
void disconnect( boolean b );
|
||||
void disconnect(boolean b);
|
||||
|
||||
IAECluster getCluster();
|
||||
IAECluster getCluster();
|
||||
|
||||
boolean isValid();
|
||||
boolean isValid();
|
||||
}
|
||||
|
||||
@@ -19,222 +19,186 @@
|
||||
package appeng.me.cluster;
|
||||
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.api.util.WorldCoord;
|
||||
import appeng.core.AELog;
|
||||
import appeng.util.Platform;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
||||
public abstract class MBCalculator
|
||||
{
|
||||
public abstract class MBCalculator {
|
||||
|
||||
private final IAEMultiBlock target;
|
||||
private final IAEMultiBlock target;
|
||||
|
||||
public MBCalculator( final IAEMultiBlock t )
|
||||
{
|
||||
this.target = t;
|
||||
}
|
||||
public MBCalculator(final IAEMultiBlock t) {
|
||||
this.target = t;
|
||||
}
|
||||
|
||||
public void calculateMultiblock( final World world, final WorldCoord loc )
|
||||
{
|
||||
if( Platform.isClient() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
public void calculateMultiblock(final World world, final WorldCoord loc) {
|
||||
if (Platform.isClient()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final WorldCoord min = loc.copy();
|
||||
final WorldCoord max = loc.copy();
|
||||
try {
|
||||
final WorldCoord min = loc.copy();
|
||||
final WorldCoord max = loc.copy();
|
||||
|
||||
// find size of MB structure...
|
||||
while( this.isValidTileAt( world, min.x - 1, min.y, min.z ) )
|
||||
{
|
||||
min.x--;
|
||||
}
|
||||
while( this.isValidTileAt( world, min.x, min.y - 1, min.z ) )
|
||||
{
|
||||
min.y--;
|
||||
}
|
||||
while( this.isValidTileAt( world, min.x, min.y, min.z - 1 ) )
|
||||
{
|
||||
min.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 ) )
|
||||
{
|
||||
max.y++;
|
||||
}
|
||||
while( this.isValidTileAt( world, max.x, max.y, max.z + 1 ) )
|
||||
{
|
||||
max.z++;
|
||||
}
|
||||
// find size of MB structure...
|
||||
while (this.isValidTileAt(world, min.x - 1, min.y, min.z)) {
|
||||
min.x--;
|
||||
}
|
||||
while (this.isValidTileAt(world, min.x, min.y - 1, min.z)) {
|
||||
min.y--;
|
||||
}
|
||||
while (this.isValidTileAt(world, min.x, min.y, min.z - 1)) {
|
||||
min.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)) {
|
||||
max.y++;
|
||||
}
|
||||
while (this.isValidTileAt(world, max.x, max.y, max.z + 1)) {
|
||||
max.z++;
|
||||
}
|
||||
|
||||
if( this.checkMultiblockScale( min, max ) )
|
||||
{
|
||||
if( this.verifyUnownedRegion( world, min, max ) )
|
||||
{
|
||||
IAECluster c = this.createCluster( world, min, max );
|
||||
if (this.checkMultiblockScale(min, max)) {
|
||||
if (this.verifyUnownedRegion(world, min, max)) {
|
||||
IAECluster c = this.createCluster(world, min, max);
|
||||
|
||||
try
|
||||
{
|
||||
if( !this.verifyInternalStructure( world, min, max ) )
|
||||
{
|
||||
this.disconnect();
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch( final Exception err )
|
||||
{
|
||||
this.disconnect();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (!this.verifyInternalStructure(world, min, max)) {
|
||||
this.disconnect();
|
||||
return;
|
||||
}
|
||||
} catch (final Exception err) {
|
||||
this.disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
boolean updateGrid = false;
|
||||
final IAECluster cluster = this.target.getCluster();
|
||||
if( cluster == null )
|
||||
{
|
||||
this.updateTiles( c, world, min, max );
|
||||
boolean updateGrid = false;
|
||||
final IAECluster cluster = this.target.getCluster();
|
||||
if (cluster == null) {
|
||||
this.updateTiles(c, world, min, max);
|
||||
|
||||
updateGrid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = cluster;
|
||||
}
|
||||
updateGrid = true;
|
||||
} else {
|
||||
c = cluster;
|
||||
}
|
||||
|
||||
c.updateStatus( updateGrid );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( final Throwable err )
|
||||
{
|
||||
AELog.debug( err );
|
||||
}
|
||||
c.updateStatus(updateGrid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (final Throwable err) {
|
||||
AELog.debug(err);
|
||||
}
|
||||
|
||||
this.disconnect();
|
||||
}
|
||||
this.disconnect();
|
||||
}
|
||||
|
||||
private boolean isValidTileAt( final World w, final int x, final int y, final int z )
|
||||
{
|
||||
return this.isValidTile( w.getTileEntity( new BlockPos( x, y, z ) ) );
|
||||
}
|
||||
private boolean isValidTileAt(final World w, final int x, final int y, final int z) {
|
||||
return this.isValidTile(w.getTileEntity(new BlockPos(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 );
|
||||
/**
|
||||
* 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);
|
||||
|
||||
private boolean verifyUnownedRegion( final World w, final WorldCoord min, final WorldCoord max )
|
||||
{
|
||||
for( final AEPartLocation side : AEPartLocation.SIDE_LOCATIONS )
|
||||
{
|
||||
if( this.verifyUnownedRegionInner( w, min.x, min.y, min.z, max.x, max.y, max.z, side ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private boolean verifyUnownedRegion(final World w, final WorldCoord min, final WorldCoord max) {
|
||||
for (final AEPartLocation side : AEPartLocation.SIDE_LOCATIONS) {
|
||||
if (this.verifyUnownedRegionInner(w, min.x, min.y, min.z, max.x, max.y, max.z, side)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
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 );
|
||||
/**
|
||||
* 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 world, WorldCoord min, WorldCoord max );
|
||||
public abstract boolean verifyInternalStructure(World world, WorldCoord min, WorldCoord max);
|
||||
|
||||
/**
|
||||
* disassembles the multi-block.
|
||||
*/
|
||||
public abstract void disconnect();
|
||||
/**
|
||||
* 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 );
|
||||
/**
|
||||
* 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 );
|
||||
/**
|
||||
* 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);
|
||||
|
||||
private boolean verifyUnownedRegionInner( final World w, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, final AEPartLocation 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 INTERNAL:
|
||||
return false;
|
||||
}
|
||||
private boolean verifyUnownedRegionInner(final World w, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, final AEPartLocation 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 INTERNAL:
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int x = minX; x <= maxX; x++ )
|
||||
{
|
||||
for( int y = minY; y <= maxY; y++ )
|
||||
{
|
||||
for( int z = minZ; z <= maxZ; z++ )
|
||||
{
|
||||
final TileEntity te = w.getTileEntity( new BlockPos( x, y, z ) );
|
||||
if( this.isValidTile( te ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int y = minY; y <= maxY; y++) {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
final TileEntity te = w.getTileEntity(new BlockPos(x, y, z));
|
||||
if (this.isValidTile(te)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +19,6 @@
|
||||
package appeng.me.cluster.implementations;
|
||||
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
@@ -35,121 +29,100 @@ import appeng.me.cluster.IAECluster;
|
||||
import appeng.me.cluster.IAEMultiBlock;
|
||||
import appeng.me.cluster.MBCalculator;
|
||||
import appeng.tile.crafting.TileCraftingTile;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class CraftingCPUCalculator extends MBCalculator
|
||||
{
|
||||
public class CraftingCPUCalculator extends MBCalculator {
|
||||
|
||||
private final TileCraftingTile tqb;
|
||||
private final TileCraftingTile tqb;
|
||||
|
||||
public CraftingCPUCalculator( final IAEMultiBlock t )
|
||||
{
|
||||
super( t );
|
||||
this.tqb = (TileCraftingTile) t;
|
||||
}
|
||||
public CraftingCPUCalculator(final IAEMultiBlock t) {
|
||||
super(t);
|
||||
this.tqb = (TileCraftingTile) t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkMultiblockScale( final WorldCoord min, final WorldCoord max )
|
||||
{
|
||||
if( max.x - min.x > 16 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean checkMultiblockScale(final WorldCoord min, final WorldCoord max) {
|
||||
if (max.x - min.x > 16) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( max.y - min.y > 16 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (max.y - min.y > 16) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( max.z - min.z > 16 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return max.z - min.z <= 16;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public IAECluster createCluster(final World w, final WorldCoord min, final WorldCoord max) {
|
||||
return new CraftingCPUCluster(min, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAECluster createCluster( final World w, final WorldCoord min, final WorldCoord max )
|
||||
{
|
||||
return new CraftingCPUCluster( min, max );
|
||||
}
|
||||
@Override
|
||||
public boolean verifyInternalStructure(final World w, final WorldCoord min, final WorldCoord max) {
|
||||
boolean storage = false;
|
||||
|
||||
@Override
|
||||
public boolean verifyInternalStructure( final World w, final WorldCoord min, final 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++) {
|
||||
final IAEMultiBlock te = (IAEMultiBlock) w.getTileEntity(new BlockPos(x, y, z));
|
||||
|
||||
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++ )
|
||||
{
|
||||
final IAEMultiBlock te = (IAEMultiBlock) w.getTileEntity( new BlockPos( x, y, z ) );
|
||||
if (!te.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !te.isValid() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!storage && te instanceof TileCraftingTile) {
|
||||
storage = ((TileCraftingTile) te).getStorageBytes() > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !storage && te instanceof TileCraftingTile )
|
||||
{
|
||||
storage = ( (TileCraftingTile) te ).getStorageBytes() > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return storage;
|
||||
}
|
||||
|
||||
return storage;
|
||||
}
|
||||
@Override
|
||||
public void disconnect() {
|
||||
this.tqb.disconnect(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect()
|
||||
{
|
||||
this.tqb.disconnect( true );
|
||||
}
|
||||
@Override
|
||||
public void updateTiles(final IAECluster cl, final World w, final WorldCoord min, final WorldCoord max) {
|
||||
final CraftingCPUCluster c = (CraftingCPUCluster) cl;
|
||||
|
||||
@Override
|
||||
public void updateTiles( final IAECluster cl, final World w, final WorldCoord min, final WorldCoord max )
|
||||
{
|
||||
final CraftingCPUCluster c = (CraftingCPUCluster) 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++) {
|
||||
final TileCraftingTile te = (TileCraftingTile) w.getTileEntity(new BlockPos(x, y, z));
|
||||
te.updateStatus(c);
|
||||
c.addTile(te);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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++ )
|
||||
{
|
||||
final TileCraftingTile te = (TileCraftingTile) w.getTileEntity( new BlockPos( x, y, z ) );
|
||||
te.updateStatus( c );
|
||||
c.addTile( te );
|
||||
}
|
||||
}
|
||||
}
|
||||
c.done();
|
||||
|
||||
c.done();
|
||||
final Iterator<IGridHost> i = c.getTiles();
|
||||
while (i.hasNext()) {
|
||||
final IGridHost gh = i.next();
|
||||
final IGridNode n = gh.getGridNode(AEPartLocation.INTERNAL);
|
||||
if (n != null) {
|
||||
final IGrid g = n.getGrid();
|
||||
if (g != null) {
|
||||
g.postEvent(new MENetworkCraftingCpuChange(n));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Iterator<IGridHost> i = c.getTiles();
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final IGridHost gh = i.next();
|
||||
final IGridNode n = gh.getGridNode( AEPartLocation.INTERNAL );
|
||||
if( n != null )
|
||||
{
|
||||
final IGrid g = n.getGrid();
|
||||
if( g != null )
|
||||
{
|
||||
g.postEvent( new MENetworkCraftingCpuChange( n ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidTile( final TileEntity te )
|
||||
{
|
||||
return te instanceof TileCraftingTile;
|
||||
}
|
||||
@Override
|
||||
public boolean isValidTile(final TileEntity te) {
|
||||
return te instanceof TileCraftingTile;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,11 +19,6 @@
|
||||
package appeng.me.cluster.implementations;
|
||||
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.definitions.IBlockDefinition;
|
||||
import appeng.api.definitions.IBlocks;
|
||||
@@ -32,138 +27,114 @@ import appeng.me.cluster.IAECluster;
|
||||
import appeng.me.cluster.IAEMultiBlock;
|
||||
import appeng.me.cluster.MBCalculator;
|
||||
import appeng.tile.qnb.TileQuantumBridge;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
||||
public class QuantumCalculator extends MBCalculator
|
||||
{
|
||||
public class QuantumCalculator extends MBCalculator {
|
||||
|
||||
private final TileQuantumBridge tqb;
|
||||
private final TileQuantumBridge tqb;
|
||||
|
||||
public QuantumCalculator( final IAEMultiBlock t )
|
||||
{
|
||||
super( t );
|
||||
this.tqb = (TileQuantumBridge) t;
|
||||
}
|
||||
public QuantumCalculator(final IAEMultiBlock t) {
|
||||
super(t);
|
||||
this.tqb = (TileQuantumBridge) t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkMultiblockScale( final WorldCoord min, final WorldCoord max )
|
||||
{
|
||||
@Override
|
||||
public boolean checkMultiblockScale(final WorldCoord min, final WorldCoord max) {
|
||||
|
||||
if( ( max.x - min.x + 1 ) * ( max.y - min.y + 1 ) * ( max.z - min.z + 1 ) == 9 )
|
||||
{
|
||||
final int ones = ( ( max.x - min.x ) == 0 ? 1 : 0 ) + ( ( max.y - min.y ) == 0 ? 1 : 0 ) + ( ( max.z - min.z ) == 0 ? 1 : 0 );
|
||||
if ((max.x - min.x + 1) * (max.y - min.y + 1) * (max.z - min.z + 1) == 9) {
|
||||
final int ones = ((max.x - min.x) == 0 ? 1 : 0) + ((max.y - min.y) == 0 ? 1 : 0) + ((max.z - min.z) == 0 ? 1 : 0);
|
||||
|
||||
final int threes = ( ( max.x - min.x ) == 2 ? 1 : 0 ) + ( ( max.y - min.y ) == 2 ? 1 : 0 ) + ( ( max.z - min.z ) == 2 ? 1 : 0 );
|
||||
final 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;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return ones == 1 && threes == 2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAECluster createCluster( final World w, final WorldCoord min, final WorldCoord max )
|
||||
{
|
||||
return new QuantumCluster( min, max );
|
||||
}
|
||||
@Override
|
||||
public IAECluster createCluster(final World w, final WorldCoord min, final WorldCoord max) {
|
||||
return new QuantumCluster(min, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyInternalStructure( final World w, final WorldCoord min, final WorldCoord max )
|
||||
{
|
||||
@Override
|
||||
public boolean verifyInternalStructure(final World w, final WorldCoord min, final WorldCoord max) {
|
||||
|
||||
byte num = 0;
|
||||
byte num = 0;
|
||||
|
||||
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++ )
|
||||
{
|
||||
final BlockPos p = new BlockPos( x, y, z );
|
||||
final IAEMultiBlock te = (IAEMultiBlock) w.getTileEntity( p );
|
||||
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++) {
|
||||
final BlockPos p = new BlockPos(x, y, z);
|
||||
final IAEMultiBlock te = (IAEMultiBlock) w.getTileEntity(p);
|
||||
|
||||
if( !te.isValid() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!te.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
num++;
|
||||
final IBlocks blocks = AEApi.instance().definitions().blocks();
|
||||
if( num == 5 )
|
||||
{
|
||||
if( !this.isBlockAtLocation( w, p, blocks.quantumLink() ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !this.isBlockAtLocation( w, p, blocks.quantumRing() ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
num++;
|
||||
final IBlocks blocks = AEApi.instance().definitions().blocks();
|
||||
if (num == 5) {
|
||||
if (!this.isBlockAtLocation(w, p, blocks.quantumLink())) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!this.isBlockAtLocation(w, p, blocks.quantumRing())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect()
|
||||
{
|
||||
this.tqb.disconnect( true );
|
||||
}
|
||||
@Override
|
||||
public void disconnect() {
|
||||
this.tqb.disconnect(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTiles( final IAECluster cl, final World w, final WorldCoord min, final WorldCoord max )
|
||||
{
|
||||
byte num = 0;
|
||||
byte ringNum = 0;
|
||||
final QuantumCluster c = (QuantumCluster) cl;
|
||||
@Override
|
||||
public void updateTiles(final IAECluster cl, final World w, final WorldCoord min, final WorldCoord max) {
|
||||
byte num = 0;
|
||||
byte ringNum = 0;
|
||||
final 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++ )
|
||||
{
|
||||
final TileQuantumBridge te = (TileQuantumBridge) w.getTileEntity( new BlockPos( x, y, z ) );
|
||||
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++) {
|
||||
final TileQuantumBridge te = (TileQuantumBridge) w.getTileEntity(new BlockPos(x, y, z));
|
||||
|
||||
num++;
|
||||
final byte flags;
|
||||
if( num == 5 )
|
||||
{
|
||||
flags = num;
|
||||
c.setCenter( te );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( num == 1 || num == 3 || num == 7 || num == 9 )
|
||||
{
|
||||
flags = (byte) ( this.tqb.getCorner() | num );
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = num;
|
||||
}
|
||||
c.getRing()[ringNum] = te;
|
||||
ringNum++;
|
||||
}
|
||||
num++;
|
||||
final byte flags;
|
||||
if (num == 5) {
|
||||
flags = num;
|
||||
c.setCenter(te);
|
||||
} else {
|
||||
if (num == 1 || num == 3 || num == 7 || num == 9) {
|
||||
flags = (byte) (this.tqb.getCorner() | num);
|
||||
} else {
|
||||
flags = num;
|
||||
}
|
||||
c.getRing()[ringNum] = te;
|
||||
ringNum++;
|
||||
}
|
||||
|
||||
te.updateStatus( c, flags, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
te.updateStatus(c, flags, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidTile( final TileEntity te )
|
||||
{
|
||||
return te instanceof TileQuantumBridge;
|
||||
}
|
||||
@Override
|
||||
public boolean isValidTile(final TileEntity te) {
|
||||
return te instanceof TileQuantumBridge;
|
||||
}
|
||||
|
||||
private boolean isBlockAtLocation( final IBlockAccess w, final BlockPos pos, final IBlockDefinition def )
|
||||
{
|
||||
return def.maybeBlock().map( block -> block == w.getBlockState( pos ).getBlock() ).orElse( false );
|
||||
}
|
||||
private boolean isBlockAtLocation(final IBlockAccess w, final BlockPos pos, final IBlockDefinition def) {
|
||||
return def.maybeBlock().map(block -> block == w.getBlockState(pos).getBlock()).orElse(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,16 +19,6 @@
|
||||
package appeng.me.cluster.implementations;
|
||||
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.events.LocatableEventAnnounce;
|
||||
import appeng.api.events.LocatableEventAnnounce.LocatableEvent;
|
||||
@@ -43,273 +33,230 @@ import appeng.me.cache.helpers.ConnectionWrapper;
|
||||
import appeng.me.cluster.IAECluster;
|
||||
import appeng.tile.qnb.TileQuantumBridge;
|
||||
import appeng.util.iterators.ChainedIterator;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class QuantumCluster implements ILocatable, IAECluster
|
||||
{
|
||||
public class QuantumCluster implements ILocatable, IAECluster {
|
||||
|
||||
private final WorldCoord min;
|
||||
private final WorldCoord max;
|
||||
private boolean isDestroyed = false;
|
||||
private boolean updateStatus = true;
|
||||
private TileQuantumBridge[] Ring;
|
||||
private boolean registered = false;
|
||||
private ConnectionWrapper connection;
|
||||
private long thisSide;
|
||||
private long otherSide;
|
||||
private TileQuantumBridge center;
|
||||
private final WorldCoord min;
|
||||
private final WorldCoord max;
|
||||
private boolean isDestroyed = false;
|
||||
private boolean updateStatus = true;
|
||||
private TileQuantumBridge[] Ring;
|
||||
private boolean registered = false;
|
||||
private ConnectionWrapper connection;
|
||||
private long thisSide;
|
||||
private long otherSide;
|
||||
private TileQuantumBridge center;
|
||||
|
||||
public QuantumCluster( final WorldCoord min, final WorldCoord max )
|
||||
{
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.setRing( new TileQuantumBridge[8] );
|
||||
}
|
||||
public QuantumCluster(final WorldCoord min, final WorldCoord max) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.setRing(new TileQuantumBridge[8]);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onUnload( final WorldEvent.Unload e )
|
||||
{
|
||||
if( this.center.getWorld() == e.getWorld() )
|
||||
{
|
||||
this.setUpdateStatus( false );
|
||||
this.destroy();
|
||||
}
|
||||
}
|
||||
@SubscribeEvent
|
||||
public void onUnload(final WorldEvent.Unload e) {
|
||||
if (this.center.getWorld() == e.getWorld()) {
|
||||
this.setUpdateStatus(false);
|
||||
this.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStatus( final boolean updateGrid )
|
||||
{
|
||||
@Override
|
||||
public void updateStatus(final boolean updateGrid) {
|
||||
|
||||
final long qe = this.center.getQEFrequency();
|
||||
final long qe = this.center.getQEFrequency();
|
||||
|
||||
if( this.thisSide != qe && this.thisSide != -qe )
|
||||
{
|
||||
if( qe != 0 )
|
||||
{
|
||||
if( this.thisSide != 0 )
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post( new LocatableEventAnnounce( this, LocatableEvent.UNREGISTER ) );
|
||||
}
|
||||
if (this.thisSide != qe && this.thisSide != -qe) {
|
||||
if (qe != 0) {
|
||||
if (this.thisSide != 0) {
|
||||
MinecraftForge.EVENT_BUS.post(new LocatableEventAnnounce(this, LocatableEvent.UNREGISTER));
|
||||
}
|
||||
|
||||
if( this.canUseNode( -qe ) )
|
||||
{
|
||||
this.otherSide = qe;
|
||||
this.thisSide = -qe;
|
||||
}
|
||||
else if( this.canUseNode( qe ) )
|
||||
{
|
||||
this.thisSide = qe;
|
||||
this.otherSide = -qe;
|
||||
}
|
||||
if (this.canUseNode(-qe)) {
|
||||
this.otherSide = qe;
|
||||
this.thisSide = -qe;
|
||||
} else if (this.canUseNode(qe)) {
|
||||
this.thisSide = qe;
|
||||
this.otherSide = -qe;
|
||||
}
|
||||
|
||||
MinecraftForge.EVENT_BUS.post( new LocatableEventAnnounce( this, LocatableEvent.REGISTER ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post( new LocatableEventAnnounce( this, LocatableEvent.UNREGISTER ) );
|
||||
MinecraftForge.EVENT_BUS.post(new LocatableEventAnnounce(this, LocatableEvent.REGISTER));
|
||||
} else {
|
||||
MinecraftForge.EVENT_BUS.post(new LocatableEventAnnounce(this, LocatableEvent.UNREGISTER));
|
||||
|
||||
this.otherSide = 0;
|
||||
this.thisSide = 0;
|
||||
}
|
||||
}
|
||||
this.otherSide = 0;
|
||||
this.thisSide = 0;
|
||||
}
|
||||
}
|
||||
|
||||
final ILocatable myOtherSide = this.otherSide == 0 ? null : AEApi.instance().registries().locatable().getLocatableBy( this.otherSide );
|
||||
final ILocatable myOtherSide = this.otherSide == 0 ? null : AEApi.instance().registries().locatable().getLocatableBy(this.otherSide);
|
||||
|
||||
boolean shutdown = false;
|
||||
boolean shutdown = false;
|
||||
|
||||
if( myOtherSide instanceof QuantumCluster )
|
||||
{
|
||||
final QuantumCluster sideA = this;
|
||||
final QuantumCluster sideB = (QuantumCluster) myOtherSide;
|
||||
if (myOtherSide instanceof QuantumCluster) {
|
||||
final QuantumCluster sideA = this;
|
||||
final QuantumCluster sideB = (QuantumCluster) myOtherSide;
|
||||
|
||||
if( sideA.isActive() && sideB.isActive() )
|
||||
{
|
||||
if( this.connection != null && this.connection.getConnection() != null )
|
||||
{
|
||||
final IGridNode a = this.connection.getConnection().a();
|
||||
final IGridNode b = this.connection.getConnection().b();
|
||||
final IGridNode sa = sideA.getNode();
|
||||
final IGridNode sb = sideB.getNode();
|
||||
if( ( a == sa || b == sa ) && ( a == sb || b == sb ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (sideA.isActive() && sideB.isActive()) {
|
||||
if (this.connection != null && this.connection.getConnection() != null) {
|
||||
final IGridNode a = this.connection.getConnection().a();
|
||||
final IGridNode b = this.connection.getConnection().b();
|
||||
final IGridNode sa = sideA.getNode();
|
||||
final IGridNode sb = sideB.getNode();
|
||||
if ((a == sa || b == sa) && (a == sb || b == sb)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if( sideA.connection != null )
|
||||
{
|
||||
if( sideA.connection.getConnection() != null )
|
||||
{
|
||||
sideA.connection.getConnection().destroy();
|
||||
sideA.connection = new ConnectionWrapper( null );
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (sideA.connection != null) {
|
||||
if (sideA.connection.getConnection() != null) {
|
||||
sideA.connection.getConnection().destroy();
|
||||
sideA.connection = new ConnectionWrapper(null);
|
||||
}
|
||||
}
|
||||
|
||||
if( sideB.connection != null )
|
||||
{
|
||||
if( sideB.connection.getConnection() != null )
|
||||
{
|
||||
sideB.connection.getConnection().destroy();
|
||||
sideB.connection = new ConnectionWrapper( null );
|
||||
}
|
||||
}
|
||||
if (sideB.connection != null) {
|
||||
if (sideB.connection.getConnection() != null) {
|
||||
sideB.connection.getConnection().destroy();
|
||||
sideB.connection = new ConnectionWrapper(null);
|
||||
}
|
||||
}
|
||||
|
||||
sideA.connection = sideB.connection = new ConnectionWrapper( AEApi.instance()
|
||||
.grid()
|
||||
.createGridConnection( sideA.getNode(),
|
||||
sideB.getNode() ) );
|
||||
}
|
||||
catch( final FailedConnectionException e )
|
||||
{
|
||||
// :(
|
||||
AELog.debug( e );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shutdown = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shutdown = true;
|
||||
}
|
||||
sideA.connection = sideB.connection = new ConnectionWrapper(AEApi.instance()
|
||||
.grid()
|
||||
.createGridConnection(sideA.getNode(),
|
||||
sideB.getNode()));
|
||||
} catch (final FailedConnectionException e) {
|
||||
// :(
|
||||
AELog.debug(e);
|
||||
}
|
||||
} else {
|
||||
shutdown = true;
|
||||
}
|
||||
} else {
|
||||
shutdown = true;
|
||||
}
|
||||
|
||||
if( shutdown && this.connection != null )
|
||||
{
|
||||
if( this.connection.getConnection() != null )
|
||||
{
|
||||
this.connection.getConnection().destroy();
|
||||
this.connection.setConnection( null );
|
||||
this.connection = new ConnectionWrapper( null );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shutdown && this.connection != null) {
|
||||
if (this.connection.getConnection() != null) {
|
||||
this.connection.getConnection().destroy();
|
||||
this.connection.setConnection(null);
|
||||
this.connection = new ConnectionWrapper(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canUseNode( final long qe )
|
||||
{
|
||||
final QuantumCluster qc = (QuantumCluster) AEApi.instance().registries().locatable().getLocatableBy( qe );
|
||||
if( qc != null )
|
||||
{
|
||||
final World theWorld = qc.center.getWorld();
|
||||
if( !qc.isDestroyed )
|
||||
{
|
||||
final Chunk c = theWorld.getChunkFromBlockCoords( qc.center.getPos() );
|
||||
if( c.isLoaded() )
|
||||
{
|
||||
final int id = theWorld.provider.getDimension();
|
||||
final World cur = DimensionManager.getWorld( id );
|
||||
private boolean canUseNode(final long qe) {
|
||||
final QuantumCluster qc = (QuantumCluster) AEApi.instance().registries().locatable().getLocatableBy(qe);
|
||||
if (qc != null) {
|
||||
final World theWorld = qc.center.getWorld();
|
||||
if (!qc.isDestroyed) {
|
||||
final Chunk c = theWorld.getChunkFromBlockCoords(qc.center.getPos());
|
||||
if (c.isLoaded()) {
|
||||
final int id = theWorld.provider.getDimension();
|
||||
final World cur = DimensionManager.getWorld(id);
|
||||
|
||||
final TileEntity te = theWorld.getTileEntity( qc.center.getPos() );
|
||||
return te != qc.center || theWorld != cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
final TileEntity te = theWorld.getTileEntity(qc.center.getPos());
|
||||
return te != qc.center || theWorld != cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isActive()
|
||||
{
|
||||
if( this.isDestroyed || !this.registered )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
private boolean isActive() {
|
||||
if (this.isDestroyed || !this.registered) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.center.isPowered() && this.hasQES();
|
||||
}
|
||||
return this.center.isPowered() && this.hasQES();
|
||||
}
|
||||
|
||||
private IGridNode getNode()
|
||||
{
|
||||
return this.center.getGridNode( AEPartLocation.INTERNAL );
|
||||
}
|
||||
private IGridNode getNode() {
|
||||
return this.center.getGridNode(AEPartLocation.INTERNAL);
|
||||
}
|
||||
|
||||
private boolean hasQES()
|
||||
{
|
||||
return this.thisSide != 0;
|
||||
}
|
||||
private boolean hasQES() {
|
||||
return this.thisSide != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
if( this.isDestroyed )
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.isDestroyed = true;
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (this.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
this.isDestroyed = true;
|
||||
|
||||
if( this.registered )
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.unregister( this );
|
||||
this.registered = false;
|
||||
}
|
||||
if (this.registered) {
|
||||
MinecraftForge.EVENT_BUS.unregister(this);
|
||||
this.registered = false;
|
||||
}
|
||||
|
||||
if( this.thisSide != 0 )
|
||||
{
|
||||
this.updateStatus( true );
|
||||
MinecraftForge.EVENT_BUS.post( new LocatableEventAnnounce( this, LocatableEvent.UNREGISTER ) );
|
||||
}
|
||||
if (this.thisSide != 0) {
|
||||
this.updateStatus(true);
|
||||
MinecraftForge.EVENT_BUS.post(new LocatableEventAnnounce(this, LocatableEvent.UNREGISTER));
|
||||
}
|
||||
|
||||
this.center.updateStatus( null, (byte) -1, this.isUpdateStatus() );
|
||||
this.center.updateStatus(null, (byte) -1, this.isUpdateStatus());
|
||||
|
||||
for( final TileQuantumBridge r : this.getRing() )
|
||||
{
|
||||
r.updateStatus( null, (byte) -1, this.isUpdateStatus() );
|
||||
}
|
||||
for (final TileQuantumBridge r : this.getRing()) {
|
||||
r.updateStatus(null, (byte) -1, this.isUpdateStatus());
|
||||
}
|
||||
|
||||
this.center = null;
|
||||
this.setRing( new TileQuantumBridge[8] );
|
||||
}
|
||||
this.center = null;
|
||||
this.setRing(new TileQuantumBridge[8]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<IGridHost> getTiles()
|
||||
{
|
||||
return new ChainedIterator<>( this.getRing()[0], this.getRing()[1], this.getRing()[2], this.getRing()[3], this.getRing()[4], this
|
||||
.getRing()[5], this.getRing()[6], this.getRing()[7], this.center );
|
||||
}
|
||||
@Override
|
||||
public Iterator<IGridHost> getTiles() {
|
||||
return new ChainedIterator<>(this.getRing()[0], this.getRing()[1], this.getRing()[2], this.getRing()[3], this.getRing()[4], this
|
||||
.getRing()[5], this.getRing()[6], this.getRing()[7], this.center);
|
||||
}
|
||||
|
||||
public boolean isCorner( final TileQuantumBridge tileQuantumBridge )
|
||||
{
|
||||
return this.getRing()[0] == tileQuantumBridge || this.getRing()[2] == tileQuantumBridge || this.getRing()[4] == tileQuantumBridge || this
|
||||
.getRing()[6] == tileQuantumBridge;
|
||||
}
|
||||
public boolean isCorner(final TileQuantumBridge tileQuantumBridge) {
|
||||
return this.getRing()[0] == tileQuantumBridge || this.getRing()[2] == tileQuantumBridge || this.getRing()[4] == tileQuantumBridge || this
|
||||
.getRing()[6] == tileQuantumBridge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLocatableSerial()
|
||||
{
|
||||
return this.thisSide;
|
||||
}
|
||||
@Override
|
||||
public long getLocatableSerial() {
|
||||
return this.thisSide;
|
||||
}
|
||||
|
||||
public TileQuantumBridge getCenter()
|
||||
{
|
||||
return this.center;
|
||||
}
|
||||
public TileQuantumBridge getCenter() {
|
||||
return this.center;
|
||||
}
|
||||
|
||||
void setCenter( final TileQuantumBridge c )
|
||||
{
|
||||
this.registered = true;
|
||||
MinecraftForge.EVENT_BUS.register( this );
|
||||
this.center = c;
|
||||
}
|
||||
void setCenter(final TileQuantumBridge c) {
|
||||
this.registered = true;
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
this.center = c;
|
||||
}
|
||||
|
||||
private boolean isUpdateStatus()
|
||||
{
|
||||
return this.updateStatus;
|
||||
}
|
||||
private boolean isUpdateStatus() {
|
||||
return this.updateStatus;
|
||||
}
|
||||
|
||||
public void setUpdateStatus( final boolean updateStatus )
|
||||
{
|
||||
this.updateStatus = updateStatus;
|
||||
}
|
||||
public void setUpdateStatus(final boolean updateStatus) {
|
||||
this.updateStatus = updateStatus;
|
||||
}
|
||||
|
||||
TileQuantumBridge[] getRing()
|
||||
{
|
||||
return this.Ring;
|
||||
}
|
||||
TileQuantumBridge[] getRing() {
|
||||
return this.Ring;
|
||||
}
|
||||
|
||||
private void setRing( final TileQuantumBridge[] ring )
|
||||
{
|
||||
this.Ring = ring;
|
||||
}
|
||||
private void setRing(final TileQuantumBridge[] ring) {
|
||||
this.Ring = ring;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,92 +19,76 @@
|
||||
package appeng.me.cluster.implementations;
|
||||
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.api.util.WorldCoord;
|
||||
import appeng.me.cluster.IAECluster;
|
||||
import appeng.me.cluster.IAEMultiBlock;
|
||||
import appeng.me.cluster.MBCalculator;
|
||||
import appeng.tile.spatial.TileSpatialPylon;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
|
||||
public class SpatialPylonCalculator extends MBCalculator
|
||||
{
|
||||
public class SpatialPylonCalculator extends MBCalculator {
|
||||
|
||||
private final TileSpatialPylon tqb;
|
||||
private final TileSpatialPylon tqb;
|
||||
|
||||
public SpatialPylonCalculator( final IAEMultiBlock t )
|
||||
{
|
||||
super( t );
|
||||
this.tqb = (TileSpatialPylon) t;
|
||||
}
|
||||
public SpatialPylonCalculator(final IAEMultiBlock t) {
|
||||
super(t);
|
||||
this.tqb = (TileSpatialPylon) t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkMultiblockScale( final WorldCoord min, final 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 boolean checkMultiblockScale(final WorldCoord min, final 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 IAECluster createCluster( final World w, final WorldCoord min, final 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 IAECluster createCluster(final World w, final WorldCoord min, final 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 boolean verifyInternalStructure( final World w, final WorldCoord min, final WorldCoord max )
|
||||
{
|
||||
@Override
|
||||
public boolean verifyInternalStructure(final World w, final WorldCoord min, final WorldCoord max) {
|
||||
|
||||
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++ )
|
||||
{
|
||||
final IAEMultiBlock te = (IAEMultiBlock) w.getTileEntity( new BlockPos( x, y, z ) );
|
||||
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++) {
|
||||
final IAEMultiBlock te = (IAEMultiBlock) w.getTileEntity(new BlockPos(x, y, z));
|
||||
|
||||
if( !te.isValid() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!te.isValid()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect()
|
||||
{
|
||||
this.tqb.disconnect( true );
|
||||
}
|
||||
@Override
|
||||
public void disconnect() {
|
||||
this.tqb.disconnect(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTiles( final IAECluster cl, final World w, final WorldCoord min, final WorldCoord max )
|
||||
{
|
||||
final SpatialPylonCluster c = (SpatialPylonCluster) cl;
|
||||
@Override
|
||||
public void updateTiles(final IAECluster cl, final World w, final WorldCoord min, final WorldCoord max) {
|
||||
final 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++ )
|
||||
{
|
||||
final TileSpatialPylon te = (TileSpatialPylon) w.getTileEntity( new BlockPos( x, y, z ) );
|
||||
te.updateStatus( c );
|
||||
c.getLine().add( ( te ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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++) {
|
||||
final TileSpatialPylon te = (TileSpatialPylon) w.getTileEntity(new BlockPos(x, y, z));
|
||||
te.updateStatus(c);
|
||||
c.getLine().add((te));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidTile( final TileEntity te )
|
||||
{
|
||||
return te instanceof TileSpatialPylon;
|
||||
}
|
||||
@Override
|
||||
public boolean isValidTile(final TileEntity te) {
|
||||
return te instanceof TileSpatialPylon;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,123 +19,99 @@
|
||||
package appeng.me.cluster.implementations;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.me.cluster.IAECluster;
|
||||
import appeng.tile.spatial.TileSpatialPylon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class SpatialPylonCluster implements IAECluster
|
||||
{
|
||||
|
||||
private final DimensionalCoord min;
|
||||
private final DimensionalCoord max;
|
||||
private final List<TileSpatialPylon> line = new ArrayList<>();
|
||||
private boolean isDestroyed = false;
|
||||
public class SpatialPylonCluster implements IAECluster {
|
||||
|
||||
private Axis currentAxis = Axis.UNFORMED;
|
||||
private boolean isValid;
|
||||
private final DimensionalCoord min;
|
||||
private final DimensionalCoord max;
|
||||
private final List<TileSpatialPylon> line = new ArrayList<>();
|
||||
private boolean isDestroyed = false;
|
||||
|
||||
public SpatialPylonCluster( final DimensionalCoord min, final DimensionalCoord max )
|
||||
{
|
||||
this.min = min.copy();
|
||||
this.max = max.copy();
|
||||
private Axis currentAxis = Axis.UNFORMED;
|
||||
private boolean isValid;
|
||||
|
||||
if( this.getMin().x != this.getMax().x )
|
||||
{
|
||||
this.setCurrentAxis( Axis.X );
|
||||
}
|
||||
else if( this.getMin().y != this.getMax().y )
|
||||
{
|
||||
this.setCurrentAxis( Axis.Y );
|
||||
}
|
||||
else if( this.getMin().z != this.getMax().z )
|
||||
{
|
||||
this.setCurrentAxis( Axis.Z );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setCurrentAxis( Axis.UNFORMED );
|
||||
}
|
||||
}
|
||||
public SpatialPylonCluster(final DimensionalCoord min, final DimensionalCoord max) {
|
||||
this.min = min.copy();
|
||||
this.max = max.copy();
|
||||
|
||||
@Override
|
||||
public void updateStatus( final boolean updateGrid )
|
||||
{
|
||||
for( final TileSpatialPylon r : this.getLine() )
|
||||
{
|
||||
r.recalculateDisplay();
|
||||
}
|
||||
}
|
||||
if (this.getMin().x != this.getMax().x) {
|
||||
this.setCurrentAxis(Axis.X);
|
||||
} else if (this.getMin().y != this.getMax().y) {
|
||||
this.setCurrentAxis(Axis.Y);
|
||||
} else if (this.getMin().z != this.getMax().z) {
|
||||
this.setCurrentAxis(Axis.Z);
|
||||
} else {
|
||||
this.setCurrentAxis(Axis.UNFORMED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
@Override
|
||||
public void updateStatus(final boolean updateGrid) {
|
||||
for (final TileSpatialPylon r : this.getLine()) {
|
||||
r.recalculateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
if( this.isDestroyed )
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.isDestroyed = true;
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
for( final TileSpatialPylon r : this.getLine() )
|
||||
{
|
||||
r.updateStatus( null );
|
||||
}
|
||||
}
|
||||
if (this.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
this.isDestroyed = true;
|
||||
|
||||
@Override
|
||||
public Iterator<IGridHost> getTiles()
|
||||
{
|
||||
return (Iterator) this.getLine().iterator();
|
||||
}
|
||||
for (final TileSpatialPylon r : this.getLine()) {
|
||||
r.updateStatus(null);
|
||||
}
|
||||
}
|
||||
|
||||
public int tileCount()
|
||||
{
|
||||
return this.getLine().size();
|
||||
}
|
||||
@Override
|
||||
public Iterator<IGridHost> getTiles() {
|
||||
return (Iterator) this.getLine().iterator();
|
||||
}
|
||||
|
||||
public Axis getCurrentAxis()
|
||||
{
|
||||
return this.currentAxis;
|
||||
}
|
||||
public int tileCount() {
|
||||
return this.getLine().size();
|
||||
}
|
||||
|
||||
private void setCurrentAxis( final Axis currentAxis )
|
||||
{
|
||||
this.currentAxis = currentAxis;
|
||||
}
|
||||
public Axis getCurrentAxis() {
|
||||
return this.currentAxis;
|
||||
}
|
||||
|
||||
public boolean isValid()
|
||||
{
|
||||
return this.isValid;
|
||||
}
|
||||
private void setCurrentAxis(final Axis currentAxis) {
|
||||
this.currentAxis = currentAxis;
|
||||
}
|
||||
|
||||
public void setValid( final boolean isValid )
|
||||
{
|
||||
this.isValid = isValid;
|
||||
}
|
||||
public boolean isValid() {
|
||||
return this.isValid;
|
||||
}
|
||||
|
||||
public DimensionalCoord getMax()
|
||||
{
|
||||
return this.max;
|
||||
}
|
||||
public void setValid(final boolean isValid) {
|
||||
this.isValid = isValid;
|
||||
}
|
||||
|
||||
public DimensionalCoord getMin()
|
||||
{
|
||||
return this.min;
|
||||
}
|
||||
public DimensionalCoord getMax() {
|
||||
return this.max;
|
||||
}
|
||||
|
||||
List<TileSpatialPylon> getLine()
|
||||
{
|
||||
return this.line;
|
||||
}
|
||||
public DimensionalCoord getMin() {
|
||||
return this.min;
|
||||
}
|
||||
|
||||
public enum Axis
|
||||
{
|
||||
X, Y, Z, UNFORMED
|
||||
}
|
||||
List<TileSpatialPylon> getLine() {
|
||||
return this.line;
|
||||
}
|
||||
|
||||
public enum Axis {
|
||||
X, Y, Z, UNFORMED
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,96 +22,75 @@ package appeng.me.energy;
|
||||
import appeng.api.networking.energy.IEnergyWatcher;
|
||||
|
||||
|
||||
public class EnergyThreshold implements Comparable<EnergyThreshold>
|
||||
{
|
||||
public class EnergyThreshold implements Comparable<EnergyThreshold> {
|
||||
|
||||
private final double threshold;
|
||||
private final IEnergyWatcher watcher;
|
||||
private final int watcherHash;
|
||||
private final double threshold;
|
||||
private final IEnergyWatcher watcher;
|
||||
private final int watcherHash;
|
||||
|
||||
public EnergyThreshold( final double lim, final IEnergyWatcher watcher )
|
||||
{
|
||||
this.threshold = lim;
|
||||
this.watcher = watcher;
|
||||
this.watcherHash = watcher.hashCode();
|
||||
}
|
||||
public EnergyThreshold(final double lim, final IEnergyWatcher watcher) {
|
||||
this.threshold = lim;
|
||||
this.watcher = watcher;
|
||||
this.watcherHash = watcher.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Special constructor to allow querying a for a subset of thresholds.
|
||||
*
|
||||
* @param lim
|
||||
* @param bound
|
||||
*/
|
||||
public EnergyThreshold( final double lim, final int bound )
|
||||
{
|
||||
this.threshold = lim;
|
||||
this.watcher = null;
|
||||
this.watcherHash = bound;
|
||||
}
|
||||
/**
|
||||
* Special constructor to allow querying a for a subset of thresholds.
|
||||
*
|
||||
* @param lim
|
||||
* @param bound
|
||||
*/
|
||||
public EnergyThreshold(final double lim, final int bound) {
|
||||
this.threshold = lim;
|
||||
this.watcher = null;
|
||||
this.watcherHash = bound;
|
||||
}
|
||||
|
||||
public IEnergyWatcher getEnergyWatcher()
|
||||
{
|
||||
return this.watcher;
|
||||
}
|
||||
public IEnergyWatcher getEnergyWatcher() {
|
||||
return this.watcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo( EnergyThreshold o )
|
||||
{
|
||||
int a = Double.compare( this.threshold, o.threshold );
|
||||
@Override
|
||||
public int compareTo(EnergyThreshold o) {
|
||||
int a = Double.compare(this.threshold, o.threshold);
|
||||
|
||||
if( a == 0 )
|
||||
{
|
||||
return Integer.compare( this.watcherHash, o.watcherHash );
|
||||
}
|
||||
if (a == 0) {
|
||||
return Integer.compare(this.watcherHash, o.watcherHash);
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits( this.threshold );
|
||||
result = prime * result + (int) ( temp ^ ( temp >>> 32 ) );
|
||||
result = prime * result + ( ( this.watcher == null ) ? 0 : this.watcher.hashCode() );
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits(this.threshold);
|
||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||
result = prime * result + ((this.watcher == null) ? 0 : this.watcher.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object obj )
|
||||
{
|
||||
if( this == obj )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if( obj == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if( this.getClass() != obj.getClass() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (this.getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EnergyThreshold other = (EnergyThreshold) obj;
|
||||
if( Double.doubleToLongBits( this.threshold ) != Double.doubleToLongBits( other.threshold ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
EnergyThreshold other = (EnergyThreshold) obj;
|
||||
if (Double.doubleToLongBits(this.threshold) != Double.doubleToLongBits(other.threshold)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( this.watcher == null )
|
||||
{
|
||||
if( other.watcher != null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if( !this.watcher.equals( other.watcher ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (this.watcher == null) {
|
||||
return other.watcher == null;
|
||||
} else return this.watcher.equals(other.watcher);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,73 +19,63 @@
|
||||
package appeng.me.energy;
|
||||
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import appeng.api.networking.energy.IEnergyWatcher;
|
||||
import appeng.api.networking.energy.IEnergyWatcherHost;
|
||||
import appeng.me.cache.EnergyGridCache;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* Maintain my interests, and a global watch list, they should always be fully synchronized.
|
||||
*/
|
||||
public class EnergyWatcher implements IEnergyWatcher
|
||||
{
|
||||
public class EnergyWatcher implements IEnergyWatcher {
|
||||
|
||||
private final EnergyGridCache gsc;
|
||||
private final IEnergyWatcherHost watcherHost;
|
||||
private final Set<EnergyThreshold> myInterests = new HashSet<>();
|
||||
private final EnergyGridCache gsc;
|
||||
private final IEnergyWatcherHost watcherHost;
|
||||
private final Set<EnergyThreshold> myInterests = new HashSet<>();
|
||||
|
||||
public EnergyWatcher( final EnergyGridCache cache, final IEnergyWatcherHost host )
|
||||
{
|
||||
this.gsc = cache;
|
||||
this.watcherHost = host;
|
||||
}
|
||||
public EnergyWatcher(final EnergyGridCache cache, final IEnergyWatcherHost host) {
|
||||
this.gsc = cache;
|
||||
this.watcherHost = host;
|
||||
}
|
||||
|
||||
public void post( final EnergyGridCache energyGridCache )
|
||||
{
|
||||
this.watcherHost.onThresholdPass( energyGridCache );
|
||||
}
|
||||
public void post(final EnergyGridCache energyGridCache) {
|
||||
this.watcherHost.onThresholdPass(energyGridCache);
|
||||
}
|
||||
|
||||
public IEnergyWatcherHost getHost()
|
||||
{
|
||||
return this.watcherHost;
|
||||
}
|
||||
public IEnergyWatcherHost getHost() {
|
||||
return this.watcherHost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add( final double amount )
|
||||
{
|
||||
final EnergyThreshold eh = new EnergyThreshold( amount, this );
|
||||
@Override
|
||||
public boolean add(final double amount) {
|
||||
final EnergyThreshold eh = new EnergyThreshold(amount, this);
|
||||
|
||||
if( this.myInterests.contains( eh ) )
|
||||
if (this.myInterests.contains(eh)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.gsc.registerEnergyInterest(eh) && this.myInterests.add(eh);
|
||||
}
|
||||
|
||||
return this.gsc.registerEnergyInterest( eh ) && this.myInterests.add( eh );
|
||||
}
|
||||
@Override
|
||||
public boolean remove(final double amount) {
|
||||
final EnergyThreshold eh = new EnergyThreshold(amount, this);
|
||||
|
||||
@Override
|
||||
public boolean remove( final double amount )
|
||||
{
|
||||
final EnergyThreshold eh = new EnergyThreshold( amount, this );
|
||||
return this.myInterests.remove(eh) && this.gsc.unregisterEnergyInterest(eh);
|
||||
}
|
||||
|
||||
return this.myInterests.remove( eh ) && this.gsc.unregisterEnergyInterest( eh );
|
||||
}
|
||||
@Override
|
||||
public void reset() {
|
||||
for (Iterator<EnergyThreshold> iterator = this.myInterests.iterator(); iterator.hasNext(); ) {
|
||||
final EnergyThreshold threshold = iterator.next();
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
for( Iterator<EnergyThreshold> iterator = this.myInterests.iterator(); iterator.hasNext(); )
|
||||
{
|
||||
final EnergyThreshold threshold = iterator.next();
|
||||
|
||||
this.gsc.unregisterEnergyInterest( threshold );
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
this.gsc.unregisterEnergyInterest(threshold);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,23 +19,8 @@
|
||||
package appeng.me.helpers;
|
||||
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.networking.GridFlags;
|
||||
import appeng.api.networking.GridNotification;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridBlock;
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.*;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
import appeng.api.networking.energy.IEnergyGrid;
|
||||
import appeng.api.networking.events.MENetworkPowerIdleChange;
|
||||
@@ -53,399 +38,333 @@ import appeng.me.cache.P2PCache;
|
||||
import appeng.parts.networking.PartCable;
|
||||
import appeng.tile.AEBaseTile;
|
||||
import appeng.util.Platform;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
|
||||
|
||||
public class AENetworkProxy implements IGridBlock
|
||||
{
|
||||
public class AENetworkProxy implements IGridBlock {
|
||||
|
||||
private final IGridProxyable gp;
|
||||
private final boolean worldNode;
|
||||
private final String nbtName; // name
|
||||
private AEColor myColor = AEColor.TRANSPARENT;
|
||||
private NBTTagCompound data = null; // input
|
||||
private ItemStack myRepInstance = ItemStack.EMPTY;
|
||||
private boolean isReady = false;
|
||||
private IGridNode node = null;
|
||||
private EnumSet<EnumFacing> validSides;
|
||||
private EnumSet<GridFlags> flags = EnumSet.noneOf( GridFlags.class );
|
||||
private double idleDraw = 1.0;
|
||||
private EntityPlayer owner;
|
||||
private final IGridProxyable gp;
|
||||
private final boolean worldNode;
|
||||
private final String nbtName; // name
|
||||
private AEColor myColor = AEColor.TRANSPARENT;
|
||||
private NBTTagCompound data = null; // input
|
||||
private ItemStack myRepInstance = ItemStack.EMPTY;
|
||||
private boolean isReady = false;
|
||||
private IGridNode node = null;
|
||||
private EnumSet<EnumFacing> validSides;
|
||||
private EnumSet<GridFlags> flags = EnumSet.noneOf(GridFlags.class);
|
||||
private double idleDraw = 1.0;
|
||||
private EntityPlayer owner;
|
||||
|
||||
public AENetworkProxy( final IGridProxyable te, final String nbtName, final ItemStack visual, final boolean inWorld )
|
||||
{
|
||||
this.gp = te;
|
||||
this.nbtName = nbtName;
|
||||
this.worldNode = inWorld;
|
||||
this.myRepInstance = visual;
|
||||
this.validSides = EnumSet.allOf( EnumFacing.class );
|
||||
}
|
||||
public AENetworkProxy(final IGridProxyable te, final String nbtName, final ItemStack visual, final boolean inWorld) {
|
||||
this.gp = te;
|
||||
this.nbtName = nbtName;
|
||||
this.worldNode = inWorld;
|
||||
this.myRepInstance = visual;
|
||||
this.validSides = EnumSet.allOf(EnumFacing.class);
|
||||
}
|
||||
|
||||
public void setVisualRepresentation( final ItemStack is )
|
||||
{
|
||||
this.myRepInstance = is;
|
||||
}
|
||||
public void setVisualRepresentation(final ItemStack is) {
|
||||
this.myRepInstance = is;
|
||||
}
|
||||
|
||||
public void writeToNBT( final NBTTagCompound tag )
|
||||
{
|
||||
if( this.node != null )
|
||||
{
|
||||
this.node.saveToNBT( this.nbtName, tag );
|
||||
}
|
||||
}
|
||||
public void writeToNBT(final NBTTagCompound tag) {
|
||||
if (this.node != null) {
|
||||
this.node.saveToNBT(this.nbtName, tag);
|
||||
}
|
||||
}
|
||||
|
||||
public void setValidSides( final EnumSet<EnumFacing> validSides )
|
||||
{
|
||||
this.validSides = validSides;
|
||||
if( this.node != null )
|
||||
{
|
||||
this.node.updateState();
|
||||
}
|
||||
}
|
||||
public void setValidSides(final EnumSet<EnumFacing> 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 validate() {
|
||||
if (this.gp instanceof AEBaseTile) {
|
||||
TickHandler.INSTANCE.addInit((AEBaseTile) this.gp);
|
||||
}
|
||||
}
|
||||
|
||||
public void onChunkUnload()
|
||||
{
|
||||
this.isReady = false;
|
||||
this.invalidate();
|
||||
}
|
||||
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 invalidate() {
|
||||
this.isReady = false;
|
||||
if (this.node != null) {
|
||||
this.node.destroy();
|
||||
this.node = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void onReady()
|
||||
{
|
||||
this.isReady = true;
|
||||
public void onReady() {
|
||||
this.isReady = true;
|
||||
|
||||
// send orientation based directionality to the node.
|
||||
if( this.gp instanceof IOrientable )
|
||||
{
|
||||
final IOrientable ori = (IOrientable) this.gp;
|
||||
if( ori.canBeRotated() )
|
||||
{
|
||||
ori.setOrientation( ori.getForward(), ori.getUp() );
|
||||
}
|
||||
}
|
||||
// send orientation based directionality to the node.
|
||||
if (this.gp instanceof IOrientable) {
|
||||
final IOrientable ori = (IOrientable) this.gp;
|
||||
if (ori.canBeRotated()) {
|
||||
ori.setOrientation(ori.getForward(), ori.getUp());
|
||||
}
|
||||
}
|
||||
|
||||
this.getNode();
|
||||
}
|
||||
this.getNode();
|
||||
}
|
||||
|
||||
public IGridNode getNode()
|
||||
{
|
||||
if( this.node == null && Platform.isServer() && this.isReady )
|
||||
{
|
||||
this.node = AEApi.instance().grid().createGridNode( this );
|
||||
this.readFromNBT( this.data );
|
||||
this.node.updateState();
|
||||
}
|
||||
public IGridNode getNode() {
|
||||
if (this.node == null && Platform.isServer() && this.isReady) {
|
||||
this.node = AEApi.instance().grid().createGridNode(this);
|
||||
this.readFromNBT(this.data);
|
||||
this.node.updateState();
|
||||
}
|
||||
|
||||
return this.node;
|
||||
}
|
||||
return this.node;
|
||||
}
|
||||
|
||||
public void readFromNBT( final NBTTagCompound tag )
|
||||
{
|
||||
this.data = tag;
|
||||
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 )
|
||||
{
|
||||
final GameProfile profile = this.owner.getGameProfile();
|
||||
final int playerID = WorldData.instance().playerData().getPlayerID( profile );
|
||||
public void readFromNBT(final NBTTagCompound tag) {
|
||||
this.data = tag;
|
||||
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) {
|
||||
final GameProfile profile = this.owner.getGameProfile();
|
||||
final int playerID = WorldData.instance().playerData().getPlayerID(profile);
|
||||
|
||||
this.node.setPlayerID( playerID );
|
||||
this.owner = null;
|
||||
}
|
||||
}
|
||||
this.node.setPlayerID(playerID);
|
||||
this.owner = null;
|
||||
}
|
||||
}
|
||||
|
||||
public IPathingGrid getPath() throws GridAccessException
|
||||
{
|
||||
final IGrid grid = this.getGrid();
|
||||
if( grid == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
final IPathingGrid pg = grid.getCache( IPathingGrid.class );
|
||||
if( pg == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
return pg;
|
||||
}
|
||||
public IPathingGrid getPath() throws GridAccessException {
|
||||
final IGrid grid = this.getGrid();
|
||||
if (grid == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
final 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();
|
||||
}
|
||||
final IGrid grid = this.node.getGrid();
|
||||
if( grid == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
return grid;
|
||||
}
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
final IGrid grid = this.node.getGrid();
|
||||
if (grid == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
return grid;
|
||||
}
|
||||
|
||||
public ITickManager getTick() throws GridAccessException
|
||||
{
|
||||
final IGrid grid = this.getGrid();
|
||||
if( grid == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
final ITickManager pg = grid.getCache( ITickManager.class );
|
||||
if( pg == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
return pg;
|
||||
}
|
||||
public ITickManager getTick() throws GridAccessException {
|
||||
final IGrid grid = this.getGrid();
|
||||
if (grid == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
final ITickManager pg = grid.getCache(ITickManager.class);
|
||||
if (pg == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
return pg;
|
||||
}
|
||||
|
||||
public IStorageGrid getStorage() throws GridAccessException
|
||||
{
|
||||
final IGrid grid = this.getGrid();
|
||||
if( grid == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
public IStorageGrid getStorage() throws GridAccessException {
|
||||
final IGrid grid = this.getGrid();
|
||||
if (grid == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
|
||||
final IStorageGrid pg = grid.getCache( IStorageGrid.class );
|
||||
final IStorageGrid pg = grid.getCache(IStorageGrid.class);
|
||||
|
||||
if( pg == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
if (pg == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
|
||||
return pg;
|
||||
}
|
||||
return pg;
|
||||
}
|
||||
|
||||
public P2PCache getP2P() throws GridAccessException
|
||||
{
|
||||
final IGrid grid = this.getGrid();
|
||||
if( grid == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
public P2PCache getP2P() throws GridAccessException {
|
||||
final IGrid grid = this.getGrid();
|
||||
if (grid == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
|
||||
final P2PCache pg = grid.getCache( P2PCache.class );
|
||||
final P2PCache pg = grid.getCache(P2PCache.class);
|
||||
|
||||
if( pg == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
if (pg == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
|
||||
return pg;
|
||||
}
|
||||
return pg;
|
||||
}
|
||||
|
||||
public ISecurityGrid getSecurity() throws GridAccessException
|
||||
{
|
||||
final IGrid grid = this.getGrid();
|
||||
if( grid == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
public ISecurityGrid getSecurity() throws GridAccessException {
|
||||
final IGrid grid = this.getGrid();
|
||||
if (grid == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
|
||||
final ISecurityGrid sg = grid.getCache( ISecurityGrid.class );
|
||||
final ISecurityGrid sg = grid.getCache(ISecurityGrid.class);
|
||||
|
||||
if( sg == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
if (sg == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
|
||||
return sg;
|
||||
}
|
||||
return sg;
|
||||
}
|
||||
|
||||
public ICraftingGrid getCrafting() throws GridAccessException
|
||||
{
|
||||
final IGrid grid = this.getGrid();
|
||||
if( grid == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
public ICraftingGrid getCrafting() throws GridAccessException {
|
||||
final IGrid grid = this.getGrid();
|
||||
if (grid == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
|
||||
final ICraftingGrid sg = grid.getCache( ICraftingGrid.class );
|
||||
final ICraftingGrid sg = grid.getCache(ICraftingGrid.class);
|
||||
|
||||
if( sg == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
if (sg == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
|
||||
return sg;
|
||||
}
|
||||
return sg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getIdlePowerUsage()
|
||||
{
|
||||
return this.idleDraw;
|
||||
}
|
||||
@Override
|
||||
public double getIdlePowerUsage() {
|
||||
return this.idleDraw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<GridFlags> getFlags()
|
||||
{
|
||||
return this.flags;
|
||||
}
|
||||
@Override
|
||||
public EnumSet<GridFlags> getFlags() {
|
||||
return this.flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWorldAccessible()
|
||||
{
|
||||
return this.worldNode;
|
||||
}
|
||||
@Override
|
||||
public boolean isWorldAccessible() {
|
||||
return this.worldNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DimensionalCoord getLocation()
|
||||
{
|
||||
return this.gp.getLocation();
|
||||
}
|
||||
@Override
|
||||
public DimensionalCoord getLocation() {
|
||||
return this.gp.getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AEColor getGridColor()
|
||||
{
|
||||
return this.getColor();
|
||||
}
|
||||
@Override
|
||||
public AEColor getGridColor() {
|
||||
return this.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGridNotification( final GridNotification notification )
|
||||
{
|
||||
if( this.gp instanceof PartCable )
|
||||
{
|
||||
( (PartCable) this.gp ).markForUpdate();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onGridNotification(final GridNotification notification) {
|
||||
if (this.gp instanceof PartCable) {
|
||||
((PartCable) this.gp).markForUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNetworkStatus( final IGrid grid, final int channelsInUse )
|
||||
{
|
||||
@Override
|
||||
public void setNetworkStatus(final IGrid grid, final int channelsInUse) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<EnumFacing> getConnectableSides()
|
||||
{
|
||||
return this.validSides;
|
||||
}
|
||||
@Override
|
||||
public EnumSet<EnumFacing> getConnectableSides() {
|
||||
return this.validSides;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGridHost getMachine()
|
||||
{
|
||||
return this.gp;
|
||||
}
|
||||
@Override
|
||||
public IGridHost getMachine() {
|
||||
return this.gp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gridChanged()
|
||||
{
|
||||
this.gp.gridChanged();
|
||||
}
|
||||
@Override
|
||||
public void gridChanged() {
|
||||
this.gp.gridChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getMachineRepresentation()
|
||||
{
|
||||
return this.myRepInstance;
|
||||
}
|
||||
@Override
|
||||
public ItemStack getMachineRepresentation() {
|
||||
return this.myRepInstance;
|
||||
}
|
||||
|
||||
public void setFlags( final GridFlags... requireChannel )
|
||||
{
|
||||
final EnumSet<GridFlags> flags = EnumSet.noneOf( GridFlags.class );
|
||||
public void setFlags(final GridFlags... requireChannel) {
|
||||
final EnumSet<GridFlags> flags = EnumSet.noneOf(GridFlags.class);
|
||||
|
||||
Collections.addAll( flags, requireChannel );
|
||||
Collections.addAll(flags, requireChannel);
|
||||
|
||||
this.flags = flags;
|
||||
}
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
public void setIdlePowerUsage( final double idle )
|
||||
{
|
||||
this.idleDraw = idle;
|
||||
public void setIdlePowerUsage(final double idle) {
|
||||
this.idleDraw = idle;
|
||||
|
||||
if( this.node != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
final IGrid g = this.getGrid();
|
||||
g.postEvent( new MENetworkPowerIdleChange( this.node ) );
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
{
|
||||
// not ready for this yet..
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.node != null) {
|
||||
try {
|
||||
final IGrid g = this.getGrid();
|
||||
g.postEvent(new MENetworkPowerIdleChange(this.node));
|
||||
} catch (final GridAccessException e) {
|
||||
// not ready for this yet..
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isReady()
|
||||
{
|
||||
return this.isReady;
|
||||
}
|
||||
public boolean isReady() {
|
||||
return this.isReady;
|
||||
}
|
||||
|
||||
public boolean isActive()
|
||||
{
|
||||
if( this.node == null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public boolean isActive() {
|
||||
if (this.node == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.node.isActive();
|
||||
}
|
||||
return this.node.isActive();
|
||||
}
|
||||
|
||||
public boolean isPowered()
|
||||
{
|
||||
try
|
||||
{
|
||||
return this.getEnergy().isNetworkPowered();
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public boolean isPowered() {
|
||||
try {
|
||||
return this.getEnergy().isNetworkPowered();
|
||||
} catch (final GridAccessException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnergyGrid getEnergy() throws GridAccessException
|
||||
{
|
||||
final IGrid grid = this.getGrid();
|
||||
if( grid == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
final IEnergyGrid eg = grid.getCache( IEnergyGrid.class );
|
||||
if( eg == null )
|
||||
{
|
||||
throw new GridAccessException();
|
||||
}
|
||||
return eg;
|
||||
}
|
||||
public IEnergyGrid getEnergy() throws GridAccessException {
|
||||
final IGrid grid = this.getGrid();
|
||||
if (grid == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
final IEnergyGrid eg = grid.getCache(IEnergyGrid.class);
|
||||
if (eg == null) {
|
||||
throw new GridAccessException();
|
||||
}
|
||||
return eg;
|
||||
}
|
||||
|
||||
public void setOwner( final EntityPlayer player )
|
||||
{
|
||||
this.owner = player;
|
||||
}
|
||||
public void setOwner(final EntityPlayer player) {
|
||||
this.owner = player;
|
||||
}
|
||||
|
||||
public AEColor getColor()
|
||||
{
|
||||
return this.myColor;
|
||||
}
|
||||
public AEColor getColor() {
|
||||
return this.myColor;
|
||||
}
|
||||
|
||||
public void setColor( final AEColor myColor )
|
||||
{
|
||||
this.myColor = myColor;
|
||||
}
|
||||
public void setColor(final AEColor myColor) {
|
||||
this.myColor = myColor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,39 +19,33 @@
|
||||
package appeng.me.helpers;
|
||||
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import appeng.api.networking.IGridMultiblock;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.me.cluster.IAECluster;
|
||||
import appeng.me.cluster.IAEMultiBlock;
|
||||
import appeng.util.iterators.ChainedIterator;
|
||||
import appeng.util.iterators.ProxyNodeIterator;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class AENetworkProxyMultiblock extends AENetworkProxy implements IGridMultiblock
|
||||
{
|
||||
public class AENetworkProxyMultiblock extends AENetworkProxy implements IGridMultiblock {
|
||||
|
||||
public AENetworkProxyMultiblock( final IGridProxyable te, final String nbtName, final ItemStack itemStack, final boolean inWorld )
|
||||
{
|
||||
super( te, nbtName, itemStack, inWorld );
|
||||
}
|
||||
public AENetworkProxyMultiblock(final IGridProxyable te, final String nbtName, final ItemStack itemStack, final boolean inWorld) {
|
||||
super(te, nbtName, itemStack, inWorld);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<IGridNode> getMultiblockNodes()
|
||||
{
|
||||
if( this.getCluster() == null )
|
||||
{
|
||||
return new ChainedIterator<>();
|
||||
}
|
||||
@Override
|
||||
public Iterator<IGridNode> getMultiblockNodes() {
|
||||
if (this.getCluster() == null) {
|
||||
return new ChainedIterator<>();
|
||||
}
|
||||
|
||||
return new ProxyNodeIterator( this.getCluster().getTiles() );
|
||||
}
|
||||
return new ProxyNodeIterator(this.getCluster().getTiles());
|
||||
}
|
||||
|
||||
private IAECluster getCluster()
|
||||
{
|
||||
return ( (IAEMultiBlock) this.getMachine() ).getCluster();
|
||||
}
|
||||
private IAECluster getCluster() {
|
||||
return ((IAEMultiBlock) this.getMachine()).getCluster();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,32 +19,27 @@
|
||||
package appeng.me.helpers;
|
||||
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import appeng.api.networking.security.IActionHost;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
public class BaseActionSource implements IActionSource
|
||||
{
|
||||
public class BaseActionSource implements IActionSource {
|
||||
|
||||
@Override
|
||||
public Optional<EntityPlayer> player()
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
@Override
|
||||
public Optional<EntityPlayer> player() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IActionHost> machine()
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
@Override
|
||||
public Optional<IActionHost> machine() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> context( Class<T> key )
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
@Override
|
||||
public <T> Optional<T> context(Class<T> key) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,25 +25,21 @@ import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.energy.IEnergySource;
|
||||
|
||||
|
||||
public class ChannelPowerSrc implements IEnergySource
|
||||
{
|
||||
public class ChannelPowerSrc implements IEnergySource {
|
||||
|
||||
private final IGridNode node;
|
||||
private final IEnergySource realSrc;
|
||||
private final IGridNode node;
|
||||
private final IEnergySource realSrc;
|
||||
|
||||
public ChannelPowerSrc( final IGridNode networkNode, final IEnergySource src )
|
||||
{
|
||||
this.node = networkNode;
|
||||
this.realSrc = src;
|
||||
}
|
||||
public ChannelPowerSrc(final IGridNode networkNode, final IEnergySource src) {
|
||||
this.node = networkNode;
|
||||
this.realSrc = src;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double extractAEPower( final double amt, final Actionable mode, final PowerMultiplier usePowerMultiplier )
|
||||
{
|
||||
if( this.node.isActive() )
|
||||
{
|
||||
return this.realSrc.extractAEPower( amt, mode, usePowerMultiplier );
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
@Override
|
||||
public double extractAEPower(final double amt, final Actionable mode, final PowerMultiplier usePowerMultiplier) {
|
||||
if (this.node.isActive()) {
|
||||
return this.realSrc.extractAEPower(amt, mode, usePowerMultiplier);
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,108 +19,85 @@
|
||||
package appeng.me.helpers;
|
||||
|
||||
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
public class GenericInterestManager<T> {
|
||||
|
||||
private final Multimap<IAEStack, T> container;
|
||||
private List<SavedTransactions> transactions = null;
|
||||
private int transDepth = 0;
|
||||
|
||||
public class GenericInterestManager<T>
|
||||
{
|
||||
public GenericInterestManager(final Multimap<IAEStack, T> interests) {
|
||||
this.container = interests;
|
||||
}
|
||||
|
||||
private final Multimap<IAEStack, T> container;
|
||||
private List<SavedTransactions> transactions = null;
|
||||
private int transDepth = 0;
|
||||
public void enableTransactions() {
|
||||
if (this.transDepth == 0) {
|
||||
this.transactions = new ArrayList<>();
|
||||
}
|
||||
|
||||
public GenericInterestManager( final Multimap<IAEStack, T> interests )
|
||||
{
|
||||
this.container = interests;
|
||||
}
|
||||
this.transDepth++;
|
||||
}
|
||||
|
||||
public void enableTransactions()
|
||||
{
|
||||
if( this.transDepth == 0 )
|
||||
{
|
||||
this.transactions = new ArrayList<>();
|
||||
}
|
||||
public void disableTransactions() {
|
||||
this.transDepth--;
|
||||
|
||||
this.transDepth++;
|
||||
}
|
||||
if (this.transDepth == 0) {
|
||||
final List<SavedTransactions> myActions = this.transactions;
|
||||
this.transactions = null;
|
||||
|
||||
public void disableTransactions()
|
||||
{
|
||||
this.transDepth--;
|
||||
for (final SavedTransactions t : myActions) {
|
||||
if (t.put) {
|
||||
this.put(t.stack, t.iw);
|
||||
} else {
|
||||
this.remove(t.stack, t.iw);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( this.transDepth == 0 )
|
||||
{
|
||||
final List<SavedTransactions> myActions = this.transactions;
|
||||
this.transactions = null;
|
||||
public boolean put(final IAEStack stack, final T iw) {
|
||||
if (this.transactions != null) {
|
||||
this.transactions.add(new SavedTransactions(true, stack, iw));
|
||||
return true;
|
||||
} else {
|
||||
return this.container.put(stack, iw);
|
||||
}
|
||||
}
|
||||
|
||||
for( final SavedTransactions t : myActions )
|
||||
{
|
||||
if( t.put )
|
||||
{
|
||||
this.put( t.stack, t.iw );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.remove( t.stack, t.iw );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public boolean remove(final IAEStack stack, final T iw) {
|
||||
if (this.transactions != null) {
|
||||
this.transactions.add(new SavedTransactions(false, stack, iw));
|
||||
return true;
|
||||
} else {
|
||||
return this.container.remove(stack, iw);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean put( final IAEStack stack, final T iw )
|
||||
{
|
||||
if( this.transactions != null )
|
||||
{
|
||||
this.transactions.add( new SavedTransactions( true, stack, iw ) );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.container.put( stack, iw );
|
||||
}
|
||||
}
|
||||
public boolean containsKey(final IAEStack stack) {
|
||||
return this.container.containsKey(stack);
|
||||
}
|
||||
|
||||
public boolean remove( final IAEStack stack, final T iw )
|
||||
{
|
||||
if( this.transactions != null )
|
||||
{
|
||||
this.transactions.add( new SavedTransactions( false, stack, iw ) );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.container.remove( stack, iw );
|
||||
}
|
||||
}
|
||||
public Collection<T> get(final IAEStack stack) {
|
||||
return this.container.get(stack);
|
||||
}
|
||||
|
||||
public boolean containsKey( final IAEStack stack )
|
||||
{
|
||||
return this.container.containsKey( stack );
|
||||
}
|
||||
private class SavedTransactions {
|
||||
|
||||
public Collection<T> get( final IAEStack stack )
|
||||
{
|
||||
return this.container.get( stack );
|
||||
}
|
||||
private final boolean put;
|
||||
private final IAEStack stack;
|
||||
private final T iw;
|
||||
|
||||
private class SavedTransactions
|
||||
{
|
||||
|
||||
private final boolean put;
|
||||
private final IAEStack stack;
|
||||
private final T iw;
|
||||
|
||||
public SavedTransactions( final boolean putOperation, final IAEStack myStack, final T watcher )
|
||||
{
|
||||
this.put = putOperation;
|
||||
this.stack = myStack;
|
||||
this.iw = watcher;
|
||||
}
|
||||
}
|
||||
public SavedTransactions(final boolean putOperation, final IAEStack myStack, final T watcher) {
|
||||
this.put = putOperation;
|
||||
this.stack = myStack;
|
||||
this.iw = watcher;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,12 +23,11 @@ import appeng.api.networking.IGridHost;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
|
||||
|
||||
public interface IGridProxyable extends IGridHost
|
||||
{
|
||||
public interface IGridProxyable extends IGridHost {
|
||||
|
||||
AENetworkProxy getProxy();
|
||||
AENetworkProxy getProxy();
|
||||
|
||||
DimensionalCoord getLocation();
|
||||
DimensionalCoord getLocation();
|
||||
|
||||
void gridChanged();
|
||||
void gridChanged();
|
||||
}
|
||||
|
||||
@@ -24,10 +24,6 @@
|
||||
package appeng.me.helpers;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
@@ -38,153 +34,130 @@ import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
/**
|
||||
* Common implementation of a simple class that monitors injection/extraction of a inventory to send events to a list of
|
||||
* listeners.
|
||||
*
|
||||
* @param <T>
|
||||
*
|
||||
* TODO: Needs to be redesigned to solve performance issues.
|
||||
* @param <T> TODO: Needs to be redesigned to solve performance issues.
|
||||
*/
|
||||
public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T>
|
||||
{
|
||||
public class MEMonitorHandler<T extends IAEStack<T>> implements IMEMonitor<T> {
|
||||
|
||||
private final IMEInventoryHandler<T> internalHandler;
|
||||
private final IItemList<T> cachedList;
|
||||
private final HashMap<IMEMonitorHandlerReceiver<T>, Object> listeners = new HashMap<>();
|
||||
private final IMEInventoryHandler<T> internalHandler;
|
||||
private final IItemList<T> cachedList;
|
||||
private final HashMap<IMEMonitorHandlerReceiver<T>, Object> listeners = new HashMap<>();
|
||||
|
||||
protected boolean hasChanged = true;
|
||||
protected boolean hasChanged = true;
|
||||
|
||||
public MEMonitorHandler( final IMEInventoryHandler<T> t )
|
||||
{
|
||||
this.internalHandler = t;
|
||||
this.cachedList = t.getChannel().createList();
|
||||
}
|
||||
public MEMonitorHandler(final IMEInventoryHandler<T> t) {
|
||||
this.internalHandler = t;
|
||||
this.cachedList = t.getChannel().createList();
|
||||
}
|
||||
|
||||
public MEMonitorHandler( final IMEInventoryHandler<T> t, final IStorageChannel<T> chan )
|
||||
{
|
||||
this.internalHandler = t;
|
||||
this.cachedList = chan.createList();
|
||||
}
|
||||
public MEMonitorHandler(final IMEInventoryHandler<T> t, final IStorageChannel<T> chan) {
|
||||
this.internalHandler = t;
|
||||
this.cachedList = chan.createList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener( final IMEMonitorHandlerReceiver<T> l, final Object verificationToken )
|
||||
{
|
||||
this.listeners.put( l, verificationToken );
|
||||
}
|
||||
@Override
|
||||
public void addListener(final IMEMonitorHandlerReceiver<T> l, final Object verificationToken) {
|
||||
this.listeners.put(l, verificationToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener( final IMEMonitorHandlerReceiver<T> l )
|
||||
{
|
||||
this.listeners.remove( l );
|
||||
}
|
||||
@Override
|
||||
public void removeListener(final IMEMonitorHandlerReceiver<T> l) {
|
||||
this.listeners.remove(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T injectItems( final T input, final Actionable mode, final IActionSource src )
|
||||
{
|
||||
return this.getHandler().injectItems( input, mode, src );
|
||||
}
|
||||
@Override
|
||||
public T injectItems(final T input, final Actionable mode, final IActionSource src) {
|
||||
return this.getHandler().injectItems(input, mode, src);
|
||||
}
|
||||
|
||||
protected IMEInventoryHandler<T> getHandler()
|
||||
{
|
||||
return this.internalHandler;
|
||||
}
|
||||
protected IMEInventoryHandler<T> getHandler() {
|
||||
return this.internalHandler;
|
||||
}
|
||||
|
||||
public void postChangesToListeners( final Iterable<T> changes, final IActionSource src )
|
||||
{
|
||||
this.notifyListenersOfChange( changes, src );
|
||||
}
|
||||
public void postChangesToListeners(final Iterable<T> changes, final IActionSource src) {
|
||||
this.notifyListenersOfChange(changes, src);
|
||||
}
|
||||
|
||||
protected void notifyListenersOfChange( final Iterable<T> diff, final IActionSource src )
|
||||
{
|
||||
this.hasChanged = true;// need to update the cache.
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
|
||||
final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
|
||||
if( receiver.isValid( o.getValue() ) )
|
||||
{
|
||||
receiver.postChange( this, diff, src );
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
protected void notifyListenersOfChange(final Iterable<T> diff, final IActionSource src) {
|
||||
this.hasChanged = true;// need to update the cache.
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
|
||||
while (i.hasNext()) {
|
||||
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
|
||||
final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
|
||||
if (receiver.isValid(o.getValue())) {
|
||||
receiver.postChange(this, diff, src);
|
||||
} else {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> getListeners()
|
||||
{
|
||||
return this.listeners.entrySet().iterator();
|
||||
}
|
||||
protected Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> getListeners() {
|
||||
return this.listeners.entrySet().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T extractItems( final T request, final Actionable mode, final IActionSource src )
|
||||
{
|
||||
return this.getHandler().extractItems( request, mode, src );
|
||||
}
|
||||
@Override
|
||||
public T extractItems(final T request, final Actionable mode, final IActionSource src) {
|
||||
return this.getHandler().extractItems(request, mode, src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel<T> getChannel()
|
||||
{
|
||||
return this.getHandler().getChannel();
|
||||
}
|
||||
@Override
|
||||
public IStorageChannel<T> getChannel() {
|
||||
return this.getHandler().getChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessRestriction getAccess()
|
||||
{
|
||||
return this.getHandler().getAccess();
|
||||
}
|
||||
@Override
|
||||
public AccessRestriction getAccess() {
|
||||
return this.getHandler().getAccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<T> getStorageList()
|
||||
{
|
||||
if( this.hasChanged )
|
||||
{
|
||||
this.hasChanged = false;
|
||||
this.cachedList.resetStatus();
|
||||
return this.getAvailableItems( this.cachedList );
|
||||
}
|
||||
@Override
|
||||
public IItemList<T> getStorageList() {
|
||||
if (this.hasChanged) {
|
||||
this.hasChanged = false;
|
||||
this.cachedList.resetStatus();
|
||||
return this.getAvailableItems(this.cachedList);
|
||||
}
|
||||
|
||||
return this.cachedList;
|
||||
}
|
||||
return this.cachedList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrioritized( final T input )
|
||||
{
|
||||
return this.getHandler().isPrioritized( input );
|
||||
}
|
||||
@Override
|
||||
public boolean isPrioritized(final T input) {
|
||||
return this.getHandler().isPrioritized(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccept( final T input )
|
||||
{
|
||||
return this.getHandler().canAccept( input );
|
||||
}
|
||||
@Override
|
||||
public boolean canAccept(final T input) {
|
||||
return this.getHandler().canAccept(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems( final IItemList<T> out )
|
||||
{
|
||||
return this.getHandler().getAvailableItems( out );
|
||||
}
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems(final IItemList<T> out) {
|
||||
return this.getHandler().getAvailableItems(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority()
|
||||
{
|
||||
return this.getHandler().getPriority();
|
||||
}
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return this.getHandler().getPriority();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlot()
|
||||
{
|
||||
return this.getHandler().getSlot();
|
||||
}
|
||||
@Override
|
||||
public int getSlot() {
|
||||
return this.getHandler().getSlot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validForPass( final int i )
|
||||
{
|
||||
return this.getHandler().validForPass( i );
|
||||
}
|
||||
@Override
|
||||
public boolean validForPass(final int i) {
|
||||
return this.getHandler().validForPass(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,61 +19,51 @@
|
||||
package appeng.me.helpers;
|
||||
|
||||
|
||||
import appeng.api.networking.security.IActionHost;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import appeng.api.networking.security.IActionHost;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
public class MachineSource implements IActionSource {
|
||||
|
||||
private final IActionHost via;
|
||||
|
||||
public class MachineSource implements IActionSource
|
||||
{
|
||||
public MachineSource(final IActionHost v) {
|
||||
this.via = v;
|
||||
}
|
||||
|
||||
private final IActionHost via;
|
||||
@Override
|
||||
public Optional<EntityPlayer> player() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public MachineSource( final IActionHost v )
|
||||
{
|
||||
this.via = v;
|
||||
}
|
||||
@Override
|
||||
public Optional<IActionHost> machine() {
|
||||
return Optional.of(this.via);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<EntityPlayer> player()
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
@Override
|
||||
public <T> Optional<T> context(Class<T> key) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IActionHost> machine()
|
||||
{
|
||||
return Optional.of( this.via );
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
MachineSource that = (MachineSource) o;
|
||||
return via.equals(that.via);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> context( Class<T> key )
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object o )
|
||||
{
|
||||
if( this == o )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if( o == null || getClass() != o.getClass() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
MachineSource that = (MachineSource) o;
|
||||
return via.equals( that.via );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hash( via );
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(via);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,44 +19,37 @@
|
||||
package appeng.me.helpers;
|
||||
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import appeng.api.networking.security.IActionHost;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
public class PlayerSource implements IActionSource
|
||||
{
|
||||
public class PlayerSource implements IActionSource {
|
||||
|
||||
private final EntityPlayer player;
|
||||
private final IActionHost via;
|
||||
private final EntityPlayer player;
|
||||
private final IActionHost via;
|
||||
|
||||
public PlayerSource( final EntityPlayer p, final IActionHost v )
|
||||
{
|
||||
Preconditions.checkNotNull( p );
|
||||
this.player = p;
|
||||
this.via = v;
|
||||
}
|
||||
public PlayerSource(final EntityPlayer p, final IActionHost v) {
|
||||
Preconditions.checkNotNull(p);
|
||||
this.player = p;
|
||||
this.via = v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<EntityPlayer> player()
|
||||
{
|
||||
return Optional.of( this.player );
|
||||
}
|
||||
@Override
|
||||
public Optional<EntityPlayer> player() {
|
||||
return Optional.of(this.player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IActionHost> machine()
|
||||
{
|
||||
return Optional.ofNullable( this.via );
|
||||
}
|
||||
@Override
|
||||
public Optional<IActionHost> machine() {
|
||||
return Optional.ofNullable(this.via);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> context( Class<T> key )
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
@Override
|
||||
public <T> Optional<T> context(Class<T> key) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,32 +26,28 @@ import appeng.me.GridConnection;
|
||||
import appeng.me.GridNode;
|
||||
|
||||
|
||||
public class AdHocChannelUpdater implements IGridConnectionVisitor
|
||||
{
|
||||
public class AdHocChannelUpdater implements IGridConnectionVisitor {
|
||||
|
||||
private final int usedChannels;
|
||||
private final int usedChannels;
|
||||
|
||||
public AdHocChannelUpdater( final int used )
|
||||
{
|
||||
this.usedChannels = used;
|
||||
}
|
||||
public AdHocChannelUpdater(final int used) {
|
||||
this.usedChannels = used;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitNode( final IGridNode n )
|
||||
{
|
||||
final GridNode gn = (GridNode) n;
|
||||
gn.setControllerRoute( null, true );
|
||||
gn.incrementChannelCount( this.usedChannels );
|
||||
gn.finalizeChannels();
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean visitNode(final IGridNode n) {
|
||||
final GridNode gn = (GridNode) n;
|
||||
gn.setControllerRoute(null, true);
|
||||
gn.incrementChannelCount(this.usedChannels);
|
||||
gn.finalizeChannels();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitConnection( final IGridConnection gcc )
|
||||
{
|
||||
final GridConnection gc = (GridConnection) gcc;
|
||||
gc.setControllerRoute( null, true );
|
||||
gc.incrementChannelCount( this.usedChannels );
|
||||
gc.finalizeChannels();
|
||||
}
|
||||
@Override
|
||||
public void visitConnection(final IGridConnection gcc) {
|
||||
final GridConnection gc = (GridConnection) gcc;
|
||||
gc.setControllerRoute(null, true);
|
||||
gc.incrementChannelCount(this.usedChannels);
|
||||
gc.finalizeChannels();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,21 +26,18 @@ import appeng.me.GridConnection;
|
||||
import appeng.me.GridNode;
|
||||
|
||||
|
||||
public class ControllerChannelUpdater implements IGridConnectionVisitor
|
||||
{
|
||||
public class ControllerChannelUpdater implements IGridConnectionVisitor {
|
||||
|
||||
@Override
|
||||
public boolean visitNode( final IGridNode n )
|
||||
{
|
||||
final GridNode gn = (GridNode) n;
|
||||
gn.finalizeChannels();
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean visitNode(final IGridNode n) {
|
||||
final GridNode gn = (GridNode) n;
|
||||
gn.finalizeChannels();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitConnection( final IGridConnection gcc )
|
||||
{
|
||||
final GridConnection gc = (GridConnection) gcc;
|
||||
gc.finalizeChannels();
|
||||
}
|
||||
@Override
|
||||
public void visitConnection(final IGridConnection gcc) {
|
||||
final GridConnection gc = (GridConnection) gcc;
|
||||
gc.finalizeChannels();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,87 +19,75 @@
|
||||
package appeng.me.pathfinding;
|
||||
|
||||
|
||||
import appeng.core.AEConfig;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.IGridVisitor;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.tile.networking.TileController;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
|
||||
public class ControllerValidator implements IGridVisitor
|
||||
{
|
||||
public class ControllerValidator implements IGridVisitor {
|
||||
|
||||
private boolean isValid = true;
|
||||
private int found = 0;
|
||||
private int minX;
|
||||
private int minY;
|
||||
private int minZ;
|
||||
private int maxX;
|
||||
private int maxY;
|
||||
private int maxZ;
|
||||
private boolean isValid = true;
|
||||
private int found = 0;
|
||||
private int minX;
|
||||
private int minY;
|
||||
private int minZ;
|
||||
private int maxX;
|
||||
private int maxY;
|
||||
private int maxZ;
|
||||
|
||||
public ControllerValidator( final int x, final int y, final int z )
|
||||
{
|
||||
this.minX = x;
|
||||
this.maxX = x;
|
||||
this.minY = y;
|
||||
this.maxY = y;
|
||||
this.minZ = z;
|
||||
this.maxZ = z;
|
||||
}
|
||||
public ControllerValidator(final int x, final int y, final int z) {
|
||||
this.minX = x;
|
||||
this.maxX = x;
|
||||
this.minY = y;
|
||||
this.maxY = y;
|
||||
this.minZ = z;
|
||||
this.maxZ = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitNode( final IGridNode n )
|
||||
{
|
||||
final IGridHost host = n.getMachine();
|
||||
if( this.isValid() && host instanceof TileController )
|
||||
{
|
||||
final TileController c = (TileController) host;
|
||||
@Override
|
||||
public boolean visitNode(final IGridNode n) {
|
||||
final IGridHost host = n.getMachine();
|
||||
if (this.isValid() && host instanceof TileController) {
|
||||
final TileController c = (TileController) host;
|
||||
|
||||
final BlockPos pos = c.getPos();
|
||||
final BlockPos pos = c.getPos();
|
||||
|
||||
this.minX = Math.min( pos.getX(), this.minX );
|
||||
this.maxX = Math.max( pos.getX(), this.maxX );
|
||||
this.minY = Math.min( pos.getY(), this.minY );
|
||||
this.maxY = Math.max( pos.getY(), this.maxY );
|
||||
this.minZ = Math.min( pos.getZ(), this.minZ );
|
||||
this.maxZ = Math.max( pos.getZ(), this.maxZ );
|
||||
this.minX = Math.min(pos.getX(), this.minX);
|
||||
this.maxX = Math.max(pos.getX(), this.maxX);
|
||||
this.minY = Math.min(pos.getY(), this.minY);
|
||||
this.maxY = Math.max(pos.getY(), this.maxY);
|
||||
this.minZ = Math.min(pos.getZ(), this.minZ);
|
||||
this.maxZ = Math.max(pos.getZ(), this.maxZ);
|
||||
|
||||
if( this.maxX - this.minX < AEConfig.instance().getMaxControllerSizeX() && this.maxY - this.minY < AEConfig.instance().getMaxControllerSizeY() && this.maxZ - this.minZ < AEConfig.instance().getMaxControllerSizeZ() )
|
||||
{
|
||||
this.setFound( this.getFound() + 1 );
|
||||
return true;
|
||||
}
|
||||
if (this.maxX - this.minX < AEConfig.instance().getMaxControllerSizeX() && this.maxY - this.minY < AEConfig.instance().getMaxControllerSizeY() && this.maxZ - this.minZ < AEConfig.instance().getMaxControllerSizeZ()) {
|
||||
this.setFound(this.getFound() + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
this.setValid( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
this.setValid(false);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.isValid();
|
||||
}
|
||||
return this.isValid();
|
||||
}
|
||||
|
||||
public boolean isValid()
|
||||
{
|
||||
return this.isValid;
|
||||
}
|
||||
public boolean isValid() {
|
||||
return this.isValid;
|
||||
}
|
||||
|
||||
private void setValid( final boolean isValid )
|
||||
{
|
||||
this.isValid = isValid;
|
||||
}
|
||||
private void setValid(final boolean isValid) {
|
||||
this.isValid = isValid;
|
||||
}
|
||||
|
||||
public int getFound()
|
||||
{
|
||||
return this.found;
|
||||
}
|
||||
public int getFound() {
|
||||
return this.found;
|
||||
}
|
||||
|
||||
private void setFound( final int found )
|
||||
{
|
||||
this.found = found;
|
||||
}
|
||||
private void setFound(final int found) {
|
||||
this.found = found;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,43 +19,42 @@
|
||||
package appeng.me.pathfinding;
|
||||
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import appeng.api.networking.GridFlags;
|
||||
import appeng.api.util.IReadOnlyCollection;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
public interface IPathItem
|
||||
{
|
||||
|
||||
IPathItem getControllerRoute();
|
||||
public interface IPathItem {
|
||||
|
||||
void setControllerRoute( IPathItem fast, boolean zeroOut );
|
||||
IPathItem getControllerRoute();
|
||||
|
||||
/**
|
||||
* used to determine if the finder can continue.
|
||||
*/
|
||||
boolean canSupportMoreChannels();
|
||||
void setControllerRoute(IPathItem fast, boolean zeroOut);
|
||||
|
||||
/**
|
||||
* find possible choices for other pathing.
|
||||
*/
|
||||
IReadOnlyCollection<IPathItem> getPossibleOptions();
|
||||
/**
|
||||
* used to determine if the finder can continue.
|
||||
*/
|
||||
boolean canSupportMoreChannels();
|
||||
|
||||
/**
|
||||
* add one to the channel count, this is mostly for cables.
|
||||
*/
|
||||
void incrementChannelCount( int usedChannels );
|
||||
/**
|
||||
* find possible choices for other pathing.
|
||||
*/
|
||||
IReadOnlyCollection<IPathItem> getPossibleOptions();
|
||||
|
||||
/**
|
||||
* get the grid flags for this IPathItem.
|
||||
*
|
||||
* @return the flag set.
|
||||
*/
|
||||
EnumSet<GridFlags> getFlags();
|
||||
/**
|
||||
* add one to the channel count, this is mostly for cables.
|
||||
*/
|
||||
void incrementChannelCount(int usedChannels);
|
||||
|
||||
/**
|
||||
* channels are done, wrap it up.
|
||||
*/
|
||||
void finalizeChannels();
|
||||
/**
|
||||
* get the grid flags for this IPathItem.
|
||||
*
|
||||
* @return the flag set.
|
||||
*/
|
||||
EnumSet<GridFlags> getFlags();
|
||||
|
||||
/**
|
||||
* channels are done, wrap it up.
|
||||
*/
|
||||
void finalizeChannels();
|
||||
}
|
||||
|
||||
@@ -19,153 +19,123 @@
|
||||
package appeng.me.pathfinding;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import appeng.api.networking.GridFlags;
|
||||
import appeng.api.networking.IGridMultiblock;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.me.cache.PathGridCache;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class PathSegment
|
||||
{
|
||||
|
||||
private final PathGridCache pgc;
|
||||
private final Set<IPathItem> semiOpen;
|
||||
private final Set<IPathItem> closed;
|
||||
private boolean isDead;
|
||||
private List<IPathItem> open;
|
||||
public class PathSegment {
|
||||
|
||||
public PathSegment( final PathGridCache myPGC, final List<IPathItem> open, final Set<IPathItem> semiOpen, final Set<IPathItem> closed )
|
||||
{
|
||||
this.open = open;
|
||||
this.semiOpen = semiOpen;
|
||||
this.closed = closed;
|
||||
this.pgc = myPGC;
|
||||
this.setDead( false );
|
||||
}
|
||||
private final PathGridCache pgc;
|
||||
private final Set<IPathItem> semiOpen;
|
||||
private final Set<IPathItem> closed;
|
||||
private boolean isDead;
|
||||
private List<IPathItem> open;
|
||||
|
||||
public boolean step()
|
||||
{
|
||||
final List<IPathItem> oldOpen = this.open;
|
||||
this.open = new ArrayList<>();
|
||||
public PathSegment(final PathGridCache myPGC, final List<IPathItem> open, final Set<IPathItem> semiOpen, final Set<IPathItem> closed) {
|
||||
this.open = open;
|
||||
this.semiOpen = semiOpen;
|
||||
this.closed = closed;
|
||||
this.pgc = myPGC;
|
||||
this.setDead(false);
|
||||
}
|
||||
|
||||
for( final IPathItem i : oldOpen )
|
||||
{
|
||||
for( final IPathItem pi : i.getPossibleOptions() )
|
||||
{
|
||||
final EnumSet<GridFlags> flags = pi.getFlags();
|
||||
public boolean step() {
|
||||
final List<IPathItem> oldOpen = this.open;
|
||||
this.open = new ArrayList<>();
|
||||
|
||||
if( !this.closed.contains( pi ) )
|
||||
{
|
||||
pi.setControllerRoute( i, true );
|
||||
for (final IPathItem i : oldOpen) {
|
||||
for (final IPathItem pi : i.getPossibleOptions()) {
|
||||
final EnumSet<GridFlags> flags = pi.getFlags();
|
||||
|
||||
if( flags.contains( GridFlags.REQUIRE_CHANNEL ) )
|
||||
{
|
||||
// close the semi open.
|
||||
if( !this.semiOpen.contains( pi ) )
|
||||
{
|
||||
final boolean worked;
|
||||
if (!this.closed.contains(pi)) {
|
||||
pi.setControllerRoute(i, true);
|
||||
|
||||
if( flags.contains( GridFlags.COMPRESSED_CHANNEL ) )
|
||||
{
|
||||
worked = this.useDenseChannel( pi );
|
||||
}
|
||||
else
|
||||
{
|
||||
worked = this.useChannel( pi );
|
||||
}
|
||||
if (flags.contains(GridFlags.REQUIRE_CHANNEL)) {
|
||||
// close the semi open.
|
||||
if (!this.semiOpen.contains(pi)) {
|
||||
final boolean worked;
|
||||
|
||||
if( worked && flags.contains( GridFlags.MULTIBLOCK ) )
|
||||
{
|
||||
final Iterator<IGridNode> oni = ( (IGridMultiblock) ( (IGridNode) pi ).getGridBlock() ).getMultiblockNodes();
|
||||
while( oni.hasNext() )
|
||||
{
|
||||
final IGridNode otherNodes = oni.next();
|
||||
if( otherNodes != pi )
|
||||
{
|
||||
this.semiOpen.add( (IPathItem) otherNodes );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pi.incrementChannelCount( 1 ); // give a channel.
|
||||
this.semiOpen.remove( pi );
|
||||
}
|
||||
}
|
||||
if (flags.contains(GridFlags.COMPRESSED_CHANNEL)) {
|
||||
worked = this.useDenseChannel(pi);
|
||||
} else {
|
||||
worked = this.useChannel(pi);
|
||||
}
|
||||
|
||||
this.closed.add( pi );
|
||||
this.open.add( pi );
|
||||
}
|
||||
}
|
||||
}
|
||||
if (worked && flags.contains(GridFlags.MULTIBLOCK)) {
|
||||
final Iterator<IGridNode> oni = ((IGridMultiblock) ((IGridNode) pi).getGridBlock()).getMultiblockNodes();
|
||||
while (oni.hasNext()) {
|
||||
final IGridNode otherNodes = oni.next();
|
||||
if (otherNodes != pi) {
|
||||
this.semiOpen.add((IPathItem) otherNodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pi.incrementChannelCount(1); // give a channel.
|
||||
this.semiOpen.remove(pi);
|
||||
}
|
||||
}
|
||||
|
||||
return this.open.isEmpty();
|
||||
}
|
||||
this.closed.add(pi);
|
||||
this.open.add(pi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean useDenseChannel( final IPathItem start )
|
||||
{
|
||||
IPathItem pi = start;
|
||||
while( pi != null )
|
||||
{
|
||||
if( !pi.canSupportMoreChannels() || pi.getFlags().contains( GridFlags.CANNOT_CARRY_COMPRESSED ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.open.isEmpty();
|
||||
}
|
||||
|
||||
pi = pi.getControllerRoute();
|
||||
}
|
||||
private boolean useDenseChannel(final IPathItem start) {
|
||||
IPathItem pi = start;
|
||||
while (pi != null) {
|
||||
if (!pi.canSupportMoreChannels() || pi.getFlags().contains(GridFlags.CANNOT_CARRY_COMPRESSED)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pi = start;
|
||||
while( pi != null )
|
||||
{
|
||||
this.pgc.setChannelsByBlocks( this.pgc.getChannelsByBlocks() + 1 );
|
||||
pi.incrementChannelCount( 1 );
|
||||
pi = pi.getControllerRoute();
|
||||
}
|
||||
pi = pi.getControllerRoute();
|
||||
}
|
||||
|
||||
this.pgc.setChannelsInUse( this.pgc.getChannelsInUse() + 1 );
|
||||
return true;
|
||||
}
|
||||
pi = start;
|
||||
while (pi != null) {
|
||||
this.pgc.setChannelsByBlocks(this.pgc.getChannelsByBlocks() + 1);
|
||||
pi.incrementChannelCount(1);
|
||||
pi = pi.getControllerRoute();
|
||||
}
|
||||
|
||||
private boolean useChannel( final IPathItem start )
|
||||
{
|
||||
IPathItem pi = start;
|
||||
while( pi != null )
|
||||
{
|
||||
if( !pi.canSupportMoreChannels() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
this.pgc.setChannelsInUse(this.pgc.getChannelsInUse() + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
pi = pi.getControllerRoute();
|
||||
}
|
||||
private boolean useChannel(final IPathItem start) {
|
||||
IPathItem pi = start;
|
||||
while (pi != null) {
|
||||
if (!pi.canSupportMoreChannels()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pi = start;
|
||||
while( pi != null )
|
||||
{
|
||||
this.pgc.setChannelsByBlocks( this.pgc.getChannelsByBlocks() + 1 );
|
||||
pi.incrementChannelCount( 1 );
|
||||
pi = pi.getControllerRoute();
|
||||
}
|
||||
pi = pi.getControllerRoute();
|
||||
}
|
||||
|
||||
this.pgc.setChannelsInUse( this.pgc.getChannelsInUse() + 1 );
|
||||
return true;
|
||||
}
|
||||
pi = start;
|
||||
while (pi != null) {
|
||||
this.pgc.setChannelsByBlocks(this.pgc.getChannelsByBlocks() + 1);
|
||||
pi.incrementChannelCount(1);
|
||||
pi = pi.getControllerRoute();
|
||||
}
|
||||
|
||||
public boolean isDead()
|
||||
{
|
||||
return this.isDead;
|
||||
}
|
||||
this.pgc.setChannelsInUse(this.pgc.getChannelsInUse() + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setDead( final boolean isDead )
|
||||
{
|
||||
this.isDead = isDead;
|
||||
}
|
||||
public boolean isDead() {
|
||||
return this.isDead;
|
||||
}
|
||||
|
||||
public void setDead(final boolean isDead) {
|
||||
this.isDead = isDead;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
package appeng.me.storage;
|
||||
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.implementations.items.IStorageCell;
|
||||
import appeng.api.storage.ICellInventory;
|
||||
@@ -30,6 +26,9 @@ import appeng.api.storage.ISaveProvider;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.util.Platform;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
|
||||
/**
|
||||
@@ -37,316 +36,267 @@ import appeng.util.Platform;
|
||||
* @version rv6 - 2018-01-17
|
||||
* @since rv6 2018-01-17
|
||||
*/
|
||||
public abstract class AbstractCellInventory<T extends IAEStack<T>> implements ICellInventory<T>
|
||||
{
|
||||
private static final int MAX_ITEM_TYPES = 63;
|
||||
private static final String ITEM_TYPE_TAG = "it";
|
||||
private static final String ITEM_COUNT_TAG = "ic";
|
||||
private static final String ITEM_SLOT = "#";
|
||||
private static final String ITEM_SLOT_COUNT = "@";
|
||||
protected static final String ITEM_PRE_FORMATTED_COUNT = "PF";
|
||||
protected static final String ITEM_PRE_FORMATTED_SLOT = "PF#";
|
||||
protected static final String ITEM_PRE_FORMATTED_NAME = "PN";
|
||||
protected static final String ITEM_PRE_FORMATTED_FUZZY = "FP";
|
||||
private static final String[] ITEM_SLOT_KEYS = new String[MAX_ITEM_TYPES];
|
||||
private static final String[] ITEM_SLOT_COUNT_KEYS = new String[MAX_ITEM_TYPES];
|
||||
private final NBTTagCompound tagCompound;
|
||||
protected final ISaveProvider container;
|
||||
private int maxItemTypes = MAX_ITEM_TYPES;
|
||||
private short storedItems = 0;
|
||||
private int storedItemCount = 0;
|
||||
protected IItemList<T> cellItems;
|
||||
private final ItemStack i;
|
||||
protected final IStorageCell<T> cellType;
|
||||
protected final int itemsPerByte;
|
||||
private boolean isPersisted = true;
|
||||
public abstract class AbstractCellInventory<T extends IAEStack<T>> implements ICellInventory<T> {
|
||||
private static final int MAX_ITEM_TYPES = 63;
|
||||
private static final String ITEM_TYPE_TAG = "it";
|
||||
private static final String ITEM_COUNT_TAG = "ic";
|
||||
private static final String ITEM_SLOT = "#";
|
||||
private static final String ITEM_SLOT_COUNT = "@";
|
||||
protected static final String ITEM_PRE_FORMATTED_COUNT = "PF";
|
||||
protected static final String ITEM_PRE_FORMATTED_SLOT = "PF#";
|
||||
protected static final String ITEM_PRE_FORMATTED_NAME = "PN";
|
||||
protected static final String ITEM_PRE_FORMATTED_FUZZY = "FP";
|
||||
private static final String[] ITEM_SLOT_KEYS = new String[MAX_ITEM_TYPES];
|
||||
private static final String[] ITEM_SLOT_COUNT_KEYS = new String[MAX_ITEM_TYPES];
|
||||
private final NBTTagCompound tagCompound;
|
||||
protected final ISaveProvider container;
|
||||
private int maxItemTypes = MAX_ITEM_TYPES;
|
||||
private short storedItems = 0;
|
||||
private int storedItemCount = 0;
|
||||
protected IItemList<T> cellItems;
|
||||
private final ItemStack i;
|
||||
protected final IStorageCell<T> cellType;
|
||||
protected final int itemsPerByte;
|
||||
private boolean isPersisted = true;
|
||||
|
||||
static
|
||||
{
|
||||
for( int x = 0; x < MAX_ITEM_TYPES; x++ )
|
||||
{
|
||||
ITEM_SLOT_KEYS[x] = ITEM_SLOT + x;
|
||||
ITEM_SLOT_COUNT_KEYS[x] = ITEM_SLOT_COUNT + x;
|
||||
}
|
||||
}
|
||||
static {
|
||||
for (int x = 0; x < MAX_ITEM_TYPES; x++) {
|
||||
ITEM_SLOT_KEYS[x] = ITEM_SLOT + x;
|
||||
ITEM_SLOT_COUNT_KEYS[x] = ITEM_SLOT_COUNT + x;
|
||||
}
|
||||
}
|
||||
|
||||
protected AbstractCellInventory( final IStorageCell<T> cellType, final ItemStack o, final ISaveProvider container )
|
||||
{
|
||||
this.i = o;
|
||||
this.cellType = cellType;
|
||||
this.itemsPerByte = this.cellType.getChannel().getUnitsPerByte();
|
||||
this.maxItemTypes = this.cellType.getTotalTypes( this.i );
|
||||
protected AbstractCellInventory(final IStorageCell<T> cellType, final ItemStack o, final ISaveProvider container) {
|
||||
this.i = o;
|
||||
this.cellType = cellType;
|
||||
this.itemsPerByte = this.cellType.getChannel().getUnitsPerByte();
|
||||
this.maxItemTypes = this.cellType.getTotalTypes(this.i);
|
||||
|
||||
if( this.maxItemTypes > MAX_ITEM_TYPES )
|
||||
{
|
||||
this.maxItemTypes = MAX_ITEM_TYPES;
|
||||
}
|
||||
if( this.maxItemTypes < 1 )
|
||||
{
|
||||
this.maxItemTypes = 1;
|
||||
}
|
||||
if (this.maxItemTypes > MAX_ITEM_TYPES) {
|
||||
this.maxItemTypes = MAX_ITEM_TYPES;
|
||||
}
|
||||
if (this.maxItemTypes < 1) {
|
||||
this.maxItemTypes = 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
protected IItemList<T> getCellItems()
|
||||
{
|
||||
if( this.cellItems == null )
|
||||
{
|
||||
this.cellItems = this.getChannel().createList();
|
||||
this.loadCellItems();
|
||||
}
|
||||
protected IItemList<T> getCellItems() {
|
||||
if (this.cellItems == null) {
|
||||
this.cellItems = this.getChannel().createList();
|
||||
this.loadCellItems();
|
||||
}
|
||||
|
||||
return this.cellItems;
|
||||
}
|
||||
return this.cellItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void persist()
|
||||
{
|
||||
if( this.isPersisted )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public void persist() {
|
||||
if (this.isPersisted) {
|
||||
return;
|
||||
}
|
||||
|
||||
int itemCount = 0;
|
||||
int itemCount = 0;
|
||||
|
||||
// add new pretty stuff...
|
||||
int x = 0;
|
||||
for( final T v : this.cellItems )
|
||||
{
|
||||
itemCount += v.getStackSize();
|
||||
// add new pretty stuff...
|
||||
int x = 0;
|
||||
for (final T v : this.cellItems) {
|
||||
itemCount += v.getStackSize();
|
||||
|
||||
final NBTTagCompound g = new NBTTagCompound();
|
||||
v.writeToNBT( g );
|
||||
this.tagCompound.setTag( ITEM_SLOT_KEYS[x], g );
|
||||
this.tagCompound.setInteger( ITEM_SLOT_COUNT_KEYS[x], (int) v.getStackSize() );
|
||||
final NBTTagCompound g = new NBTTagCompound();
|
||||
v.writeToNBT(g);
|
||||
this.tagCompound.setTag(ITEM_SLOT_KEYS[x], g);
|
||||
this.tagCompound.setInteger(ITEM_SLOT_COUNT_KEYS[x], (int) v.getStackSize());
|
||||
|
||||
x++;
|
||||
}
|
||||
x++;
|
||||
}
|
||||
|
||||
final short oldStoredItems = this.storedItems;
|
||||
final short oldStoredItems = this.storedItems;
|
||||
|
||||
this.storedItems = (short) this.cellItems.size();
|
||||
if( this.cellItems.isEmpty() )
|
||||
{
|
||||
this.tagCompound.removeTag( ITEM_TYPE_TAG );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.tagCompound.setShort( ITEM_TYPE_TAG, this.storedItems );
|
||||
}
|
||||
this.storedItems = (short) this.cellItems.size();
|
||||
if (this.cellItems.isEmpty()) {
|
||||
this.tagCompound.removeTag(ITEM_TYPE_TAG);
|
||||
} else {
|
||||
this.tagCompound.setShort(ITEM_TYPE_TAG, this.storedItems);
|
||||
}
|
||||
|
||||
this.storedItemCount = itemCount;
|
||||
if( itemCount == 0 )
|
||||
{
|
||||
this.tagCompound.removeTag( ITEM_COUNT_TAG );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.tagCompound.setInteger( ITEM_COUNT_TAG, itemCount );
|
||||
}
|
||||
this.storedItemCount = itemCount;
|
||||
if (itemCount == 0) {
|
||||
this.tagCompound.removeTag(ITEM_COUNT_TAG);
|
||||
} else {
|
||||
this.tagCompound.setInteger(ITEM_COUNT_TAG, itemCount);
|
||||
}
|
||||
|
||||
// clean any old crusty stuff...
|
||||
for( ; x >= oldStoredItems && x < this.maxItemTypes; x++ )
|
||||
{
|
||||
this.tagCompound.removeTag( ITEM_SLOT_KEYS[x] );
|
||||
this.tagCompound.removeTag( ITEM_SLOT_COUNT_KEYS[x] );
|
||||
}
|
||||
// clean any old crusty stuff...
|
||||
for (; x >= oldStoredItems && x < this.maxItemTypes; x++) {
|
||||
this.tagCompound.removeTag(ITEM_SLOT_KEYS[x]);
|
||||
this.tagCompound.removeTag(ITEM_SLOT_COUNT_KEYS[x]);
|
||||
}
|
||||
|
||||
this.isPersisted = true;
|
||||
}
|
||||
this.isPersisted = true;
|
||||
}
|
||||
|
||||
protected void saveChanges()
|
||||
{
|
||||
// recalculate values
|
||||
this.storedItems = (short) this.cellItems.size();
|
||||
this.storedItemCount = 0;
|
||||
for( final T v : this.cellItems )
|
||||
{
|
||||
this.storedItemCount += v.getStackSize();
|
||||
}
|
||||
protected void saveChanges() {
|
||||
// recalculate values
|
||||
this.storedItems = (short) this.cellItems.size();
|
||||
this.storedItemCount = 0;
|
||||
for (final T v : this.cellItems) {
|
||||
this.storedItemCount += v.getStackSize();
|
||||
}
|
||||
|
||||
this.isPersisted = false;
|
||||
if( this.container != null )
|
||||
{
|
||||
this.container.saveChanges( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
// if there is no ISaveProvider, store to NBT immediately
|
||||
this.persist();
|
||||
}
|
||||
}
|
||||
this.isPersisted = false;
|
||||
if (this.container != null) {
|
||||
this.container.saveChanges(this);
|
||||
} else {
|
||||
// if there is no ISaveProvider, store to NBT immediately
|
||||
this.persist();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadCellItems()
|
||||
{
|
||||
if( this.cellItems == null )
|
||||
{
|
||||
this.cellItems = this.getChannel().createList();
|
||||
}
|
||||
private void loadCellItems() {
|
||||
if (this.cellItems == null) {
|
||||
this.cellItems = this.getChannel().createList();
|
||||
}
|
||||
|
||||
this.cellItems.resetStatus(); // clears totals and stuff.
|
||||
this.cellItems.resetStatus(); // clears totals and stuff.
|
||||
|
||||
final int types = (int) this.getStoredItemTypes();
|
||||
boolean needsUpdate = false;
|
||||
final int types = (int) this.getStoredItemTypes();
|
||||
boolean needsUpdate = false;
|
||||
|
||||
for( int slot = 0; slot < types; slot++ )
|
||||
{
|
||||
NBTTagCompound compoundTag = this.tagCompound.getCompoundTag( ITEM_SLOT_KEYS[slot] );
|
||||
int stackSize = this.tagCompound.getInteger( ITEM_SLOT_COUNT_KEYS[slot] );
|
||||
needsUpdate |= !this.loadCellItem( compoundTag, stackSize );
|
||||
}
|
||||
for (int slot = 0; slot < types; slot++) {
|
||||
NBTTagCompound compoundTag = this.tagCompound.getCompoundTag(ITEM_SLOT_KEYS[slot]);
|
||||
int stackSize = this.tagCompound.getInteger(ITEM_SLOT_COUNT_KEYS[slot]);
|
||||
needsUpdate |= !this.loadCellItem(compoundTag, stackSize);
|
||||
}
|
||||
|
||||
if( needsUpdate )
|
||||
{
|
||||
this.saveChanges();
|
||||
}
|
||||
}
|
||||
if (needsUpdate) {
|
||||
this.saveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a single item.
|
||||
*
|
||||
* @param compoundTag
|
||||
* @param stackSize
|
||||
* @return true when successfully loaded
|
||||
*/
|
||||
protected abstract boolean loadCellItem( NBTTagCompound compoundTag, int stackSize );
|
||||
/**
|
||||
* Load a single item.
|
||||
*
|
||||
* @param compoundTag
|
||||
* @param stackSize
|
||||
* @return true when successfully loaded
|
||||
*/
|
||||
protected abstract boolean loadCellItem(NBTTagCompound compoundTag, int stackSize);
|
||||
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems( final IItemList<T> out )
|
||||
{
|
||||
for( final T item : this.getCellItems() )
|
||||
{
|
||||
out.add( item );
|
||||
}
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems(final IItemList<T> out) {
|
||||
for (final T item : this.getCellItems()) {
|
||||
out.add(item);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack()
|
||||
{
|
||||
return this.i;
|
||||
}
|
||||
@Override
|
||||
public ItemStack getItemStack() {
|
||||
return this.i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getIdleDrain()
|
||||
{
|
||||
return this.cellType.getIdleDrain();
|
||||
}
|
||||
@Override
|
||||
public double getIdleDrain() {
|
||||
return this.cellType.getIdleDrain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FuzzyMode getFuzzyMode()
|
||||
{
|
||||
return this.cellType.getFuzzyMode( this.i );
|
||||
}
|
||||
@Override
|
||||
public FuzzyMode getFuzzyMode() {
|
||||
return this.cellType.getFuzzyMode(this.i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemHandler getConfigInventory()
|
||||
{
|
||||
return this.cellType.getConfigInventory( this.i );
|
||||
}
|
||||
@Override
|
||||
public IItemHandler getConfigInventory() {
|
||||
return this.cellType.getConfigInventory(this.i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemHandler getUpgradesInventory()
|
||||
{
|
||||
return this.cellType.getUpgradesInventory( this.i );
|
||||
}
|
||||
@Override
|
||||
public IItemHandler getUpgradesInventory() {
|
||||
return this.cellType.getUpgradesInventory(this.i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBytesPerType()
|
||||
{
|
||||
return this.cellType.getBytesPerType( this.i );
|
||||
}
|
||||
@Override
|
||||
public int getBytesPerType() {
|
||||
return this.cellType.getBytesPerType(this.i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canHoldNewItem()
|
||||
{
|
||||
final long bytesFree = this.getFreeBytes();
|
||||
return ( bytesFree > this.getBytesPerType() || ( bytesFree == this.getBytesPerType() && this.getUnusedItemCount() > 0 ) ) && this
|
||||
.getRemainingItemTypes() > 0;
|
||||
}
|
||||
@Override
|
||||
public boolean canHoldNewItem() {
|
||||
final 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 getTotalBytes() {
|
||||
return this.cellType.getBytes(this.i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getFreeBytes()
|
||||
{
|
||||
return this.getTotalBytes() - this.getUsedBytes();
|
||||
}
|
||||
@Override
|
||||
public long getFreeBytes() {
|
||||
return this.getTotalBytes() - this.getUsedBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTotalItemTypes()
|
||||
{
|
||||
return this.maxItemTypes;
|
||||
}
|
||||
@Override
|
||||
public long getTotalItemTypes() {
|
||||
return this.maxItemTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStoredItemCount()
|
||||
{
|
||||
return this.storedItemCount;
|
||||
}
|
||||
@Override
|
||||
public long getStoredItemCount() {
|
||||
return this.storedItemCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStoredItemTypes()
|
||||
{
|
||||
return this.storedItems;
|
||||
}
|
||||
@Override
|
||||
public long getStoredItemTypes() {
|
||||
return this.storedItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRemainingItemTypes()
|
||||
{
|
||||
final long basedOnStorage = this.getFreeBytes() / this.getBytesPerType();
|
||||
final long baseOnTotal = this.getTotalItemTypes() - this.getStoredItemTypes();
|
||||
return basedOnStorage > baseOnTotal ? baseOnTotal : basedOnStorage;
|
||||
}
|
||||
@Override
|
||||
public long getRemainingItemTypes() {
|
||||
final long basedOnStorage = this.getFreeBytes() / this.getBytesPerType();
|
||||
final long baseOnTotal = this.getTotalItemTypes() - this.getStoredItemTypes();
|
||||
return basedOnStorage > baseOnTotal ? baseOnTotal : basedOnStorage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getUsedBytes()
|
||||
{
|
||||
final long bytesForItemCount = ( this.getStoredItemCount() + this.getUnusedItemCount() ) / this.itemsPerByte;
|
||||
return this.getStoredItemTypes() * this.getBytesPerType() + bytesForItemCount;
|
||||
}
|
||||
@Override
|
||||
public long getUsedBytes() {
|
||||
final long bytesForItemCount = (this.getStoredItemCount() + this.getUnusedItemCount()) / this.itemsPerByte;
|
||||
return this.getStoredItemTypes() * this.getBytesPerType() + bytesForItemCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRemainingItemCount()
|
||||
{
|
||||
final long remaining = this.getFreeBytes() * this.itemsPerByte + this.getUnusedItemCount();
|
||||
return remaining > 0 ? remaining : 0;
|
||||
}
|
||||
@Override
|
||||
public long getRemainingItemCount() {
|
||||
final long remaining = this.getFreeBytes() * this.itemsPerByte + this.getUnusedItemCount();
|
||||
return remaining > 0 ? remaining : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUnusedItemCount()
|
||||
{
|
||||
final int div = (int) ( this.getStoredItemCount() % 8 );
|
||||
@Override
|
||||
public int getUnusedItemCount() {
|
||||
final int div = (int) (this.getStoredItemCount() % 8);
|
||||
|
||||
if( div == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (div == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this.itemsPerByte - div;
|
||||
}
|
||||
return this.itemsPerByte - div;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusForCell()
|
||||
{
|
||||
if( this.canHoldNewItem() )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if( this.getRemainingItemCount() > 0 )
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
@Override
|
||||
public int getStatusForCell() {
|
||||
if (this.canHoldNewItem()) {
|
||||
return 1;
|
||||
}
|
||||
if (this.getRemainingItemCount() > 0) {
|
||||
return 2;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
|
||||
package appeng.me.storage;
|
||||
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.exceptions.AppEngException;
|
||||
import appeng.api.implementations.items.IStorageCell;
|
||||
@@ -18,272 +13,222 @@ import appeng.api.storage.data.IAEStack;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AELog;
|
||||
import appeng.util.item.AEStack;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
|
||||
public class BasicCellInventory<T extends IAEStack<T>> extends AbstractCellInventory<T>
|
||||
{
|
||||
private final IStorageChannel<T> channel;
|
||||
public class BasicCellInventory<T extends IAEStack<T>> extends AbstractCellInventory<T> {
|
||||
private final IStorageChannel<T> channel;
|
||||
|
||||
private BasicCellInventory( final IStorageCell<T> cellType, final ItemStack o, final ISaveProvider container )
|
||||
{
|
||||
super( cellType, o, container );
|
||||
this.channel = cellType.getChannel();
|
||||
}
|
||||
private BasicCellInventory(final IStorageCell<T> cellType, final ItemStack o, final ISaveProvider container) {
|
||||
super(cellType, o, container);
|
||||
this.channel = cellType.getChannel();
|
||||
}
|
||||
|
||||
public static <T extends IAEStack<T>> ICellInventory<T> createInventory( final ItemStack o, final ISaveProvider container )
|
||||
{
|
||||
try
|
||||
{
|
||||
if( o == null )
|
||||
{
|
||||
throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" );
|
||||
}
|
||||
public static <T extends IAEStack<T>> ICellInventory<T> createInventory(final ItemStack o, final ISaveProvider container) {
|
||||
try {
|
||||
if (o == null) {
|
||||
throw new AppEngException("ItemStack was used as a cell, but was not a cell!");
|
||||
}
|
||||
|
||||
final Item type = o.getItem();
|
||||
final IStorageCell<T> cellType;
|
||||
if( type instanceof IStorageCell )
|
||||
{
|
||||
cellType = (IStorageCell<T>) type;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" );
|
||||
}
|
||||
final Item type = o.getItem();
|
||||
final IStorageCell<T> cellType;
|
||||
if (type instanceof IStorageCell) {
|
||||
cellType = (IStorageCell<T>) type;
|
||||
} else {
|
||||
throw new AppEngException("ItemStack was used as a cell, but was not a cell!");
|
||||
}
|
||||
|
||||
if( !cellType.isStorageCell( o ) )
|
||||
{
|
||||
throw new AppEngException( "ItemStack was used as a cell, but was not a cell!" );
|
||||
}
|
||||
if (!cellType.isStorageCell(o)) {
|
||||
throw new AppEngException("ItemStack was used as a cell, but was not a cell!");
|
||||
}
|
||||
|
||||
return new BasicCellInventory<T>( cellType, o, container );
|
||||
}
|
||||
catch( final AppEngException e )
|
||||
{
|
||||
AELog.error( e );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return new BasicCellInventory<T>(cellType, o, container);
|
||||
} catch (final AppEngException e) {
|
||||
AELog.error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends AEStack<T>> boolean isCellOfType( final ItemStack input, IStorageChannel<?> channel )
|
||||
{
|
||||
final IStorageCell<?> type = getStorageCell( input );
|
||||
public static <T extends AEStack<T>> boolean isCellOfType(final ItemStack input, IStorageChannel<?> channel) {
|
||||
final IStorageCell<?> type = getStorageCell(input);
|
||||
|
||||
return type != null && type.getChannel() == channel;
|
||||
}
|
||||
return type != null && type.getChannel() == channel;
|
||||
}
|
||||
|
||||
public static boolean isCell( final ItemStack input )
|
||||
{
|
||||
return getStorageCell( input ) != null;
|
||||
}
|
||||
public static boolean isCell(final ItemStack input) {
|
||||
return getStorageCell(input) != null;
|
||||
}
|
||||
|
||||
private boolean isStorageCell( final T input )
|
||||
{
|
||||
if( input instanceof IAEItemStack )
|
||||
{
|
||||
final IAEItemStack stack = (IAEItemStack) input;
|
||||
final IStorageCell<?> type = getStorageCell( stack.getDefinition() );
|
||||
private boolean isStorageCell(final T input) {
|
||||
if (input instanceof IAEItemStack) {
|
||||
final IAEItemStack stack = (IAEItemStack) input;
|
||||
final IStorageCell<?> type = getStorageCell(stack.getDefinition());
|
||||
|
||||
return type != null && !type.storableInStorageCell();
|
||||
}
|
||||
return type != null && !type.storableInStorageCell();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static IStorageCell<?> getStorageCell( final ItemStack input )
|
||||
{
|
||||
if( input != null )
|
||||
{
|
||||
final Item type = input.getItem();
|
||||
private static IStorageCell<?> getStorageCell(final ItemStack input) {
|
||||
if (input != null) {
|
||||
final Item type = input.getItem();
|
||||
|
||||
if( type instanceof IStorageCell )
|
||||
{
|
||||
return (IStorageCell<?>) type;
|
||||
}
|
||||
}
|
||||
if (type instanceof IStorageCell) {
|
||||
return (IStorageCell<?>) type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings( { "rawtypes", "unchecked" } )
|
||||
private static boolean isCellEmpty( ICellInventory inv )
|
||||
{
|
||||
if( inv != null )
|
||||
{
|
||||
return inv.getAvailableItems( inv.getChannel().createList() ).isEmpty();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private static boolean isCellEmpty(ICellInventory inv) {
|
||||
if (inv != null) {
|
||||
return inv.getAvailableItems(inv.getChannel().createList()).isEmpty();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T injectItems( T input, Actionable mode, IActionSource src )
|
||||
{
|
||||
if( input == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if( input.getStackSize() == 0 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public T injectItems(T input, Actionable mode, IActionSource src) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
if (input.getStackSize() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if( this.cellType.isBlackListed( this.getItemStack(), input ) )
|
||||
{
|
||||
return input;
|
||||
}
|
||||
// This is slightly hacky as it expects a read-only access, but fine for now.
|
||||
// TODO: Guarantee a read-only access. E.g. provide an isEmpty() method and ensure CellInventory does not write
|
||||
// any NBT data for empty cells instead of relying on an empty IItemContainer
|
||||
if( this.isStorageCell( input ) )
|
||||
{
|
||||
final ICellInventory<?> meInventory = createInventory( ( (IAEItemStack) input ).createItemStack(), null );
|
||||
if( !isCellEmpty( meInventory ) )
|
||||
{
|
||||
return input;
|
||||
}
|
||||
}
|
||||
if (this.cellType.isBlackListed(this.getItemStack(), input)) {
|
||||
return input;
|
||||
}
|
||||
// This is slightly hacky as it expects a read-only access, but fine for now.
|
||||
// TODO: Guarantee a read-only access. E.g. provide an isEmpty() method and ensure CellInventory does not write
|
||||
// any NBT data for empty cells instead of relying on an empty IItemContainer
|
||||
if (this.isStorageCell(input)) {
|
||||
final ICellInventory<?> meInventory = createInventory(((IAEItemStack) input).createItemStack(), null);
|
||||
if (!isCellEmpty(meInventory)) {
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
final T l = this.getCellItems().findPrecise( input );
|
||||
if( l != null )
|
||||
{
|
||||
final long remainingItemCount = this.getRemainingItemCount();
|
||||
if( remainingItemCount <= 0 )
|
||||
{
|
||||
return input;
|
||||
}
|
||||
final T l = this.getCellItems().findPrecise(input);
|
||||
if (l != null) {
|
||||
final long remainingItemCount = this.getRemainingItemCount();
|
||||
if (remainingItemCount <= 0) {
|
||||
return input;
|
||||
}
|
||||
|
||||
if( input.getStackSize() > remainingItemCount )
|
||||
{
|
||||
final T r = input.copy();
|
||||
r.setStackSize( r.getStackSize() - remainingItemCount );
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
l.setStackSize( l.getStackSize() + remainingItemCount );
|
||||
this.saveChanges();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
l.setStackSize( l.getStackSize() + input.getStackSize() );
|
||||
this.saveChanges();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (input.getStackSize() > remainingItemCount) {
|
||||
final T r = input.copy();
|
||||
r.setStackSize(r.getStackSize() - remainingItemCount);
|
||||
if (mode == Actionable.MODULATE) {
|
||||
l.setStackSize(l.getStackSize() + remainingItemCount);
|
||||
this.saveChanges();
|
||||
}
|
||||
return r;
|
||||
} else {
|
||||
if (mode == Actionable.MODULATE) {
|
||||
l.setStackSize(l.getStackSize() + input.getStackSize());
|
||||
this.saveChanges();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if( this.canHoldNewItem() ) // room for new type, and for at least one item!
|
||||
{
|
||||
final int remainingItemCount = (int) this.getRemainingItemCount() - this.getBytesPerType() * this.itemsPerByte;
|
||||
if( remainingItemCount > 0 )
|
||||
{
|
||||
if( input.getStackSize() > remainingItemCount )
|
||||
{
|
||||
final T toReturn = input.copy();
|
||||
toReturn.setStackSize( input.getStackSize() - remainingItemCount );
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
final T toWrite = input.copy();
|
||||
toWrite.setStackSize( remainingItemCount );
|
||||
if (this.canHoldNewItem()) // room for new type, and for at least one item!
|
||||
{
|
||||
final int remainingItemCount = (int) this.getRemainingItemCount() - this.getBytesPerType() * this.itemsPerByte;
|
||||
if (remainingItemCount > 0) {
|
||||
if (input.getStackSize() > remainingItemCount) {
|
||||
final T toReturn = input.copy();
|
||||
toReturn.setStackSize(input.getStackSize() - remainingItemCount);
|
||||
if (mode == Actionable.MODULATE) {
|
||||
final T toWrite = input.copy();
|
||||
toWrite.setStackSize(remainingItemCount);
|
||||
|
||||
this.cellItems.add( toWrite );
|
||||
this.saveChanges();
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
this.cellItems.add(toWrite);
|
||||
this.saveChanges();
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
this.cellItems.add( input );
|
||||
this.saveChanges();
|
||||
}
|
||||
if (mode == Actionable.MODULATE) {
|
||||
this.cellItems.add(input);
|
||||
this.saveChanges();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T extractItems( T request, Actionable mode, IActionSource src )
|
||||
{
|
||||
if( request == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public T extractItems(T request, Actionable mode, IActionSource src) {
|
||||
if (request == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final long size = Math.min( Integer.MAX_VALUE, request.getStackSize() );
|
||||
final long size = Math.min(Integer.MAX_VALUE, request.getStackSize());
|
||||
|
||||
T Results = null;
|
||||
T Results = null;
|
||||
|
||||
final T l = this.getCellItems().findPrecise( request );
|
||||
if( l != null )
|
||||
{
|
||||
Results = l.copy();
|
||||
final T l = this.getCellItems().findPrecise(request);
|
||||
if (l != null) {
|
||||
Results = l.copy();
|
||||
|
||||
if( l.getStackSize() <= size )
|
||||
{
|
||||
Results.setStackSize( l.getStackSize() );
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
l.setStackSize( 0 );
|
||||
this.saveChanges();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Results.setStackSize( size );
|
||||
if( mode == Actionable.MODULATE )
|
||||
{
|
||||
l.setStackSize( l.getStackSize() - size );
|
||||
this.saveChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (l.getStackSize() <= size) {
|
||||
Results.setStackSize(l.getStackSize());
|
||||
if (mode == Actionable.MODULATE) {
|
||||
l.setStackSize(0);
|
||||
this.saveChanges();
|
||||
}
|
||||
} else {
|
||||
Results.setStackSize(size);
|
||||
if (mode == Actionable.MODULATE) {
|
||||
l.setStackSize(l.getStackSize() - size);
|
||||
this.saveChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Results;
|
||||
}
|
||||
return Results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel<T> getChannel()
|
||||
{
|
||||
return this.channel;
|
||||
}
|
||||
@Override
|
||||
public IStorageChannel<T> getChannel() {
|
||||
return this.channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean loadCellItem( NBTTagCompound compoundTag, int stackSize )
|
||||
{
|
||||
// Now load the item stack
|
||||
final T t;
|
||||
try
|
||||
{
|
||||
t = this.getChannel().createFromNBT( compoundTag );
|
||||
if( t == null )
|
||||
{
|
||||
AELog.warn( "Removing item " + compoundTag + " from storage cell because the associated item type couldn't be found." );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch( Throwable ex )
|
||||
{
|
||||
if( AEConfig.instance().isRemoveCrashingItemsOnLoad() )
|
||||
{
|
||||
AELog.warn( ex, "Removing item " + compoundTag + " from storage cell because loading the ItemStack crashed." );
|
||||
return false;
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
@Override
|
||||
protected boolean loadCellItem(NBTTagCompound compoundTag, int stackSize) {
|
||||
// Now load the item stack
|
||||
final T t;
|
||||
try {
|
||||
t = this.getChannel().createFromNBT(compoundTag);
|
||||
if (t == null) {
|
||||
AELog.warn("Removing item " + compoundTag + " from storage cell because the associated item type couldn't be found.");
|
||||
return false;
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
if (AEConfig.instance().isRemoveCrashingItemsOnLoad()) {
|
||||
AELog.warn(ex, "Removing item " + compoundTag + " from storage cell because loading the ItemStack crashed.");
|
||||
return false;
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
|
||||
t.setStackSize( stackSize );
|
||||
t.setCraftable( false );
|
||||
t.setStackSize(stackSize);
|
||||
t.setCraftable(false);
|
||||
|
||||
if( stackSize > 0 )
|
||||
{
|
||||
this.cellItems.add( t );
|
||||
}
|
||||
if (stackSize > 0) {
|
||||
this.cellItems.add(t);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
package appeng.me.storage;
|
||||
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.config.IncludeExclude;
|
||||
import appeng.api.config.Upgrades;
|
||||
@@ -36,6 +32,9 @@ import appeng.api.storage.data.IItemList;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.prioritylist.FuzzyPriorityList;
|
||||
import appeng.util.prioritylist.PrecisePriorityList;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
|
||||
/**
|
||||
@@ -43,108 +42,88 @@ import appeng.util.prioritylist.PrecisePriorityList;
|
||||
* @version rv6 - 2018-01-23
|
||||
* @since rv6 2018-01-23
|
||||
*/
|
||||
public class BasicCellInventoryHandler<T extends IAEStack<T>> extends MEInventoryHandler<T> implements ICellInventoryHandler<T>
|
||||
{
|
||||
public BasicCellInventoryHandler( final IMEInventory c, final IStorageChannel<T> channel )
|
||||
{
|
||||
super( c, channel );
|
||||
public class BasicCellInventoryHandler<T extends IAEStack<T>> extends MEInventoryHandler<T> implements ICellInventoryHandler<T> {
|
||||
public BasicCellInventoryHandler(final IMEInventory c, final IStorageChannel<T> channel) {
|
||||
super(c, channel);
|
||||
|
||||
final ICellInventory ci = this.getCellInv();
|
||||
if( ci != null )
|
||||
{
|
||||
final IItemList<T> priorityList = channel.createList();
|
||||
final ICellInventory ci = this.getCellInv();
|
||||
if (ci != null) {
|
||||
final IItemList<T> priorityList = channel.createList();
|
||||
|
||||
final IItemHandler upgrades = ci.getUpgradesInventory();
|
||||
final IItemHandler config = ci.getConfigInventory();
|
||||
final FuzzyMode fzMode = ci.getFuzzyMode();
|
||||
final IItemHandler upgrades = ci.getUpgradesInventory();
|
||||
final IItemHandler config = ci.getConfigInventory();
|
||||
final FuzzyMode fzMode = ci.getFuzzyMode();
|
||||
|
||||
boolean hasInverter = false;
|
||||
boolean hasFuzzy = false;
|
||||
boolean hasInverter = false;
|
||||
boolean hasFuzzy = false;
|
||||
|
||||
for( int x = 0; x < upgrades.getSlots(); x++ )
|
||||
{
|
||||
final ItemStack is = upgrades.getStackInSlot( x );
|
||||
if( !is.isEmpty() && is.getItem() instanceof IUpgradeModule )
|
||||
{
|
||||
final Upgrades u = ( (IUpgradeModule) is.getItem() ).getType( is );
|
||||
if( u != null )
|
||||
{
|
||||
switch( u )
|
||||
{
|
||||
case FUZZY:
|
||||
hasFuzzy = true;
|
||||
break;
|
||||
case INVERTER:
|
||||
hasInverter = true;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < upgrades.getSlots(); x++) {
|
||||
final ItemStack is = upgrades.getStackInSlot(x);
|
||||
if (!is.isEmpty() && is.getItem() instanceof IUpgradeModule) {
|
||||
final Upgrades u = ((IUpgradeModule) is.getItem()).getType(is);
|
||||
if (u != null) {
|
||||
switch (u) {
|
||||
case FUZZY:
|
||||
hasFuzzy = true;
|
||||
break;
|
||||
case INVERTER:
|
||||
hasInverter = true;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( int x = 0; x < config.getSlots(); x++ )
|
||||
{
|
||||
final ItemStack is = config.getStackInSlot( x );
|
||||
if( !is.isEmpty() )
|
||||
{
|
||||
final T configItem = channel.createStack( is );
|
||||
if( configItem != null )
|
||||
{
|
||||
priorityList.add( configItem );
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < config.getSlots(); x++) {
|
||||
final ItemStack is = config.getStackInSlot(x);
|
||||
if (!is.isEmpty()) {
|
||||
final T configItem = channel.createStack(is);
|
||||
if (configItem != null) {
|
||||
priorityList.add(configItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setWhitelist( hasInverter ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST );
|
||||
this.setWhitelist(hasInverter ? IncludeExclude.BLACKLIST : IncludeExclude.WHITELIST);
|
||||
|
||||
if( !priorityList.isEmpty() )
|
||||
{
|
||||
if( hasFuzzy )
|
||||
{
|
||||
this.setPartitionList( new FuzzyPriorityList<>( priorityList, fzMode ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setPartitionList( new PrecisePriorityList<>( priorityList ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!priorityList.isEmpty()) {
|
||||
if (hasFuzzy) {
|
||||
this.setPartitionList(new FuzzyPriorityList<>(priorityList, fzMode));
|
||||
} else {
|
||||
this.setPartitionList(new PrecisePriorityList<>(priorityList));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICellInventory getCellInv()
|
||||
{
|
||||
Object o = this.getInternal();
|
||||
@Override
|
||||
public ICellInventory getCellInv() {
|
||||
Object o = this.getInternal();
|
||||
|
||||
if( o instanceof MEPassThrough )
|
||||
{
|
||||
o = ( (MEPassThrough) o ).getInternal();
|
||||
}
|
||||
if (o instanceof MEPassThrough) {
|
||||
o = ((MEPassThrough) o).getInternal();
|
||||
}
|
||||
|
||||
return (ICellInventory) ( o instanceof ICellInventory ? o : null );
|
||||
}
|
||||
return (ICellInventory) (o instanceof ICellInventory ? o : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreformatted()
|
||||
{
|
||||
return !this.getPartitionList().isEmpty();
|
||||
}
|
||||
@Override
|
||||
public boolean isPreformatted() {
|
||||
return !this.getPartitionList().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFuzzy()
|
||||
{
|
||||
return this.getPartitionList() instanceof FuzzyPriorityList;
|
||||
}
|
||||
@Override
|
||||
public boolean isFuzzy() {
|
||||
return this.getPartitionList() instanceof FuzzyPriorityList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IncludeExclude getIncludeExcludeMode()
|
||||
{
|
||||
return this.getWhitelist();
|
||||
}
|
||||
@Override
|
||||
public IncludeExclude getIncludeExcludeMode() {
|
||||
return this.getWhitelist();
|
||||
}
|
||||
|
||||
NBTTagCompound openNbtData()
|
||||
{
|
||||
return Platform.openNbtData( this.getCellInv().getItemStack() );
|
||||
}
|
||||
NBTTagCompound openNbtData() {
|
||||
return Platform.openNbtData(this.getCellInv().getItemStack());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
package appeng.me.storage;
|
||||
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Actionable;
|
||||
@@ -33,105 +31,88 @@ import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.items.contents.CellConfig;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
|
||||
public class CreativeCellInventory implements IMEInventoryHandler<IAEItemStack>
|
||||
{
|
||||
public class CreativeCellInventory implements IMEInventoryHandler<IAEItemStack> {
|
||||
|
||||
private final IItemList<IAEItemStack> itemListCache = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
private final IItemList<IAEItemStack> itemListCache = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
||||
|
||||
protected CreativeCellInventory( final ItemStack o )
|
||||
{
|
||||
final CellConfig cc = new CellConfig( o );
|
||||
for( final ItemStack is : cc )
|
||||
{
|
||||
if( !is.isEmpty() )
|
||||
{
|
||||
final IAEItemStack i = AEItemStack.fromItemStack( is );
|
||||
i.setStackSize( Integer.MAX_VALUE );
|
||||
this.itemListCache.add( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
protected CreativeCellInventory(final ItemStack o) {
|
||||
final CellConfig cc = new CellConfig(o);
|
||||
for (final ItemStack is : cc) {
|
||||
if (!is.isEmpty()) {
|
||||
final IAEItemStack i = AEItemStack.fromItemStack(is);
|
||||
i.setStackSize(Integer.MAX_VALUE);
|
||||
this.itemListCache.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ICellInventoryHandler getCell( final ItemStack o )
|
||||
{
|
||||
return new BasicCellInventoryHandler( new CreativeCellInventory( o ), AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
|
||||
}
|
||||
public static ICellInventoryHandler getCell(final ItemStack o) {
|
||||
return new BasicCellInventoryHandler(new CreativeCellInventory(o), AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEItemStack injectItems( final IAEItemStack input, final Actionable mode, final IActionSource src )
|
||||
{
|
||||
final IAEItemStack local = this.itemListCache.findPrecise( input );
|
||||
if( local == null )
|
||||
{
|
||||
return input;
|
||||
}
|
||||
@Override
|
||||
public IAEItemStack injectItems(final IAEItemStack input, final Actionable mode, final IActionSource src) {
|
||||
final IAEItemStack local = this.itemListCache.findPrecise(input);
|
||||
if (local == null) {
|
||||
return input;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEItemStack extractItems( final IAEItemStack request, final Actionable mode, final IActionSource src )
|
||||
{
|
||||
final IAEItemStack local = this.itemListCache.findPrecise( request );
|
||||
if( local == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public IAEItemStack extractItems(final IAEItemStack request, final Actionable mode, final IActionSource src) {
|
||||
final IAEItemStack local = this.itemListCache.findPrecise(request);
|
||||
if (local == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return request.copy();
|
||||
}
|
||||
return request.copy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<IAEItemStack> getAvailableItems( final IItemList out )
|
||||
{
|
||||
for( final IAEItemStack ais : this.itemListCache )
|
||||
{
|
||||
out.add( ais );
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@Override
|
||||
public IItemList<IAEItemStack> getAvailableItems(final IItemList out) {
|
||||
for (final IAEItemStack ais : this.itemListCache) {
|
||||
out.add(ais);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel getChannel()
|
||||
{
|
||||
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
|
||||
}
|
||||
@Override
|
||||
public IStorageChannel getChannel() {
|
||||
return AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessRestriction getAccess()
|
||||
{
|
||||
return AccessRestriction.READ_WRITE;
|
||||
}
|
||||
@Override
|
||||
public AccessRestriction getAccess() {
|
||||
return AccessRestriction.READ_WRITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrioritized( final IAEItemStack input )
|
||||
{
|
||||
return this.itemListCache.findPrecise( input ) != null;
|
||||
}
|
||||
@Override
|
||||
public boolean isPrioritized(final IAEItemStack input) {
|
||||
return this.itemListCache.findPrecise(input) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccept( final IAEItemStack input )
|
||||
{
|
||||
return this.itemListCache.findPrecise( input ) != null;
|
||||
}
|
||||
@Override
|
||||
public boolean canAccept(final IAEItemStack input) {
|
||||
return this.itemListCache.findPrecise(input) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlot()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getSlot() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validForPass( final int i )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean validForPass(final int i) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,101 +19,85 @@
|
||||
package appeng.me.storage;
|
||||
|
||||
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.storage.ICellHandler;
|
||||
import appeng.api.storage.ICellInventoryHandler;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.core.features.registries.cell.CreativeCellHandler;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.me.helpers.MachineSource;
|
||||
import appeng.tile.storage.TileDrive;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.storage.ICellHandler;
|
||||
import appeng.api.storage.ICellInventoryHandler;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
|
||||
public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
|
||||
{
|
||||
public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T> {
|
||||
|
||||
private int oldStatus = 0;
|
||||
private final ItemStack is;
|
||||
private final ICellHandler handler;
|
||||
private final TileDrive drive;
|
||||
private IActionSource source;
|
||||
private int oldStatus = 0;
|
||||
private final ItemStack is;
|
||||
private final ICellHandler handler;
|
||||
private final TileDrive drive;
|
||||
private final IActionSource source;
|
||||
|
||||
public DriveWatcher( final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final TileDrive drive )
|
||||
{
|
||||
super( i, i.getChannel() );
|
||||
this.is = is;
|
||||
this.handler = han;
|
||||
this.drive = drive;
|
||||
this.source = new MachineSource( drive );
|
||||
}
|
||||
public DriveWatcher(final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final TileDrive drive) {
|
||||
super(i, i.getChannel());
|
||||
this.is = is;
|
||||
this.handler = han;
|
||||
this.drive = drive;
|
||||
this.source = new MachineSource(drive);
|
||||
}
|
||||
|
||||
public int getStatus()
|
||||
{
|
||||
return this.handler.getStatusForCell( this.is, (ICellInventoryHandler) this.getInternal() );
|
||||
}
|
||||
public int getStatus() {
|
||||
return this.handler.getStatusForCell(this.is, (ICellInventoryHandler) this.getInternal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public T injectItems( final T input, final Actionable type, final IActionSource src )
|
||||
{
|
||||
final long size = input.getStackSize();
|
||||
@Override
|
||||
public T injectItems(final T input, final Actionable type, final IActionSource src) {
|
||||
final long size = input.getStackSize();
|
||||
|
||||
final T remainder = super.injectItems( input, type, src );
|
||||
final T remainder = super.injectItems(input, type, src);
|
||||
|
||||
if( type == Actionable.MODULATE && ( remainder == null || remainder.getStackSize() != size ) )
|
||||
{
|
||||
final int newStatus = this.getStatus();
|
||||
if (type == Actionable.MODULATE && (remainder == null || remainder.getStackSize() != size)) {
|
||||
final int newStatus = this.getStatus();
|
||||
|
||||
if( newStatus != this.oldStatus )
|
||||
{
|
||||
this.drive.blinkCell( this.getSlot() );
|
||||
this.oldStatus = newStatus;
|
||||
}
|
||||
if (this.drive.getProxy().isActive() && !(handler instanceof CreativeCellHandler))
|
||||
{
|
||||
try
|
||||
{
|
||||
this.drive.getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), Collections.singletonList( input.copy().setStackSize( input.getStackSize() - ( remainder == null ? 0 : remainder.getStackSize() ) ) ), this.source );
|
||||
} catch ( GridAccessException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newStatus != this.oldStatus) {
|
||||
this.drive.blinkCell(this.getSlot());
|
||||
this.oldStatus = newStatus;
|
||||
}
|
||||
if (this.drive.getProxy().isActive() && !(handler instanceof CreativeCellHandler)) {
|
||||
try {
|
||||
this.drive.getProxy().getStorage().postAlterationOfStoredItems(this.getChannel(), Collections.singletonList(input.copy().setStackSize(input.getStackSize() - (remainder == null ? 0 : remainder.getStackSize()))), this.source);
|
||||
} catch (GridAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return remainder;
|
||||
}
|
||||
return remainder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T extractItems( final T request, final Actionable type, final IActionSource src )
|
||||
{
|
||||
final T extractable = super.extractItems( request, type, src );
|
||||
@Override
|
||||
public T extractItems(final T request, final Actionable type, final IActionSource src) {
|
||||
final T extractable = super.extractItems(request, type, src);
|
||||
|
||||
if( type == Actionable.MODULATE && extractable != null )
|
||||
{
|
||||
final int newStatus = this.getStatus();
|
||||
if (type == Actionable.MODULATE && extractable != null) {
|
||||
final int newStatus = this.getStatus();
|
||||
|
||||
if( newStatus != this.oldStatus )
|
||||
{
|
||||
this.drive.blinkCell( this.getSlot() );
|
||||
this.oldStatus = newStatus;
|
||||
}
|
||||
if (this.drive.getProxy().isActive() && !(handler instanceof CreativeCellHandler ))
|
||||
{
|
||||
try
|
||||
{
|
||||
this.drive.getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), Collections.singletonList( request.copy().setStackSize( -extractable.getStackSize() ) ), this.source );
|
||||
} catch ( GridAccessException e )
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newStatus != this.oldStatus) {
|
||||
this.drive.blinkCell(this.getSlot());
|
||||
this.oldStatus = newStatus;
|
||||
}
|
||||
if (this.drive.getProxy().isActive() && !(handler instanceof CreativeCellHandler)) {
|
||||
try {
|
||||
this.drive.getProxy().getStorage().postAlterationOfStoredItems(this.getChannel(), Collections.singletonList(request.copy().setStackSize(-extractable.getStackSize())), this.source);
|
||||
} catch (GridAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return extractable;
|
||||
}
|
||||
return extractable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,15 +24,13 @@ import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.networking.ticking.TickRateModulation;
|
||||
|
||||
|
||||
public interface ITickingMonitor
|
||||
{
|
||||
public interface ITickingMonitor {
|
||||
|
||||
TickRateModulation onTick();
|
||||
TickRateModulation onTick();
|
||||
|
||||
void setActionSource( IActionSource actionSource );
|
||||
void setActionSource(IActionSource actionSource);
|
||||
|
||||
default void setMode( StorageFilter setting )
|
||||
{
|
||||
default void setMode(StorageFilter setting) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,63 +19,55 @@
|
||||
package appeng.me.storage;
|
||||
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import appeng.api.networking.storage.IStackWatcher;
|
||||
import appeng.api.networking.storage.IStackWatcherHost;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.me.cache.GridStorageCache;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* Maintain my interests, and a global watch list, they should always be fully synchronized.
|
||||
*/
|
||||
public class ItemWatcher implements IStackWatcher
|
||||
{
|
||||
public class ItemWatcher implements IStackWatcher {
|
||||
|
||||
private final GridStorageCache gsc;
|
||||
private final IStackWatcherHost myObject;
|
||||
private final Set<IAEStack> myInterests = new HashSet<>();
|
||||
private final GridStorageCache gsc;
|
||||
private final IStackWatcherHost myObject;
|
||||
private final Set<IAEStack> myInterests = new HashSet<>();
|
||||
|
||||
public ItemWatcher( final GridStorageCache cache, final IStackWatcherHost host )
|
||||
{
|
||||
this.gsc = cache;
|
||||
this.myObject = host;
|
||||
}
|
||||
public ItemWatcher(final GridStorageCache cache, final IStackWatcherHost host) {
|
||||
this.gsc = cache;
|
||||
this.myObject = host;
|
||||
}
|
||||
|
||||
public IStackWatcherHost getHost()
|
||||
{
|
||||
return this.myObject;
|
||||
}
|
||||
public IStackWatcherHost getHost() {
|
||||
return this.myObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add( final IAEStack e )
|
||||
{
|
||||
if( this.myInterests.contains( e ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean add(final IAEStack e) {
|
||||
if (this.myInterests.contains(e)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.myInterests.add( e.copy() ) && this.gsc.getInterestManager().put( e, this );
|
||||
}
|
||||
return this.myInterests.add(e.copy()) && this.gsc.getInterestManager().put(e, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove( final IAEStack o )
|
||||
{
|
||||
return this.myInterests.remove( o ) && this.gsc.getInterestManager().remove( o, this );
|
||||
}
|
||||
@Override
|
||||
public boolean remove(final IAEStack o) {
|
||||
return this.myInterests.remove(o) && this.gsc.getInterestManager().remove(o, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
final Iterator<IAEStack> i = this.myInterests.iterator();
|
||||
@Override
|
||||
public void reset() {
|
||||
final Iterator<IAEStack> i = this.myInterests.iterator();
|
||||
|
||||
while( i.hasNext() )
|
||||
{
|
||||
this.gsc.getInterestManager().remove( i.next(), this );
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
while (i.hasNext()) {
|
||||
this.gsc.getInterestManager().remove(i.next(), this);
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,168 +32,138 @@ import appeng.util.prioritylist.DefaultPriorityList;
|
||||
import appeng.util.prioritylist.IPartitionList;
|
||||
|
||||
|
||||
public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHandler<T>
|
||||
{
|
||||
public class MEInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHandler<T> {
|
||||
|
||||
private final IMEInventoryHandler<T> internal;
|
||||
private int myPriority;
|
||||
private IncludeExclude myWhitelist;
|
||||
private AccessRestriction myAccess;
|
||||
private IPartitionList<T> myPartitionList;
|
||||
private final IMEInventoryHandler<T> internal;
|
||||
private int myPriority;
|
||||
private IncludeExclude myWhitelist;
|
||||
private AccessRestriction myAccess;
|
||||
private IPartitionList<T> myPartitionList;
|
||||
|
||||
private AccessRestriction cachedAccessRestriction;
|
||||
private boolean hasReadAccess;
|
||||
private boolean hasWriteAccess;
|
||||
private AccessRestriction cachedAccessRestriction;
|
||||
private boolean hasReadAccess;
|
||||
private boolean hasWriteAccess;
|
||||
|
||||
public MEInventoryHandler( final IMEInventory<T> i, final IStorageChannel<T> channel )
|
||||
{
|
||||
if( i instanceof IMEInventoryHandler )
|
||||
{
|
||||
this.internal = (IMEInventoryHandler<T>) i;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.internal = new MEPassThrough<>( i, channel );
|
||||
}
|
||||
public MEInventoryHandler(final IMEInventory<T> i, final IStorageChannel<T> channel) {
|
||||
if (i instanceof IMEInventoryHandler) {
|
||||
this.internal = (IMEInventoryHandler<T>) i;
|
||||
} else {
|
||||
this.internal = new MEPassThrough<>(i, channel);
|
||||
}
|
||||
|
||||
this.myPriority = 0;
|
||||
this.myWhitelist = IncludeExclude.WHITELIST;
|
||||
this.setBaseAccess( AccessRestriction.READ_WRITE );
|
||||
this.myPartitionList = new DefaultPriorityList<>();
|
||||
}
|
||||
this.myPriority = 0;
|
||||
this.myWhitelist = IncludeExclude.WHITELIST;
|
||||
this.setBaseAccess(AccessRestriction.READ_WRITE);
|
||||
this.myPartitionList = new DefaultPriorityList<>();
|
||||
}
|
||||
|
||||
IncludeExclude getWhitelist()
|
||||
{
|
||||
return this.myWhitelist;
|
||||
}
|
||||
IncludeExclude getWhitelist() {
|
||||
return this.myWhitelist;
|
||||
}
|
||||
|
||||
public void setWhitelist( final IncludeExclude myWhitelist )
|
||||
{
|
||||
this.myWhitelist = myWhitelist;
|
||||
}
|
||||
public void setWhitelist(final IncludeExclude myWhitelist) {
|
||||
this.myWhitelist = myWhitelist;
|
||||
}
|
||||
|
||||
public AccessRestriction getBaseAccess()
|
||||
{
|
||||
return this.myAccess;
|
||||
}
|
||||
public AccessRestriction getBaseAccess() {
|
||||
return this.myAccess;
|
||||
}
|
||||
|
||||
public void setBaseAccess( final AccessRestriction myAccess )
|
||||
{
|
||||
this.myAccess = myAccess;
|
||||
this.cachedAccessRestriction = this.myAccess.restrictPermissions( this.internal.getAccess() );
|
||||
this.hasReadAccess = this.cachedAccessRestriction.hasPermission( AccessRestriction.READ );
|
||||
this.hasWriteAccess = this.cachedAccessRestriction.hasPermission( AccessRestriction.WRITE );
|
||||
}
|
||||
public void setBaseAccess(final AccessRestriction myAccess) {
|
||||
this.myAccess = myAccess;
|
||||
this.cachedAccessRestriction = this.myAccess.restrictPermissions(this.internal.getAccess());
|
||||
this.hasReadAccess = this.cachedAccessRestriction.hasPermission(AccessRestriction.READ);
|
||||
this.hasWriteAccess = this.cachedAccessRestriction.hasPermission(AccessRestriction.WRITE);
|
||||
}
|
||||
|
||||
IPartitionList<T> getPartitionList()
|
||||
{
|
||||
return this.myPartitionList;
|
||||
}
|
||||
IPartitionList<T> getPartitionList() {
|
||||
return this.myPartitionList;
|
||||
}
|
||||
|
||||
public void setPartitionList( final IPartitionList<T> myPartitionList )
|
||||
{
|
||||
this.myPartitionList = myPartitionList;
|
||||
}
|
||||
public void setPartitionList(final IPartitionList<T> myPartitionList) {
|
||||
this.myPartitionList = myPartitionList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T injectItems( final T input, final Actionable type, final IActionSource src )
|
||||
{
|
||||
if( !this.canAccept( input ) )
|
||||
{
|
||||
return input;
|
||||
}
|
||||
@Override
|
||||
public T injectItems(final T input, final Actionable type, final IActionSource src) {
|
||||
if (!this.canAccept(input)) {
|
||||
return input;
|
||||
}
|
||||
|
||||
return this.internal.injectItems( input, type, src );
|
||||
}
|
||||
return this.internal.injectItems(input, type, src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T extractItems( final T request, final Actionable type, final IActionSource src )
|
||||
{
|
||||
if( !this.hasReadAccess )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public T extractItems(final T request, final Actionable type, final IActionSource src) {
|
||||
if (!this.hasReadAccess) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.internal.extractItems( request, type, src );
|
||||
}
|
||||
return this.internal.extractItems(request, type, src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems( final IItemList<T> out )
|
||||
{
|
||||
if( !this.hasReadAccess )
|
||||
{
|
||||
return out;
|
||||
}
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems(final IItemList<T> out) {
|
||||
if (!this.hasReadAccess) {
|
||||
return out;
|
||||
}
|
||||
|
||||
return this.internal.getAvailableItems( out );
|
||||
}
|
||||
return this.internal.getAvailableItems(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel<T> getChannel()
|
||||
{
|
||||
return this.internal.getChannel();
|
||||
}
|
||||
@Override
|
||||
public IStorageChannel<T> getChannel() {
|
||||
return this.internal.getChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessRestriction getAccess()
|
||||
{
|
||||
return this.cachedAccessRestriction;
|
||||
}
|
||||
@Override
|
||||
public AccessRestriction getAccess() {
|
||||
return this.cachedAccessRestriction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrioritized( final T input )
|
||||
{
|
||||
if( this.myWhitelist == IncludeExclude.WHITELIST )
|
||||
{
|
||||
return this.myPartitionList.isListed( input ) || this.internal.isPrioritized( input );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean isPrioritized(final T input) {
|
||||
if (this.myWhitelist == IncludeExclude.WHITELIST) {
|
||||
return this.myPartitionList.isListed(input) || this.internal.isPrioritized(input);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccept( final T input )
|
||||
{
|
||||
if( !this.hasWriteAccess )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean canAccept(final T input) {
|
||||
if (!this.hasWriteAccess) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( this.myWhitelist == IncludeExclude.BLACKLIST && this.myPartitionList.isListed( input ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if( this.myPartitionList.isEmpty() || this.myWhitelist == IncludeExclude.BLACKLIST )
|
||||
{
|
||||
return this.internal.canAccept( input );
|
||||
}
|
||||
return this.myPartitionList.isListed( input ) && this.internal.canAccept( input );
|
||||
}
|
||||
if (this.myWhitelist == IncludeExclude.BLACKLIST && this.myPartitionList.isListed(input)) {
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return this.myPriority;
|
||||
}
|
||||
|
||||
public void setPriority( final int myPriority )
|
||||
{
|
||||
this.myPriority = myPriority;
|
||||
}
|
||||
public void setPriority(final int myPriority) {
|
||||
this.myPriority = myPriority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlot()
|
||||
{
|
||||
return this.internal.getSlot();
|
||||
}
|
||||
@Override
|
||||
public int getSlot() {
|
||||
return this.internal.getSlot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validForPass( final int i )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean validForPass(final int i) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public IMEInventory<T> getInternal()
|
||||
{
|
||||
return this.internal;
|
||||
}
|
||||
public IMEInventory<T> getInternal() {
|
||||
return this.internal;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,15 +19,6 @@
|
||||
package appeng.me.storage;
|
||||
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
|
||||
import appeng.fluids.util.AEFluidStack;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidTankProperties;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Actionable;
|
||||
@@ -40,234 +31,201 @@ import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.channels.IFluidStorageChannel;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.fluids.util.AEFluidStack;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidTankProperties;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITickingMonitor
|
||||
{
|
||||
private final IFluidHandler handler;
|
||||
private IItemList<IAEFluidStack> cache = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
|
||||
private final HashMap<IMEMonitorHandlerReceiver<IAEFluidStack>, Object> listeners = new HashMap<>();
|
||||
private IActionSource mySource;
|
||||
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
|
||||
public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITickingMonitor {
|
||||
private final IFluidHandler handler;
|
||||
private IItemList<IAEFluidStack> cache = AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class).createList();
|
||||
private final HashMap<IMEMonitorHandlerReceiver<IAEFluidStack>, Object> listeners = new HashMap<>();
|
||||
private IActionSource mySource;
|
||||
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
|
||||
|
||||
public MEMonitorIFluidHandler( final IFluidHandler handler )
|
||||
{
|
||||
this.handler = handler;
|
||||
}
|
||||
public MEMonitorIFluidHandler(final IFluidHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener( final IMEMonitorHandlerReceiver<IAEFluidStack> l, final Object verificationToken )
|
||||
{
|
||||
this.listeners.put( l, verificationToken );
|
||||
}
|
||||
@Override
|
||||
public void addListener(final IMEMonitorHandlerReceiver<IAEFluidStack> l, final Object verificationToken) {
|
||||
this.listeners.put(l, verificationToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener( final IMEMonitorHandlerReceiver<IAEFluidStack> l )
|
||||
{
|
||||
this.listeners.remove( l );
|
||||
}
|
||||
@Override
|
||||
public void removeListener(final IMEMonitorHandlerReceiver<IAEFluidStack> l) {
|
||||
this.listeners.remove(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEFluidStack injectItems( final IAEFluidStack input, final Actionable type, final IActionSource src )
|
||||
{
|
||||
final int filled = this.handler.fill( input.getFluidStack(), type == Actionable.MODULATE );
|
||||
@Override
|
||||
public IAEFluidStack injectItems(final IAEFluidStack input, final Actionable type, final IActionSource src) {
|
||||
final int filled = this.handler.fill(input.getFluidStack(), type == Actionable.MODULATE);
|
||||
|
||||
if( filled == 0 )
|
||||
{
|
||||
return input.copy();
|
||||
}
|
||||
if (filled == 0) {
|
||||
return input.copy();
|
||||
}
|
||||
|
||||
if( filled == input.getStackSize() )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (filled == input.getStackSize()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final IAEFluidStack o = input.copy();
|
||||
o.setStackSize( input.getStackSize() - filled );
|
||||
final IAEFluidStack o = input.copy();
|
||||
o.setStackSize(input.getStackSize() - filled);
|
||||
|
||||
if( type == Actionable.MODULATE )
|
||||
{
|
||||
IAEFluidStack added = o.copy();
|
||||
this.cache.add( added );
|
||||
this.postDifference( Collections.singletonList( added ) );
|
||||
this.onTick();
|
||||
}
|
||||
if (type == Actionable.MODULATE) {
|
||||
IAEFluidStack added = o.copy();
|
||||
this.cache.add(added);
|
||||
this.postDifference(Collections.singletonList(added));
|
||||
this.onTick();
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEFluidStack extractItems( final IAEFluidStack request, final Actionable type, final IActionSource src )
|
||||
{
|
||||
final FluidStack removed = this.handler.drain( request.getFluidStack(), type == Actionable.MODULATE );
|
||||
@Override
|
||||
public IAEFluidStack extractItems(final IAEFluidStack request, final Actionable type, final IActionSource src) {
|
||||
final FluidStack removed = this.handler.drain(request.getFluidStack(), type == Actionable.MODULATE);
|
||||
|
||||
if( removed == null || removed.amount == 0 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (removed == null || removed.amount == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final IAEFluidStack o = request.copy();
|
||||
o.setStackSize( removed.amount );
|
||||
final IAEFluidStack o = request.copy();
|
||||
o.setStackSize(removed.amount);
|
||||
|
||||
if( type == Actionable.MODULATE )
|
||||
{
|
||||
IAEFluidStack cachedStack = this.cache.findPrecise( request );
|
||||
if( cachedStack != null )
|
||||
{
|
||||
cachedStack.decStackSize( o.getStackSize() );
|
||||
this.postDifference( Collections.singletonList( o.copy().setStackSize( -o.getStackSize() ) ) );
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
if (type == Actionable.MODULATE) {
|
||||
IAEFluidStack cachedStack = this.cache.findPrecise(request);
|
||||
if (cachedStack != null) {
|
||||
cachedStack.decStackSize(o.getStackSize());
|
||||
this.postDifference(Collections.singletonList(o.copy().setStackSize(-o.getStackSize())));
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel getChannel()
|
||||
{
|
||||
return AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class );
|
||||
}
|
||||
@Override
|
||||
public IStorageChannel getChannel() {
|
||||
return AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickRateModulation onTick()
|
||||
{
|
||||
boolean changed = false;
|
||||
@Override
|
||||
public TickRateModulation onTick() {
|
||||
boolean changed = false;
|
||||
|
||||
final List<IAEFluidStack> changes = new ArrayList<>();
|
||||
final IFluidTankProperties[] tankProperties = this.handler.getTankProperties();
|
||||
final List<IAEFluidStack> changes = new ArrayList<>();
|
||||
final IFluidTankProperties[] tankProperties = this.handler.getTankProperties();
|
||||
|
||||
IItemList<IAEFluidStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
|
||||
IItemList<IAEFluidStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class).createList();
|
||||
|
||||
for( IFluidTankProperties tankProperty : tankProperties )
|
||||
{
|
||||
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && this.handler.drain( 1, false ) == null )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) );
|
||||
}
|
||||
for (IFluidTankProperties tankProperty : tankProperties) {
|
||||
if (this.mode == StorageFilter.EXTRACTABLE_ONLY && this.handler.drain(1, false) == null) {
|
||||
continue;
|
||||
}
|
||||
currentlyOnStorage.add(AEFluidStack.fromFluidStack(tankProperty.getContents()));
|
||||
}
|
||||
|
||||
for( final IAEFluidStack is : cache )
|
||||
{
|
||||
is.setStackSize( -is.getStackSize() );
|
||||
}
|
||||
for (final IAEFluidStack is : cache) {
|
||||
is.setStackSize(-is.getStackSize());
|
||||
}
|
||||
|
||||
for( final IAEFluidStack is : currentlyOnStorage )
|
||||
{
|
||||
cache.add( is );
|
||||
}
|
||||
for (final IAEFluidStack is : currentlyOnStorage) {
|
||||
cache.add(is);
|
||||
}
|
||||
|
||||
for( final IAEFluidStack is : cache )
|
||||
{
|
||||
if( is.getStackSize() != 0 )
|
||||
{
|
||||
changes.add( is );
|
||||
}
|
||||
}
|
||||
for (final IAEFluidStack is : cache) {
|
||||
if (is.getStackSize() != 0) {
|
||||
changes.add(is);
|
||||
}
|
||||
}
|
||||
|
||||
cache = currentlyOnStorage;
|
||||
cache = currentlyOnStorage;
|
||||
|
||||
if( !changes.isEmpty() )
|
||||
{
|
||||
this.postDifference( changes );
|
||||
changed = true;
|
||||
}
|
||||
if (!changes.isEmpty()) {
|
||||
this.postDifference(changes);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
|
||||
}
|
||||
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
|
||||
}
|
||||
|
||||
private void postDifference( final Iterable<IAEFluidStack> a )
|
||||
{
|
||||
if( a != null )
|
||||
{
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<IAEFluidStack>, Object>> i = this.listeners.entrySet().iterator();
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final Entry<IMEMonitorHandlerReceiver<IAEFluidStack>, Object> l = i.next();
|
||||
final IMEMonitorHandlerReceiver<IAEFluidStack> key = l.getKey();
|
||||
if( key.isValid( l.getValue() ) )
|
||||
{
|
||||
key.postChange( this, a, this.getActionSource() );
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void postDifference(final Iterable<IAEFluidStack> a) {
|
||||
if (a != null) {
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<IAEFluidStack>, Object>> i = this.listeners.entrySet().iterator();
|
||||
while (i.hasNext()) {
|
||||
final Entry<IMEMonitorHandlerReceiver<IAEFluidStack>, Object> l = i.next();
|
||||
final IMEMonitorHandlerReceiver<IAEFluidStack> key = l.getKey();
|
||||
if (key.isValid(l.getValue())) {
|
||||
key.postChange(this, a, this.getActionSource());
|
||||
} else {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessRestriction getAccess()
|
||||
{
|
||||
return AccessRestriction.READ_WRITE;
|
||||
}
|
||||
@Override
|
||||
public AccessRestriction getAccess() {
|
||||
return AccessRestriction.READ_WRITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrioritized( final IAEFluidStack input )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean isPrioritized(final IAEFluidStack input) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccept( final IAEFluidStack input )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean canAccept(final IAEFluidStack input) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlot()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getSlot() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validForPass( final int i )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean validForPass(final int i) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<IAEFluidStack> getAvailableItems( final IItemList out )
|
||||
{
|
||||
for( final IAEFluidStack fs : cache )
|
||||
{
|
||||
out.addStorage( fs );
|
||||
}
|
||||
@Override
|
||||
public IItemList<IAEFluidStack> getAvailableItems(final IItemList out) {
|
||||
for (final IAEFluidStack fs : cache) {
|
||||
out.addStorage(fs);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<IAEFluidStack> getStorageList()
|
||||
{
|
||||
return this.cache;
|
||||
}
|
||||
@Override
|
||||
public IItemList<IAEFluidStack> getStorageList() {
|
||||
return this.cache;
|
||||
}
|
||||
|
||||
private StorageFilter getMode()
|
||||
{
|
||||
return this.mode;
|
||||
}
|
||||
private StorageFilter getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
public void setMode( final StorageFilter mode )
|
||||
{
|
||||
this.mode = mode;
|
||||
}
|
||||
public void setMode(final StorageFilter mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
private IActionSource getActionSource()
|
||||
{
|
||||
return this.mySource;
|
||||
}
|
||||
private IActionSource getActionSource() {
|
||||
return this.mySource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionSource( final IActionSource mySource )
|
||||
{
|
||||
this.mySource = mySource;
|
||||
}
|
||||
@Override
|
||||
public void setActionSource(final IActionSource mySource) {
|
||||
this.mySource = mySource;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,12 +19,6 @@
|
||||
package appeng.me.storage;
|
||||
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Actionable;
|
||||
@@ -38,254 +32,212 @@ import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.util.InventoryAdaptor;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.inv.ItemSlot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMonitor
|
||||
{
|
||||
public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMonitor {
|
||||
|
||||
private final InventoryAdaptor adaptor;
|
||||
private IItemList<IAEItemStack> cache = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
private final InventoryAdaptor adaptor;
|
||||
private IItemList<IAEItemStack> cache = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
||||
|
||||
private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
|
||||
private IActionSource mySource;
|
||||
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
|
||||
private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
|
||||
private IActionSource mySource;
|
||||
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
|
||||
|
||||
public MEMonitorIInventory( final InventoryAdaptor adaptor )
|
||||
{
|
||||
this.adaptor = adaptor;
|
||||
}
|
||||
public MEMonitorIInventory(final InventoryAdaptor adaptor) {
|
||||
this.adaptor = adaptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener( final IMEMonitorHandlerReceiver<IAEItemStack> l, final Object verificationToken )
|
||||
{
|
||||
this.listeners.put( l, verificationToken );
|
||||
}
|
||||
@Override
|
||||
public void addListener(final IMEMonitorHandlerReceiver<IAEItemStack> l, final Object verificationToken) {
|
||||
this.listeners.put(l, verificationToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener( final IMEMonitorHandlerReceiver<IAEItemStack> l )
|
||||
{
|
||||
this.listeners.remove( l );
|
||||
}
|
||||
@Override
|
||||
public void removeListener(final IMEMonitorHandlerReceiver<IAEItemStack> l) {
|
||||
this.listeners.remove(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEItemStack injectItems( final IAEItemStack input, final Actionable type, final IActionSource src )
|
||||
{
|
||||
ItemStack out = ItemStack.EMPTY;
|
||||
@Override
|
||||
public IAEItemStack injectItems(final IAEItemStack input, final Actionable type, final IActionSource src) {
|
||||
ItemStack out = ItemStack.EMPTY;
|
||||
|
||||
if( type == Actionable.SIMULATE )
|
||||
{
|
||||
out = this.adaptor.simulateAdd( input.createItemStack() );
|
||||
}
|
||||
else
|
||||
{
|
||||
out = this.adaptor.addItems( input.createItemStack() );
|
||||
}
|
||||
if (type == Actionable.SIMULATE) {
|
||||
out = this.adaptor.simulateAdd(input.createItemStack());
|
||||
} else {
|
||||
out = this.adaptor.addItems(input.createItemStack());
|
||||
}
|
||||
|
||||
if( out.isEmpty() )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (out.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// better then doing construction from scratch :3
|
||||
final IAEItemStack o = input.copy();
|
||||
o.setStackSize( out.getCount() );
|
||||
// better then doing construction from scratch :3
|
||||
final IAEItemStack o = input.copy();
|
||||
o.setStackSize(out.getCount());
|
||||
|
||||
if( type == Actionable.MODULATE )
|
||||
{
|
||||
IAEItemStack added = o.copy();
|
||||
this.cache.add( added );
|
||||
this.postDifference( Collections.singletonList( added ) );
|
||||
this.onTick();
|
||||
}
|
||||
if (type == Actionable.MODULATE) {
|
||||
IAEItemStack added = o.copy();
|
||||
this.cache.add(added);
|
||||
this.postDifference(Collections.singletonList(added));
|
||||
this.onTick();
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEItemStack extractItems( final IAEItemStack request, final Actionable type, final IActionSource src )
|
||||
{
|
||||
ItemStack out = ItemStack.EMPTY;
|
||||
@Override
|
||||
public IAEItemStack extractItems(final IAEItemStack request, final Actionable type, final IActionSource src) {
|
||||
ItemStack out = ItemStack.EMPTY;
|
||||
|
||||
if( type == Actionable.SIMULATE )
|
||||
{
|
||||
out = this.adaptor.simulateRemove( (int) request.getStackSize(), request.getDefinition(), null );
|
||||
}
|
||||
else
|
||||
{
|
||||
out = this.adaptor.removeItems( (int) request.getStackSize(), request.getDefinition(), null );
|
||||
}
|
||||
if (type == Actionable.SIMULATE) {
|
||||
out = this.adaptor.simulateRemove((int) request.getStackSize(), request.getDefinition(), null);
|
||||
} else {
|
||||
out = this.adaptor.removeItems((int) request.getStackSize(), request.getDefinition(), null);
|
||||
}
|
||||
|
||||
if( out.isEmpty() )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (out.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// better then doing construction from scratch :3
|
||||
final IAEItemStack o = request.copy();
|
||||
o.setStackSize( out.getCount() );
|
||||
// better then doing construction from scratch :3
|
||||
final IAEItemStack o = request.copy();
|
||||
o.setStackSize(out.getCount());
|
||||
|
||||
if( type == Actionable.MODULATE )
|
||||
{
|
||||
IAEItemStack cachedStack = this.cache.findPrecise( request );
|
||||
if( cachedStack != null )
|
||||
{
|
||||
cachedStack.decStackSize( o.getStackSize() );
|
||||
this.postDifference( Collections.singletonList( o.copy().setStackSize( -o.getStackSize() ) ) );
|
||||
}
|
||||
this.onTick();
|
||||
}
|
||||
if (type == Actionable.MODULATE) {
|
||||
IAEItemStack cachedStack = this.cache.findPrecise(request);
|
||||
if (cachedStack != null) {
|
||||
cachedStack.decStackSize(o.getStackSize());
|
||||
this.postDifference(Collections.singletonList(o.copy().setStackSize(-o.getStackSize())));
|
||||
}
|
||||
this.onTick();
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel getChannel()
|
||||
{
|
||||
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
|
||||
}
|
||||
@Override
|
||||
public IStorageChannel getChannel() {
|
||||
return AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TickRateModulation onTick()
|
||||
{
|
||||
boolean changed = false;
|
||||
@Override
|
||||
public TickRateModulation onTick() {
|
||||
boolean changed = false;
|
||||
|
||||
final List<IAEItemStack> changes = new ArrayList<>();
|
||||
final List<IAEItemStack> changes = new ArrayList<>();
|
||||
|
||||
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
||||
|
||||
for( final ItemSlot is : adaptor )
|
||||
{
|
||||
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
currentlyOnStorage.add( is.getAEItemStack() );
|
||||
}
|
||||
for (final ItemSlot is : adaptor) {
|
||||
if (this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable()) {
|
||||
continue;
|
||||
}
|
||||
currentlyOnStorage.add(is.getAEItemStack());
|
||||
}
|
||||
|
||||
for( final IAEItemStack is : cache )
|
||||
{
|
||||
is.setStackSize( -is.getStackSize() );
|
||||
}
|
||||
for (final IAEItemStack is : cache) {
|
||||
is.setStackSize(-is.getStackSize());
|
||||
}
|
||||
|
||||
for( final IAEItemStack is : currentlyOnStorage )
|
||||
{
|
||||
cache.add( is );
|
||||
}
|
||||
for (final IAEItemStack is : currentlyOnStorage) {
|
||||
cache.add(is);
|
||||
}
|
||||
|
||||
for( final IAEItemStack is : cache )
|
||||
{
|
||||
if( is.getStackSize() != 0 )
|
||||
{
|
||||
changes.add( is );
|
||||
}
|
||||
}
|
||||
for (final IAEItemStack is : cache) {
|
||||
if (is.getStackSize() != 0) {
|
||||
changes.add(is);
|
||||
}
|
||||
}
|
||||
|
||||
cache = currentlyOnStorage;
|
||||
cache = currentlyOnStorage;
|
||||
|
||||
if( !changes.isEmpty() )
|
||||
{
|
||||
this.postDifference( changes );
|
||||
changed = true;
|
||||
}
|
||||
if (!changes.isEmpty()) {
|
||||
this.postDifference(changes);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
|
||||
}
|
||||
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
|
||||
}
|
||||
|
||||
private void postDifference( final Iterable<IAEItemStack> a )
|
||||
{
|
||||
if( a != null )
|
||||
{
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
|
||||
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
|
||||
if( key.isValid( l.getValue() ) )
|
||||
{
|
||||
key.postChange( this, a, this.getActionSource() );
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void postDifference(final Iterable<IAEItemStack> a) {
|
||||
if (a != null) {
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
|
||||
while (i.hasNext()) {
|
||||
final Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object> l = i.next();
|
||||
final IMEMonitorHandlerReceiver<IAEItemStack> key = l.getKey();
|
||||
if (key.isValid(l.getValue())) {
|
||||
key.postChange(this, a, this.getActionSource());
|
||||
} else {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessRestriction getAccess()
|
||||
{
|
||||
return AccessRestriction.READ_WRITE;
|
||||
}
|
||||
@Override
|
||||
public AccessRestriction getAccess() {
|
||||
return AccessRestriction.READ_WRITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrioritized( final IAEItemStack input )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean isPrioritized(final IAEItemStack input) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccept( final IAEItemStack input )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean canAccept(final IAEItemStack input) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlot()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getSlot() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validForPass( final int i )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean validForPass(final int i) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<IAEItemStack> getAvailableItems( final IItemList out )
|
||||
{
|
||||
for( IAEItemStack is : cache )
|
||||
{
|
||||
out.addStorage( is );
|
||||
}
|
||||
@Override
|
||||
public IItemList<IAEItemStack> getAvailableItems(final IItemList out) {
|
||||
for (IAEItemStack is : cache) {
|
||||
out.addStorage(is);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<IAEItemStack> getStorageList()
|
||||
{
|
||||
return this.cache;
|
||||
}
|
||||
@Override
|
||||
public IItemList<IAEItemStack> getStorageList() {
|
||||
return this.cache;
|
||||
}
|
||||
|
||||
private StorageFilter getMode()
|
||||
{
|
||||
return this.mode;
|
||||
}
|
||||
private StorageFilter getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
public void setMode( final StorageFilter mode )
|
||||
{
|
||||
this.mode = mode;
|
||||
}
|
||||
public void setMode(final StorageFilter mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
private IActionSource getActionSource()
|
||||
{
|
||||
return this.mySource;
|
||||
}
|
||||
private IActionSource getActionSource() {
|
||||
return this.mySource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionSource( final IActionSource mySource )
|
||||
{
|
||||
this.mySource = mySource;
|
||||
}
|
||||
@Override
|
||||
public void setActionSource(final IActionSource mySource) {
|
||||
this.mySource = mySource;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
package appeng.me.storage;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.networking.storage.IBaseMonitor;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
@@ -34,142 +30,119 @@ import appeng.api.storage.data.IItemList;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.inv.ItemListIgnoreCrafting;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T> implements IMEMonitor<T>, IMEMonitorHandlerReceiver<T>
|
||||
{
|
||||
|
||||
private final HashMap<IMEMonitorHandlerReceiver<T>, Object> listeners = new HashMap<>();
|
||||
private IActionSource changeSource;
|
||||
private IMEMonitor<T> monitor;
|
||||
public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T> implements IMEMonitor<T>, IMEMonitorHandlerReceiver<T> {
|
||||
|
||||
public MEMonitorPassThrough( final IMEInventory<T> i, final IStorageChannel channel )
|
||||
{
|
||||
super( i, channel );
|
||||
if( i instanceof IMEMonitor )
|
||||
{
|
||||
this.monitor = (IMEMonitor<T>) i;
|
||||
}
|
||||
}
|
||||
private final HashMap<IMEMonitorHandlerReceiver<T>, Object> listeners = new HashMap<>();
|
||||
private IActionSource changeSource;
|
||||
private IMEMonitor<T> monitor;
|
||||
|
||||
@Override
|
||||
public void setInternal( final IMEInventory<T> i )
|
||||
{
|
||||
if( this.monitor != null )
|
||||
{
|
||||
this.monitor.removeListener( this );
|
||||
}
|
||||
public MEMonitorPassThrough(final IMEInventory<T> i, final IStorageChannel channel) {
|
||||
super(i, channel);
|
||||
if (i instanceof IMEMonitor) {
|
||||
this.monitor = (IMEMonitor<T>) i;
|
||||
}
|
||||
}
|
||||
|
||||
this.monitor = null;
|
||||
final IItemList<T> before = this.getInternal() == null ? this.getWrappedChannel().createList() : this.getInternal()
|
||||
.getAvailableItems( new ItemListIgnoreCrafting( this.getWrappedChannel().createList() ) );
|
||||
@Override
|
||||
public void setInternal(final IMEInventory<T> i) {
|
||||
if (this.monitor != null) {
|
||||
this.monitor.removeListener(this);
|
||||
}
|
||||
|
||||
super.setInternal( i );
|
||||
if( i instanceof IMEMonitor )
|
||||
{
|
||||
this.monitor = (IMEMonitor<T>) i;
|
||||
}
|
||||
this.monitor = null;
|
||||
final IItemList<T> before = this.getInternal() == null ? this.getWrappedChannel().createList() : this.getInternal()
|
||||
.getAvailableItems(new ItemListIgnoreCrafting(this.getWrappedChannel().createList()));
|
||||
|
||||
final IItemList<T> after = this.getInternal() == null ? this.getWrappedChannel().createList() : this.getInternal()
|
||||
.getAvailableItems( new ItemListIgnoreCrafting( this.getWrappedChannel().createList() ) );
|
||||
super.setInternal(i);
|
||||
if (i instanceof IMEMonitor) {
|
||||
this.monitor = (IMEMonitor<T>) i;
|
||||
}
|
||||
|
||||
if( this.monitor != null && this.listeners.size() > 0 )
|
||||
{
|
||||
this.monitor.addListener( this, this.monitor );
|
||||
}
|
||||
final IItemList<T> after = this.getInternal() == null ? this.getWrappedChannel().createList() : this.getInternal()
|
||||
.getAvailableItems(new ItemListIgnoreCrafting(this.getWrappedChannel().createList()));
|
||||
|
||||
Platform.postListChanges( before, after, this, this.getChangeSource() );
|
||||
}
|
||||
if (this.monitor != null && this.listeners.size() > 0) {
|
||||
this.monitor.addListener(this, this.monitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems( final IItemList out )
|
||||
{
|
||||
super.getAvailableItems( new ItemListIgnoreCrafting( out ) );
|
||||
return out;
|
||||
}
|
||||
Platform.postListChanges(before, after, this, this.getChangeSource());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener( final IMEMonitorHandlerReceiver<T> l, final Object verificationToken )
|
||||
{
|
||||
if( this.listeners.size() == 0 )
|
||||
{
|
||||
if( this.monitor != null )
|
||||
{
|
||||
this.monitor.addListener( this, this.monitor );
|
||||
}
|
||||
}
|
||||
this.listeners.put( l, verificationToken );
|
||||
}
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems(final IItemList out) {
|
||||
super.getAvailableItems(new ItemListIgnoreCrafting(out));
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener( final IMEMonitorHandlerReceiver<T> l )
|
||||
{
|
||||
this.listeners.remove( l );
|
||||
}
|
||||
@Override
|
||||
public void addListener(final IMEMonitorHandlerReceiver<T> l, final Object verificationToken) {
|
||||
if (this.listeners.size() == 0) {
|
||||
if (this.monitor != null) {
|
||||
this.monitor.addListener(this, this.monitor);
|
||||
}
|
||||
}
|
||||
this.listeners.put(l, verificationToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<T> getStorageList()
|
||||
{
|
||||
if( this.monitor == null )
|
||||
{
|
||||
final IItemList<T> out = this.getWrappedChannel().createList();
|
||||
this.getInternal().getAvailableItems( new ItemListIgnoreCrafting( out ) );
|
||||
return out;
|
||||
}
|
||||
return this.monitor.getStorageList();
|
||||
}
|
||||
@Override
|
||||
public void removeListener(final IMEMonitorHandlerReceiver<T> l) {
|
||||
this.listeners.remove(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid( final Object verificationToken )
|
||||
{
|
||||
return verificationToken == this.monitor;
|
||||
}
|
||||
@Override
|
||||
public IItemList<T> getStorageList() {
|
||||
if (this.monitor == null) {
|
||||
final IItemList<T> out = this.getWrappedChannel().createList();
|
||||
this.getInternal().getAvailableItems(new ItemListIgnoreCrafting(out));
|
||||
return out;
|
||||
}
|
||||
return this.monitor.getStorageList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postChange( final IBaseMonitor<T> monitor, final Iterable<T> change, final IActionSource source )
|
||||
{
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.listeners.entrySet().iterator();
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final Entry<IMEMonitorHandlerReceiver<T>, Object> e = i.next();
|
||||
final IMEMonitorHandlerReceiver<T> receiver = e.getKey();
|
||||
if( receiver.isValid( e.getValue() ) )
|
||||
{
|
||||
receiver.postChange( this, change, source );
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean isValid(final Object verificationToken) {
|
||||
return verificationToken == this.monitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListUpdate()
|
||||
{
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.listeners.entrySet().iterator();
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final Entry<IMEMonitorHandlerReceiver<T>, Object> e = i.next();
|
||||
final IMEMonitorHandlerReceiver<T> receiver = e.getKey();
|
||||
if( receiver.isValid( e.getValue() ) )
|
||||
{
|
||||
receiver.onListUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void postChange(final IBaseMonitor<T> monitor, final Iterable<T> change, final IActionSource source) {
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.listeners.entrySet().iterator();
|
||||
while (i.hasNext()) {
|
||||
final Entry<IMEMonitorHandlerReceiver<T>, Object> e = i.next();
|
||||
final IMEMonitorHandlerReceiver<T> receiver = e.getKey();
|
||||
if (receiver.isValid(e.getValue())) {
|
||||
receiver.postChange(this, change, source);
|
||||
} else {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IActionSource getChangeSource()
|
||||
{
|
||||
return this.changeSource;
|
||||
}
|
||||
@Override
|
||||
public void onListUpdate() {
|
||||
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.listeners.entrySet().iterator();
|
||||
while (i.hasNext()) {
|
||||
final Entry<IMEMonitorHandlerReceiver<T>, Object> e = i.next();
|
||||
final IMEMonitorHandlerReceiver<T> receiver = e.getKey();
|
||||
if (receiver.isValid(e.getValue())) {
|
||||
receiver.onListUpdate();
|
||||
} else {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setChangeSource( final IActionSource changeSource )
|
||||
{
|
||||
this.changeSource = changeSource;
|
||||
}
|
||||
private IActionSource getChangeSource() {
|
||||
return this.changeSource;
|
||||
}
|
||||
|
||||
public void setChangeSource(final IActionSource changeSource) {
|
||||
this.changeSource = changeSource;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,90 +29,75 @@ import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
|
||||
|
||||
public class MEPassThrough<T extends IAEStack<T>> implements IMEInventoryHandler<T>
|
||||
{
|
||||
public class MEPassThrough<T extends IAEStack<T>> implements IMEInventoryHandler<T> {
|
||||
|
||||
private final IStorageChannel wrappedChannel;
|
||||
private IMEInventory<T> internal;
|
||||
private final IStorageChannel wrappedChannel;
|
||||
private IMEInventory<T> internal;
|
||||
|
||||
public MEPassThrough( final IMEInventory<T> i, final IStorageChannel channel )
|
||||
{
|
||||
this.wrappedChannel = channel;
|
||||
this.setInternal( i );
|
||||
}
|
||||
public MEPassThrough(final IMEInventory<T> i, final IStorageChannel channel) {
|
||||
this.wrappedChannel = channel;
|
||||
this.setInternal(i);
|
||||
}
|
||||
|
||||
public IMEInventory<T> getInternal()
|
||||
{
|
||||
return this.internal;
|
||||
}
|
||||
public IMEInventory<T> getInternal() {
|
||||
return this.internal;
|
||||
}
|
||||
|
||||
public void setInternal( final IMEInventory<T> i )
|
||||
{
|
||||
this.internal = i;
|
||||
}
|
||||
public void setInternal(final IMEInventory<T> i) {
|
||||
this.internal = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T injectItems( final T input, final Actionable type, final IActionSource src )
|
||||
{
|
||||
return this.internal.injectItems( input, type, src );
|
||||
}
|
||||
@Override
|
||||
public T injectItems(final T input, final Actionable type, final IActionSource src) {
|
||||
return this.internal.injectItems(input, type, src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T extractItems( final T request, final Actionable type, final IActionSource src )
|
||||
{
|
||||
return this.internal.extractItems( request, type, src );
|
||||
}
|
||||
@Override
|
||||
public T extractItems(final T request, final Actionable type, final IActionSource src) {
|
||||
return this.internal.extractItems(request, type, src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems( final IItemList out )
|
||||
{
|
||||
return this.internal.getAvailableItems( out );
|
||||
}
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems(final IItemList out) {
|
||||
return this.internal.getAvailableItems(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel getChannel()
|
||||
{
|
||||
return this.internal.getChannel();
|
||||
}
|
||||
@Override
|
||||
public IStorageChannel getChannel() {
|
||||
return this.internal.getChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessRestriction getAccess()
|
||||
{
|
||||
return AccessRestriction.READ_WRITE;
|
||||
}
|
||||
@Override
|
||||
public AccessRestriction getAccess() {
|
||||
return AccessRestriction.READ_WRITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrioritized( final T input )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean isPrioritized(final T input) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccept( final T input )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean canAccept(final T input) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlot()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getSlot() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validForPass( final int i )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean validForPass(final int i) {
|
||||
return true;
|
||||
}
|
||||
|
||||
IStorageChannel getWrappedChannel()
|
||||
{
|
||||
return this.wrappedChannel;
|
||||
}
|
||||
IStorageChannel getWrappedChannel() {
|
||||
return this.wrappedChannel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,15 +19,6 @@
|
||||
package appeng.me.storage;
|
||||
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
@@ -41,289 +32,236 @@ import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.me.cache.SecurityCache;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHandler<T>
|
||||
{
|
||||
|
||||
private static final ThreadLocal<Deque> DEPTH_MOD = new ThreadLocal<>();
|
||||
private static final ThreadLocal<Deque> DEPTH_SIM = new ThreadLocal<>();
|
||||
private static final Comparator<Integer> PRIORITY_SORTER = ( o1, o2 ) -> Integer.compare( o2, o1 );
|
||||
public class NetworkInventoryHandler<T extends IAEStack<T>> implements IMEInventoryHandler<T> {
|
||||
|
||||
private static int currentPass = 0;
|
||||
private final IStorageChannel<T> myChannel;
|
||||
private final SecurityCache security;
|
||||
private final NavigableMap<Integer, List<IMEInventoryHandler<T>>> priorityInventory;
|
||||
private int myPass = 0;
|
||||
private static final ThreadLocal<Deque> DEPTH_MOD = new ThreadLocal<>();
|
||||
private static final ThreadLocal<Deque> DEPTH_SIM = new ThreadLocal<>();
|
||||
private static final Comparator<Integer> PRIORITY_SORTER = (o1, o2) -> Integer.compare(o2, o1);
|
||||
|
||||
public NetworkInventoryHandler( final IStorageChannel<T> chan, final SecurityCache security )
|
||||
{
|
||||
this.myChannel = chan;
|
||||
this.security = security;
|
||||
this.priorityInventory = new TreeMap<>( PRIORITY_SORTER );
|
||||
}
|
||||
private static int currentPass = 0;
|
||||
private final IStorageChannel<T> myChannel;
|
||||
private final SecurityCache security;
|
||||
private final NavigableMap<Integer, List<IMEInventoryHandler<T>>> priorityInventory;
|
||||
private int myPass = 0;
|
||||
|
||||
public void addNewStorage( final IMEInventoryHandler<T> h )
|
||||
{
|
||||
final int priority = h.getPriority();
|
||||
List<IMEInventoryHandler<T>> list = this.priorityInventory.get( priority );
|
||||
if( list == null )
|
||||
{
|
||||
this.priorityInventory.put( priority, list = new ArrayList<>() );
|
||||
}
|
||||
public NetworkInventoryHandler(final IStorageChannel<T> chan, final SecurityCache security) {
|
||||
this.myChannel = chan;
|
||||
this.security = security;
|
||||
this.priorityInventory = new TreeMap<>(PRIORITY_SORTER);
|
||||
}
|
||||
|
||||
list.add( h );
|
||||
}
|
||||
public void addNewStorage(final IMEInventoryHandler<T> h) {
|
||||
final int priority = h.getPriority();
|
||||
List<IMEInventoryHandler<T>> list = this.priorityInventory.get(priority);
|
||||
if (list == null) {
|
||||
this.priorityInventory.put(priority, list = new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public T injectItems( T input, final Actionable type, final IActionSource src )
|
||||
{
|
||||
if( this.diveList( this, type ) )
|
||||
{
|
||||
return input;
|
||||
}
|
||||
list.add(h);
|
||||
}
|
||||
|
||||
if( this.testPermission( src, SecurityPermissions.INJECT ) )
|
||||
{
|
||||
this.surface( this, type );
|
||||
return input;
|
||||
}
|
||||
@Override
|
||||
public T injectItems(T input, final Actionable type, final IActionSource src) {
|
||||
if (this.diveList(this, type)) {
|
||||
return input;
|
||||
}
|
||||
|
||||
for( final List<IMEInventoryHandler<T>> invList : this.priorityInventory.values() )
|
||||
{
|
||||
Iterator<IMEInventoryHandler<T>> ii = invList.iterator();
|
||||
while( ii.hasNext() && input != null )
|
||||
{
|
||||
final IMEInventoryHandler<T> inv = ii.next();
|
||||
if (this.testPermission(src, SecurityPermissions.INJECT)) {
|
||||
this.surface(this, type);
|
||||
return input;
|
||||
}
|
||||
|
||||
if( inv.validForPass( 1 ) && inv
|
||||
.canAccept( input ) && ( inv.isPrioritized( input ) || inv.extractItems( input, Actionable.SIMULATE, src ) != null ) )
|
||||
{
|
||||
input = inv.injectItems( input, type, src );
|
||||
}
|
||||
}
|
||||
for (final List<IMEInventoryHandler<T>> invList : this.priorityInventory.values()) {
|
||||
Iterator<IMEInventoryHandler<T>> ii = invList.iterator();
|
||||
while (ii.hasNext() && input != null) {
|
||||
final IMEInventoryHandler<T> inv = ii.next();
|
||||
|
||||
// We need to ignore prioritized inventories in the second pass. If they were not able to store everything
|
||||
// during the first pass, they will do so in the second, but as this is stateless we will just report twice
|
||||
// the amount of storable items.
|
||||
// ignores craftingcache on the second pass.
|
||||
ii = invList.iterator();
|
||||
while( ii.hasNext() && input != null )
|
||||
{
|
||||
final IMEInventoryHandler<T> inv = ii.next();
|
||||
if (inv.validForPass(1) && inv
|
||||
.canAccept(input) && (inv.isPrioritized(input) || inv.extractItems(input, Actionable.SIMULATE, src) != null)) {
|
||||
input = inv.injectItems(input, type, src);
|
||||
}
|
||||
}
|
||||
|
||||
if( inv.validForPass( 2 ) && inv.canAccept( input ) && !inv.isPrioritized( input ) )
|
||||
{
|
||||
input = inv.injectItems( input, type, src );
|
||||
}
|
||||
}
|
||||
}
|
||||
// We need to ignore prioritized inventories in the second pass. If they were not able to store everything
|
||||
// during the first pass, they will do so in the second, but as this is stateless we will just report twice
|
||||
// the amount of storable items.
|
||||
// ignores craftingcache on the second pass.
|
||||
ii = invList.iterator();
|
||||
while (ii.hasNext() && input != null) {
|
||||
final IMEInventoryHandler<T> inv = ii.next();
|
||||
|
||||
this.surface( this, type );
|
||||
if (inv.validForPass(2) && inv.canAccept(input) && !inv.isPrioritized(input)) {
|
||||
input = inv.injectItems(input, type, src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
this.surface(this, type);
|
||||
|
||||
private boolean diveList( final NetworkInventoryHandler<T> networkInventoryHandler, final Actionable type )
|
||||
{
|
||||
final Deque cDepth = this.getDepth( type );
|
||||
if( cDepth.contains( networkInventoryHandler ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
cDepth.push( this );
|
||||
return false;
|
||||
}
|
||||
private boolean diveList(final NetworkInventoryHandler<T> networkInventoryHandler, final Actionable type) {
|
||||
final Deque cDepth = this.getDepth(type);
|
||||
if (cDepth.contains(networkInventoryHandler)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean testPermission( final IActionSource src, final SecurityPermissions permission )
|
||||
{
|
||||
if( src.player().isPresent() )
|
||||
{
|
||||
if( !this.security.hasPermission( src.player().get(), permission ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if( src.machine().isPresent() )
|
||||
{
|
||||
if( this.security.isAvailable() )
|
||||
{
|
||||
final IGridNode n = src.machine().get().getActionableNode();
|
||||
if( n == null )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
cDepth.push(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
final IGrid gn = n.getGrid();
|
||||
if( gn != this.security.getGrid() )
|
||||
{
|
||||
private boolean testPermission(final IActionSource src, final SecurityPermissions permission) {
|
||||
if (src.player().isPresent()) {
|
||||
return !this.security.hasPermission(src.player().get(), permission);
|
||||
} else if (src.machine().isPresent()) {
|
||||
if (this.security.isAvailable()) {
|
||||
final IGridNode n = src.machine().get().getActionableNode();
|
||||
if (n == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final ISecurityGrid sg = gn.getCache( ISecurityGrid.class );
|
||||
final int playerID = sg.getOwner();
|
||||
final IGrid gn = n.getGrid();
|
||||
if (gn != this.security.getGrid()) {
|
||||
|
||||
if( !this.security.hasPermission( playerID, permission ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final ISecurityGrid sg = gn.getCache(ISecurityGrid.class);
|
||||
final int playerID = sg.getOwner();
|
||||
|
||||
return false;
|
||||
}
|
||||
return !this.security.hasPermission(playerID, permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void surface( final NetworkInventoryHandler<T> networkInventoryHandler, final Actionable type )
|
||||
{
|
||||
if( this.getDepth( type ).pop() != this )
|
||||
{
|
||||
throw new IllegalStateException( "Invalid Access to Networked Storage API detected." );
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Deque getDepth( final Actionable type )
|
||||
{
|
||||
final ThreadLocal<Deque> depth = type == Actionable.MODULATE ? DEPTH_MOD : DEPTH_SIM;
|
||||
private void surface(final NetworkInventoryHandler<T> networkInventoryHandler, final Actionable type) {
|
||||
if (this.getDepth(type).pop() != this) {
|
||||
throw new IllegalStateException("Invalid Access to Networked Storage API detected.");
|
||||
}
|
||||
}
|
||||
|
||||
Deque s = depth.get();
|
||||
private Deque getDepth(final Actionable type) {
|
||||
final ThreadLocal<Deque> depth = type == Actionable.MODULATE ? DEPTH_MOD : DEPTH_SIM;
|
||||
|
||||
if( s == null )
|
||||
{
|
||||
depth.set( s = new ArrayDeque<>() );
|
||||
}
|
||||
Deque s = depth.get();
|
||||
|
||||
return s;
|
||||
}
|
||||
if (s == null) {
|
||||
depth.set(s = new ArrayDeque<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public T extractItems( T request, final Actionable mode, final IActionSource src )
|
||||
{
|
||||
if( this.diveList( this, mode ) )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
if( this.testPermission( src, SecurityPermissions.EXTRACT ) )
|
||||
{
|
||||
this.surface( this, mode );
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public T extractItems(T request, final Actionable mode, final IActionSource src) {
|
||||
if (this.diveList(this, mode)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Iterator<List<IMEInventoryHandler<T>>> i = this.priorityInventory.descendingMap().values().iterator();// priorityInventory.asMap().descendingMap().entrySet().iterator();
|
||||
if (this.testPermission(src, SecurityPermissions.EXTRACT)) {
|
||||
this.surface(this, mode);
|
||||
return null;
|
||||
}
|
||||
|
||||
final T output = request.copy();
|
||||
request = request.copy();
|
||||
output.setStackSize( 0 );
|
||||
final long req = request.getStackSize();
|
||||
final Iterator<List<IMEInventoryHandler<T>>> i = this.priorityInventory.descendingMap().values().iterator();// priorityInventory.asMap().descendingMap().entrySet().iterator();
|
||||
|
||||
while( i.hasNext() )
|
||||
{
|
||||
final List<IMEInventoryHandler<T>> invList = i.next();
|
||||
final T output = request.copy();
|
||||
request = request.copy();
|
||||
output.setStackSize(0);
|
||||
final long req = request.getStackSize();
|
||||
|
||||
final Iterator<IMEInventoryHandler<T>> ii = invList.iterator();
|
||||
while( ii.hasNext() && output.getStackSize() < req )
|
||||
{
|
||||
final IMEInventoryHandler<T> inv = ii.next();
|
||||
while (i.hasNext()) {
|
||||
final List<IMEInventoryHandler<T>> invList = i.next();
|
||||
|
||||
request.setStackSize( req - output.getStackSize() );
|
||||
output.add( inv.extractItems( request, mode, src ) );
|
||||
}
|
||||
}
|
||||
final Iterator<IMEInventoryHandler<T>> ii = invList.iterator();
|
||||
while (ii.hasNext() && output.getStackSize() < req) {
|
||||
final IMEInventoryHandler<T> inv = ii.next();
|
||||
|
||||
this.surface( this, mode );
|
||||
request.setStackSize(req - output.getStackSize());
|
||||
output.add(inv.extractItems(request, mode, src));
|
||||
}
|
||||
}
|
||||
|
||||
if( output.getStackSize() <= 0 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
this.surface(this, mode);
|
||||
|
||||
return output;
|
||||
}
|
||||
if (output.getStackSize() <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems( IItemList<T> out )
|
||||
{
|
||||
if( this.diveIteration( this, Actionable.SIMULATE ) )
|
||||
{
|
||||
return out;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
// for (Entry<Integer, IMEInventoryHandler<T>> h : priorityInventory.entries())
|
||||
for( final List<IMEInventoryHandler<T>> i : this.priorityInventory.values() )
|
||||
{
|
||||
for( final IMEInventoryHandler<T> j : i )
|
||||
{
|
||||
out = j.getAvailableItems( out );
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems(IItemList<T> out) {
|
||||
if (this.diveIteration(this, Actionable.SIMULATE)) {
|
||||
return out;
|
||||
}
|
||||
|
||||
this.surface( this, Actionable.SIMULATE );
|
||||
// for (Entry<Integer, IMEInventoryHandler<T>> h : priorityInventory.entries())
|
||||
for (final List<IMEInventoryHandler<T>> i : this.priorityInventory.values()) {
|
||||
for (final IMEInventoryHandler<T> j : i) {
|
||||
out = j.getAvailableItems(out);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
this.surface(this, Actionable.SIMULATE);
|
||||
|
||||
private boolean diveIteration( final NetworkInventoryHandler<T> networkInventoryHandler, final Actionable type )
|
||||
{
|
||||
final Deque cDepth = this.getDepth( type );
|
||||
if( cDepth.isEmpty() )
|
||||
{
|
||||
currentPass++;
|
||||
this.myPass = currentPass;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( currentPass == this.myPass )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.myPass = currentPass;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
cDepth.push( this );
|
||||
return false;
|
||||
}
|
||||
private boolean diveIteration(final NetworkInventoryHandler<T> networkInventoryHandler, final Actionable type) {
|
||||
final Deque cDepth = this.getDepth(type);
|
||||
if (cDepth.isEmpty()) {
|
||||
currentPass++;
|
||||
this.myPass = currentPass;
|
||||
} else {
|
||||
if (currentPass == this.myPass) {
|
||||
return true;
|
||||
} else {
|
||||
this.myPass = currentPass;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel<T> getChannel()
|
||||
{
|
||||
return this.myChannel;
|
||||
}
|
||||
cDepth.push(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessRestriction getAccess()
|
||||
{
|
||||
return AccessRestriction.READ_WRITE;
|
||||
}
|
||||
@Override
|
||||
public IStorageChannel<T> getChannel() {
|
||||
return this.myChannel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrioritized( final T input )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public AccessRestriction getAccess() {
|
||||
return AccessRestriction.READ_WRITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccept( final T input )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean isPrioritized(final T input) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public boolean canAccept(final T input) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlot()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validForPass( final int i )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public int getSlot() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validForPass(final int i) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,66 +30,55 @@ import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
|
||||
|
||||
public class NullInventory<T extends IAEStack<T>> implements IMEInventoryHandler<T>
|
||||
{
|
||||
public class NullInventory<T extends IAEStack<T>> implements IMEInventoryHandler<T> {
|
||||
|
||||
@Override
|
||||
public T injectItems( final T input, final Actionable mode, final IActionSource src )
|
||||
{
|
||||
return input;
|
||||
}
|
||||
@Override
|
||||
public T injectItems(final T input, final Actionable mode, final IActionSource src) {
|
||||
return input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T extractItems( final T request, final Actionable mode, final IActionSource src )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public T extractItems(final T request, final Actionable mode, final IActionSource src) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems( final IItemList out )
|
||||
{
|
||||
return out;
|
||||
}
|
||||
@Override
|
||||
public IItemList<T> getAvailableItems(final IItemList out) {
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel getChannel()
|
||||
{
|
||||
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
|
||||
}
|
||||
@Override
|
||||
public IStorageChannel getChannel() {
|
||||
return AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessRestriction getAccess()
|
||||
{
|
||||
return AccessRestriction.READ;
|
||||
}
|
||||
@Override
|
||||
public AccessRestriction getAccess() {
|
||||
return AccessRestriction.READ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrioritized( final T input )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean isPrioritized(final T input) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccept( final T input )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean canAccept(final T input) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlot()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getSlot() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validForPass( final int i )
|
||||
{
|
||||
return i == 2;
|
||||
}
|
||||
@Override
|
||||
public boolean validForPass(final int i) {
|
||||
return i == 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
package appeng.me.storage;
|
||||
|
||||
|
||||
import appeng.me.helpers.MEMonitorHandler;
|
||||
import appeng.me.helpers.MachineSource;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.AccessRestriction;
|
||||
import appeng.api.config.Actionable;
|
||||
@@ -35,181 +31,150 @@ import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.me.helpers.MEMonitorHandler;
|
||||
import appeng.me.helpers.MachineSource;
|
||||
import appeng.tile.misc.TileSecurityStation;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
|
||||
public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStack>
|
||||
{
|
||||
public class SecurityStationInventory implements IMEInventoryHandler<IAEItemStack> {
|
||||
|
||||
private final IItemList<IAEItemStack> storedItems = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
|
||||
private final TileSecurityStation securityTile;
|
||||
private final MachineSource src;
|
||||
private final IItemList<IAEItemStack> storedItems = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
||||
private final TileSecurityStation securityTile;
|
||||
private final MachineSource src;
|
||||
|
||||
public SecurityStationInventory( final TileSecurityStation ts )
|
||||
{
|
||||
this.securityTile = ts;
|
||||
this.src = new MachineSource( securityTile );
|
||||
}
|
||||
public SecurityStationInventory(final TileSecurityStation ts) {
|
||||
this.securityTile = ts;
|
||||
this.src = new MachineSource(securityTile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEItemStack injectItems( final IAEItemStack input, final Actionable type, final IActionSource src )
|
||||
{
|
||||
if( this.hasPermission( src ) )
|
||||
{
|
||||
if( AEApi.instance().definitions().items().biometricCard().isSameAs( input.createItemStack() ) )
|
||||
{
|
||||
if( this.canAccept( input ) )
|
||||
{
|
||||
if( type == Actionable.SIMULATE )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public IAEItemStack injectItems(final IAEItemStack input, final Actionable type, final IActionSource src) {
|
||||
if (this.hasPermission(src)) {
|
||||
if (AEApi.instance().definitions().items().biometricCard().isSameAs(input.createItemStack())) {
|
||||
if (this.canAccept(input)) {
|
||||
if (type == Actionable.SIMULATE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if( securityTile.getProxy().isActive() )
|
||||
{
|
||||
( ( MEMonitorHandler<IAEItemStack> ) securityTile.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) ).postChangesToListeners( Collections.singletonList( input.copy() ), this.src );
|
||||
}
|
||||
if (securityTile.getProxy().isActive()) {
|
||||
((MEMonitorHandler<IAEItemStack>) securityTile.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class))).postChangesToListeners(Collections.singletonList(input.copy()), this.src);
|
||||
}
|
||||
|
||||
this.getStoredItems().add( input );
|
||||
this.securityTile.inventoryChanged();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return input;
|
||||
}
|
||||
this.getStoredItems().add(input);
|
||||
this.securityTile.inventoryChanged();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
private boolean hasPermission( final IActionSource src )
|
||||
{
|
||||
if( src.player().isPresent() )
|
||||
{
|
||||
try
|
||||
{
|
||||
return this.securityTile.getProxy().getSecurity().hasPermission( src.player().get(), SecurityPermissions.SECURITY );
|
||||
}
|
||||
catch( final GridAccessException e )
|
||||
{
|
||||
// :P
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private boolean hasPermission(final IActionSource src) {
|
||||
if (src.player().isPresent()) {
|
||||
try {
|
||||
return this.securityTile.getProxy().getSecurity().hasPermission(src.player().get(), SecurityPermissions.SECURITY);
|
||||
} catch (final GridAccessException e) {
|
||||
// :P
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEItemStack extractItems( final IAEItemStack request, final Actionable mode, final IActionSource src )
|
||||
{
|
||||
if( this.hasPermission( src ) )
|
||||
{
|
||||
final IAEItemStack target = this.getStoredItems().findPrecise( request );
|
||||
if( target != null )
|
||||
{
|
||||
final IAEItemStack output = target.copy();
|
||||
@Override
|
||||
public IAEItemStack extractItems(final IAEItemStack request, final Actionable mode, final IActionSource src) {
|
||||
if (this.hasPermission(src)) {
|
||||
final IAEItemStack target = this.getStoredItems().findPrecise(request);
|
||||
if (target != null) {
|
||||
final IAEItemStack output = target.copy();
|
||||
|
||||
if( mode == Actionable.SIMULATE )
|
||||
{
|
||||
return output;
|
||||
}
|
||||
if (mode == Actionable.SIMULATE) {
|
||||
return output;
|
||||
}
|
||||
|
||||
if( securityTile.getProxy().isActive() )
|
||||
{
|
||||
( ( MEMonitorHandler<IAEItemStack> ) securityTile.getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) ).postChangesToListeners( Collections.singletonList( target.copy().setStackSize( -target.getStackSize() ) ), this.src );
|
||||
}
|
||||
if (securityTile.getProxy().isActive()) {
|
||||
((MEMonitorHandler<IAEItemStack>) securityTile.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class))).postChangesToListeners(Collections.singletonList(target.copy().setStackSize(-target.getStackSize())), this.src);
|
||||
}
|
||||
|
||||
target.setStackSize( 0 );
|
||||
this.securityTile.inventoryChanged();
|
||||
return output;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
target.setStackSize(0);
|
||||
this.securityTile.inventoryChanged();
|
||||
return output;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemList<IAEItemStack> getAvailableItems( final IItemList out )
|
||||
{
|
||||
for( final IAEItemStack ais : this.getStoredItems() )
|
||||
{
|
||||
out.add( ais );
|
||||
}
|
||||
@Override
|
||||
public IItemList<IAEItemStack> getAvailableItems(final IItemList out) {
|
||||
for (final IAEItemStack ais : this.getStoredItems()) {
|
||||
out.add(ais);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel getChannel()
|
||||
{
|
||||
return AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class );
|
||||
}
|
||||
@Override
|
||||
public IStorageChannel getChannel() {
|
||||
return AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessRestriction getAccess()
|
||||
{
|
||||
return AccessRestriction.READ_WRITE;
|
||||
}
|
||||
@Override
|
||||
public AccessRestriction getAccess() {
|
||||
return AccessRestriction.READ_WRITE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrioritized( final IAEItemStack input )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean isPrioritized(final IAEItemStack input) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccept( final IAEItemStack input )
|
||||
{
|
||||
if( input.getItem() instanceof IBiometricCard )
|
||||
{
|
||||
final IBiometricCard tbc = (IBiometricCard) input.getItem();
|
||||
final GameProfile newUser = tbc.getProfile( input.createItemStack() );
|
||||
@Override
|
||||
public boolean canAccept(final IAEItemStack input) {
|
||||
if (input.getItem() instanceof IBiometricCard) {
|
||||
final IBiometricCard tbc = (IBiometricCard) input.getItem();
|
||||
final GameProfile newUser = tbc.getProfile(input.createItemStack());
|
||||
|
||||
final int PlayerID = AEApi.instance().registries().players().getID( newUser );
|
||||
if( this.securityTile.getOwner() == PlayerID )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final int PlayerID = AEApi.instance().registries().players().getID(newUser);
|
||||
if (this.securityTile.getOwner() == PlayerID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for( final IAEItemStack ais : this.getStoredItems() )
|
||||
{
|
||||
if( ais.isMeaningful() )
|
||||
{
|
||||
final GameProfile thisUser = tbc.getProfile( ais.createItemStack() );
|
||||
if( thisUser == newUser )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (final IAEItemStack ais : this.getStoredItems()) {
|
||||
if (ais.isMeaningful()) {
|
||||
final GameProfile thisUser = tbc.getProfile(ais.createItemStack());
|
||||
if (thisUser == newUser) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( thisUser != null && thisUser.equals( newUser ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (thisUser != null && thisUser.equals(newUser)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlot()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public int getSlot() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validForPass( final int i )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean validForPass(final int i) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public IItemList<IAEItemStack> getStoredItems()
|
||||
{
|
||||
return this.storedItems;
|
||||
}
|
||||
public IItemList<IAEItemStack> getStoredItems() {
|
||||
return this.storedItems;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user