From d807812bc8b2ff61ee1bef8feb65a21b86bf16de Mon Sep 17 00:00:00 2001 From: AlgorithmX2 Date: Tue, 10 Jun 2014 12:16:14 -0500 Subject: [PATCH] Buffer changes from Interest List. --- me/Grid.java | 474 ++++++++++++------------- me/cache/GridStorageCache.java | 4 +- me/cache/NetworkMonitor.java | 10 +- me/helpers/StorageInterestManager.java | 84 +++++ me/storage/ItemWatcher.java | 8 +- 5 files changed, 334 insertions(+), 246 deletions(-) create mode 100644 me/helpers/StorageInterestManager.java diff --git a/me/Grid.java b/me/Grid.java index 8bc2b1f1..dce6123a 100644 --- a/me/Grid.java +++ b/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, Set> Machines = new HashMap, Set>(); - HashMap, GridCacheWrapper> caches = new HashMap, GridCacheWrapper>(); - - GridNode pivot; - int isImportant; // how import is this network? - - public Grid(GridNode center) { - this.pivot = center; - - HashMap, IGridCache> myCaches = AEApi.instance().registries().gridCache().createCacheInstance( this ); - for (Class 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> 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 nodes = Machines.get( gridNode.getMachineClass() ); - if ( nodes != null ) - nodes.remove( gridNode ); - - gridNode.setGridStorage( null ); - - if ( pivot == gridNode ) - { - Iterator 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 mClass = gridNode.getMachineClass(); - Set 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 getNodes() - { - return new NodeIteratable( Machines ); - } - - @Override - public IReadOnlyCollection> getMachinesClasses() - { - return new ReadOnlyCollection>( Machines.keySet() ); - } - - @Override - public IMachineSet getMachines(Class c) - { - MachineSet s = (MachineSet) Machines.get( c ); - if ( s == null ) - return new MachineSet( c ); - return s; - } - - @Override - public C getCache(Class 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 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, Set> Machines = new HashMap, Set>(); + HashMap, GridCacheWrapper> caches = new HashMap, GridCacheWrapper>(); + + GridNode pivot; + int isImportant; // how import is this network? + + public Grid(GridNode center) { + this.pivot = center; + + HashMap, IGridCache> myCaches = AEApi.instance().registries().gridCache().createCacheInstance( this ); + for (Class 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> 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 nodes = Machines.get( gridNode.getMachineClass() ); + if ( nodes != null ) + nodes.remove( gridNode ); + + gridNode.setGridStorage( null ); + + if ( pivot == gridNode ) + { + Iterator 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 mClass = gridNode.getMachineClass(); + Set 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 getNodes() + { + return new NodeIteratable( Machines ); + } + + @Override + public IReadOnlyCollection> getMachinesClasses() + { + return new ReadOnlyCollection>( Machines.keySet() ); + } + + @Override + public IMachineSet getMachines(Class c) + { + MachineSet s = (MachineSet) Machines.get( c ); + if ( s == null ) + return new MachineSet( c ); + return s; + } + + @Override + public C getCache(Class 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 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); + } + +} diff --git a/me/cache/GridStorageCache.java b/me/cache/GridStorageCache.java index 34c842ef..c5ea94b4 100644 --- a/me/cache/GridStorageCache.java +++ b/me/cache/GridStorageCache.java @@ -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 interests = HashMultimap.create(); + final private SetMultimap interests = HashMultimap.create(); + final public StorageInterestManager interestManager = new StorageInterestManager( interests ); final HashSet activeCellContainers = new HashSet(); final HashSet inactiveCellContainers = new HashSet(); diff --git a/me/cache/NetworkMonitor.java b/me/cache/NetworkMonitor.java index 9fe06d5b..dfccffc9 100644 --- a/me/cache/NetworkMonitor.java +++ b/me/cache/NetworkMonitor.java @@ -59,9 +59,9 @@ public class NetworkMonitor> extends MEMonitorHandler sendEvent = true; super.postChange( diff, src ); - if ( myGridCache.interests.containsKey( diff ) ) + if ( myGridCache.interestManager.containsKey( diff ) ) { - Set list = myGridCache.interests.get( diff ); + Set list = myGridCache.interestManager.get( diff ); if ( !list.isEmpty() ) { IItemList myStorageList = getStorageList(); @@ -72,9 +72,13 @@ public class NetworkMonitor> extends MEMonitorHandler fullStack = diff.copy(); fullStack.setStackSize( 0 ); } - + + myGridCache.interestManager.enableTransactions(); + for (ItemWatcher iw : list) iw.getHost().onStackChange( myStorageList, fullStack, diff, src, getChannel() ); + + myGridCache.interestManager.disableTransactions(); } } diff --git a/me/helpers/StorageInterestManager.java b/me/helpers/StorageInterestManager.java new file mode 100644 index 00000000..c4e9761f --- /dev/null +++ b/me/helpers/StorageInterestManager.java @@ -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 container; + private LinkedList transactions = null; + + public StorageInterestManager(SetMultimap interests) { + container = interests; + } + + public void enableTransactions() + { + transactions = new LinkedList(); + } + + public void disableTransactions() + { + LinkedList 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 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 ); + } + +} diff --git a/me/storage/ItemWatcher.java b/me/storage/ItemWatcher.java index a97539eb..08a990f6 100644 --- a/me/storage/ItemWatcher.java +++ b/me/storage/ItemWatcher.java @@ -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 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