Buffer changes from Interest List.
This commit is contained in:
parent
a73109b62e
commit
d807812bc8
5 changed files with 334 additions and 246 deletions
474
me/Grid.java
474
me/Grid.java
|
@ -1,238 +1,236 @@
|
|||
package appeng.me;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
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.IMachineSet;
|
||||
import appeng.api.networking.events.MENetworkEvent;
|
||||
import appeng.api.networking.events.MENetworkPostCacheConstruction;
|
||||
import appeng.api.util.IReadOnlyCollection;
|
||||
import appeng.core.WorldSettings;
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.util.ReadOnlyCollection;
|
||||
|
||||
public class Grid implements IGrid
|
||||
{
|
||||
|
||||
GridStorage myStorage;
|
||||
|
||||
NetworkEventBus bus = new NetworkEventBus();
|
||||
HashMap<Class<? extends IGridHost>, Set> Machines = new HashMap<Class<? extends IGridHost>, Set>();
|
||||
HashMap<Class<? extends IGridCache>, GridCacheWrapper> caches = new HashMap<Class<? extends IGridCache>, GridCacheWrapper>();
|
||||
|
||||
GridNode pivot;
|
||||
int isImportant; // how import is this network?
|
||||
|
||||
public Grid(GridNode center) {
|
||||
this.pivot = center;
|
||||
|
||||
HashMap<Class<? extends IGridCache>, IGridCache> myCaches = AEApi.instance().registries().gridCache().createCacheInstance( this );
|
||||
for (Class<? extends IGridCache> c : myCaches.keySet())
|
||||
{
|
||||
bus.readClass( c, myCaches.get( c ).getClass() );
|
||||
caches.put( c, new GridCacheWrapper( myCaches.get( c ) ) );
|
||||
}
|
||||
|
||||
TickHandler.instance.addNetwork( this );
|
||||
center.setGrid( this );
|
||||
|
||||
postEvent( new MENetworkPostCacheConstruction() );
|
||||
}
|
||||
|
||||
public Set<Class<? extends IGridHost>> getMachineClasses()
|
||||
{
|
||||
return Machines.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGridNode getPivot()
|
||||
{
|
||||
return pivot;
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
int out = 0;
|
||||
for (Collection<?> x : Machines.values())
|
||||
out += x.size();
|
||||
return out;
|
||||
}
|
||||
|
||||
public void remove(GridNode gridNode)
|
||||
{
|
||||
for (IGridCache c : caches.values())
|
||||
c.removeNode( gridNode, gridNode.getMachine() );
|
||||
|
||||
Collection<IGridNode> nodes = Machines.get( gridNode.getMachineClass() );
|
||||
if ( nodes != null )
|
||||
nodes.remove( gridNode );
|
||||
|
||||
gridNode.setGridStorage( null );
|
||||
|
||||
if ( pivot == gridNode )
|
||||
{
|
||||
Iterator<IGridNode> n = getNodes().iterator();
|
||||
if ( n.hasNext() )
|
||||
pivot = (GridNode) n.next();
|
||||
else
|
||||
{
|
||||
pivot = null;
|
||||
TickHandler.instance.removeNetwork( this );
|
||||
myStorage.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void add(GridNode gridNode)
|
||||
{
|
||||
Class<? extends IGridHost> mClass = gridNode.getMachineClass();
|
||||
Set<IGridNode> nodes = Machines.get( mClass );
|
||||
if ( nodes == null )
|
||||
{
|
||||
Machines.put( mClass, nodes = new MachineSet( mClass ) );
|
||||
bus.readClass( mClass, mClass );
|
||||
}
|
||||
|
||||
// handle loading grid storages.
|
||||
if ( gridNode.getGridStorage() != null )
|
||||
{
|
||||
GridStorage gs = gridNode.getGridStorage();
|
||||
|
||||
if ( gs.getGrid() == null )
|
||||
{
|
||||
myStorage = gs;
|
||||
myStorage.setGrid( this );
|
||||
|
||||
for (IGridCache gc : caches.values())
|
||||
gc.onJoin( myStorage );
|
||||
}
|
||||
else if ( gs.getGrid() != this )
|
||||
{
|
||||
if ( myStorage == null )
|
||||
{
|
||||
myStorage = WorldSettings.getInstance().getNewGridStorage();
|
||||
myStorage.setGrid( this );
|
||||
}
|
||||
|
||||
GridStorage tmp = new GridStorage();
|
||||
if ( !gs.hasDivided( myStorage ) )
|
||||
{
|
||||
gs.addDivided( myStorage );
|
||||
|
||||
for (IGridCache gc : ((Grid) gs.getGrid()).caches.values())
|
||||
gc.onSplit( tmp );
|
||||
|
||||
for (IGridCache gc : caches.values())
|
||||
gc.onJoin( tmp );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( myStorage == null )
|
||||
{
|
||||
myStorage = WorldSettings.getInstance().getNewGridStorage();
|
||||
myStorage.setGrid( this );
|
||||
}
|
||||
|
||||
// update grid node...
|
||||
gridNode.setGridStorage( myStorage );
|
||||
|
||||
// track node.
|
||||
nodes.add( gridNode );
|
||||
|
||||
for (IGridCache c : caches.values())
|
||||
c.addNode( gridNode, gridNode.getMachine() );
|
||||
|
||||
gridNode.gridProxy.gridChanged();
|
||||
// postEventTo( gridNode, networkChanged );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IReadOnlyCollection<IGridNode> getNodes()
|
||||
{
|
||||
return new NodeIteratable( Machines );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IReadOnlyCollection<Class<? extends IGridHost>> getMachinesClasses()
|
||||
{
|
||||
return new ReadOnlyCollection<Class<? extends IGridHost>>( Machines.keySet() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMachineSet getMachines(Class<? extends IGridHost> c)
|
||||
{
|
||||
MachineSet s = (MachineSet) Machines.get( c );
|
||||
if ( s == null )
|
||||
return new MachineSet( c );
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <C extends IGridCache> C getCache(Class<? extends IGridCache> iface)
|
||||
{
|
||||
return (C) caches.get( iface ).myCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MENetworkEvent postEventTo(IGridNode node, MENetworkEvent ev)
|
||||
{
|
||||
return bus.postEventTo( this, (GridNode) node, ev );
|
||||
}
|
||||
|
||||
@Override
|
||||
public MENetworkEvent postEvent(MENetworkEvent ev)
|
||||
{
|
||||
return bus.postEvent( this, ev );
|
||||
}
|
||||
|
||||
public void requestSave()
|
||||
{
|
||||
myStorage.markDirty();
|
||||
WorldSettings.getInstance().save();
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
// are ther any nodes left?
|
||||
if ( pivot != null )
|
||||
{
|
||||
for (IGridCache gc : caches.values())
|
||||
{
|
||||
gc.onUpdateTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Iterable<GridCacheWrapper> getCacheWrappers()
|
||||
{
|
||||
return caches.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return pivot == null;
|
||||
}
|
||||
|
||||
public void saveState()
|
||||
{
|
||||
for (IGridCache c : caches.values())
|
||||
{
|
||||
c.populateGridStorage( myStorage );
|
||||
}
|
||||
}
|
||||
|
||||
public void setImportantFlag(int i, boolean publicHasPower)
|
||||
{
|
||||
int flag = 1 << i;
|
||||
isImportant = (isImportant & ~flag) | (publicHasPower ? flag : 0);
|
||||
}
|
||||
|
||||
}
|
||||
package appeng.me;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
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.IMachineSet;
|
||||
import appeng.api.networking.events.MENetworkEvent;
|
||||
import appeng.api.networking.events.MENetworkPostCacheConstruction;
|
||||
import appeng.api.util.IReadOnlyCollection;
|
||||
import appeng.core.WorldSettings;
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.util.ReadOnlyCollection;
|
||||
|
||||
public class Grid implements IGrid
|
||||
{
|
||||
|
||||
GridStorage myStorage;
|
||||
|
||||
NetworkEventBus bus = new NetworkEventBus();
|
||||
HashMap<Class<? extends IGridHost>, Set> Machines = new HashMap<Class<? extends IGridHost>, Set>();
|
||||
HashMap<Class<? extends IGridCache>, GridCacheWrapper> caches = new HashMap<Class<? extends IGridCache>, GridCacheWrapper>();
|
||||
|
||||
GridNode pivot;
|
||||
int isImportant; // how import is this network?
|
||||
|
||||
public Grid(GridNode center) {
|
||||
this.pivot = center;
|
||||
|
||||
HashMap<Class<? extends IGridCache>, IGridCache> myCaches = AEApi.instance().registries().gridCache().createCacheInstance( this );
|
||||
for (Class<? extends IGridCache> c : myCaches.keySet())
|
||||
{
|
||||
bus.readClass( c, myCaches.get( c ).getClass() );
|
||||
caches.put( c, new GridCacheWrapper( myCaches.get( c ) ) );
|
||||
}
|
||||
|
||||
TickHandler.instance.addNetwork( this );
|
||||
center.setGrid( this );
|
||||
|
||||
postEvent( new MENetworkPostCacheConstruction() );
|
||||
}
|
||||
|
||||
public Set<Class<? extends IGridHost>> getMachineClasses()
|
||||
{
|
||||
return Machines.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGridNode getPivot()
|
||||
{
|
||||
return pivot;
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
int out = 0;
|
||||
for (Collection<?> x : Machines.values())
|
||||
out += x.size();
|
||||
return out;
|
||||
}
|
||||
|
||||
public void remove(GridNode gridNode)
|
||||
{
|
||||
for (IGridCache c : caches.values())
|
||||
c.removeNode( gridNode, gridNode.getMachine() );
|
||||
|
||||
Collection<IGridNode> nodes = Machines.get( gridNode.getMachineClass() );
|
||||
if ( nodes != null )
|
||||
nodes.remove( gridNode );
|
||||
|
||||
gridNode.setGridStorage( null );
|
||||
|
||||
if ( pivot == gridNode )
|
||||
{
|
||||
Iterator<IGridNode> n = getNodes().iterator();
|
||||
if ( n.hasNext() )
|
||||
pivot = (GridNode) n.next();
|
||||
else
|
||||
{
|
||||
pivot = null;
|
||||
TickHandler.instance.removeNetwork( this );
|
||||
myStorage.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void add(GridNode gridNode)
|
||||
{
|
||||
Class<? extends IGridHost> mClass = gridNode.getMachineClass();
|
||||
Set<IGridNode> nodes = Machines.get( mClass );
|
||||
if ( nodes == null )
|
||||
{
|
||||
Machines.put( mClass, nodes = new MachineSet( mClass ) );
|
||||
bus.readClass( mClass, mClass );
|
||||
}
|
||||
|
||||
// handle loading grid storages.
|
||||
if ( gridNode.getGridStorage() != null )
|
||||
{
|
||||
GridStorage gs = gridNode.getGridStorage();
|
||||
|
||||
if ( gs.getGrid() == null )
|
||||
{
|
||||
myStorage = gs;
|
||||
myStorage.setGrid( this );
|
||||
|
||||
for (IGridCache gc : caches.values())
|
||||
gc.onJoin( myStorage );
|
||||
}
|
||||
else if ( gs.getGrid() != this )
|
||||
{
|
||||
if ( myStorage == null )
|
||||
{
|
||||
myStorage = WorldSettings.getInstance().getNewGridStorage();
|
||||
myStorage.setGrid( this );
|
||||
}
|
||||
|
||||
GridStorage tmp = new GridStorage();
|
||||
if ( !gs.hasDivided( myStorage ) )
|
||||
{
|
||||
gs.addDivided( myStorage );
|
||||
|
||||
for (IGridCache gc : ((Grid) gs.getGrid()).caches.values())
|
||||
gc.onSplit( tmp );
|
||||
|
||||
for (IGridCache gc : caches.values())
|
||||
gc.onJoin( tmp );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( myStorage == null )
|
||||
{
|
||||
myStorage = WorldSettings.getInstance().getNewGridStorage();
|
||||
myStorage.setGrid( this );
|
||||
}
|
||||
|
||||
// update grid node...
|
||||
gridNode.setGridStorage( myStorage );
|
||||
|
||||
// track node.
|
||||
nodes.add( gridNode );
|
||||
|
||||
for (IGridCache c : caches.values())
|
||||
c.addNode( gridNode, gridNode.getMachine() );
|
||||
|
||||
gridNode.gridProxy.gridChanged();
|
||||
// postEventTo( gridNode, networkChanged );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IReadOnlyCollection<IGridNode> getNodes()
|
||||
{
|
||||
return new NodeIteratable( Machines );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IReadOnlyCollection<Class<? extends IGridHost>> getMachinesClasses()
|
||||
{
|
||||
return new ReadOnlyCollection<Class<? extends IGridHost>>( Machines.keySet() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMachineSet getMachines(Class<? extends IGridHost> c)
|
||||
{
|
||||
MachineSet s = (MachineSet) Machines.get( c );
|
||||
if ( s == null )
|
||||
return new MachineSet( c );
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <C extends IGridCache> C getCache(Class<? extends IGridCache> iface)
|
||||
{
|
||||
return (C) caches.get( iface ).myCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MENetworkEvent postEventTo(IGridNode node, MENetworkEvent ev)
|
||||
{
|
||||
return bus.postEventTo( this, (GridNode) node, ev );
|
||||
}
|
||||
|
||||
@Override
|
||||
public MENetworkEvent postEvent(MENetworkEvent ev)
|
||||
{
|
||||
return bus.postEvent( this, ev );
|
||||
}
|
||||
|
||||
public void requestSave()
|
||||
{
|
||||
myStorage.markDirty();
|
||||
WorldSettings.getInstance().save();
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
for (IGridCache gc : caches.values())
|
||||
{
|
||||
// are there any nodes left?
|
||||
if ( pivot != null )
|
||||
gc.onUpdateTick();
|
||||
}
|
||||
}
|
||||
|
||||
public Iterable<GridCacheWrapper> getCacheWrappers()
|
||||
{
|
||||
return caches.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return pivot == null;
|
||||
}
|
||||
|
||||
public void saveState()
|
||||
{
|
||||
for (IGridCache c : caches.values())
|
||||
{
|
||||
c.populateGridStorage( myStorage );
|
||||
}
|
||||
}
|
||||
|
||||
public void setImportantFlag(int i, boolean publicHasPower)
|
||||
{
|
||||
int flag = 1 << i;
|
||||
isImportant = (isImportant & ~flag) | (publicHasPower ? flag : 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
4
me/cache/GridStorageCache.java
vendored
4
me/cache/GridStorageCache.java
vendored
|
@ -25,6 +25,7 @@ import appeng.api.storage.data.IAEFluidStack;
|
|||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.api.storage.data.IItemList;
|
||||
import appeng.me.helpers.StorageInterestManager;
|
||||
import appeng.me.storage.ItemWatcher;
|
||||
import appeng.me.storage.NetworkInventoryHandler;
|
||||
|
||||
|
@ -34,7 +35,8 @@ import com.google.common.collect.SetMultimap;
|
|||
public class GridStorageCache implements IStorageGrid
|
||||
{
|
||||
|
||||
public SetMultimap<IAEStack, ItemWatcher> interests = HashMultimap.create();
|
||||
final private SetMultimap<IAEStack, ItemWatcher> interests = HashMultimap.create();
|
||||
final public StorageInterestManager interestManager = new StorageInterestManager( interests );
|
||||
|
||||
final HashSet<ICellContainer> activeCellContainers = new HashSet();
|
||||
final HashSet<ICellContainer> inactiveCellContainers = new HashSet();
|
||||
|
|
10
me/cache/NetworkMonitor.java
vendored
10
me/cache/NetworkMonitor.java
vendored
|
@ -59,9 +59,9 @@ public class NetworkMonitor<T extends IAEStack<T>> extends MEMonitorHandler<T>
|
|||
sendEvent = true;
|
||||
super.postChange( diff, src );
|
||||
|
||||
if ( myGridCache.interests.containsKey( diff ) )
|
||||
if ( myGridCache.interestManager.containsKey( diff ) )
|
||||
{
|
||||
Set<ItemWatcher> list = myGridCache.interests.get( diff );
|
||||
Set<ItemWatcher> list = myGridCache.interestManager.get( diff );
|
||||
if ( !list.isEmpty() )
|
||||
{
|
||||
IItemList<T> myStorageList = getStorageList();
|
||||
|
@ -72,9 +72,13 @@ public class NetworkMonitor<T extends IAEStack<T>> extends MEMonitorHandler<T>
|
|||
fullStack = diff.copy();
|
||||
fullStack.setStackSize( 0 );
|
||||
}
|
||||
|
||||
|
||||
myGridCache.interestManager.enableTransactions();
|
||||
|
||||
for (ItemWatcher iw : list)
|
||||
iw.getHost().onStackChange( myStorageList, fullStack, diff, src, getChannel() );
|
||||
|
||||
myGridCache.interestManager.disableTransactions();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
84
me/helpers/StorageInterestManager.java
Normal file
84
me/helpers/StorageInterestManager.java
Normal file
|
@ -0,0 +1,84 @@
|
|||
package appeng.me.helpers;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
|
||||
import appeng.api.storage.data.IAEStack;
|
||||
import appeng.me.storage.ItemWatcher;
|
||||
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
public class StorageInterestManager {
|
||||
|
||||
class SavedTransactions {
|
||||
public final boolean put;
|
||||
public final IAEStack stack;
|
||||
public final ItemWatcher iw;
|
||||
|
||||
public SavedTransactions( boolean putOperation, IAEStack myStack, ItemWatcher watcher )
|
||||
{
|
||||
put = putOperation;
|
||||
stack = myStack;
|
||||
iw = watcher;
|
||||
}
|
||||
};
|
||||
|
||||
private final SetMultimap<IAEStack, ItemWatcher> container;
|
||||
private LinkedList<SavedTransactions> transactions = null;
|
||||
|
||||
public StorageInterestManager(SetMultimap<IAEStack, ItemWatcher> interests) {
|
||||
container = interests;
|
||||
}
|
||||
|
||||
public void enableTransactions()
|
||||
{
|
||||
transactions = new LinkedList();
|
||||
}
|
||||
|
||||
public void disableTransactions()
|
||||
{
|
||||
LinkedList<SavedTransactions> myActions = transactions;
|
||||
transactions = null;
|
||||
|
||||
for ( SavedTransactions t : myActions )
|
||||
{
|
||||
if ( t.put )
|
||||
put( t.stack, t.iw );
|
||||
else
|
||||
remove( t.stack, t.iw );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsKey( IAEStack stack )
|
||||
{
|
||||
return container.containsKey( stack );
|
||||
}
|
||||
|
||||
public Set<ItemWatcher> get( IAEStack stack )
|
||||
{
|
||||
return container.get( stack );
|
||||
}
|
||||
|
||||
public boolean put( IAEStack stack, ItemWatcher iw )
|
||||
{
|
||||
if ( transactions != null )
|
||||
{
|
||||
transactions.add( new SavedTransactions( true, stack, iw ) );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return container.put( stack, iw );
|
||||
}
|
||||
|
||||
public boolean remove( IAEStack stack, ItemWatcher iw )
|
||||
{
|
||||
if ( transactions != null )
|
||||
{
|
||||
transactions.add( new SavedTransactions( true, stack, iw ) );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return container.remove( stack, iw );
|
||||
}
|
||||
|
||||
}
|
|
@ -42,7 +42,7 @@ public class ItemWatcher implements IStackWatcher
|
|||
@Override
|
||||
public void remove()
|
||||
{
|
||||
gsc.interests.remove( myLast, watcher );
|
||||
gsc.interestManager.remove( myLast, watcher );
|
||||
interestIterator.remove();
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ public class ItemWatcher implements IStackWatcher
|
|||
if ( myInterests.contains( e ) )
|
||||
return false;
|
||||
|
||||
return myInterests.add( e.copy() ) && gsc.interests.put( e, this );
|
||||
return myInterests.add( e.copy() ) && gsc.interestManager.put( e, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -88,7 +88,7 @@ public class ItemWatcher implements IStackWatcher
|
|||
Iterator<IAEStack> i = myInterests.iterator();
|
||||
while (i.hasNext())
|
||||
{
|
||||
gsc.interests.remove( i.next(), this );
|
||||
gsc.interestManager.remove( i.next(), this );
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ public class ItemWatcher implements IStackWatcher
|
|||
@Override
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
return myInterests.remove( o ) && gsc.interests.remove( o, this );
|
||||
return myInterests.remove( o ) && gsc.interestManager.remove( (IAEStack)o, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue