diff --git a/CHANGELOG.md b/CHANGELOG.md index b0b0ae158..ed71b807d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### 1.6.9 - Fixed OpenComputers "unknown error" when using extract item API (raoulvdberge) +- Fixed client FPS stuttering when opening a Crafting Grid (raoulvdberge) ### 1.6.8 - Fixed Ender IO incompatibility (raoulvdberge) diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/IGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/IGrid.java index d51bf9e46..98b2a6e5b 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/IGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/IGrid.java @@ -73,6 +73,18 @@ public interface IGrid { @Nullable IFluidGridHandler getFluidHandler(); + /** + * @param listener the listener + */ + default void addCraftingListener(IGridCraftingListener listener) { + } + + /** + * @param listener the listener + */ + default void removeCraftingListener(IGridCraftingListener listener) { + } + /** * @return an unlocalized gui title */ diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/IGridCraftingListener.java b/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/IGridCraftingListener.java new file mode 100644 index 000000000..5375056f7 --- /dev/null +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/network/grid/IGridCraftingListener.java @@ -0,0 +1,12 @@ +package com.raoulvdberge.refinedstorage.api.network.grid; + +/** + * A crafting listener for the grid. + */ +public interface IGridCraftingListener { + /** + * Called when the crafting output changes. + * Usually you'd send slot updates for the crafting slots (and output slot) here, so that all clients get an actual view. + */ + void onCraftingOutputChanged(); +} diff --git a/src/main/java/com/raoulvdberge/refinedstorage/api/storage/IStorageCacheListener.java b/src/main/java/com/raoulvdberge/refinedstorage/api/storage/IStorageCacheListener.java index 732029baf..d9816ed06 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/api/storage/IStorageCacheListener.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/api/storage/IStorageCacheListener.java @@ -1,6 +1,5 @@ package com.raoulvdberge.refinedstorage.api.storage; -import net.minecraft.item.ItemStack; import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nonnull; @@ -30,5 +29,10 @@ public interface IStorageCacheListener { */ void onChanged(@Nonnull T stack, int size); + /** + * Called when the storage cache changes. + * + * @param stacks a list of stacks that are changed, with the size changed (negative if the amount decreases) + */ void onChangedBulk(@Nonnull List> stacks); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeGrid.java index 92f23dee6..35412d5c7 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/apiimpl/network/node/NetworkNodeGrid.java @@ -4,10 +4,7 @@ import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.RSBlocks; import com.raoulvdberge.refinedstorage.RSItems; 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.IGridNetworkAware; -import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab; +import com.raoulvdberge.refinedstorage.api.network.grid.*; 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.INetworkItem; @@ -55,7 +52,9 @@ import net.minecraftforge.items.wrapper.InvWrapper; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware, IType { public static final String ID = "grid"; @@ -80,7 +79,9 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware, I @Override public void onCraftMatrixChanged(IInventory inventory) { - onCraftingMatrixChanged(); + if (!world.isRemote) { + onCraftingMatrixChanged(); + } } }; private IRecipe currentRecipe; @@ -89,6 +90,8 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware, I private ItemHandlerBase processingMatrix = new ItemHandlerBase(9 * 2, new ListenerNetworkNode(this)); private FluidInventory processingMatrixFluids = new FluidInventory(9 * 2, Fluid.BUCKET_VOLUME * 64, new ListenerNetworkNode(this)); + private Set craftingListeners = new HashSet<>(); + private ItemHandlerBase patterns = new ItemHandlerBase(2, new ListenerNetworkNode(this), new ItemValidatorBasic(RSItems.PATTERN)) { @Override protected void onContentsChanged(int slot) { @@ -252,6 +255,16 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware, I return network != null ? network.getFluidGridHandler() : null; } + @Override + public void addCraftingListener(IGridCraftingListener listener) { + craftingListeners.add(listener); + } + + @Override + public void removeCraftingListener(IGridCraftingListener listener) { + craftingListeners.remove(listener); + } + @Override public String getGuiTitle() { GridType type = getGridType(); @@ -317,6 +330,8 @@ public class NetworkNodeGrid extends NetworkNode implements IGridNetworkAware, I result.setInventorySlotContents(0, currentRecipe.getCraftingResult(matrix)); } + craftingListeners.forEach(IGridCraftingListener::onCraftingOutputChanged); + markDirty(); } diff --git a/src/main/java/com/raoulvdberge/refinedstorage/container/ContainerGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/container/ContainerGrid.java index 33e1a9064..55308cba7 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/container/ContainerGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/container/ContainerGrid.java @@ -2,6 +2,7 @@ package com.raoulvdberge.refinedstorage.container; import com.raoulvdberge.refinedstorage.api.network.grid.GridType; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; +import com.raoulvdberge.refinedstorage.api.network.grid.IGridCraftingListener; 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; @@ -25,11 +26,12 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.IContainerListener; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; +import net.minecraft.network.play.server.SPacketSetSlot; import net.minecraftforge.items.SlotItemHandler; import javax.annotation.Nullable; -public class ContainerGrid extends ContainerBase { +public class ContainerGrid extends ContainerBase implements IGridCraftingListener { private IGrid grid; private IStorageCache cache; private IStorageCacheListener listener; @@ -45,6 +47,8 @@ public class ContainerGrid extends ContainerBase { this.display = display; initSlots(); + + grid.addCraftingListener(this); } public void initSlots() { @@ -73,7 +77,7 @@ public class ContainerGrid extends ContainerBase { if (slot == craftingResultSlot) { grid.onCraftedShift(getPlayer()); - sendCraftingSlots(); + onCraftingOutputChanged(); detectAndSendChanges(); } else { @@ -199,13 +203,17 @@ public class ContainerGrid extends ContainerBase { return grid; } - public void sendCraftingSlots() { + @Override + public void onCraftingOutputChanged() { for (int i = 0; i < inventorySlots.size(); ++i) { Slot slot = inventorySlots.get(i); if (slot instanceof SlotGridCrafting || slot == craftingResultSlot) { for (IContainerListener listener : listeners) { - listener.sendSlotContents(this, i, slot.getStack()); + // @Volatile: We can't use IContainerListener#sendSlotContents since EntityPlayerMP blocks SlotCrafting changes... + if (listener instanceof EntityPlayerMP) { + ((EntityPlayerMP) listener).connection.sendPacket(new SPacketSetSlot(windowId, i, slot.getStack())); + } } } } @@ -246,6 +254,8 @@ public class ContainerGrid extends ContainerBase { cache.removeListener(listener); } } + + grid.removeCraftingListener(this); } @Override diff --git a/src/main/java/com/raoulvdberge/refinedstorage/container/slot/grid/SlotGridCraftingResult.java b/src/main/java/com/raoulvdberge/refinedstorage/container/slot/grid/SlotGridCraftingResult.java index be730baef..cb24b491b 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/container/slot/grid/SlotGridCraftingResult.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/container/slot/grid/SlotGridCraftingResult.java @@ -27,7 +27,7 @@ public class SlotGridCraftingResult extends SlotCrafting { if (!player.getEntityWorld().isRemote) { grid.onCrafted(player); - container.sendCraftingSlots(); + container.onCraftingOutputChanged(); } return ItemStack.EMPTY; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessFluidGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessFluidGrid.java index 0d5b1750e..dc7cbc309 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessFluidGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessFluidGrid.java @@ -2,10 +2,7 @@ package com.raoulvdberge.refinedstorage.tile.grid; import com.raoulvdberge.refinedstorage.RS; 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.IGridNetworkAware; -import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab; +import com.raoulvdberge.refinedstorage.api.network.grid.*; 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; @@ -133,6 +130,16 @@ public class WirelessFluidGrid implements IGridNetworkAware { return network != null ? network.getFluidGridHandler() : null; } + @Override + public void addCraftingListener(IGridCraftingListener listener) { + // NO OP + } + + @Override + public void removeCraftingListener(IGridCraftingListener listener) { + // NO OP + } + @Override public String getGuiTitle() { return "gui.refinedstorage:fluid_grid"; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessGrid.java index d4d6e3d44..9dfae61ed 100755 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/WirelessGrid.java @@ -2,10 +2,7 @@ package com.raoulvdberge.refinedstorage.tile.grid; import com.raoulvdberge.refinedstorage.RS; 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.IGridNetworkAware; -import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab; +import com.raoulvdberge.refinedstorage.api.network.grid.*; 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; @@ -135,6 +132,16 @@ public class WirelessGrid implements IGridNetworkAware { return null; } + @Override + public void addCraftingListener(IGridCraftingListener listener) { + // NO OP + } + + @Override + public void removeCraftingListener(IGridCraftingListener listener) { + // NO OP + } + @Override public String getGuiTitle() { return "gui.refinedstorage:grid"; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/PortableGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/PortableGrid.java index ef26416e9..8b9055d75 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/PortableGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/PortableGrid.java @@ -3,6 +3,7 @@ package com.raoulvdberge.refinedstorage.tile.grid.portable; import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.api.network.grid.GridType; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; +import com.raoulvdberge.refinedstorage.api.network.grid.IGridCraftingListener; import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IFluidGridHandler; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IItemGridHandler; @@ -236,6 +237,16 @@ public class PortableGrid implements IGrid, IPortableGrid, IStorageDiskContainer return fluidHandler; } + @Override + public void addCraftingListener(IGridCraftingListener listener) { + // NO OP + } + + @Override + public void removeCraftingListener(IGridCraftingListener listener) { + // NO OP + } + @Override public String getGuiTitle() { return "gui.refinedstorage:portable_grid"; diff --git a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/TilePortableGrid.java b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/TilePortableGrid.java index 7002d1713..371994da4 100644 --- a/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/TilePortableGrid.java +++ b/src/main/java/com/raoulvdberge/refinedstorage/tile/grid/portable/TilePortableGrid.java @@ -4,6 +4,7 @@ import com.raoulvdberge.refinedstorage.RS; import com.raoulvdberge.refinedstorage.RSBlocks; import com.raoulvdberge.refinedstorage.api.network.grid.GridType; import com.raoulvdberge.refinedstorage.api.network.grid.IGrid; +import com.raoulvdberge.refinedstorage.api.network.grid.IGridCraftingListener; import com.raoulvdberge.refinedstorage.api.network.grid.IGridTab; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IFluidGridHandler; import com.raoulvdberge.refinedstorage.api.network.grid.handler.IItemGridHandler; @@ -313,6 +314,16 @@ public class TilePortableGrid extends TileBase implements IGrid, IPortableGrid, return fluidHandler; } + @Override + public void addCraftingListener(IGridCraftingListener listener) { + // NO OP + } + + @Override + public void removeCraftingListener(IGridCraftingListener listener) { + // NO OP + } + @Override public String getGuiTitle() { return "gui.refinedstorage:portable_grid";