The Interface now exposes the entire storage inventory (if no slots are set for exporting) for interaction with other mods or vanilla, fixes #1322

This commit is contained in:
raoulvdberge
2017-06-23 21:01:21 +02:00
parent 345b3eb18a
commit f45a478d59
20 changed files with 180 additions and 61 deletions

View File

@@ -4,7 +4,6 @@ import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.util.IStackList;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.function.BiConsumer;
@@ -49,11 +48,18 @@ public interface IStorageCache<T> {
void remove(@Nonnull T stack, int size);
/**
* Sets a listener to be called when this storage cache changes.
* Adds a listener to be called when this storage cache changes.
*
* @param listener the listener, or null when no listener is needed
* @param listener the listener
*/
void setListener(@Nullable BiConsumer<T, Integer> listener);
void addListener(BiConsumer<T, Integer> listener);
/**
* Removes a listener from the storage cache.
*
* @param listener the listener
*/
void removeListener(BiConsumer<T, Integer> listener);
/**
* Resorts the storages in this cache according to their priority.

View File

@@ -31,7 +31,7 @@ import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageDiskBehavior;
import com.raoulvdberge.refinedstorage.apiimpl.util.Comparer;
import com.raoulvdberge.refinedstorage.apiimpl.util.StackListFluid;
import com.raoulvdberge.refinedstorage.apiimpl.util.StackListItem;
import com.raoulvdberge.refinedstorage.proxy.CapabilityNetworkNodeProxy;
import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;

View File

@@ -21,7 +21,7 @@ import java.util.Collection;
import java.util.Queue;
import java.util.Set;
import static com.raoulvdberge.refinedstorage.proxy.CapabilityNetworkNodeProxy.NETWORK_NODE_PROXY_CAPABILITY;
import static com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy.NETWORK_NODE_PROXY_CAPABILITY;
public class NetworkNodeGraph implements INetworkNodeGraph {
private TileController controller;

View File

@@ -5,7 +5,7 @@ import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy;
import com.raoulvdberge.refinedstorage.api.network.security.Permission;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.proxy.CapabilityNetworkNodeProxy;
import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.event.world.BlockEvent;

View File

@@ -2,13 +2,11 @@ package com.raoulvdberge.refinedstorage.apiimpl.network.node;
import com.raoulvdberge.refinedstorage.RS;
import com.raoulvdberge.refinedstorage.RSUtils;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.apiimpl.network.node.externalstorage.StorageItemItemHandler;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerListenerNetworkNode;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerProxy;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerUpgrade;
import com.raoulvdberge.refinedstorage.inventory.*;
import com.raoulvdberge.refinedstorage.item.ItemUpgrade;
import com.raoulvdberge.refinedstorage.tile.config.IComparable;
import net.minecraft.item.ItemStack;
@@ -28,7 +26,8 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable {
private ItemHandlerBase exportSpecimenItems = new ItemHandlerBase(9, new ItemHandlerListenerNetworkNode(this));
private ItemHandlerBase exportItems = new ItemHandlerBase(9, new ItemHandlerListenerNetworkNode(this));
private ItemHandlerProxy items = new ItemHandlerProxy(importItems, exportItems);
private IItemHandler items = new ItemHandlerProxy(importItems, exportItems);
private ItemHandlerInterface itemsNetwork;
private ItemHandlerUpgrade upgrades = new ItemHandlerUpgrade(4, new ItemHandlerListenerNetworkNode(this), ItemUpgrade.TYPE_SPEED, ItemUpgrade.TYPE_STACK, ItemUpgrade.TYPE_CRAFTING);
@@ -119,6 +118,21 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable {
}
}
@Override
protected void onConnectedStateChange(INetwork network, boolean state) {
super.onConnectedStateChange(network, state);
if (state) {
itemsNetwork = new ItemHandlerInterface(network, network.getItemStorageCache(), importItems);
network.getItemStorageCache().addListener(itemsNetwork);
} else if (itemsNetwork != null) {
network.getItemStorageCache().removeListener(itemsNetwork);
itemsNetwork = null;
}
}
@Override
public int getCompare() {
return compare;
@@ -190,8 +204,8 @@ public class NetworkNodeInterface extends NetworkNode implements IComparable {
return exportItems;
}
public ItemHandlerProxy getItems() {
return items;
public IItemHandler getItems() {
return (itemsNetwork != null && exportSpecimenItems.isEmpty()) ? itemsNetwork : items;
}
public IItemHandler getUpgrades() {

View File

@@ -11,10 +11,10 @@ import com.raoulvdberge.refinedstorage.api.storage.IStorageProvider;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import com.raoulvdberge.refinedstorage.apiimpl.network.node.IGuiStorage;
import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNode;
import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFluid;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerListenerNetworkNode;
import com.raoulvdberge.refinedstorage.proxy.CapabilityNetworkNodeProxy;
import com.raoulvdberge.refinedstorage.tile.TileExternalStorage;
import com.raoulvdberge.refinedstorage.tile.config.*;
import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter;

View File

@@ -11,7 +11,7 @@ import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.BiConsumer;
@@ -20,8 +20,7 @@ public class StorageCacheFluid implements IStorageCache<FluidStack> {
private INetwork network;
private CopyOnWriteArrayList<IStorage<FluidStack>> storages = new CopyOnWriteArrayList<>();
private IStackList<FluidStack> list = API.instance().createFluidStackList();
@Nullable
private BiConsumer<FluidStack, Integer> listener;
private List<BiConsumer<FluidStack, Integer>> listeners = new LinkedList<>();
public StorageCacheFluid(INetwork network) {
this.network = network;
@@ -59,9 +58,7 @@ public class StorageCacheFluid implements IStorageCache<FluidStack> {
if (!rebuilding) {
network.sendFluidStorageDeltaToClient(stack, size);
if (listener != null) {
listener.accept(stack, size);
}
listeners.forEach(l -> l.accept(stack, size));
}
}
@@ -70,15 +67,18 @@ public class StorageCacheFluid implements IStorageCache<FluidStack> {
if (list.remove(stack, size)) {
network.sendFluidStorageDeltaToClient(stack, -size);
if (listener != null) {
listener.accept(stack, -size);
}
listeners.forEach(l -> l.accept(stack, -size));
}
}
@Override
public void setListener(@Nullable BiConsumer<FluidStack, Integer> listener) {
this.listener = listener;
public void addListener(BiConsumer<FluidStack, Integer> listener) {
listeners.add(listener);
}
@Override
public void removeListener(BiConsumer<FluidStack, Integer> listener) {
listeners.remove(listener);
}
@Override

View File

@@ -11,7 +11,7 @@ import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.BiConsumer;
@@ -20,8 +20,7 @@ public class StorageCacheItem implements IStorageCache<ItemStack> {
private INetwork network;
private CopyOnWriteArrayList<IStorage<ItemStack>> storages = new CopyOnWriteArrayList<>();
private IStackList<ItemStack> list = API.instance().createItemStackList();
@Nullable
private BiConsumer<ItemStack, Integer> listener;
private List<BiConsumer<ItemStack, Integer>> listeners = new LinkedList<>();
public StorageCacheItem(INetwork network) {
this.network = network;
@@ -60,11 +59,9 @@ public class StorageCacheItem implements IStorageCache<ItemStack> {
if (!rebuilding) {
network.sendItemStorageDeltaToClient(stack, size);
if (listener != null) {
listener.accept(stack, size);
}
}
listeners.forEach(l -> l.accept(stack, size));
}
@Override
@@ -72,15 +69,18 @@ public class StorageCacheItem implements IStorageCache<ItemStack> {
if (list.remove(stack, size)) {
network.sendItemStorageDeltaToClient(stack, -size);
if (listener != null) {
listener.accept(stack, -size);
}
listeners.forEach(l -> l.accept(stack, -size));
}
}
@Override
public void setListener(@Nullable BiConsumer<ItemStack, Integer> listener) {
this.listener = listener;
public void addListener(BiConsumer<ItemStack, Integer> listener) {
listeners.add(listener);
}
@Override
public void removeListener(BiConsumer<ItemStack, Integer> listener) {
listeners.remove(listener);
}
@Override

View File

@@ -14,16 +14,15 @@ import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.function.BiConsumer;
public class StorageCacheItemPortable implements IStorageCache<ItemStack> {
private IPortableGrid portableGrid;
private IStackList<ItemStack> list = API.instance().createItemStackList();
@Nullable
private BiConsumer<ItemStack, Integer> listener;
private List<BiConsumer<ItemStack, Integer>> listeners = new LinkedList<>();
public StorageCacheItemPortable(IPortableGrid portableGrid) {
this.portableGrid = portableGrid;
@@ -47,9 +46,7 @@ public class StorageCacheItemPortable implements IStorageCache<ItemStack> {
if (!rebuilding) {
portableGrid.getWatchers().forEach(w -> RS.INSTANCE.network.sendTo(new MessageGridItemDelta(null, stack, size), (EntityPlayerMP) w));
if (listener != null) {
listener.accept(stack, size);
}
listeners.forEach(l -> l.accept(stack, size));
}
}
@@ -58,15 +55,18 @@ public class StorageCacheItemPortable implements IStorageCache<ItemStack> {
if (list.remove(stack, size)) {
portableGrid.getWatchers().forEach(w -> RS.INSTANCE.network.sendTo(new MessageGridItemDelta(null, stack, -size), (EntityPlayerMP) w));
if (listener != null) {
listener.accept(stack, -size);
}
listeners.forEach(l -> l.accept(stack, -size));
}
}
@Override
public void setListener(@Nullable BiConsumer<ItemStack, Integer> listener) {
this.listener = listener;
public void addListener(BiConsumer<ItemStack, Integer> listener) {
listeners.add(listener);
}
@Override
public void removeListener(BiConsumer<ItemStack, Integer> listener) {
listeners.remove(listener);
}
@Override

View File

@@ -5,11 +5,11 @@ import com.raoulvdberge.refinedstorage.RSUtils;
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy;
import com.raoulvdberge.refinedstorage.api.network.security.Permission;
import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
import com.raoulvdberge.refinedstorage.container.ContainerBase;
import com.raoulvdberge.refinedstorage.integration.mcmp.IntegrationMCMP;
import com.raoulvdberge.refinedstorage.integration.mcmp.RSMCMPAddon;
import com.raoulvdberge.refinedstorage.item.ItemBlockBase;
import com.raoulvdberge.refinedstorage.proxy.CapabilityNetworkNodeProxy;
import com.raoulvdberge.refinedstorage.tile.TileBase;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;

View File

@@ -1,9 +1,9 @@
package com.raoulvdberge.refinedstorage.block;
import com.raoulvdberge.refinedstorage.RSUtils;
import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
import com.raoulvdberge.refinedstorage.integration.mcmp.IntegrationMCMP;
import com.raoulvdberge.refinedstorage.integration.mcmp.RSMCMPAddon;
import com.raoulvdberge.refinedstorage.proxy.CapabilityNetworkNodeProxy;
import com.raoulvdberge.refinedstorage.tile.TileCable;
import com.raoulvdberge.refinedstorage.tile.TileNode;
import net.minecraft.block.properties.PropertyBool;

View File

@@ -1,4 +1,4 @@
package com.raoulvdberge.refinedstorage.proxy;
package com.raoulvdberge.refinedstorage.capability;
import com.google.common.base.Preconditions;
import com.raoulvdberge.refinedstorage.api.network.node.INetworkNode;

View File

@@ -12,6 +12,8 @@ public class ItemHandlerBase extends ItemStackHandler {
@Nullable
private Consumer<Integer> listener;
private boolean empty = true;
protected Predicate<ItemStack>[] validators;
public ItemHandlerBase(int size, @Nullable Consumer<Integer> listener, Predicate<ItemStack>... validators) {
@@ -57,6 +59,12 @@ public class ItemHandlerBase extends ItemStackHandler {
if (listener != null) {
listener.accept(slot);
}
this.empty = stacks.stream().allMatch(ItemStack::isEmpty);
}
public boolean isEmpty() {
return empty;
}
@Nonnull

View File

@@ -0,0 +1,79 @@
package com.raoulvdberge.refinedstorage.inventory;
import com.raoulvdberge.refinedstorage.RSUtils;
import com.raoulvdberge.refinedstorage.api.network.INetwork;
import com.raoulvdberge.refinedstorage.api.storage.IStorageCache;
import com.raoulvdberge.refinedstorage.api.util.IComparer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nonnull;
import java.util.function.BiConsumer;
public class ItemHandlerInterface implements IItemHandler, BiConsumer<ItemStack, Integer> {
private INetwork network;
private IStorageCache<ItemStack> storageCache;
private IItemHandler importItems;
private ItemStack[] storageCacheData;
public ItemHandlerInterface(INetwork network, IStorageCache<ItemStack> storageCache, IItemHandler importItems) {
this.network = network;
this.storageCache = storageCache;
this.importItems = importItems;
invalidate();
}
@Override
public int getSlots() {
return importItems.getSlots() + storageCacheData.length;
}
@Nonnull
@Override
public ItemStack getStackInSlot(int slot) {
if (slot < importItems.getSlots()) {
return importItems.getStackInSlot(slot);
} else if (slot < importItems.getSlots() + storageCacheData.length) {
return storageCacheData[slot - importItems.getSlots()];
}
return ItemStack.EMPTY;
}
@Nonnull
@Override
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
if (slot < importItems.getSlots()) {
return importItems.insertItem(slot, stack, simulate);
}
return stack;
}
@Nonnull
@Override
public ItemStack extractItem(int slot, int amount, boolean simulate) {
if (slot < importItems.getSlots()) {
return ItemStack.EMPTY;
} else if (slot < importItems.getSlots() + storageCacheData.length) {
return RSUtils.transformNullToEmpty(network.extractItem(storageCacheData[slot - importItems.getSlots()], amount, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT, simulate));
}
return ItemStack.EMPTY;
}
@Override
public int getSlotLimit(int slot) {
return 64;
}
@Override
public void accept(ItemStack stack, Integer amount) {
invalidate();
}
private void invalidate() {
this.storageCacheData = storageCache.getList().getStacks().toArray(new ItemStack[0]);
}
}

View File

@@ -8,17 +8,18 @@ import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nonnull;
import java.util.function.BiConsumer;
public class ItemHandlerStorage implements IItemHandler {
public class ItemHandlerStorage implements IItemHandler, BiConsumer<ItemStack, Integer> {
private IStorage<ItemStack> storage;
private IStorageCache<ItemStack> storageCache;
private ItemStack[] storageCacheData;
public ItemHandlerStorage(IStorage<ItemStack> storage, IStorageCache<ItemStack> storageCache) {
this.storage = storage;
this.storageCache = storageCache;
storageCache.setListener((stack, size) -> invalidate(storageCache));
invalidate(storageCache);
invalidate();
}
@Override
@@ -50,7 +51,12 @@ public class ItemHandlerStorage implements IItemHandler {
return 64;
}
private void invalidate(IStorageCache<ItemStack> storageCache) {
@Override
public void accept(ItemStack stack, Integer amount) {
invalidate();
}
private void invalidate() {
this.storageCacheData = storageCache.getList().getStacks().toArray(new ItemStack[0]);
}
}

View File

@@ -19,6 +19,7 @@ import com.raoulvdberge.refinedstorage.block.BlockBase;
import com.raoulvdberge.refinedstorage.block.FluidStorageType;
import com.raoulvdberge.refinedstorage.block.GridType;
import com.raoulvdberge.refinedstorage.block.ItemStorageType;
import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
import com.raoulvdberge.refinedstorage.gui.GuiHandler;
import com.raoulvdberge.refinedstorage.integration.craftingtweaks.IntegrationCraftingTweaks;
import com.raoulvdberge.refinedstorage.integration.forgeenergy.ReaderWriterHandlerForgeEnergy;

View File

@@ -33,12 +33,12 @@ import com.raoulvdberge.refinedstorage.apiimpl.storage.StorageCacheItem;
import com.raoulvdberge.refinedstorage.block.BlockController;
import com.raoulvdberge.refinedstorage.block.ControllerType;
import com.raoulvdberge.refinedstorage.block.GridType;
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.proxy.CapabilityNetworkNodeProxy;
import com.raoulvdberge.refinedstorage.tile.config.IRedstoneConfigurable;
import com.raoulvdberge.refinedstorage.tile.config.RedstoneMode;
import com.raoulvdberge.refinedstorage.tile.data.ITileDataProducer;

View File

@@ -5,7 +5,7 @@ import com.raoulvdberge.refinedstorage.api.network.node.INetworkNodeProxy;
import com.raoulvdberge.refinedstorage.api.util.IWrenchable;
import com.raoulvdberge.refinedstorage.apiimpl.API;
import com.raoulvdberge.refinedstorage.apiimpl.network.node.NetworkNode;
import com.raoulvdberge.refinedstorage.proxy.CapabilityNetworkNodeProxy;
import com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodeProxy;
import com.raoulvdberge.refinedstorage.tile.config.IRedstoneConfigurable;
import com.raoulvdberge.refinedstorage.tile.config.RedstoneMode;
import com.raoulvdberge.refinedstorage.tile.data.TileDataParameter;

View File

@@ -172,6 +172,10 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid,
super.onContentsChanged(slot);
if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) {
if (itemHandler != null) {
cache.removeListener(itemHandler);
}
if (getStackInSlot(slot).isEmpty()) {
storage = null;
} else {
@@ -186,12 +190,11 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid,
}
cache.invalidate();
cache.setListener(null);
if (storage == null) {
itemHandler = null;
} else {
itemHandler = new ItemHandlerStorage(storage, cache);
cache.addListener(itemHandler = new ItemHandlerStorage(storage, cache));
}
if (world != null) {