diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetwork.java b/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetwork.java index 7841bdb45..58c4b7a7d 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetwork.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetwork.java @@ -79,48 +79,6 @@ public interface INetwork { */ IStorageCache getFluidStorageCache(); - /** - * Sends a grid update packet with all the items to all clients that are watching a grid connected to this network. - */ - void sendItemStorageToClient(); - - /** - * Sends a grid update packet with all the items to a specific player. - */ - void sendItemStorageToClient(EntityPlayerMP player); - - /** - * Sends a item storage change to all clients that are watching a grid connected to this network. - * - * @param stack the stack - * @param delta the delta - * @param batched whether the delta can be batched to be sent all at once using {@link #sendBatchedItemStorageDeltaToClient()} - */ - void sendItemStorageDeltaToClient(ItemStack stack, int delta, boolean batched); - - /** - * Sends batched item storage deltas, accumulated through {@link #sendItemStorageDeltaToClient(ItemStack, int, boolean)}. - */ - void sendBatchedItemStorageDeltaToClient(); - - /** - * Sends a grid update packet with all the fluids to all clients that are watching a grid connected to this network. - */ - void sendFluidStorageToClient(); - - /** - * Sends a grid packet with all the fluids to a specific player. - */ - void sendFluidStorageToClient(EntityPlayerMP player); - - /** - * Sends a fluids storage change to all clients that are watching a grid connected to this network. - * - * @param stack the stack - * @param delta the delta - */ - void sendFluidStorageDeltaToClient(FluidStack stack, int delta); - /** * Makes the network send a crafting monitor update to all players as soon as it can. */ diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeGraph.java b/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeGraph.java index 2a2f179ee..96fb69335 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeGraph.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/network/INetworkNodeGraph.java @@ -17,9 +17,9 @@ public interface INetworkNodeGraph { /** * Adds a runnable that is run after the graph is rebuilt. * - * @param action the action to run + * @param handler the action to run */ - void schedulePostRebuildAction(Consumer action); + void addPostRebuildHandler(Consumer handler); /** * @return a collection of all connected nodes diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/IGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/IGrid.java index 053d2a675..5ddf7b91a 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/IGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/IGrid.java @@ -3,8 +3,11 @@ package com.raoulvdberge.refinedstorage.api.network.grid; import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IFluidGridHandler; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IItemGridHandler; +import com.raoulvdberge.refinedstorage.api.storage.IStorageCache; +import com.raoulvdberge.refinedstorage.api.storage.IStorageCacheListener; import com.raoulvdberge.refinedstorage.api.util.IFilter; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; @@ -53,6 +56,25 @@ public interface IGrid { @Nullable INetwork getNetwork(); + /** + * @return a listener for this grid + */ + IStorageCacheListener createListener(EntityPlayerMP player); + + /** + * @return the storage cache for this grid + */ + @Nullable + default IStorageCache getStorageCache() { + INetwork network = getNetwork(); + + if (network == null) { + return null; + } + + return getType() == GridType.FLUID ? network.getFluidStorageCache() : network.getItemStorageCache(); + } + /** * @return the item grid handler of the network of the grid, or null if the network is unavailable */ diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/storage/IStorageCache.java b/src/main/java/com/raoulvdberge/refinedstorage/api/storage/IStorageCache.java index 0c7f6aad3..c9d568f94 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/storage/IStorageCache.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/storage/IStorageCache.java @@ -48,19 +48,24 @@ public interface IStorageCache { */ void remove(@Nonnull T stack, int size, boolean batched); + /** + * Notifies storage cache listeners about batched up storage cache changes. + */ + void flush(); + /** * Adds a listener to be called when this storage cache changes. * * @param listener the listener */ - void addListener(Runnable listener); + void addListener(IStorageCacheListener listener); /** * Removes a listener from the storage cache. * * @param listener the listener */ - void removeListener(Runnable listener); + void removeListener(IStorageCacheListener listener); /** * Resorts the storages in this cache according to their priority. diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/storage/IStorageCacheListener.java b/src/main/java/com/raoulvdberge/refinedstorage/api/storage/IStorageCacheListener.java new file mode 100644 index 000000000..c630656ad --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/storage/IStorageCacheListener.java @@ -0,0 +1,28 @@ +package com.raoulvdberge.refinedstorage.api.storage; + +import javax.annotation.Nonnull; + +/** + * Listens for storage cache changes. + * + * @param the type + */ +public interface IStorageCacheListener { + /** + * Called when this storage cache listener is attached to a storage cache. + */ + void onAttached(); + + /** + * Called when the cache invalidates. + */ + void onInvalidated(); + + /** + * Called when the storage cache changes. + * + * @param stack the stack + * @param size the size, negative if the amount decreases + */ + void onChanged(@Nonnull T stack, int size); +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeGraph.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeGraph.java index c387a12b7..5864ad7a6 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeGraph.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/NetworkNodeGraph.java @@ -25,7 +25,7 @@ import static com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodePr public class NetworkNodeGraph implements INetworkNodeGraph { private TileController controller; private Set nodes = Sets.newConcurrentHashSet(); - private Set> postRebuildActions = new HashSet<>(); + private Set> postRebuildHandlers = new HashSet<>(); private boolean rebuilding = false; public NetworkNodeGraph(TileController controller) { @@ -69,8 +69,8 @@ public class NetworkNodeGraph implements INetworkNodeGraph { node.onDisconnected(controller); } - postRebuildActions.forEach(a -> a.accept(controller)); - postRebuildActions.clear(); + postRebuildHandlers.forEach(h -> h.accept(controller)); + postRebuildHandlers.clear(); if (!operator.newNodes.isEmpty() || !operator.previousNodes.isEmpty()) { controller.getDataManager().sendParameterToWatchers(TileController.NODES); @@ -80,11 +80,11 @@ public class NetworkNodeGraph implements INetworkNodeGraph { } @Override - public void schedulePostRebuildAction(Consumer action) { + public void addPostRebuildHandler(Consumer handler) { if (rebuilding) { - postRebuildActions.add(action); + postRebuildHandlers.add(handler); } else { - action.accept(controller); + handler.accept(controller); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/item/NetworkItemWirelessFluidGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/item/NetworkItemWirelessFluidGrid.java index e857fafaa..8a7ec043a 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/item/NetworkItemWirelessFluidGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/item/NetworkItemWirelessFluidGrid.java @@ -11,7 +11,6 @@ import com.raoulvdberge.refinedstorage.item.ItemWirelessFluidGrid; import com.raoulvdberge.refinedstorage.tile.grid.WirelessFluidGrid; import com.raoulvdberge.refinedstorage.util.WorldUtils; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumHand; import net.minecraftforge.energy.CapabilityEnergy; @@ -47,8 +46,6 @@ public class NetworkItemWirelessFluidGrid implements INetworkItem { API.instance().openWirelessGrid(player, hand, network.world().provider.getDimension(), WirelessFluidGrid.ID); - network.sendFluidStorageToClient((EntityPlayerMP) player); - drainEnergy(RS.INSTANCE.config.wirelessFluidGridOpenUsage); return true; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/item/NetworkItemWirelessGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/item/NetworkItemWirelessGrid.java index 2958ec871..0a08738a9 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/item/NetworkItemWirelessGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/item/NetworkItemWirelessGrid.java @@ -11,7 +11,6 @@ import com.raoulvdberge.refinedstorage.item.ItemWirelessGrid; import com.raoulvdberge.refinedstorage.tile.grid.WirelessGrid; import com.raoulvdberge.refinedstorage.util.WorldUtils; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumHand; import net.minecraftforge.energy.CapabilityEnergy; @@ -47,8 +46,6 @@ public class NetworkItemWirelessGrid implements INetworkItem { API.instance().openWirelessGrid(player, hand, network.world().provider.getDimension(), WirelessGrid.ID); - network.sendItemStorageToClient((EntityPlayerMP) player); - drainEnergy(RS.INSTANCE.config.wirelessGridOpenUsage); return true; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeFluidStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeFluidStorage.java index c0ca7fa35..98197a619 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeFluidStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeFluidStorage.java @@ -118,7 +118,7 @@ public class NetworkNodeFluidStorage extends NetworkNode implements IGuiStorage, public void onConnectedStateChange(INetwork network, boolean state) { super.onConnectedStateChange(network, state); - network.getNodeGraph().schedulePostRebuildAction(StorageCacheFluid.INVALIDATE); + network.getNodeGraph().addPostRebuildHandler(StorageCacheFluid.INVALIDATE); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeGrid.java index 9d4ab9133..64cd6d600 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeGrid.java @@ -10,9 +10,11 @@ import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab; import com.raoulvdberge.refinedstorage.api.network.item.INetworkItem; import com.raoulvdberge.refinedstorage.api.network.item.NetworkItemAction; import com.raoulvdberge.refinedstorage.api.network.security.Permission; +import com.raoulvdberge.refinedstorage.api.storage.IStorageCacheListener; import com.raoulvdberge.refinedstorage.api.util.IComparer; import com.raoulvdberge.refinedstorage.api.util.IFilter; import com.raoulvdberge.refinedstorage.apiimpl.API; +import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheListenerGridItem; import com.raoulvdberge.refinedstorage.block.BlockGrid; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFilter; @@ -188,14 +190,9 @@ public class NetworkNodeGrid extends NetworkNode implements IGrid { return type == null ? GridType.NORMAL : type; } - public void onOpened(EntityPlayer player) { - if (network != null) { - if (getType() == GridType.FLUID) { - network.sendFluidStorageToClient((EntityPlayerMP) player); - } else { - network.sendItemStorageToClient((EntityPlayerMP) player); - } - } + @Override + public IStorageCacheListener createListener(EntityPlayerMP player) { + return new StorageCacheListenerGridItem(player, network); } @Override @@ -491,7 +488,7 @@ public class NetworkNodeGrid extends NetworkNode implements IGrid { patterns.setStackInSlot(1, pattern); } } - + private boolean isPatternAvailable() { return !(patterns.getStackInSlot(0).isEmpty() && patterns.getStackInSlot(1).isEmpty()); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeStorage.java index d03fed716..90fcab864 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeStorage.java @@ -115,7 +115,7 @@ public class NetworkNodeStorage extends NetworkNode implements IGuiStorage, ISto public void onConnectedStateChange(INetwork network, boolean state) { super.onConnectedStateChange(network, state); - network.getNodeGraph().schedulePostRebuildAction(StorageCacheItem.INVALIDATE); + network.getNodeGraph().addPostRebuildHandler(StorageCacheItem.INVALIDATE); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskdrive/NetworkNodeDiskDrive.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskdrive/NetworkNodeDiskDrive.java index f5a2c2299..3d1e00833 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskdrive/NetworkNodeDiskDrive.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/diskdrive/NetworkNodeDiskDrive.java @@ -139,8 +139,8 @@ public class NetworkNodeDiskDrive extends NetworkNode implements IGuiStorage, IS public void onConnectedStateChange(INetwork network, boolean state) { super.onConnectedStateChange(network, state); - network.getNodeGraph().schedulePostRebuildAction(StorageCacheItem.INVALIDATE); - network.getNodeGraph().schedulePostRebuildAction(StorageCacheFluid.INVALIDATE); + network.getNodeGraph().addPostRebuildHandler(StorageCacheItem.INVALIDATE); + network.getNodeGraph().addPostRebuildHandler(StorageCacheFluid.INVALIDATE); WorldUtils.updateBlock(world, pos); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/externalstorage/NetworkNodeExternalStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/externalstorage/NetworkNodeExternalStorage.java index 30cd995b8..4489dd22a 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/externalstorage/NetworkNodeExternalStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/externalstorage/NetworkNodeExternalStorage.java @@ -228,8 +228,8 @@ public class NetworkNodeExternalStorage extends NetworkNode implements IStorageP } } - network.getNodeGraph().schedulePostRebuildAction(StorageCacheItem.INVALIDATE); - network.getNodeGraph().schedulePostRebuildAction(StorageCacheFluid.INVALIDATE); + network.getNodeGraph().addPostRebuildHandler(StorageCacheItem.INVALIDATE); + network.getNodeGraph().addPostRebuildHandler(StorageCacheFluid.INVALIDATE); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/externalstorage/StorageItemExternal.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/externalstorage/StorageItemExternal.java index 6f3a9bb28..94662b275 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/externalstorage/StorageItemExternal.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/externalstorage/StorageItemExternal.java @@ -84,7 +84,7 @@ public abstract class StorageItemExternal implements IStorage { this.cache = newStacks; - network.sendBatchedItemStorageDeltaToClient(); + network.getItemStorageCache().flush(); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheFluid.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheFluid.java index 1c38af1ba..9376a79ff 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheFluid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheFluid.java @@ -1,10 +1,7 @@ package com.raoulvdberge.refinedstorage.apiimpl.storage; import com.raoulvdberge.refinedstorage.api.network.INetwork; -import com.raoulvdberge.refinedstorage.api.storage.AccessType; -import com.raoulvdberge.refinedstorage.api.storage.IStorage; -import com.raoulvdberge.refinedstorage.api.storage.IStorageCache; -import com.raoulvdberge.refinedstorage.api.storage.IStorageProvider; +import com.raoulvdberge.refinedstorage.api.storage.*; import com.raoulvdberge.refinedstorage.api.util.IStackList; import com.raoulvdberge.refinedstorage.apiimpl.API; import net.minecraftforge.fluids.FluidStack; @@ -21,7 +18,7 @@ public class StorageCacheFluid implements IStorageCache { private INetwork network; private CopyOnWriteArrayList> storages = new CopyOnWriteArrayList<>(); private IStackList list = API.instance().createFluidStackList(); - private List listeners = new LinkedList<>(); + private List> listeners = new LinkedList<>(); public StorageCacheFluid(INetwork network) { this.network = network; @@ -49,9 +46,7 @@ public class StorageCacheFluid implements IStorageCache { } } - listeners.forEach(Runnable::run); - - network.sendFluidStorageToClient(); + listeners.forEach(IStorageCacheListener::onInvalidated); } @Override @@ -59,28 +54,31 @@ public class StorageCacheFluid implements IStorageCache { list.add(stack, size); if (!rebuilding) { - network.sendFluidStorageDeltaToClient(stack, size); - - listeners.forEach(Runnable::run); + listeners.forEach(l -> l.onChanged(stack, size)); } } @Override public synchronized void remove(@Nonnull FluidStack stack, int size, boolean batched) { if (list.remove(stack, size)) { - network.sendFluidStorageDeltaToClient(stack, -size); - - listeners.forEach(Runnable::run); + listeners.forEach(l -> l.onChanged(stack, -size)); } } @Override - public void addListener(Runnable listener) { - listeners.add(listener); + public void flush() { + throw new UnsupportedOperationException("Cannot flush fluid storage cache"); } @Override - public void removeListener(Runnable listener) { + public void addListener(IStorageCacheListener listener) { + listeners.add(listener); + + listener.onAttached(); + } + + @Override + public void removeListener(IStorageCacheListener listener) { listeners.remove(listener); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheItem.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheItem.java index c90ad4103..ec08d38ac 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheItem.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheItem.java @@ -1,15 +1,14 @@ package com.raoulvdberge.refinedstorage.apiimpl.storage; import com.raoulvdberge.refinedstorage.api.network.INetwork; -import com.raoulvdberge.refinedstorage.api.storage.AccessType; -import com.raoulvdberge.refinedstorage.api.storage.IStorage; -import com.raoulvdberge.refinedstorage.api.storage.IStorageCache; -import com.raoulvdberge.refinedstorage.api.storage.IStorageProvider; +import com.raoulvdberge.refinedstorage.api.storage.*; import com.raoulvdberge.refinedstorage.api.util.IStackList; import com.raoulvdberge.refinedstorage.apiimpl.API; import net.minecraft.item.ItemStack; +import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nonnull; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -21,7 +20,8 @@ public class StorageCacheItem implements IStorageCache { private INetwork network; private CopyOnWriteArrayList> storages = new CopyOnWriteArrayList<>(); private IStackList list = API.instance().createItemStackList(); - private List listeners = new LinkedList<>(); + private List> listeners = new LinkedList<>(); + private List> batchedChanges = new ArrayList<>(); public StorageCacheItem(INetwork network) { this.network = network; @@ -51,9 +51,7 @@ public class StorageCacheItem implements IStorageCache { } } - listeners.forEach(Runnable::run); - - network.sendItemStorageToClient(); + listeners.forEach(IStorageCacheListener::onInvalidated); } @Override @@ -61,28 +59,42 @@ public class StorageCacheItem implements IStorageCache { list.add(stack, size); if (!rebuilding) { - network.sendItemStorageDeltaToClient(stack, size, batched); - - listeners.forEach(Runnable::run); + if (!batched) { + listeners.forEach(l -> l.onChanged(stack, size)); + } else { + batchedChanges.add(Pair.of(stack, size)); + } } } @Override public synchronized void remove(@Nonnull ItemStack stack, int size, boolean batched) { if (list.remove(stack, size)) { - network.sendItemStorageDeltaToClient(stack, -size, batched); - - listeners.forEach(Runnable::run); + if (!batched) { + listeners.forEach(l -> l.onChanged(stack, -size)); + } else { + batchedChanges.add(Pair.of(stack, -size)); + } } } @Override - public void addListener(Runnable listener) { - listeners.add(listener); + public void flush() { + if (!batchedChanges.isEmpty()) { + batchedChanges.forEach(c -> listeners.forEach(l -> l.onChanged(c.getKey(), c.getValue()))); + batchedChanges.clear(); + } } @Override - public void removeListener(Runnable listener) { + public void addListener(IStorageCacheListener listener) { + listeners.add(listener); + + listener.onAttached(); + } + + @Override + public void removeListener(IStorageCacheListener listener) { listeners.remove(listener); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheItemPortable.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheItemPortable.java index 12f367dd2..2f8b2d188 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheItemPortable.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheItemPortable.java @@ -1,19 +1,12 @@ package com.raoulvdberge.refinedstorage.apiimpl.storage; -import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.api.storage.IStorage; import com.raoulvdberge.refinedstorage.api.storage.IStorageCache; -import com.raoulvdberge.refinedstorage.api.storage.IStorageTracker; +import com.raoulvdberge.refinedstorage.api.storage.IStorageCacheListener; import com.raoulvdberge.refinedstorage.api.util.IStackList; import com.raoulvdberge.refinedstorage.apiimpl.API; -import com.raoulvdberge.refinedstorage.network.MessageGridItemDelta; -import com.raoulvdberge.refinedstorage.network.MessageGridItemUpdate; import com.raoulvdberge.refinedstorage.tile.grid.portable.IPortableGrid; -import com.raoulvdberge.refinedstorage.util.StackUtils; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.network.ByteBufUtils; import javax.annotation.Nonnull; import java.util.Collections; @@ -23,7 +16,7 @@ import java.util.List; public class StorageCacheItemPortable implements IStorageCache { private IPortableGrid portableGrid; private IStackList list = API.instance().createItemStackList(); - private List listeners = new LinkedList<>(); + private List> listeners = new LinkedList<>(); public StorageCacheItemPortable(IPortableGrid portableGrid) { this.portableGrid = portableGrid; @@ -37,9 +30,7 @@ public class StorageCacheItemPortable implements IStorageCache { portableGrid.getStorage().getStacks().forEach(list::add); } - listeners.forEach(Runnable::run); - - portableGrid.getWatchers().forEach(this::sendUpdateTo); + listeners.forEach(IStorageCacheListener::onInvalidated); } @Override @@ -47,28 +38,31 @@ public class StorageCacheItemPortable implements IStorageCache { list.add(stack, size); if (!rebuilding) { - portableGrid.getWatchers().forEach(w -> RS.INSTANCE.network.sendTo(new MessageGridItemDelta(null, portableGrid.getStorageTracker(), stack, size), (EntityPlayerMP) w)); - - listeners.forEach(Runnable::run); + listeners.forEach(l -> l.onChanged(stack, size)); } } @Override public void remove(@Nonnull ItemStack stack, int size, boolean batched) { if (list.remove(stack, size)) { - portableGrid.getWatchers().forEach(w -> RS.INSTANCE.network.sendTo(new MessageGridItemDelta(null, portableGrid.getStorageTracker(), stack, -size), (EntityPlayerMP) w)); - - listeners.forEach(Runnable::run); + listeners.forEach(l -> l.onChanged(stack, -size)); } } @Override - public void addListener(Runnable listener) { - listeners.add(listener); + public void flush() { + throw new UnsupportedOperationException("Cannot flush portable grid storage cache"); } @Override - public void removeListener(Runnable listener) { + public void addListener(IStorageCacheListener listener) { + listeners.add(listener); + + listener.onAttached(); + } + + @Override + public void removeListener(IStorageCacheListener listener) { listeners.remove(listener); } @@ -86,21 +80,4 @@ public class StorageCacheItemPortable implements IStorageCache { public List> getStorages() { return Collections.emptyList(); } - - public void sendUpdateTo(EntityPlayer player) { - RS.INSTANCE.network.sendTo(new MessageGridItemUpdate(buf -> { - buf.writeInt(list.getStacks().size()); - - for (ItemStack stack : list.getStacks()) { - StackUtils.writeItemStack(buf, stack, null, false); - - IStorageTracker.IStorageTrackerEntry entry = portableGrid.getStorageTracker().get(stack); - buf.writeBoolean(entry != null); - if (entry != null) { - buf.writeLong(entry.getTime()); - ByteBufUtils.writeUTF8String(buf, entry.getName()); - } - } - }, false), (EntityPlayerMP) player); - } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheListenerGridFluid.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheListenerGridFluid.java new file mode 100644 index 000000000..fc78ec0d8 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheListenerGridFluid.java @@ -0,0 +1,37 @@ +package com.raoulvdberge.refinedstorage.apiimpl.storage; + +import com.raoulvdberge.refinedstorage.RS; +import com.raoulvdberge.refinedstorage.api.network.INetwork; +import com.raoulvdberge.refinedstorage.api.network.security.Permission; +import com.raoulvdberge.refinedstorage.api.storage.IStorageCacheListener; +import com.raoulvdberge.refinedstorage.network.MessageGridFluidDelta; +import com.raoulvdberge.refinedstorage.network.MessageGridFluidUpdate; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraftforge.fluids.FluidStack; + +import javax.annotation.Nonnull; + +public class StorageCacheListenerGridFluid implements IStorageCacheListener { + private EntityPlayerMP player; + private INetwork network; + + public StorageCacheListenerGridFluid(EntityPlayerMP player, INetwork network) { + this.player = player; + this.network = network; + } + + @Override + public void onAttached() { + RS.INSTANCE.network.sendTo(new MessageGridFluidUpdate(network, network.getSecurityManager().hasPermission(Permission.AUTOCRAFTING, player)), player); + } + + @Override + public void onInvalidated() { + // NO OP + } + + @Override + public void onChanged(@Nonnull FluidStack stack, int size) { + RS.INSTANCE.network.sendTo(new MessageGridFluidDelta(network, stack, size), player); + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheListenerGridItem.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheListenerGridItem.java new file mode 100644 index 000000000..9784467a2 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheListenerGridItem.java @@ -0,0 +1,37 @@ +package com.raoulvdberge.refinedstorage.apiimpl.storage; + +import com.raoulvdberge.refinedstorage.RS; +import com.raoulvdberge.refinedstorage.api.network.INetwork; +import com.raoulvdberge.refinedstorage.api.network.security.Permission; +import com.raoulvdberge.refinedstorage.api.storage.IStorageCacheListener; +import com.raoulvdberge.refinedstorage.network.MessageGridItemDelta; +import com.raoulvdberge.refinedstorage.network.MessageGridItemUpdate; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; + +import javax.annotation.Nonnull; + +public class StorageCacheListenerGridItem implements IStorageCacheListener { + private EntityPlayerMP player; + private INetwork network; + + public StorageCacheListenerGridItem(EntityPlayerMP player, INetwork network) { + this.player = player; + this.network = network; + } + + @Override + public void onAttached() { + RS.INSTANCE.network.sendTo(new MessageGridItemUpdate(network, network.getSecurityManager().hasPermission(Permission.AUTOCRAFTING, player)), player); + } + + @Override + public void onInvalidated() { + // NO OP + } + + @Override + public void onChanged(@Nonnull ItemStack stack, int size) { + RS.INSTANCE.network.sendTo(new MessageGridItemDelta(network, network.getItemStorageTracker(), stack, size), player); + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheListenerGridPortable.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheListenerGridPortable.java new file mode 100644 index 000000000..3d80a113d --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/storage/StorageCacheListenerGridPortable.java @@ -0,0 +1,52 @@ +package com.raoulvdberge.refinedstorage.apiimpl.storage; + +import com.raoulvdberge.refinedstorage.RS; +import com.raoulvdberge.refinedstorage.api.storage.IStorageCacheListener; +import com.raoulvdberge.refinedstorage.api.storage.IStorageTracker; +import com.raoulvdberge.refinedstorage.network.MessageGridItemDelta; +import com.raoulvdberge.refinedstorage.network.MessageGridItemUpdate; +import com.raoulvdberge.refinedstorage.tile.grid.portable.IPortableGrid; +import com.raoulvdberge.refinedstorage.util.StackUtils; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fml.common.network.ByteBufUtils; + +import javax.annotation.Nonnull; + +public class StorageCacheListenerGridPortable implements IStorageCacheListener { + private IPortableGrid portableGrid; + private EntityPlayerMP player; + + public StorageCacheListenerGridPortable(IPortableGrid portableGrid, EntityPlayerMP player) { + this.portableGrid = portableGrid; + this.player = player; + } + + @Override + public void onAttached() { + RS.INSTANCE.network.sendTo(new MessageGridItemUpdate(buf -> { + buf.writeInt(portableGrid.getCache().getList().getStacks().size()); + + for (ItemStack stack : portableGrid.getCache().getList().getStacks()) { + StackUtils.writeItemStack(buf, stack, null, false); + + IStorageTracker.IStorageTrackerEntry entry = portableGrid.getStorageTracker().get(stack); + buf.writeBoolean(entry != null); + if (entry != null) { + buf.writeLong(entry.getTime()); + ByteBufUtils.writeUTF8String(buf, entry.getName()); + } + } + }, false), player); + } + + @Override + public void onInvalidated() { + // NO OP + } + + @Override + public void onChanged(@Nonnull ItemStack stack, int size) { + RS.INSTANCE.network.sendTo(new MessageGridItemDelta(null, portableGrid.getStorageTracker(), stack, size), player); + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockGrid.java index 440ab4ddc..1982b21ce 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockGrid.java @@ -56,8 +56,8 @@ public class BlockGrid extends BlockNode { @Override public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) { - if (!world.isRemote && tryOpenNetworkGui(RSGui.GRID, player, world, pos, side)) { - ((TileGrid) world.getTileEntity(pos)).getNode().onOpened(player); + if (!world.isRemote) { + tryOpenNetworkGui(RSGui.GRID, player, world, pos, side); } return true; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockPortableGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockPortableGrid.java index 2e9ae95d5..e97b51b1e 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/block/BlockPortableGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/block/BlockPortableGrid.java @@ -11,7 +11,6 @@ import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; @@ -122,7 +121,7 @@ public class BlockPortableGrid extends BlockBase { if (!world.isRemote) { player.openGui(RS.INSTANCE, RSGui.PORTABLE_GRID, world, pos.getX(), pos.getY(), pos.getZ()); - ((TilePortableGrid) world.getTileEntity(pos)).onOpened((EntityPlayerMP) player); + ((TilePortableGrid) world.getTileEntity(pos)).onOpened(); } return true; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/container/ContainerGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/container/ContainerGrid.java index c92e7ffaf..c8794546f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/container/ContainerGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/container/ContainerGrid.java @@ -5,6 +5,8 @@ import com.raoulvdberge.refinedstorage.api.network.grid.GridType; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IFluidGridHandler; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IItemGridHandler; +import com.raoulvdberge.refinedstorage.api.storage.IStorageCache; +import com.raoulvdberge.refinedstorage.api.storage.IStorageCacheListener; import com.raoulvdberge.refinedstorage.api.storage.IStorageDiskProvider; import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeGrid; import com.raoulvdberge.refinedstorage.container.slot.*; @@ -27,6 +29,8 @@ public class ContainerGrid extends ContainerBase { public static final int TAB_HEIGHT = 31; private IGrid grid; + private IStorageCache cache; + private IStorageCacheListener listener; private IGridDisplay display; private SlotGridCraftingResult craftingResultSlot; @@ -158,12 +162,40 @@ public class ContainerGrid extends ContainerBase { } } + @Override + public void detectAndSendChanges() { + if (!getPlayer().world.isRemote) { + // The grid is offline. + if (grid.getStorageCache() == null) { + // The grid just went offline, there is still a listener. + if (listener != null) { + // Remove it from the previous cache and clean up. + cache.removeListener(listener); + + listener = null; + cache = null; + } + } else if (listener == null) { // The grid came online. + listener = grid.createListener((EntityPlayerMP) getPlayer()); + cache = grid.getStorageCache(); + + cache.addListener(listener); + } + } + + super.detectAndSendChanges(); + } + @Override public void onContainerClosed(EntityPlayer player) { super.onContainerClosed(player); if (!player.getEntityWorld().isRemote) { grid.onClosed(player); + + if (cache != null && listener != null) { + cache.removeListener(listener); + } } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiBase.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiBase.java index ef3c5df99..0f52661b6 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiBase.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/GuiBase.java @@ -24,13 +24,12 @@ import org.lwjgl.input.Mouse; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.function.Consumer; public abstract class GuiBase extends GuiContainer { private static final Map TEXTURE_CACHE = new HashMap<>(); + private static final Map> RUNNABLES = new HashMap<>(); public static final RenderUtils.FluidRenderer FLUID_RENDERER = new RenderUtils.FluidRenderer(-1, 16, 16); @@ -77,6 +76,16 @@ public abstract class GuiBase extends GuiContainer { this.ySize = screenHeight; } + private void runRunnables() { + Queue queue = RUNNABLES.get(getClass()); + if (queue != null && !queue.isEmpty()) { + Consumer callback; + while ((callback = queue.poll()) != null) { + callback.accept(this); + } + } + } + public Scrollbar getScrollbar() { return scrollbar; } @@ -92,6 +101,8 @@ public abstract class GuiBase extends GuiContainer { lastButtonId = 0; lastSideButtonY = getSideButtonYStart(); + runRunnables(); + init(guiLeft, guiTop); } @@ -106,6 +117,8 @@ public abstract class GuiBase extends GuiContainer { public void updateScreen() { super.updateScreen(); + runRunnables(); + update(guiLeft, guiTop); } @@ -365,4 +378,14 @@ public abstract class GuiBase extends GuiContainer { public int getGuiTop() { return guiTop; } + + public static void executeLater(Class clazz, Consumer callback) { + Queue queue = RUNNABLES.get(clazz); + + if (queue == null) { + RUNNABLES.put(clazz, queue = new ArrayDeque<>()); + } + + queue.add(callback); + } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GuiGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GuiGrid.java index 6f3f207f0..66b2bc45f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GuiGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/GuiGrid.java @@ -1,9 +1,6 @@ package com.raoulvdberge.refinedstorage.gui.grid; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.ListMultimap; import com.google.common.collect.Lists; -import com.google.common.collect.Multimaps; import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.RSKeyBindings; import com.raoulvdberge.refinedstorage.api.network.grid.GridType; @@ -14,10 +11,12 @@ import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeGrid; import com.raoulvdberge.refinedstorage.container.ContainerGrid; import com.raoulvdberge.refinedstorage.gui.GuiBase; import com.raoulvdberge.refinedstorage.gui.Scrollbar; -import com.raoulvdberge.refinedstorage.gui.grid.sorting.Sorter; -import com.raoulvdberge.refinedstorage.gui.grid.stack.GridStackFluid; +import com.raoulvdberge.refinedstorage.gui.grid.sorting.*; import com.raoulvdberge.refinedstorage.gui.grid.stack.GridStackItem; import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; +import com.raoulvdberge.refinedstorage.gui.grid.view.GridViewFluid; +import com.raoulvdberge.refinedstorage.gui.grid.view.GridViewItem; +import com.raoulvdberge.refinedstorage.gui.grid.view.IGridView; import com.raoulvdberge.refinedstorage.gui.sidebutton.*; import com.raoulvdberge.refinedstorage.integration.jei.IntegrationJEI; import com.raoulvdberge.refinedstorage.integration.jei.RSJEIPlugin; @@ -37,13 +36,11 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.resources.I18n; import net.minecraft.init.SoundEvents; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.client.event.RenderTooltipEvent; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fml.client.config.GuiCheckBox; import net.minecraftforge.fml.client.config.GuiUtils; import net.minecraftforge.fml.common.FMLCommonHandler; @@ -51,44 +48,43 @@ import org.lwjgl.input.Keyboard; import java.io.IOException; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; public class GuiGrid extends GuiBase implements IGridDisplay { - private static final List SEARCH_HISTORY = new ArrayList<>(); - - public static final ListMultimap ITEMS = Multimaps.synchronizedListMultimap(ArrayListMultimap.create()); - public static final ListMultimap FLUIDS = Multimaps.synchronizedListMultimap(ArrayListMultimap.create()); - - public static List STACKS = new ArrayList<>(); - public static boolean CAN_CRAFT; - - private static final Sorter SORTER = new Sorter(); - private static boolean SCHEDULE_SORT; - - private boolean wasConnected; + private IGridView view; private GuiTextField searchField; - private GuiCheckBox oredictPattern; private GuiCheckBox processingPattern; private GuiCheckBox blockingPattern; - private GuiButton tabPageLeft; private GuiButton tabPageRight; private IGrid grid; + private boolean wasConnected; private boolean hadTabs = false; + private int tabHovering = -1; private int slotNumber; - private int searchHistory = -1; + private List searchHistory = new ArrayList<>(); + private int searchHistoryIndex = -1; public GuiGrid(ContainerGrid container, IGrid grid) { super(container, grid.getType() == GridType.FLUID ? 193 : 227, 0); + List defaultSorters = new LinkedList<>(); + defaultSorters.add(new GridSorterName()); + defaultSorters.add(new GridSorterQuantity()); + defaultSorters.add(new GridSorterID()); + defaultSorters.add(new GridSorterInventoryTweaks()); + defaultSorters.add(new GridSorterLastModified()); + this.grid = grid; + this.view = grid.getType() == GridType.FLUID ? new GridViewFluid(this, defaultSorters) : new GridViewItem(this, defaultSorters); this.wasConnected = this.grid.isActive(); } @@ -149,7 +145,7 @@ public class GuiGrid extends GuiBase implements IGridDisplay { addSideButton(new SideButtonGridSearchBoxMode(this)); addSideButton(new SideButtonGridSize(this, grid)); - scheduleSort(); + view.sort(); } @Override @@ -161,8 +157,8 @@ public class GuiGrid extends GuiBase implements IGridDisplay { return grid; } - public static void scheduleSort() { - SCHEDULE_SORT = true; + public IGridView getView() { + return view; } @Override @@ -170,7 +166,7 @@ public class GuiGrid extends GuiBase implements IGridDisplay { if (wasConnected != grid.isActive()) { wasConnected = grid.isActive(); - scheduleSort(); + view.sort(); } boolean hasTabs = !getGrid().getTabs().isEmpty(); @@ -180,12 +176,6 @@ public class GuiGrid extends GuiBase implements IGridDisplay { initGui(); } - - if (SCHEDULE_SORT) { - SCHEDULE_SORT = false; - - SORTER.startIfPossible(this); - } } @Override @@ -221,7 +211,7 @@ public class GuiGrid extends GuiBase implements IGridDisplay { @Override public int getRows() { - return Math.max(0, (int) Math.ceil((float) STACKS.size() / 9F)); + return Math.max(0, (int) Math.ceil((float) view.getStacks().size() / 9F)); } @Override @@ -243,7 +233,7 @@ public class GuiGrid extends GuiBase implements IGridDisplay { } public boolean isOverSlotWithStack() { - return grid.isActive() && isOverSlot() && slotNumber < STACKS.size(); + return grid.isActive() && isOverSlot() && slotNumber < view.getStacks().size(); } private boolean isOverSlot() { @@ -420,8 +410,8 @@ public class GuiGrid extends GuiBase implements IGridDisplay { this.slotNumber = slot; } - if (slot < STACKS.size()) { - STACKS.get(slot).draw(this, x, y); + if (slot < view.getStacks().size()) { + view.getStacks().get(slot).draw(this, x, y); } if (inBounds(x, y, 16, 16, mouseX, mouseY) || !grid.isActive()) { @@ -449,7 +439,7 @@ public class GuiGrid extends GuiBase implements IGridDisplay { } if (isOverSlotWithStack()) { - drawGridTooltip(STACKS.get(slotNumber), mouseX, mouseY); + drawGridTooltip(view.getStacks().get(slotNumber), mouseX, mouseY); } if (isOverClear(mouseX, mouseY)) { @@ -653,7 +643,7 @@ public class GuiGrid extends GuiBase implements IGridDisplay { searchField.setText(""); searchField.setFocused(true); - scheduleSort(); + view.sort(); updateJEI(); } else if (wasSearchFieldFocused != searchField.isFocused()) { @@ -681,9 +671,9 @@ public class GuiGrid extends GuiBase implements IGridDisplay { if (isOverSlotWithStack()) { if (grid.getType() != GridType.FLUID && (held.isEmpty() || (!held.isEmpty() && clickedButton == 2))) { - GridStackItem stack = (GridStackItem) STACKS.get(slotNumber); + GridStackItem stack = (GridStackItem) view.getStacks().get(slotNumber); - if (stack.isCraftable() && (stack.doesDisplayCraftText() || (GuiScreen.isShiftKeyDown() && GuiScreen.isCtrlKeyDown())) && CAN_CRAFT) { + if (stack.isCraftable() && (stack.doesDisplayCraftText() || (GuiScreen.isShiftKeyDown() && GuiScreen.isCtrlKeyDown())) && view.canCraft()) { FMLCommonHandler.instance().showGuiScreen(new GuiCraftingStart(this, ((ContainerGrid) this.inventorySlots).getPlayer(), stack)); } else { int flags = 0; @@ -703,7 +693,7 @@ public class GuiGrid extends GuiBase implements IGridDisplay { RS.INSTANCE.network.sendToServer(new MessageGridItemPull(stack.getHash(), flags)); } } else if (grid.getType() == GridType.FLUID && held.isEmpty()) { - RS.INSTANCE.network.sendToServer(new MessageGridFluidPull(STACKS.get(slotNumber).getHash(), GuiScreen.isShiftKeyDown())); + RS.INSTANCE.network.sendToServer(new MessageGridFluidPull(view.getStacks().get(slotNumber).getHash(), GuiScreen.isShiftKeyDown())); } } } @@ -723,7 +713,7 @@ public class GuiGrid extends GuiBase implements IGridDisplay { // NO OP } else if (searchField.textboxKeyTyped(character, keyCode)) { updateJEI(); - scheduleSort(); + view.sort(); keyHandled = true; } else if (searchField.isFocused() && (keyCode == Keyboard.KEY_UP || keyCode == Keyboard.KEY_DOWN || keyCode == Keyboard.KEY_RETURN)) { @@ -752,25 +742,25 @@ public class GuiGrid extends GuiBase implements IGridDisplay { } private void updateSearchHistory(int delta) { - if (SEARCH_HISTORY.isEmpty()) { + if (searchHistory.isEmpty()) { return; } - if (searchHistory == -1) { - searchHistory = SEARCH_HISTORY.size(); + if (searchHistoryIndex == -1) { + searchHistoryIndex = searchHistory.size(); } - searchHistory += delta; + searchHistoryIndex += delta; - if (searchHistory < 0) { - searchHistory = 0; - } else if (searchHistory > SEARCH_HISTORY.size() - 1) { - searchHistory = SEARCH_HISTORY.size() - 1; + if (searchHistoryIndex < 0) { + searchHistoryIndex = 0; + } else if (searchHistoryIndex > searchHistory.size() - 1) { + searchHistoryIndex = searchHistory.size() - 1; if (delta == 1) { searchField.setText(""); - scheduleSort(); + view.sort(); updateJEI(); @@ -778,20 +768,20 @@ public class GuiGrid extends GuiBase implements IGridDisplay { } } - searchField.setText(SEARCH_HISTORY.get(searchHistory)); + searchField.setText(searchHistory.get(searchHistoryIndex)); - scheduleSort(); + view.sort(); updateJEI(); } private void saveHistory() { - if (!SEARCH_HISTORY.isEmpty() && SEARCH_HISTORY.get(SEARCH_HISTORY.size() - 1).equals(searchField.getText())) { + if (!searchHistory.isEmpty() && searchHistory.get(searchHistory.size() - 1).equals(searchField.getText())) { return; } if (!searchField.getText().trim().isEmpty()) { - SEARCH_HISTORY.add(searchField.getText()); + searchHistory.add(searchField.getText()); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterDirection.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterDirection.java new file mode 100644 index 000000000..7d77da0dc --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterDirection.java @@ -0,0 +1,6 @@ +package com.raoulvdberge.refinedstorage.gui.grid.sorting; + +public enum GridSorterDirection { + ASCENDING, + DESCENDING +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingID.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterID.java similarity index 64% rename from src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingID.java rename to src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterID.java index 953aabe74..672170d16 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingID.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterID.java @@ -5,9 +5,14 @@ import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -public class GridSortingID extends GridSorting { +public class GridSorterID implements IGridSorter { @Override - public int compare(IGridStack left, IGridStack right) { + public boolean isApplicable(IGrid grid) { + return grid.getSortingType() == IGrid.SORTING_TYPE_ID; + } + + @Override + public int compare(IGridStack left, IGridStack right, GridSorterDirection sortingDirection) { int x = left.getHash(); int y = right.getHash(); @@ -17,9 +22,9 @@ public class GridSortingID extends GridSorting { } if (x != y) { - if (sortingDirection == IGrid.SORTING_DIRECTION_DESCENDING) { + if (sortingDirection == GridSorterDirection.DESCENDING) { return Integer.compare(x, y); - } else if (sortingDirection == IGrid.SORTING_DIRECTION_ASCENDING) { + } else if (sortingDirection == GridSorterDirection.ASCENDING) { return Integer.compare(y, x); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingInventoryTweaks.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterInventoryTweaks.java similarity index 64% rename from src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingInventoryTweaks.java rename to src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterInventoryTweaks.java index e42471475..7e29ad953 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingInventoryTweaks.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterInventoryTweaks.java @@ -1,17 +1,17 @@ package com.raoulvdberge.refinedstorage.gui.grid.sorting; -import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeGrid; +import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; import com.raoulvdberge.refinedstorage.gui.grid.stack.GridStackItem; import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; import invtweaks.api.InvTweaksAPI; import net.minecraftforge.fml.common.Loader; -public class GridSortingInventoryTweaks extends GridSorting { +public class GridSorterInventoryTweaks implements IGridSorter { public static final String MOD_ID = "inventorytweaks"; private InvTweaksAPI api = null; - public GridSortingInventoryTweaks() { + public GridSorterInventoryTweaks() { try { api = (InvTweaksAPI) Class.forName("invtweaks.forge.InvTweaksMod", true, Loader.instance().getModClassLoader()).getField("instance").get(null); } catch (Exception e) { @@ -20,15 +20,21 @@ public class GridSortingInventoryTweaks extends GridSorting { } @Override - public int compare(IGridStack left, IGridStack right) { + public boolean isApplicable(IGrid grid) { + return grid.getSortingType() == IGrid.SORTING_TYPE_INVENTORYTWEAKS; + } + + @Override + public int compare(IGridStack left, IGridStack right, GridSorterDirection sortingDirection) { if (api != null && left instanceof GridStackItem && right instanceof GridStackItem) { - if (sortingDirection == NetworkNodeGrid.SORTING_DIRECTION_DESCENDING) { + if (sortingDirection == GridSorterDirection.DESCENDING) { return api.compareItems(((GridStackItem) left).getStack(), ((GridStackItem) right).getStack()); - } else if (sortingDirection == NetworkNodeGrid.SORTING_DIRECTION_ASCENDING) { + } else if (sortingDirection == GridSorterDirection.ASCENDING) { return api.compareItems(((GridStackItem) right).getStack(), ((GridStackItem) left).getStack()); } } return 0; } + } \ No newline at end of file diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingLastModified.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterLastModified.java similarity index 57% rename from src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingLastModified.java rename to src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterLastModified.java index 322632811..4b0b09216 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingLastModified.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterLastModified.java @@ -3,17 +3,22 @@ package com.raoulvdberge.refinedstorage.gui.grid.sorting; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; -public class GridSortingLastModified extends GridSorting { +public class GridSorterLastModified implements IGridSorter { @Override - public int compare(IGridStack left, IGridStack right) { + public boolean isApplicable(IGrid grid) { + return grid.getSortingType() == IGrid.SORTING_TYPE_LAST_MODIFIED; + } + + @Override + public int compare(IGridStack left, IGridStack right, GridSorterDirection sortingDirection) { long lt = left.getTrackerEntry() != null ? left.getTrackerEntry().getTime() : 0; long rt = right.getTrackerEntry() != null ? right.getTrackerEntry().getTime() : 0; if (lt != rt) { // For "last modified" the comparison is reversed - if (sortingDirection == IGrid.SORTING_DIRECTION_DESCENDING) { + if (sortingDirection == GridSorterDirection.DESCENDING) { return Long.compare(rt, lt); - } else if (sortingDirection == IGrid.SORTING_DIRECTION_ASCENDING) { + } else if (sortingDirection == GridSorterDirection.ASCENDING) { return Long.compare(lt, rt); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingName.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterName.java old mode 100755 new mode 100644 similarity index 50% rename from src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingName.java rename to src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterName.java index e8bdf5014..ce4b002a0 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingName.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterName.java @@ -3,15 +3,20 @@ package com.raoulvdberge.refinedstorage.gui.grid.sorting; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; -public class GridSortingName extends GridSorting { +public class GridSorterName implements IGridSorter { @Override - public int compare(IGridStack left, IGridStack right) { + public boolean isApplicable(IGrid grid) { + return grid.getSortingType() == IGrid.SORTING_TYPE_NAME; + } + + @Override + public int compare(IGridStack left, IGridStack right, GridSorterDirection sortingDirection) { String leftName = left.getName(); String rightName = right.getName(); - if (sortingDirection == IGrid.SORTING_DIRECTION_ASCENDING) { + if (sortingDirection == GridSorterDirection.ASCENDING) { return leftName.compareTo(rightName); - } else if (sortingDirection == IGrid.SORTING_DIRECTION_DESCENDING) { + } else if (sortingDirection == GridSorterDirection.DESCENDING) { return rightName.compareTo(leftName); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingQuantity.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterQuantity.java old mode 100755 new mode 100644 similarity index 52% rename from src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingQuantity.java rename to src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterQuantity.java index e40e5cbf8..b8b075bb0 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSortingQuantity.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorterQuantity.java @@ -3,16 +3,21 @@ package com.raoulvdberge.refinedstorage.gui.grid.sorting; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; -public class GridSortingQuantity extends GridSorting { +public class GridSorterQuantity implements IGridSorter { @Override - public int compare(IGridStack left, IGridStack right) { + public boolean isApplicable(IGrid grid) { + return grid.getSortingType() == IGrid.SORTING_TYPE_QUANTITY; + } + + @Override + public int compare(IGridStack left, IGridStack right, GridSorterDirection sortingDirection) { int leftSize = left.getQuantity(); int rightSize = right.getQuantity(); if (leftSize != rightSize) { - if (sortingDirection == IGrid.SORTING_DIRECTION_ASCENDING) { + if (sortingDirection == GridSorterDirection.ASCENDING) { return (leftSize > rightSize) ? 1 : -1; - } else if (sortingDirection == IGrid.SORTING_DIRECTION_DESCENDING) { + } else if (sortingDirection == GridSorterDirection.DESCENDING) { return (rightSize > leftSize) ? 1 : -1; } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorting.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorting.java deleted file mode 100755 index 23c1db2f8..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/GridSorting.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.raoulvdberge.refinedstorage.gui.grid.sorting; - -import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; - -import java.util.Comparator; - -public abstract class GridSorting implements Comparator { - protected int sortingDirection; - - public void setSortingDirection(int sortingDirection) { - this.sortingDirection = sortingDirection; - } -} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/IGridSorter.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/IGridSorter.java new file mode 100644 index 000000000..cad527dd5 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/IGridSorter.java @@ -0,0 +1,10 @@ +package com.raoulvdberge.refinedstorage.gui.grid.sorting; + +import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; +import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; + +public interface IGridSorter { + boolean isApplicable(IGrid grid); + + int compare(IGridStack left, IGridStack right, GridSorterDirection direction); +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/Sorter.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/Sorter.java deleted file mode 100644 index 3a20dc084..000000000 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/sorting/Sorter.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.raoulvdberge.refinedstorage.gui.grid.sorting; - -import com.raoulvdberge.refinedstorage.api.network.grid.GridType; -import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; -import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; -import com.raoulvdberge.refinedstorage.gui.grid.filtering.GridFilterParser; -import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.function.Predicate; - -public class Sorter implements Runnable { - private static final GridSorting SORTING_QUANTITY = new GridSortingQuantity(); - private static final GridSorting SORTING_NAME = new GridSortingName(); - private static final GridSorting SORTING_ID = new GridSortingID(); - private static final GridSorting SORTING_INVENTORYTWEAKS = new GridSortingInventoryTweaks(); - private static final GridSorting SORTING_LAST_MODIFIED = new GridSortingLastModified(); - - private boolean busy; - - private GuiGrid gui; - - @Override - public void run() { - IGrid grid = gui.getGrid(); - - List stacks = new ArrayList<>(); - - if (grid.isActive()) { - stacks.addAll(grid.getType() == GridType.FLUID ? GuiGrid.FLUIDS.values() : GuiGrid.ITEMS.values()); - - List> filters = GridFilterParser.getFilters( - grid, - gui.getSearchField() != null ? gui.getSearchField().getText() : "", - (grid.getTabSelected() >= 0 && grid.getTabSelected() < grid.getTabs().size()) ? grid.getTabs().get(grid.getTabSelected()).getFilters() : grid.getFilters() - ); - - Iterator t = stacks.iterator(); - - while (t.hasNext()) { - IGridStack stack = t.next(); - - for (Predicate filter : filters) { - if (!filter.test(stack)) { - t.remove(); - - break; - } - } - } - - SORTING_NAME.setSortingDirection(grid.getSortingDirection()); - SORTING_QUANTITY.setSortingDirection(grid.getSortingDirection()); - SORTING_ID.setSortingDirection(grid.getSortingDirection()); - SORTING_INVENTORYTWEAKS.setSortingDirection(grid.getSortingDirection()); - SORTING_LAST_MODIFIED.setSortingDirection(grid.getSortingDirection()); - - stacks.sort(SORTING_NAME); - - if (grid.getSortingType() == IGrid.SORTING_TYPE_QUANTITY) { - stacks.sort(SORTING_QUANTITY); - } else if (grid.getSortingType() == IGrid.SORTING_TYPE_ID) { - stacks.sort(SORTING_ID); - } else if (grid.getSortingType() == IGrid.SORTING_TYPE_INVENTORYTWEAKS) { - stacks.sort(SORTING_INVENTORYTWEAKS); - } else if (grid.getSortingType() == IGrid.SORTING_TYPE_LAST_MODIFIED) { - stacks.sort(SORTING_LAST_MODIFIED); - } - } - - GuiGrid.STACKS = stacks; - - if (gui.getScrollbar() != null) { - gui.getScrollbar().setEnabled(gui.getRows() > gui.getVisibleRows()); - gui.getScrollbar().setMaxOffset(gui.getRows() - gui.getVisibleRows()); - } - - if (gui.getTabPageLeft() != null) { - gui.getTabPageLeft().visible = grid.getTotalTabPages() > 0; - } - - if (gui.getTabPageRight() != null) { - gui.getTabPageRight().visible = grid.getTotalTabPages() > 0; - } - - this.busy = false; - } - - public void startIfPossible(GuiGrid gui) { - if (!busy) { - this.busy = true; - this.gui = gui; - - new Thread(this, "RS grid sorting").start(); - } - } -} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/stack/GridStackFluid.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/stack/GridStackFluid.java index dbb17fc18..5d89d93c9 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/stack/GridStackFluid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/stack/GridStackFluid.java @@ -85,9 +85,4 @@ public class GridStackFluid implements IGridStack { public void setTrackerEntry(@Nullable IStorageTracker.IStorageTrackerEntry entry) { this.entry = entry; } - - @Override - public boolean equals(Object obj) { - return obj instanceof GridStackFluid && ((GridStackFluid) obj).getStack().isFluidEqual(stack); - } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/stack/GridStackItem.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/stack/GridStackItem.java index f4f669f6e..ad40b7234 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/stack/GridStackItem.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/stack/GridStackItem.java @@ -150,9 +150,4 @@ public class GridStackItem implements IGridStack { public void setTrackerEntry(@Nullable IStorageTracker.IStorageTrackerEntry entry) { this.entry = entry; } - - @Override - public boolean equals(Object obj) { - return obj instanceof IGridStack && ((GridStackItem) obj).getHash() == hash; - } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/view/GridViewBase.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/view/GridViewBase.java new file mode 100644 index 000000000..ad4b151a5 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/view/GridViewBase.java @@ -0,0 +1,62 @@ +package com.raoulvdberge.refinedstorage.gui.grid.view; + +import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; +import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; +import com.raoulvdberge.refinedstorage.gui.grid.filtering.GridFilterParser; +import com.raoulvdberge.refinedstorage.gui.grid.sorting.GridSorterDirection; +import com.raoulvdberge.refinedstorage.gui.grid.sorting.GridSorterName; +import com.raoulvdberge.refinedstorage.gui.grid.sorting.IGridSorter; +import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; + +import java.util.Iterator; +import java.util.List; +import java.util.function.Predicate; + +public abstract class GridViewBase implements IGridView { + protected void sortAndFilter(GuiGrid gui, List stacks, List sorters) { + IGrid grid = gui.getGrid(); + + List> filters = GridFilterParser.getFilters( + grid, + gui.getSearchField() != null ? gui.getSearchField().getText() : "", + (grid.getTabSelected() >= 0 && grid.getTabSelected() < grid.getTabs().size()) ? grid.getTabs().get(grid.getTabSelected()).getFilters() : grid.getFilters() + ); + + Iterator it = stacks.iterator(); + + while (it.hasNext()) { + IGridStack stack = it.next(); + + for (Predicate filter : filters) { + if (!filter.test(stack)) { + it.remove(); + + break; + } + } + } + + GridSorterDirection sortingDirection = grid.getSortingDirection() == IGrid.SORTING_DIRECTION_DESCENDING ? GridSorterDirection.DESCENDING : GridSorterDirection.ASCENDING; + + stacks.sort((left, right) -> new GridSorterName().compare(left, right, sortingDirection)); + + sorters.stream().filter(s -> s.isApplicable(grid)).forEach(s -> { + stacks.sort((left, right) -> s.compare(left, right, sortingDirection)); + }); + } + + protected void updateUI(GuiGrid gui) { + if (gui.getScrollbar() != null) { + gui.getScrollbar().setEnabled(gui.getRows() > gui.getVisibleRows()); + gui.getScrollbar().setMaxOffset(gui.getRows() - gui.getVisibleRows()); + } + + if (gui.getTabPageLeft() != null) { + gui.getTabPageLeft().visible = gui.getGrid().getTotalTabPages() > 0; + } + + if (gui.getTabPageRight() != null) { + gui.getTabPageRight().visible = gui.getGrid().getTotalTabPages() > 0; + } + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/view/GridViewFluid.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/view/GridViewFluid.java new file mode 100644 index 000000000..e0d3fe75f --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/view/GridViewFluid.java @@ -0,0 +1,80 @@ +package com.raoulvdberge.refinedstorage.gui.grid.view; + +import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; +import com.raoulvdberge.refinedstorage.gui.grid.sorting.IGridSorter; +import com.raoulvdberge.refinedstorage.gui.grid.stack.GridStackFluid; +import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class GridViewFluid extends GridViewBase { + private Map map = new HashMap<>(); + private List stacks; + private GuiGrid gui; + private List sorters; + private boolean canCraft; + + public GridViewFluid(GuiGrid gui, List sorters) { + this.sorters = sorters; + this.gui = gui; + } + + @Override + public List getStacks() { + return stacks; + } + + @Override + public void setStacks(List stacks) { + map.clear(); + + for (IGridStack stack : stacks) { + map.put(stack.getHash(), (GridStackFluid) stack); + } + } + + @Override + public void postChange(IGridStack stack, int delta) { + GridStackFluid existing = map.get(stack.getHash()); + + if (existing == null) { + map.put(stack.getHash(), (GridStackFluid) stack); + } else { + if (existing.getStack().amount + delta <= 0) { + map.remove(existing.getHash()); + } else { + existing.getStack().amount += delta; + } + + existing.setTrackerEntry(stack.getTrackerEntry()); + } + } + + @Override + public void setCanCraft(boolean canCraft) { + this.canCraft = canCraft; + } + + @Override + public boolean canCraft() { + return canCraft; + } + + @Override + public void sort() { + List stacks = new ArrayList<>(); + + if (gui.getGrid().isActive()) { + stacks.addAll(map.values()); + + new Thread(() -> sortAndFilter(gui, stacks, sorters)).start(); + } + + this.stacks = stacks; + + updateUI(gui); + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/view/GridViewItem.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/view/GridViewItem.java new file mode 100644 index 000000000..5ae067b50 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/view/GridViewItem.java @@ -0,0 +1,97 @@ +package com.raoulvdberge.refinedstorage.gui.grid.view; + +import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; +import com.raoulvdberge.refinedstorage.gui.grid.sorting.IGridSorter; +import com.raoulvdberge.refinedstorage.gui.grid.stack.GridStackItem; +import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class GridViewItem extends GridViewBase { + private Map map = new HashMap<>(); + private List stacks; + private GuiGrid gui; + private List sorters; + private boolean canCraft; + + public GridViewItem(GuiGrid gui, List sorters) { + this.gui = gui; + this.sorters = sorters; + } + + @Override + public List getStacks() { + return stacks; + } + + @Override + public void setStacks(List stacks) { + map.clear(); + + for (IGridStack stack : stacks) { + // Don't let a craftable stack override a normal stack + if (((GridStackItem) stack).doesDisplayCraftText() && map.containsKey(stack.getHash())) { + continue; + } + + map.put(stack.getHash(), (GridStackItem) stack); + } + } + + @Override + public void postChange(IGridStack stack, int delta) { + GridStackItem existing = map.get(stack.getHash()); + + if (existing == null) { + ((GridStackItem) stack).getStack().setCount(delta); + + map.put(stack.getHash(), (GridStackItem) stack); + } else { + if (existing.getStack().getCount() + delta <= 0) { + if (existing.isCraftable()) { + existing.setDisplayCraftText(true); + } else { + map.remove(existing.getHash()); + } + } else { + if (existing.doesDisplayCraftText()) { + existing.setDisplayCraftText(false); + + existing.getStack().setCount(delta); + } else { + existing.getStack().grow(delta); + } + } + + existing.setTrackerEntry(stack.getTrackerEntry()); + } + } + + @Override + public void setCanCraft(boolean canCraft) { + this.canCraft = canCraft; + } + + @Override + public boolean canCraft() { + return canCraft; + } + + @Override + public void sort() { + List stacks = new ArrayList<>(); + + if (gui.getGrid().isActive()) { + stacks.addAll(map.values()); + + new Thread(() -> sortAndFilter(gui, stacks, sorters)).start(); + } + + this.stacks = stacks; + + updateUI(gui); + } +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/view/IGridView.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/view/IGridView.java new file mode 100644 index 000000000..79bbbfe20 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/grid/view/IGridView.java @@ -0,0 +1,19 @@ +package com.raoulvdberge.refinedstorage.gui.grid.view; + +import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; + +import java.util.List; + +public interface IGridView { + List getStacks(); + + void setStacks(List stacks); + + void postChange(IGridStack stack, int delta); + + void setCanCraft(boolean canCraft); + + boolean canCraft(); + + void sort(); +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/gui/sidebutton/SideButtonGridSortingType.java b/src/main/java/com/raoulvdberge/refinedstorage/gui/sidebutton/SideButtonGridSortingType.java index 4c6fc8962..17a6db67f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/gui/sidebutton/SideButtonGridSortingType.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/gui/sidebutton/SideButtonGridSortingType.java @@ -4,7 +4,7 @@ import com.raoulvdberge.refinedstorage.api.network.grid.GridType; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeGrid; import com.raoulvdberge.refinedstorage.gui.GuiBase; -import com.raoulvdberge.refinedstorage.gui.grid.sorting.GridSortingInventoryTweaks; +import com.raoulvdberge.refinedstorage.gui.grid.sorting.GridSorterInventoryTweaks; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.fml.common.Loader; @@ -46,7 +46,7 @@ public class SideButtonGridSortingType extends SideButton { } else if (type == IGrid.SORTING_TYPE_ID) { type = IGrid.SORTING_TYPE_LAST_MODIFIED; } else if (type == NetworkNodeGrid.SORTING_TYPE_LAST_MODIFIED) { - if (grid.getType() == GridType.FLUID || !Loader.isModLoaded(GridSortingInventoryTweaks.MOD_ID)) { + if (grid.getType() == GridType.FLUID || !Loader.isModLoaded(GridSorterInventoryTweaks.MOD_ID)) { type = IGrid.SORTING_TYPE_QUANTITY; } else { type = IGrid.SORTING_TYPE_INVENTORYTWEAKS; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/integration/jei/GuiHandlerGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/integration/jei/GuiHandlerGrid.java index 6f9b54c16..308850fd3 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/integration/jei/GuiHandlerGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/integration/jei/GuiHandlerGrid.java @@ -26,7 +26,7 @@ public class GuiHandlerGrid implements IAdvancedGuiHandler { mouseY -= gui.getGuiTop(); if (gui.getScrollbar() != null && !gui.getSearchField().isFocused() && gui.isOverSlotArea(mouseX, mouseY)) { - return gui.getSlotNumber() >= 0 && gui.getSlotNumber() < GuiGrid.STACKS.size() ? GuiGrid.STACKS.get(gui.getSlotNumber()).getIngredient() : null; + return gui.getSlotNumber() >= 0 && gui.getSlotNumber() < gui.getView().getStacks().size() ? gui.getView().getStacks().get(gui.getSlotNumber()).getIngredient() : null; } return null; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerFilter.java b/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerFilter.java index 008ec823e..2ad707121 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerFilter.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerFilter.java @@ -5,6 +5,7 @@ import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab; import com.raoulvdberge.refinedstorage.api.util.IFilter; import com.raoulvdberge.refinedstorage.apiimpl.network.grid.GridTab; import com.raoulvdberge.refinedstorage.apiimpl.util.Filter; +import com.raoulvdberge.refinedstorage.gui.GuiBase; import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; import com.raoulvdberge.refinedstorage.item.ItemFilter; import net.minecraft.item.ItemStack; @@ -43,7 +44,7 @@ public class ItemHandlerFilter extends ItemHandlerBase { } if (FMLCommonHandler.instance().getSide() == Side.CLIENT) { - GuiGrid.scheduleSort(); + GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort()); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerInterface.java b/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerInterface.java index d32209dba..3d4301624 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerInterface.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerInterface.java @@ -2,6 +2,7 @@ package com.raoulvdberge.refinedstorage.inventory; import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.storage.IStorageCache; +import com.raoulvdberge.refinedstorage.api.storage.IStorageCacheListener; import com.raoulvdberge.refinedstorage.api.util.IComparer; import com.raoulvdberge.refinedstorage.util.StackUtils; import net.minecraft.item.ItemStack; @@ -9,7 +10,7 @@ import net.minecraftforge.items.IItemHandler; import javax.annotation.Nonnull; -public class ItemHandlerInterface implements IItemHandler, Runnable { +public class ItemHandlerInterface implements IItemHandler, IStorageCacheListener { private INetwork network; private IStorageCache storageCache; private IItemHandler importItems; @@ -67,12 +68,22 @@ public class ItemHandlerInterface implements IItemHandler, Runnable { return 64; } - @Override - public void run() { - invalidate(); - } - private void invalidate() { this.storageCacheData = storageCache.getList().getStacks().toArray(new ItemStack[0]); } + + @Override + public void onAttached() { + // NO OP + } + + @Override + public void onInvalidated() { + invalidate(); + } + + @Override + public void onChanged(@Nonnull ItemStack stack, int size) { + invalidate(); + } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerStorage.java b/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerStorage.java index 9b45c9161..9cb2b3fcf 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerStorage.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/inventory/ItemHandlerStorage.java @@ -9,7 +9,7 @@ import net.minecraftforge.items.IItemHandler; import javax.annotation.Nonnull; -public class ItemHandlerStorage implements IItemHandler, Runnable { +public class ItemHandlerStorage implements IItemHandler { private IStorage storage; private IStorageCache storageCache; private ItemStack[] storageCacheData; @@ -50,12 +50,7 @@ public class ItemHandlerStorage implements IItemHandler, Runnable { return 64; } - @Override - public void run() { - invalidate(); - } - - private void invalidate() { + public void invalidate() { this.storageCacheData = storageCache.getList().getStacks().toArray(new ItemStack[0]); } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridFluidDelta.java b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridFluidDelta.java index 87fec4043..eeb6e8530 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridFluidDelta.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridFluidDelta.java @@ -3,11 +3,11 @@ package com.raoulvdberge.refinedstorage.network; import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.storage.IStorageTracker; import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageTrackerEntry; +import com.raoulvdberge.refinedstorage.gui.GuiBase; import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; import com.raoulvdberge.refinedstorage.gui.grid.stack.GridStackFluid; import com.raoulvdberge.refinedstorage.util.StackUtils; import io.netty.buffer.ByteBuf; -import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; @@ -52,26 +52,10 @@ public class MessageGridFluidDelta implements IMessage, IMessageHandler { + grid.getView().postChange(message.clientStack, message.delta); + grid.getView().sort(); + }); return null; } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridFluidUpdate.java b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridFluidUpdate.java index 0998dcf66..cff87323a 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridFluidUpdate.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridFluidUpdate.java @@ -3,8 +3,10 @@ package com.raoulvdberge.refinedstorage.network; import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.storage.IStorageTracker; import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageTrackerEntry; +import com.raoulvdberge.refinedstorage.gui.GuiBase; import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; import com.raoulvdberge.refinedstorage.gui.grid.stack.GridStackFluid; +import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; import com.raoulvdberge.refinedstorage.util.StackUtils; import io.netty.buffer.ByteBuf; import net.minecraftforge.fluids.FluidStack; @@ -19,7 +21,7 @@ import java.util.List; public class MessageGridFluidUpdate implements IMessage, IMessageHandler { private INetwork network; private boolean canCraft; - private List stacks = new ArrayList<>(); + private List stacks = new ArrayList<>(); public MessageGridFluidUpdate() { } @@ -60,15 +62,11 @@ public class MessageGridFluidUpdate implements IMessage, IMessageHandler { + grid.getView().setCanCraft(message.canCraft); + grid.getView().setStacks(message.stacks); + grid.getView().sort(); + }); return null; } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridItemDelta.java b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridItemDelta.java index 03a4af773..b7167e4fd 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridItemDelta.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridItemDelta.java @@ -2,11 +2,11 @@ package com.raoulvdberge.refinedstorage.network; import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.storage.IStorageTracker; +import com.raoulvdberge.refinedstorage.gui.GuiBase; import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; import com.raoulvdberge.refinedstorage.gui.grid.stack.GridStackItem; import com.raoulvdberge.refinedstorage.util.StackUtils; import io.netty.buffer.ByteBuf; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; @@ -99,46 +99,16 @@ public class MessageGridItemDelta implements IMessage, IMessageHandler process(p.getLeft(), p.getRight())); - } + GuiBase.executeLater(GuiGrid.class, grid -> { + if (message.gridStack != null) { + grid.getView().postChange(message.gridStack, message.delta); + } else { + message.gridStacks.forEach(p -> grid.getView().postChange(p.getLeft(), p.getRight())); + } - GuiGrid.scheduleSort(); + grid.getView().sort(); + }); return null; } - - private void process(GridStackItem gridStack, int delta) { - Item item = gridStack.getStack().getItem(); - - for (GridStackItem stack : GuiGrid.ITEMS.get(item)) { - if (stack.equals(gridStack)) { - if (stack.getStack().getCount() + delta <= 0) { - if (gridStack.isCraftable()) { - stack.setDisplayCraftText(true); - } else { - GuiGrid.ITEMS.remove(item, stack); - } - } else { - if (stack.doesDisplayCraftText()) { - stack.setDisplayCraftText(false); - - stack.getStack().setCount(delta); - } else { - stack.getStack().grow(delta); - } - } - - stack.setTrackerEntry(gridStack.getTrackerEntry()); - - return; - } - } - - gridStack.getStack().setCount(delta); - - GuiGrid.ITEMS.put(item, gridStack); - } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridItemUpdate.java b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridItemUpdate.java index 29d878f2a..262b50c78 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridItemUpdate.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/network/MessageGridItemUpdate.java @@ -3,9 +3,10 @@ package com.raoulvdberge.refinedstorage.network; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingPattern; import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.storage.IStorageTracker; -import com.raoulvdberge.refinedstorage.apiimpl.API; +import com.raoulvdberge.refinedstorage.gui.GuiBase; import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; import com.raoulvdberge.refinedstorage.gui.grid.stack.GridStackItem; +import com.raoulvdberge.refinedstorage.gui.grid.stack.IGridStack; import com.raoulvdberge.refinedstorage.util.StackUtils; import io.netty.buffer.ByteBuf; import net.minecraft.item.ItemStack; @@ -22,7 +23,7 @@ import java.util.function.Consumer; public class MessageGridItemUpdate implements IMessage, IMessageHandler { private Consumer sendHandler; private boolean canCraft; - private List stacks = new ArrayList<>(); + private List stacks = new ArrayList<>(); public MessageGridItemUpdate() { } @@ -92,30 +93,11 @@ public class MessageGridItemUpdate implements IMessage, IMessageHandler { + grid.getView().setCanCraft(message.canCraft); + grid.getView().setStacks(message.stacks); + grid.getView().sort(); + }); return null; } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyClient.java b/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyClient.java index 18d03bcde..9df7119d3 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyClient.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/proxy/ProxyClient.java @@ -281,7 +281,7 @@ public class ProxyClient extends ProxyCommon { ModelLoader.setCustomMeshDefinition(Item.getItemFromBlock(RSBlocks.PORTABLE_GRID), stack -> { PortableGrid portableGrid = new PortableGrid(null, stack); - return new ModelResourceLocation("refinedstorage:portable_grid", "connected=" + Boolean.toString(portableGrid.getEnergy() != 0) + ",direction=north,disk_state=" + TilePortableGrid.getDiskState(portableGrid)); + return new ModelResourceLocation("refinedstorage:portable_grid", "connected=" + Boolean.toString(portableGrid.getEnergy() != 0 && !portableGrid.getDisk().getStackInSlot(0).isEmpty()) + ",direction=north,disk_state=" + TilePortableGrid.getDiskState(portableGrid)); }); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileController.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileController.java index 091070d3b..24d01bcbb 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/TileController.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/TileController.java @@ -6,8 +6,6 @@ import com.raoulvdberge.refinedstorage.RSBlocks; import com.raoulvdberge.refinedstorage.api.autocrafting.ICraftingManager; import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.network.INetworkNodeGraph; -import com.raoulvdberge.refinedstorage.api.network.grid.GridType; -import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IFluidGridHandler; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IItemGridHandler; import com.raoulvdberge.refinedstorage.api.network.item.INetworkItemHandler; @@ -16,7 +14,6 @@ import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy; import com.raoulvdberge.refinedstorage.api.network.readerwriter.IReaderWriterChannel; import com.raoulvdberge.refinedstorage.api.network.readerwriter.IReaderWriterHandler; import com.raoulvdberge.refinedstorage.api.network.security.ISecurityManager; -import com.raoulvdberge.refinedstorage.api.network.security.Permission; import com.raoulvdberge.refinedstorage.api.storage.AccessType; import com.raoulvdberge.refinedstorage.api.storage.IStorage; import com.raoulvdberge.refinedstorage.api.storage.IStorageCache; @@ -39,10 +36,10 @@ import com.raoulvdberge.refinedstorage.block.ControllerEnergyType; import com.raoulvdberge.refinedstorage.block.ControllerType; import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy; import com.raoulvdberge.refinedstorage.container.ContainerCraftingMonitor; -import com.raoulvdberge.refinedstorage.container.ContainerGrid; import com.raoulvdberge.refinedstorage.container.ContainerReaderWriter; import com.raoulvdberge.refinedstorage.integration.forgeenergy.EnergyForge; -import com.raoulvdberge.refinedstorage.network.*; +import com.raoulvdberge.refinedstorage.network.MessageCraftingMonitorElements; +import com.raoulvdberge.refinedstorage.network.MessageReaderWriterUpdate; import com.raoulvdberge.refinedstorage.tile.config.IRedstoneConfigurable; import com.raoulvdberge.refinedstorage.tile.config.RedstoneMode; import com.raoulvdberge.refinedstorage.tile.data.RSSerializers; @@ -50,7 +47,6 @@ import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter; import com.raoulvdberge.refinedstorage.util.StackUtils; import com.raoulvdberge.refinedstorage.util.WorldUtils; import net.minecraft.block.state.IBlockState; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -66,7 +62,6 @@ import net.minecraftforge.common.util.Constants; import net.minecraftforge.energy.CapabilityEnergy; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.items.ItemHandlerHelper; -import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -140,7 +135,6 @@ public class TileController extends TileBase implements ITickable, INetwork, IRe private IStorageCache itemStorage = new StorageCacheItem(this); private StorageTrackerItem itemStorageTracker = new StorageTrackerItem(this::markDirty); - private List> batchedItemStorageDeltas = new LinkedList<>(); private IStorageCache fluidStorage = new StorageCacheFluid(this); private StorageTrackerFluid fluidStorageTracker = new StorageTrackerFluid(this::markDirty); @@ -298,71 +292,6 @@ public class TileController extends TileBase implements ITickable, INetwork, IRe return fluidStorage; } - @Override - public void sendItemStorageToClient() { - world.getMinecraftServer().getPlayerList().getPlayers().stream() - .filter(player -> isWatchingGrid(player, GridType.NORMAL, GridType.CRAFTING, GridType.PATTERN)) - .forEach(this::sendItemStorageToClient); - } - - @Override - public void sendItemStorageToClient(EntityPlayerMP player) { - RS.INSTANCE.network.sendTo(new MessageGridItemUpdate(this, securityManager.hasPermission(Permission.AUTOCRAFTING, player)), player); - } - - @Override - public void sendBatchedItemStorageDeltaToClient() { - if (!batchedItemStorageDeltas.isEmpty()) { - world.getMinecraftServer().getPlayerList().getPlayers().stream() - .filter(player -> isWatchingGrid(player, GridType.NORMAL, GridType.CRAFTING, GridType.PATTERN)) - .forEach(player -> RS.INSTANCE.network.sendTo(new MessageGridItemDelta(this, itemStorageTracker, batchedItemStorageDeltas), player)); - - batchedItemStorageDeltas.clear(); - } - } - - @Override - public void sendItemStorageDeltaToClient(ItemStack stack, int delta, boolean batched) { - if (!batched) { - world.getMinecraftServer().getPlayerList().getPlayers().stream() - .filter(player -> isWatchingGrid(player, GridType.NORMAL, GridType.CRAFTING, GridType.PATTERN)) - .forEach(player -> RS.INSTANCE.network.sendTo(new MessageGridItemDelta(this, itemStorageTracker, stack, delta), player)); - } else { - batchedItemStorageDeltas.add(Pair.of(stack, delta)); - } - } - - @Override - public void sendFluidStorageToClient() { - world.getMinecraftServer().getPlayerList().getPlayers().stream() - .filter(player -> isWatchingGrid(player, GridType.FLUID)) - .forEach(this::sendFluidStorageToClient); - } - - @Override - public void sendFluidStorageToClient(EntityPlayerMP player) { - RS.INSTANCE.network.sendTo(new MessageGridFluidUpdate(this, securityManager.hasPermission(Permission.AUTOCRAFTING, player)), player); - } - - @Override - public void sendFluidStorageDeltaToClient(FluidStack stack, int delta) { - world.getMinecraftServer().getPlayerList().getPlayers().stream() - .filter(player -> isWatchingGrid(player, GridType.FLUID)) - .forEach(player -> RS.INSTANCE.network.sendTo(new MessageGridFluidDelta(this, stack, delta), player)); - } - - private boolean isWatchingGrid(EntityPlayer player, GridType... types) { - if (player.openContainer.getClass() == ContainerGrid.class) { - IGrid grid = ((ContainerGrid) player.openContainer).getGrid(); - - if (grid.getNetwork() != null && pos.equals(grid.getNetwork().getPosition())) { - return Arrays.asList(types).contains(grid.getType()); - } - } - - return false; - } - @Override public void markCraftingMonitorForUpdate() { craftingMonitorUpdateRequested = true; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/TileGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/TileGrid.java index b2a757f00..489b6b197 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/TileGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/TileGrid.java @@ -4,6 +4,7 @@ import com.raoulvdberge.refinedstorage.api.network.grid.GridType; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeGrid; import com.raoulvdberge.refinedstorage.container.ContainerGrid; +import com.raoulvdberge.refinedstorage.gui.GuiBase; import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; import com.raoulvdberge.refinedstorage.tile.TileNode; import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter; @@ -24,19 +25,19 @@ public class TileGrid extends TileNode { t.getNode().setViewType(v); t.getNode().markDirty(); } - }, p -> GuiGrid.scheduleSort()); + }, p -> GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort())); public static final TileDataParameter SORTING_DIRECTION = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.getNode().getSortingDirection(), (t, v) -> { if (IGrid.isValidSortingDirection(v)) { t.getNode().setSortingDirection(v); t.getNode().markDirty(); } - }, p -> GuiGrid.scheduleSort()); + }, p -> GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort())); public static final TileDataParameter SORTING_TYPE = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.getNode().getSortingType(), (t, v) -> { if (IGrid.isValidSortingType(v)) { t.getNode().setSortingType(v); t.getNode().markDirty(); } - }, p -> GuiGrid.scheduleSort()); + }, p -> GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort())); public static final TileDataParameter SEARCH_BOX_MODE = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.getNode().getSearchBoxMode(), (t, v) -> { if (IGrid.isValidSearchBoxMode(v)) { t.getNode().setSearchBoxMode(v); @@ -60,11 +61,7 @@ public class TileGrid extends TileNode { public static final TileDataParameter TAB_SELECTED = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.getNode().getTabSelected(), (t, v) -> { t.getNode().setTabSelected(v == t.getNode().getTabSelected() ? -1 : v); t.getNode().markDirty(); - }, p -> { - if (Minecraft.getMinecraft().currentScreen instanceof GuiGrid) { - GuiGrid.scheduleSort(); - } - }); + }, p -> GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort())); public static final TileDataParameter TAB_PAGE = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.getNode().getTabPage(), (t, v) -> { if (v >= 0 && v <= t.getNode().getTotalTabPages()) { t.getNode().setTabPage(v); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessFluidGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessFluidGrid.java index 0c4e6fb50..1786a2940 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessFluidGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessFluidGrid.java @@ -5,12 +5,16 @@ import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.network.grid.GridType; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab; +import com.raoulvdberge.refinedstorage.api.storage.IStorageCacheListener; import com.raoulvdberge.refinedstorage.api.util.IFilter; +import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheListenerGridFluid; +import com.raoulvdberge.refinedstorage.gui.GuiBase; import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; import com.raoulvdberge.refinedstorage.item.ItemWirelessFluidGrid; import com.raoulvdberge.refinedstorage.network.MessageWirelessFluidGridSettingsUpdate; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; @@ -72,6 +76,11 @@ public class WirelessFluidGrid implements IGrid { return null; } + @Override + public IStorageCacheListener createListener(EntityPlayerMP player) { + return new StorageCacheListenerGridFluid(player, getNetwork()); + } + @Override public String getGuiTitle() { return "gui.refinedstorage:fluid_grid"; @@ -128,7 +137,7 @@ public class WirelessFluidGrid implements IGrid { this.sortingType = type; - GuiGrid.scheduleSort(); + GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort()); } @Override @@ -137,7 +146,7 @@ public class WirelessFluidGrid implements IGrid { this.sortingDirection = direction; - GuiGrid.scheduleSort(); + GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort()); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessGrid.java index 85cdf4a02..a2c7e138f 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessGrid.java @@ -5,7 +5,10 @@ import com.raoulvdberge.refinedstorage.api.network.INetwork; import com.raoulvdberge.refinedstorage.api.network.grid.GridType; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab; +import com.raoulvdberge.refinedstorage.api.storage.IStorageCacheListener; import com.raoulvdberge.refinedstorage.api.util.IFilter; +import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheListenerGridItem; +import com.raoulvdberge.refinedstorage.gui.GuiBase; import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFilter; import com.raoulvdberge.refinedstorage.item.ItemWirelessGrid; @@ -13,6 +16,7 @@ import com.raoulvdberge.refinedstorage.network.MessageGridSettingsUpdate; import com.raoulvdberge.refinedstorage.util.StackUtils; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; @@ -100,6 +104,11 @@ public class WirelessGrid implements IGrid { return null; } + @Override + public IStorageCacheListener createListener(EntityPlayerMP player) { + return new StorageCacheListenerGridItem(player, getNetwork()); + } + @Override public String getGuiTitle() { return "gui.refinedstorage:grid"; @@ -151,7 +160,7 @@ public class WirelessGrid implements IGrid { this.viewType = type; - GuiGrid.scheduleSort(); + GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort()); } @Override @@ -160,7 +169,7 @@ public class WirelessGrid implements IGrid { this.sortingType = type; - GuiGrid.scheduleSort(); + GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort()); } @Override @@ -169,14 +178,14 @@ public class WirelessGrid implements IGrid { this.sortingDirection = direction; - GuiGrid.scheduleSort(); + GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort()); } @Override public void onSearchBoxModeChanged(int searchBoxMode) { RS.INSTANCE.network.sendToServer(new MessageGridSettingsUpdate(getViewType(), getSortingDirection(), getSortingType(), searchBoxMode, getSize(), getTabSelected(), getTabPage())); - this.searchBoxMode = searchBoxMode; + GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort()); } @Override @@ -196,7 +205,7 @@ public class WirelessGrid implements IGrid { RS.INSTANCE.network.sendToServer(new MessageGridSettingsUpdate(getViewType(), getSortingDirection(), getSortingType(), getSearchBoxMode(), getSize(), tabSelected, getTabPage())); - GuiGrid.scheduleSort(); + GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort()); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/IPortableGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/IPortableGrid.java index 5dab33985..b28d25da4 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/IPortableGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/IPortableGrid.java @@ -4,12 +4,10 @@ import com.raoulvdberge.refinedstorage.api.storage.IStorageCache; import com.raoulvdberge.refinedstorage.api.storage.IStorageDisk; import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageTrackerItem; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraftforge.items.IItemHandlerModifiable; import javax.annotation.Nullable; -import java.util.List; public interface IPortableGrid { IStorageCache getCache(); @@ -17,8 +15,6 @@ public interface IPortableGrid { @Nullable IStorageDisk getStorage(); - List getWatchers(); - void drainEnergy(int energy); int getEnergy(); diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/PortableGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/PortableGrid.java index 6ded2b518..ec7763edf 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/PortableGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/PortableGrid.java @@ -6,16 +6,15 @@ import com.raoulvdberge.refinedstorage.api.network.grid.GridType; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IItemGridHandler; -import com.raoulvdberge.refinedstorage.api.storage.AccessType; -import com.raoulvdberge.refinedstorage.api.storage.IStorageDisk; -import com.raoulvdberge.refinedstorage.api.storage.IStorageDiskProvider; -import com.raoulvdberge.refinedstorage.api.storage.StorageDiskType; +import com.raoulvdberge.refinedstorage.api.storage.*; import com.raoulvdberge.refinedstorage.api.util.IFilter; import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.ItemGridHandlerPortable; import com.raoulvdberge.refinedstorage.apiimpl.network.node.diskdrive.NetworkNodeDiskDrive; import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheItemPortable; +import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheListenerGridPortable; import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageDiskItemPortable; import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageTrackerItem; +import com.raoulvdberge.refinedstorage.gui.GuiBase; import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFilter; @@ -26,6 +25,7 @@ import com.raoulvdberge.refinedstorage.network.MessageGridSettingsUpdate; import com.raoulvdberge.refinedstorage.util.StackUtils; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.item.ItemStack; @@ -39,7 +39,6 @@ import net.minecraftforge.items.IItemHandlerModifiable; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class PortableGrid implements IGrid, IPortableGrid { @@ -171,11 +170,6 @@ public class PortableGrid implements IGrid, IPortableGrid { return storage; } - @Override - public List getWatchers() { - return Collections.singletonList(player); - } - @Override public void drainEnergy(int energy) { if (RS.INSTANCE.config.portableGridUsesEnergy && stack.getItemDamage() != ItemBlockPortableGrid.TYPE_CREATIVE) { @@ -212,6 +206,17 @@ public class PortableGrid implements IGrid, IPortableGrid { return null; } + @Nullable + @Override + public IStorageCache getStorageCache() { + return storage != null ? cache : null; + } + + @Override + public IStorageCacheListener createListener(EntityPlayerMP player) { + return new StorageCacheListenerGridPortable(this, player); + } + @Nullable @Override public IItemGridHandler getItemHandler() { @@ -274,7 +279,7 @@ public class PortableGrid implements IGrid, IPortableGrid { this.sortingType = type; - GuiGrid.scheduleSort(); + GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort()); } @Override @@ -283,7 +288,7 @@ public class PortableGrid implements IGrid, IPortableGrid { this.sortingDirection = direction; - GuiGrid.scheduleSort(); + GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort()); } @Override @@ -310,7 +315,7 @@ public class PortableGrid implements IGrid, IPortableGrid { RS.INSTANCE.network.sendToServer(new MessageGridSettingsUpdate(getViewType(), getSortingDirection(), getSortingType(), getSearchBoxMode(), getSize(), tabSelected, getTabPage())); - GuiGrid.scheduleSort(); + GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort()); } @Override @@ -387,6 +392,10 @@ public class PortableGrid implements IGrid, IPortableGrid { return false; } + if (disk.getStackInSlot(0).isEmpty()) { + return false; + } + return true; } } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/TilePortableGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/TilePortableGrid.java index dcbf78abe..129ca8be9 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/TilePortableGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/TilePortableGrid.java @@ -13,11 +13,13 @@ import com.raoulvdberge.refinedstorage.apiimpl.network.grid.handler.ItemGridHand import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNodeGrid; import com.raoulvdberge.refinedstorage.apiimpl.network.node.diskdrive.NetworkNodeDiskDrive; import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheItemPortable; +import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheListenerGridPortable; import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageDiskItemPortable; import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageTrackerItem; import com.raoulvdberge.refinedstorage.block.BlockPortableGrid; import com.raoulvdberge.refinedstorage.block.PortableGridDiskState; import com.raoulvdberge.refinedstorage.block.PortableGridType; +import com.raoulvdberge.refinedstorage.gui.GuiBase; import com.raoulvdberge.refinedstorage.gui.grid.GuiGrid; import com.raoulvdberge.refinedstorage.integration.forgeenergy.EnergyForge; import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase; @@ -56,7 +58,7 @@ import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; -public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid, IRedstoneConfigurable { +public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid, IRedstoneConfigurable, IStorageCacheListener { public static final TileDataParameter REDSTONE_MODE = RedstoneMode.createParameter(); public static final TileDataParameter ENERGY_STORED = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.energyStorage.getEnergyStored()); public static final TileDataParameter SORTING_DIRECTION = new TileDataParameter<>(DataSerializers.VARINT, 0, TilePortableGrid::getSortingDirection, (t, v) -> { @@ -64,13 +66,13 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid, t.setSortingDirection(v); t.markDirty(); } - }, p -> GuiGrid.scheduleSort()); + }, p -> GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort())); public static final TileDataParameter SORTING_TYPE = new TileDataParameter<>(DataSerializers.VARINT, 0, TilePortableGrid::getSortingType, (t, v) -> { if (IGrid.isValidSortingType(v)) { t.setSortingType(v); t.markDirty(); } - }, p -> GuiGrid.scheduleSort()); + }, p -> GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort())); public static final TileDataParameter SEARCH_BOX_MODE = new TileDataParameter<>(DataSerializers.VARINT, 0, TilePortableGrid::getSearchBoxMode, (t, v) -> { if (IGrid.isValidSearchBoxMode(v)) { t.setSearchBoxMode(v); @@ -94,11 +96,7 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid, public static final TileDataParameter TAB_SELECTED = new TileDataParameter<>(DataSerializers.VARINT, 0, TilePortableGrid::getTabSelected, (t, v) -> { t.setTabSelected(v == t.getTabSelected() ? -1 : v); t.markDirty(); - }, p -> { - if (Minecraft.getMinecraft().currentScreen instanceof GuiGrid) { - GuiGrid.scheduleSort(); - } - }); + }, p -> GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort())); public static final TileDataParameter TAB_PAGE = new TileDataParameter<>(DataSerializers.VARINT, 0, TilePortableGrid::getTabPage, (t, v) -> { if (v >= 0 && v <= t.getTotalTabPages()) { t.setTabPage(v); @@ -134,7 +132,7 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid, if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) { if (itemHandler != null) { - cache.removeListener(itemHandler); + cache.removeListener(TilePortableGrid.this); } if (getStackInSlot(slot).isEmpty()) { @@ -157,7 +155,7 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid, } else { itemHandler = new ItemHandlerStorage(storage, cache); - cache.addListener(itemHandler); + cache.addListener(TilePortableGrid.this); } if (world != null) { @@ -285,6 +283,17 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid, return null; } + @Nullable + @Override + public IStorageCache getStorageCache() { + return storage != null ? cache : null; + } + + @Override + public IStorageCacheListener createListener(EntityPlayerMP player) { + return new StorageCacheListenerGridPortable(this, player); + } + @Nullable @Override public IItemGridHandler getItemHandler() { @@ -460,6 +469,10 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid, return false; } + if (disk.getStackInSlot(0).isEmpty()) { + return false; + } + RedstoneMode redstoneMode = !world.isRemote ? this.redstoneMode : RedstoneMode.getById(REDSTONE_MODE.getValue()); return redstoneMode.isEnabled(world, pos); @@ -476,11 +489,6 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid, return storage; } - @Override - public List getWatchers() { - return dataManager.getPlayersWatching(); - } - @Override public void drainEnergy(int energy) { if (RS.INSTANCE.config.portableGridUsesEnergy && getPortableType() != PortableGridType.CREATIVE && redstoneMode.isEnabled(world, pos)) { @@ -636,9 +644,7 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid, return super.getCapability(capability, facing); } - public void onOpened(EntityPlayerMP player) { - cache.sendUpdateTo(player); - + public void onOpened() { drainEnergy(RS.INSTANCE.config.portableGridOpenUsage); } @@ -674,4 +680,19 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid, return PortableGridDiskState.NORMAL; } } + + @Override + public void onAttached() { + // NO OP + } + + @Override + public void onInvalidated() { + itemHandler.invalidate(); + } + + @Override + public void onChanged(@Nonnull ItemStack stack, int size) { + itemHandler.invalidate(); + } }