The Portable Grid now exposes an inventory for interaction with other mods or vanilla, fixes #1315

This commit is contained in:
raoulvdberge
2017-06-21 19:10:58 +02:00
parent 78e9f7d4af
commit ca1cf2a6ef
7 changed files with 121 additions and 1 deletions

View File

@@ -2,6 +2,7 @@
### 1.5.3
- Fixed Solderer crashing (raoulvdberge)
- The Portable Grid now exposes an inventory for interaction with other mods or vanilla (raoulvdberge)
### 1.5.2
- Fixed a bug where loading nodes would abort when a single node has an error while reading (raoulvdberge)

View File

@@ -5,6 +5,7 @@ import com.raoulvdberge.refinedstorage.api.util.IStackList;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.function.BiConsumer;
/**
* This holds all stacks from all the connected storages from a {@link INetwork}.
@@ -46,6 +47,13 @@ public interface IStorageCache<T> {
*/
void remove(@Nonnull T stack, int size);
/**
* Adds a listener to be called when this storage cache changes.
*
* @param listener the listener
*/
void addListener(BiConsumer<T, Integer> listener);
/**
* Resorts the storages in this cache according to their priority.
* This needs to be called when the priority of a storage changes.

View File

@@ -11,13 +11,16 @@ import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nonnull;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.BiConsumer;
public class StorageCacheFluid implements IStorageCache<FluidStack> {
private INetwork network;
private CopyOnWriteArrayList<IStorage<FluidStack>> storages = new CopyOnWriteArrayList<>();
private IStackList<FluidStack> list = API.instance().createFluidStackList();
private List<BiConsumer<FluidStack, Integer>> listeners = new LinkedList<>();
public StorageCacheFluid(INetwork network) {
this.network = network;
@@ -54,6 +57,8 @@ public class StorageCacheFluid implements IStorageCache<FluidStack> {
if (!rebuilding) {
network.sendFluidStorageDeltaToClient(stack, size);
listeners.forEach(l -> l.accept(stack, size));
}
}
@@ -61,9 +66,16 @@ public class StorageCacheFluid implements IStorageCache<FluidStack> {
public synchronized void remove(@Nonnull FluidStack stack, int size) {
if (list.remove(stack, size)) {
network.sendFluidStorageDeltaToClient(stack, -size);
listeners.forEach(l -> l.accept(stack, -size));
}
}
@Override
public void addListener(BiConsumer<FluidStack, Integer> listener) {
listeners.add(listener);
}
@Override
public void sort() {
storages.sort(RSUtils.STORAGE_COMPARATOR);

View File

@@ -11,13 +11,16 @@ import com.raoulvdberge.refinedstorage.apiimpl.API;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.BiConsumer;
public class StorageCacheItem implements IStorageCache<ItemStack> {
private INetwork network;
private CopyOnWriteArrayList<IStorage<ItemStack>> storages = new CopyOnWriteArrayList<>();
private IStackList<ItemStack> list = API.instance().createItemStackList();
private List<BiConsumer<ItemStack, Integer>> listeners = new LinkedList<>();
public StorageCacheItem(INetwork network) {
this.network = network;
@@ -56,6 +59,8 @@ public class StorageCacheItem implements IStorageCache<ItemStack> {
if (!rebuilding) {
network.sendItemStorageDeltaToClient(stack, size);
listeners.forEach(l -> l.accept(stack, size));
}
}
@@ -63,9 +68,16 @@ public class StorageCacheItem implements IStorageCache<ItemStack> {
public synchronized void remove(@Nonnull ItemStack stack, int size) {
if (list.remove(stack, size)) {
network.sendItemStorageDeltaToClient(stack, -size);
listeners.forEach(l -> l.accept(stack, -size));
}
}
@Override
public void addListener(BiConsumer<ItemStack, Integer> listener) {
listeners.add(listener);
}
@Override
public void sort() {
storages.sort(RSUtils.STORAGE_COMPARATOR);

View File

@@ -15,11 +15,14 @@ import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
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();
private List<BiConsumer<ItemStack, Integer>> listeners = new LinkedList<>();
public StorageCacheItemPortable(IPortableGrid portableGrid) {
this.portableGrid = portableGrid;
@@ -42,6 +45,8 @@ public class StorageCacheItemPortable implements IStorageCache<ItemStack> {
if (!rebuilding) {
portableGrid.getWatchers().forEach(w -> RS.INSTANCE.network.sendTo(new MessageGridItemDelta(null, stack, size), (EntityPlayerMP) w));
listeners.forEach(l -> l.accept(stack, size));
}
}
@@ -49,9 +54,16 @@ public class StorageCacheItemPortable implements IStorageCache<ItemStack> {
public void remove(@Nonnull ItemStack stack, int size) {
if (list.remove(stack, size)) {
portableGrid.getWatchers().forEach(w -> RS.INSTANCE.network.sendTo(new MessageGridItemDelta(null, stack, -size), (EntityPlayerMP) w));
listeners.forEach(l -> l.accept(stack, -size));
}
}
@Override
public void addListener(BiConsumer<ItemStack, Integer> listener) {
listeners.add(listener);
}
@Override
public void sort() {
// NO OP

View File

@@ -0,0 +1,62 @@
package com.raoulvdberge.refinedstorage.inventory;
import com.raoulvdberge.refinedstorage.RSUtils;
import com.raoulvdberge.refinedstorage.api.storage.IStorage;
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 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;
invalidate();
}
@Override
public int getSlots() {
// Keep 1 slot extra for new items
return storageCacheData.length + 1;
}
@Nonnull
@Override
public ItemStack getStackInSlot(int slot) {
return slot >= storageCacheData.length ? ItemStack.EMPTY : storageCacheData[slot];
}
@Nonnull
@Override
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
return RSUtils.transformNullToEmpty(storage.insert(stack, stack.getCount(), simulate));
}
@Nonnull
@Override
public ItemStack extractItem(int slot, int amount, boolean simulate) {
return slot >= storageCacheData.length ? ItemStack.EMPTY : RSUtils.transformNullToEmpty(storage.extract(storageCacheData[slot], amount, IComparer.COMPARE_DAMAGE | IComparer.COMPARE_NBT, simulate));
}
@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

@@ -20,6 +20,7 @@ import com.raoulvdberge.refinedstorage.integration.forgeenergy.EnergyForge;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerBase;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerFilter;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerListenerTile;
import com.raoulvdberge.refinedstorage.inventory.ItemHandlerStorage;
import com.raoulvdberge.refinedstorage.item.ItemBlockPortableGrid;
import com.raoulvdberge.refinedstorage.item.ItemEnergyItem;
import com.raoulvdberge.refinedstorage.item.ItemWirelessGrid;
@@ -45,6 +46,7 @@ import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.items.CapabilityItemHandler;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -185,6 +187,14 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid,
cache.invalidate();
if (storage == null) {
itemHandler = null;
} else {
itemHandler = new ItemHandlerStorage(storage, cache);
cache.addListener(itemHandler);
}
if (world != null) {
checkIfDiskStateChanged();
}
@@ -206,6 +216,7 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid,
private IStorageDisk<ItemStack> storage;
private StorageCacheItemPortable cache = new StorageCacheItemPortable(this);
private ItemGridHandlerPortable handler = new ItemGridHandlerPortable(this, this);
private ItemHandlerStorage itemHandler = null;
private PortableGridDiskState diskState = PortableGridDiskState.NONE;
private boolean connected;
@@ -602,7 +613,7 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid,
@Override
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) {
return capability == CapabilityEnergy.ENERGY || super.hasCapability(capability, facing);
return capability == CapabilityEnergy.ENERGY || (itemHandler != null && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) || super.hasCapability(capability, facing);
}
@Nullable
@@ -610,6 +621,8 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid,
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) {
if (capability == CapabilityEnergy.ENERGY) {
return CapabilityEnergy.ENERGY.cast(energyStorage);
} else if (itemHandler != null && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.cast(itemHandler);
}
return super.getCapability(capability, facing);