Rewrite grid synchronization and sorting code

This commit is contained in:
raoulvdberge
2018-03-11 22:05:13 +01:00
parent 183e5b9cbd
commit e0d937e647
57 changed files with 840 additions and 590 deletions

View File

@@ -79,48 +79,6 @@ public interface INetwork {
*/
IStorageCache<FluidStack> 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.
*/

View File

@@ -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<INetwork> action);
void addPostRebuildHandler(Consumer<INetwork> handler);
/**
* @return a collection of all connected nodes

View File

@@ -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
*/

View File

@@ -48,19 +48,24 @@ public interface IStorageCache<T> {
*/
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<T> listener);
/**
* Removes a listener from the storage cache.
*
* @param listener the listener
*/
void removeListener(Runnable listener);
void removeListener(IStorageCacheListener<T> listener);
/**
* Resorts the storages in this cache according to their priority.

View File

@@ -0,0 +1,28 @@
package com.raoulvdberge.refinedstorage.api.storage;
import javax.annotation.Nonnull;
/**
* Listens for storage cache changes.
*
* @param <T> the type
*/
public interface IStorageCacheListener<T> {
/**
* 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);
}

View File

@@ -25,7 +25,7 @@ import static com.raoulvdberge.refinedstorage.capability.CapabilityNetworkNodePr
public class NetworkNodeGraph implements INetworkNodeGraph {
private TileController controller;
private Set<INetworkNode> nodes = Sets.newConcurrentHashSet();
private Set<Consumer<INetwork>> postRebuildActions = new HashSet<>();
private Set<Consumer<INetwork>> 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<INetwork> action) {
public void addPostRebuildHandler(Consumer<INetwork> handler) {
if (rebuilding) {
postRebuildActions.add(action);
postRebuildHandlers.add(handler);
} else {
action.accept(controller);
handler.accept(controller);
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -84,7 +84,7 @@ public abstract class StorageItemExternal implements IStorage<ItemStack> {
this.cache = newStacks;
network.sendBatchedItemStorageDeltaToClient();
network.getItemStorageCache().flush();
}
@Override

View File

@@ -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<FluidStack> {
private INetwork network;
private CopyOnWriteArrayList<IStorage<FluidStack>> storages = new CopyOnWriteArrayList<>();
private IStackList<FluidStack> list = API.instance().createFluidStackList();
private List<Runnable> listeners = new LinkedList<>();
private List<IStorageCacheListener<FluidStack>> listeners = new LinkedList<>();
public StorageCacheFluid(INetwork network) {
this.network = network;
@@ -49,9 +46,7 @@ public class StorageCacheFluid implements IStorageCache<FluidStack> {
}
}
listeners.forEach(Runnable::run);
network.sendFluidStorageToClient();
listeners.forEach(IStorageCacheListener::onInvalidated);
}
@Override
@@ -59,28 +54,31 @@ public class StorageCacheFluid implements IStorageCache<FluidStack> {
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<FluidStack> listener) {
listeners.add(listener);
listener.onAttached();
}
@Override
public void removeListener(IStorageCacheListener<FluidStack> listener) {
listeners.remove(listener);
}

View File

@@ -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<ItemStack> {
private INetwork network;
private CopyOnWriteArrayList<IStorage<ItemStack>> storages = new CopyOnWriteArrayList<>();
private IStackList<ItemStack> list = API.instance().createItemStackList();
private List<Runnable> listeners = new LinkedList<>();
private List<IStorageCacheListener<ItemStack>> listeners = new LinkedList<>();
private List<Pair<ItemStack, Integer>> batchedChanges = new ArrayList<>();
public StorageCacheItem(INetwork network) {
this.network = network;
@@ -51,9 +51,7 @@ public class StorageCacheItem implements IStorageCache<ItemStack> {
}
}
listeners.forEach(Runnable::run);
network.sendItemStorageToClient();
listeners.forEach(IStorageCacheListener::onInvalidated);
}
@Override
@@ -61,28 +59,42 @@ public class StorageCacheItem implements IStorageCache<ItemStack> {
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<ItemStack> listener) {
listeners.add(listener);
listener.onAttached();
}
@Override
public void removeListener(IStorageCacheListener<ItemStack> listener) {
listeners.remove(listener);
}

View File

@@ -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<ItemStack> {
private IPortableGrid portableGrid;
private IStackList<ItemStack> list = API.instance().createItemStackList();
private List<Runnable> listeners = new LinkedList<>();
private List<IStorageCacheListener<ItemStack>> listeners = new LinkedList<>();
public StorageCacheItemPortable(IPortableGrid portableGrid) {
this.portableGrid = portableGrid;
@@ -37,9 +30,7 @@ public class StorageCacheItemPortable implements IStorageCache<ItemStack> {
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<ItemStack> {
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<ItemStack> listener) {
listeners.add(listener);
listener.onAttached();
}
@Override
public void removeListener(IStorageCacheListener<ItemStack> listener) {
listeners.remove(listener);
}
@@ -86,21 +80,4 @@ public class StorageCacheItemPortable implements IStorageCache<ItemStack> {
public List<IStorage<ItemStack>> 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);
}
}

View File

@@ -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<FluidStack> {
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);
}
}

View File

@@ -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<ItemStack> {
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);
}
}

View File

@@ -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<ItemStack> {
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);
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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<String, ResourceLocation> TEXTURE_CACHE = new HashMap<>();
private static final Map<Class, Queue<Consumer>> 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<Consumer> 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 <T> void executeLater(Class<T> clazz, Consumer<T> callback) {
Queue<Consumer> queue = RUNNABLES.get(clazz);
if (queue == null) {
RUNNABLES.put(clazz, queue = new ArrayDeque<>());
}
queue.add(callback);
}
}

View File

@@ -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<String> SEARCH_HISTORY = new ArrayList<>();
public static final ListMultimap<Item, GridStackItem> ITEMS = Multimaps.synchronizedListMultimap(ArrayListMultimap.create());
public static final ListMultimap<Fluid, GridStackFluid> FLUIDS = Multimaps.synchronizedListMultimap(ArrayListMultimap.create());
public static List<IGridStack> 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<String> searchHistory = new ArrayList<>();
private int searchHistoryIndex = -1;
public GuiGrid(ContainerGrid container, IGrid grid) {
super(container, grid.getType() == GridType.FLUID ? 193 : 227, 0);
List<IGridSorter> 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());
}
}

View File

@@ -0,0 +1,6 @@
package com.raoulvdberge.refinedstorage.gui.grid.sorting;
public enum GridSorterDirection {
ASCENDING,
DESCENDING
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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<IGridStack> {
protected int sortingDirection;
public void setSortingDirection(int sortingDirection) {
this.sortingDirection = sortingDirection;
}
}

View File

@@ -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);
}

View File

@@ -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<IGridStack> stacks = new ArrayList<>();
if (grid.isActive()) {
stacks.addAll(grid.getType() == GridType.FLUID ? GuiGrid.FLUIDS.values() : GuiGrid.ITEMS.values());
List<Predicate<IGridStack>> 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<IGridStack> t = stacks.iterator();
while (t.hasNext()) {
IGridStack stack = t.next();
for (Predicate<IGridStack> 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();
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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<IGridStack> stacks, List<IGridSorter> sorters) {
IGrid grid = gui.getGrid();
List<Predicate<IGridStack>> 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<IGridStack> it = stacks.iterator();
while (it.hasNext()) {
IGridStack stack = it.next();
for (Predicate<IGridStack> 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;
}
}
}

View File

@@ -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<Integer, GridStackFluid> map = new HashMap<>();
private List<IGridStack> stacks;
private GuiGrid gui;
private List<IGridSorter> sorters;
private boolean canCraft;
public GridViewFluid(GuiGrid gui, List<IGridSorter> sorters) {
this.sorters = sorters;
this.gui = gui;
}
@Override
public List<IGridStack> getStacks() {
return stacks;
}
@Override
public void setStacks(List<IGridStack> 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<IGridStack> stacks = new ArrayList<>();
if (gui.getGrid().isActive()) {
stacks.addAll(map.values());
new Thread(() -> sortAndFilter(gui, stacks, sorters)).start();
}
this.stacks = stacks;
updateUI(gui);
}
}

View File

@@ -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<Integer, GridStackItem> map = new HashMap<>();
private List<IGridStack> stacks;
private GuiGrid gui;
private List<IGridSorter> sorters;
private boolean canCraft;
public GridViewItem(GuiGrid gui, List<IGridSorter> sorters) {
this.gui = gui;
this.sorters = sorters;
}
@Override
public List<IGridStack> getStacks() {
return stacks;
}
@Override
public void setStacks(List<IGridStack> 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<IGridStack> stacks = new ArrayList<>();
if (gui.getGrid().isActive()) {
stacks.addAll(map.values());
new Thread(() -> sortAndFilter(gui, stacks, sorters)).start();
}
this.stacks = stacks;
updateUI(gui);
}
}

View File

@@ -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<IGridStack> getStacks();
void setStacks(List<IGridStack> stacks);
void postChange(IGridStack stack, int delta);
void setCanCraft(boolean canCraft);
boolean canCraft();
void sort();
}

View File

@@ -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;

View File

@@ -26,7 +26,7 @@ public class GuiHandlerGrid implements IAdvancedGuiHandler<GuiGrid> {
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;

View File

@@ -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());
}
}

View File

@@ -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<ItemStack> {
private INetwork network;
private IStorageCache<ItemStack> 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();
}
}

View File

@@ -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<ItemStack> storage;
private IStorageCache<ItemStack> 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]);
}
}

View File

@@ -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<MessageG
@Override
public IMessage onMessage(MessageGridFluidDelta message, MessageContext ctx) {
Fluid fluid = message.clientStack.getStack().getFluid();
for (GridStackFluid stack : GuiGrid.FLUIDS.get(fluid)) {
if (stack.equals(message.clientStack)) {
if (stack.getStack().amount + message.delta <= 0) {
GuiGrid.FLUIDS.remove(fluid, stack);
} else {
stack.getStack().amount += message.delta;
}
stack.setTrackerEntry(message.clientStack.getTrackerEntry());
GuiGrid.scheduleSort();
return null;
}
}
GuiGrid.FLUIDS.put(fluid, message.clientStack);
GuiGrid.scheduleSort();
GuiBase.executeLater(GuiGrid.class, grid -> {
grid.getView().postChange(message.clientStack, message.delta);
grid.getView().sort();
});
return null;
}

View File

@@ -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<MessageGridFluidUpdate, IMessage> {
private INetwork network;
private boolean canCraft;
private List<GridStackFluid> stacks = new ArrayList<>();
private List<IGridStack> stacks = new ArrayList<>();
public MessageGridFluidUpdate() {
}
@@ -60,15 +62,11 @@ public class MessageGridFluidUpdate implements IMessage, IMessageHandler<Message
@Override
public IMessage onMessage(MessageGridFluidUpdate message, MessageContext ctx) {
GuiGrid.CAN_CRAFT = message.canCraft;
GuiGrid.FLUIDS.clear();
for (GridStackFluid item : message.stacks) {
GuiGrid.FLUIDS.put(item.getStack().getFluid(), item);
}
GuiGrid.scheduleSort();
GuiBase.executeLater(GuiGrid.class, grid -> {
grid.getView().setCanCraft(message.canCraft);
grid.getView().setStacks(message.stacks);
grid.getView().sort();
});
return null;
}

View File

@@ -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<MessageGr
@Override
public IMessage onMessage(MessageGridItemDelta message, MessageContext ctx) {
if (message.gridStack != null) {
process(message.gridStack, message.delta);
} else {
message.gridStacks.forEach(p -> 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);
}
}

View File

@@ -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<MessageGridItemUpdate, IMessage> {
private Consumer<ByteBuf> sendHandler;
private boolean canCraft;
private List<GridStackItem> stacks = new ArrayList<>();
private List<IGridStack> stacks = new ArrayList<>();
public MessageGridItemUpdate() {
}
@@ -92,30 +93,11 @@ public class MessageGridItemUpdate implements IMessage, IMessageHandler<MessageG
@Override
public IMessage onMessage(MessageGridItemUpdate message, MessageContext ctx) {
GuiGrid.CAN_CRAFT = message.canCraft;
GuiGrid.ITEMS.clear();
for (GridStackItem item : message.stacks) {
boolean canAdd = true;
if (item.doesDisplayCraftText()) {
// This is an output from a pattern being sent. Only add it if it hasn't been added before.
for (GridStackItem otherItem : GuiGrid.ITEMS.get(item.getStack().getItem())) {
if (API.instance().getComparer().isEqualNoQuantity(item.getStack(), otherItem.getStack())) {
canAdd = false;
break;
}
}
}
if (canAdd) {
GuiGrid.ITEMS.put(item.getStack().getItem(), item);
}
}
GuiGrid.scheduleSort();
GuiBase.executeLater(GuiGrid.class, grid -> {
grid.getView().setCanCraft(message.canCraft);
grid.getView().setStacks(message.stacks);
grid.getView().sort();
});
return null;
}

View File

@@ -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));
});
}

View File

@@ -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<ItemStack> itemStorage = new StorageCacheItem(this);
private StorageTrackerItem itemStorageTracker = new StorageTrackerItem(this::markDirty);
private List<Pair<ItemStack, Integer>> batchedItemStorageDeltas = new LinkedList<>();
private IStorageCache<FluidStack> 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;

View File

@@ -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<NetworkNodeGrid> {
t.getNode().setViewType(v);
t.getNode().markDirty();
}
}, p -> GuiGrid.scheduleSort());
}, p -> GuiBase.executeLater(GuiGrid.class, grid -> grid.getView().sort()));
public static final TileDataParameter<Integer, TileGrid> 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<Integer, TileGrid> 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<Integer, TileGrid> 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<NetworkNodeGrid> {
public static final TileDataParameter<Integer, TileGrid> 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<Integer, TileGrid> TAB_PAGE = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.getNode().getTabPage(), (t, v) -> {
if (v >= 0 && v <= t.getNode().getTotalTabPages()) {
t.getNode().setTabPage(v);

View File

@@ -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

View File

@@ -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

View File

@@ -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<ItemStack> getCache();
@@ -17,8 +15,6 @@ public interface IPortableGrid {
@Nullable
IStorageDisk<ItemStack> getStorage();
List<EntityPlayer> getWatchers();
void drainEnergy(int energy);
int getEnergy();

View File

@@ -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<EntityPlayer> 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;
}
}

View File

@@ -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<ItemStack> {
public static final TileDataParameter<Integer, TilePortableGrid> REDSTONE_MODE = RedstoneMode.createParameter();
public static final TileDataParameter<Integer, TilePortableGrid> ENERGY_STORED = new TileDataParameter<>(DataSerializers.VARINT, 0, t -> t.energyStorage.getEnergyStored());
public static final TileDataParameter<Integer, TilePortableGrid> 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<Integer, TilePortableGrid> 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<Integer, TilePortableGrid> 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<Integer, TilePortableGrid> 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<Integer, TilePortableGrid> 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<EntityPlayer> 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();
}
}