From e6fb553a53a8c519a7bf7085bc7d1e2997b62c8e Mon Sep 17 00:00:00 2001 From: shartte Date: Sun, 20 Sep 2020 00:26:34 +0200 Subject: [PATCH] Fixes #4741: Rework Crafting CPU cycling and extract commonalities into a separate class. (#4742) Also Fixes: - Enter key confirms the "Confirm Crafting" dialog again - Right Mouse Button correctly cycles backwards through CPUs, while left mouse button forward - Fixes an internal problem with syncing CPU names - Naming of unnamed CPUs begins at #1 now --- .../java/appeng/client/gui/AEBaseScreen.java | 23 ++- .../implementations/CraftConfirmScreen.java | 37 ++-- .../implementations/CraftingStatusScreen.java | 30 +--- .../gui/implementations/InterfaceScreen.java | 2 +- .../gui/widgets/SettingToggleButton.java | 10 +- .../appeng/container/guisync/SyncData.java | 2 + .../CraftConfirmContainer.java | 159 +++++------------- .../implementations/CraftingCPUContainer.java | 17 +- .../implementations/CraftingCPUCycler.java | 131 +++++++++++++++ .../CraftingCPUCyclingContainer.java | 12 ++ .../implementations/CraftingCPURecord.java | 17 +- .../CraftingStatusContainer.java | 112 +++--------- .../core/sync/packets/ConfigValuePacket.java | 11 +- 13 files changed, 279 insertions(+), 284 deletions(-) create mode 100644 src/main/java/appeng/container/implementations/CraftingCPUCycler.java create mode 100644 src/main/java/appeng/container/implementations/CraftingCPUCyclingContainer.java diff --git a/src/main/java/appeng/client/gui/AEBaseScreen.java b/src/main/java/appeng/client/gui/AEBaseScreen.java index 5773c0f11..c73df1de5 100644 --- a/src/main/java/appeng/client/gui/AEBaseScreen.java +++ b/src/main/java/appeng/client/gui/AEBaseScreen.java @@ -106,6 +106,7 @@ public abstract class AEBaseScreen extends ContainerS private Stopwatch dbl_clickTimer = Stopwatch.createStarted(); private ItemStack dbl_whichItem = ItemStack.EMPTY; private Slot bl_clicked; + private boolean handlingRightClick; protected final List guiSlots = new ArrayList<>(); public AEBaseScreen(T container, PlayerInventory playerInventory, ITextComponent title) { @@ -275,12 +276,18 @@ public abstract class AEBaseScreen extends ContainerS public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) { this.drag_click.clear(); + // Forward right-clicks as-if they were left-clicks if (btn == 1) { - for (final Object o : this.buttons) { - final Widget widget = (Widget) o; - if (widget.isMouseOver(xCoord, yCoord)) { - return super.mouseClicked(xCoord, yCoord, 0); + handlingRightClick = true; + try { + for (final Object o : this.buttons) { + final Widget widget = (Widget) o; + if (widget.isMouseOver(xCoord, yCoord)) { + return super.mouseClicked(xCoord, yCoord, 0); + } } + } finally { + handlingRightClick = false; } } @@ -814,4 +821,12 @@ public abstract class AEBaseScreen extends ContainerS } } + /** + * Returns true while the current event being handled is a click of the right + * mouse button. + */ + public boolean isHandlingRightClick() { + return handlingRightClick; + } + } diff --git a/src/main/java/appeng/client/gui/implementations/CraftConfirmScreen.java b/src/main/java/appeng/client/gui/implementations/CraftConfirmScreen.java index 76c14ff85..6f115c87b 100644 --- a/src/main/java/appeng/client/gui/implementations/CraftConfirmScreen.java +++ b/src/main/java/appeng/client/gui/implementations/CraftConfirmScreen.java @@ -27,6 +27,8 @@ import com.google.common.base.Joiner; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; +import org.lwjgl.glfw.GLFW; + import net.minecraft.client.gui.widget.button.Button; import net.minecraft.client.util.InputMappings; import net.minecraft.entity.player.PlayerInventory; @@ -76,10 +78,6 @@ public class CraftConfirmScreen extends AEBaseScreen { this.setScrollBar(scrollbar); } - boolean isAutoStart() { - return this.container.isAutoStart(); - } - @Override public void init() { super.init(); @@ -90,8 +88,7 @@ public class CraftConfirmScreen extends AEBaseScreen { this.addButton(this.start); this.selectCPU = new Button(this.guiLeft + (219 - 180) / 2, this.guiTop + this.ySize - 68, 180, 20, - new StringTextComponent(GuiText.CraftingCPU.getLocal() + ": " + GuiText.Automatic), - btn -> selectNextCpu()); + getNextCpuButtonLabel(), btn -> selectNextCpu()); this.selectCPU.active = false; this.addButton(this.selectCPU); @@ -139,22 +136,22 @@ public class CraftConfirmScreen extends AEBaseScreen { } private void updateCPUButtonText() { - String btnTextText = GuiText.CraftingCPU.getLocal() + ": " + GuiText.Automatic.getLocal(); - if (this.container.getSelectedCpu() >= 0)// && status.selectedCpu < status.cpus.size() ) - { - if (this.container.getName() != null) { - final String name = this.container.getName().getStringTruncated(20); - btnTextText = GuiText.CraftingCPU.getLocal() + ": " + name; - } else { - btnTextText = GuiText.CraftingCPU.getLocal() + ": #" + this.container.getSelectedCpu(); - } - } + this.selectCPU.setMessage(getNextCpuButtonLabel()); + } + private ITextComponent getNextCpuButtonLabel() { if (this.container.hasNoCPU()) { - btnTextText = GuiText.NoCraftingCPUs.getLocal(); + return GuiText.NoCraftingCPUs.text(); } - this.selectCPU.setMessage(new StringTextComponent(btnTextText)); + ITextComponent cpuName; + if (this.container.cpuName == null) { + cpuName = GuiText.Automatic.text(); + } else { + cpuName = this.container.cpuName; + } + + return GuiText.CraftingCPU.withSuffix(": ").append(cpuName); } private boolean isSimulation() { @@ -447,7 +444,7 @@ public class CraftConfirmScreen extends AEBaseScreen { @Override public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) { if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) { - if (keyCode == 28) { + if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) { this.start(); return true; } @@ -456,7 +453,7 @@ public class CraftConfirmScreen extends AEBaseScreen { } private void selectNextCpu() { - final boolean backwards = minecraft.mouseHelper.isRightDown(); + final boolean backwards = isHandlingRightClick(); NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next")); } diff --git a/src/main/java/appeng/client/gui/implementations/CraftingStatusScreen.java b/src/main/java/appeng/client/gui/implementations/CraftingStatusScreen.java index a3b4fe4ce..e98ba495a 100644 --- a/src/main/java/appeng/client/gui/implementations/CraftingStatusScreen.java +++ b/src/main/java/appeng/client/gui/implementations/CraftingStatusScreen.java @@ -16,10 +16,6 @@ * along with Applied Energistics 2. If not, see . */ -/** - * - */ - package appeng.client.gui.implementations; import com.mojang.blaze3d.matrix.MatrixStack; @@ -27,7 +23,6 @@ import com.mojang.blaze3d.matrix.MatrixStack; import net.minecraft.client.gui.widget.button.Button; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.StringTextComponent; import appeng.container.implementations.CraftingStatusContainer; import appeng.core.localization.GuiText; @@ -50,8 +45,7 @@ public class CraftingStatusScreen extends CraftingCPUScreen selectNextCpu()); this.addButton(this.selectCPU); @@ -68,23 +62,14 @@ public class CraftingStatusScreen extends CraftingCPUScreen= 0)// && status.selectedCpu < status.cpus.size() ) - { - if (this.container.myName != null) { - final String name = this.container.myName.getStringTruncated(20); - btnTextText = GuiText.CPUs.getLocal() + ": " + name; - } else { - btnTextText = GuiText.CPUs.getLocal() + ": #" + this.container.selectedCpu; - } - } + this.selectCPU.setMessage(getNextCpuButtonLabel()); + } + private ITextComponent getNextCpuButtonLabel() { if (this.container.noCPU) { - btnTextText = GuiText.NoCraftingJobs.getLocal(); + return GuiText.NoCraftingJobs.text(); } - - this.selectCPU.setMessage(new StringTextComponent(btnTextText)); + return GuiText.CraftingCPU.withSuffix(": ").append(container.cpuName); } @Override @@ -92,9 +77,8 @@ public class CraftingStatusScreen extends CraftingCPUScreen { } private void selectNextInterfaceMode() { - final boolean backwards = getMinecraft().mouseHelper.isRightDown(); + final boolean backwards = isHandlingRightClick(); NetworkHandler.instance().sendToServer(new ConfigButtonPacket(Settings.INTERFACE_TERMINAL, backwards)); } diff --git a/src/main/java/appeng/client/gui/widgets/SettingToggleButton.java b/src/main/java/appeng/client/gui/widgets/SettingToggleButton.java index f5bee7e9c..af875df65 100644 --- a/src/main/java/appeng/client/gui/widgets/SettingToggleButton.java +++ b/src/main/java/appeng/client/gui/widgets/SettingToggleButton.java @@ -25,6 +25,7 @@ import java.util.function.Predicate; import java.util.regex.Pattern; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.widget.button.Button; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; @@ -47,6 +48,7 @@ import appeng.api.config.StorageFilter; import appeng.api.config.TerminalStyle; import appeng.api.config.ViewItems; import appeng.api.config.YesNo; +import appeng.client.gui.AEBaseScreen; import appeng.core.localization.ButtonToolTips; import appeng.util.EnumCycler; @@ -232,7 +234,13 @@ public class SettingToggleButton> extends IconButton { } private void triggerPress() { - boolean backwards = Minecraft.getInstance().mouseHelper.isRightDown(); + boolean backwards = false; + // This isn't great, but we don't get any information about right-clicks + // otherwise + Screen currentScreen = Minecraft.getInstance().currentScreen; + if (currentScreen instanceof AEBaseScreen) { + backwards = ((AEBaseScreen) currentScreen).isHandlingRightClick(); + } onPress.handle(this, backwards); } diff --git a/src/main/java/appeng/container/guisync/SyncData.java b/src/main/java/appeng/container/guisync/SyncData.java index 79d692ded..f5cbb25f4 100644 --- a/src/main/java/appeng/container/guisync/SyncData.java +++ b/src/main/java/appeng/container/guisync/SyncData.java @@ -89,6 +89,8 @@ public class SyncData { NetworkHandler.instance().sendTo(new ConfigValuePacket("SyncDat." + this.channel, json), (ServerPlayerEntity) o); } + this.clientVersion = val; + return; } // Types other than ITextComponent must be non-null diff --git a/src/main/java/appeng/container/implementations/CraftConfirmContainer.java b/src/main/java/appeng/container/implementations/CraftConfirmContainer.java index 47e0e2dbd..0f8c87c90 100644 --- a/src/main/java/appeng/container/implementations/CraftConfirmContainer.java +++ b/src/main/java/appeng/container/implementations/CraftConfirmContainer.java @@ -19,14 +19,8 @@ package appeng.container.implementations; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; import java.util.concurrent.Future; -import javax.annotation.Nullable; - -import com.google.common.collect.ImmutableSet; - import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.ServerPlayerEntity; @@ -67,7 +61,7 @@ import appeng.parts.reporting.CraftingTerminalPart; import appeng.parts.reporting.PatternTerminalPart; import appeng.parts.reporting.TerminalPart; -public class CraftConfirmContainer extends AEBaseContainer { +public class CraftConfirmContainer extends AEBaseContainer implements CraftingCPUCyclingContainer { public static ContainerType TYPE; @@ -82,53 +76,42 @@ public class CraftConfirmContainer extends AEBaseContainer { return helper.open(player, locator); } - private final ArrayList cpus = new ArrayList<>(); + private final CraftingCPUCycler cpuCycler; + + private ICraftingCPU selectedCpu; + private Future job; private ICraftingJob result; @GuiSync(0) public long bytesUsed; - @GuiSync(1) - public long cpuBytesAvail; - @GuiSync(2) - public int cpuCoProcessors; @GuiSync(3) public boolean autoStart = false; @GuiSync(4) public boolean simulation = true; - @GuiSync(5) - public int selectedCpu = -1; + + // Indicates whether any CPUs are available @GuiSync(6) public boolean noCPU = true; + + // Properties of the currently selected crafting CPU, this can be null + // if no CPUs are available, or if an automatic one is selected + @GuiSync(1) + public long cpuBytesAvail; + @GuiSync(2) + public int cpuCoProcessors; @GuiSync(7) - public ITextComponent myName; + public ITextComponent cpuName; public CraftConfirmContainer(int id, PlayerInventory ip, ITerminalHost te) { super(TYPE, id, ip, te); + this.cpuCycler = new CraftingCPUCycler(this::cpuMatches, this::onCPUSelectionChanged); + // A player can select no crafting CPU to use a suitable one automatically + this.cpuCycler.setAllowNoSelection(true); } - public void cycleCpu(final boolean next) { - if (next) { - this.setSelectedCpu(this.getSelectedCpu() + 1); - } else { - this.setSelectedCpu(this.getSelectedCpu() - 1); - } - - if (this.getSelectedCpu() < -1) { - this.setSelectedCpu(this.cpus.size() - 1); - } else if (this.getSelectedCpu() >= this.cpus.size()) { - this.setSelectedCpu(-1); - } - - if (this.getSelectedCpu() == -1) { - this.setCpuAvailableBytes(0); - this.setCpuCoProcessors(0); - this.setName(null); - } else { - CraftingCPURecord cpu = this.cpus.get(this.getSelectedCpu()); - this.setName(cpu.getName()); - this.setCpuAvailableBytes(cpu.getSize()); - this.setCpuCoProcessors(cpu.getProcessors()); - } + @Override + public void cycleSelectedCPU(final boolean next) { + this.cpuCycler.cycleCpu(next); } @Override @@ -137,43 +120,7 @@ public class CraftConfirmContainer extends AEBaseContainer { return; } - final ICraftingGrid cc = this.getGrid().getCache(ICraftingGrid.class); - final ImmutableSet cpuSet = cc.getCpus(); - - int matches = 0; - boolean changed = false; - for (final ICraftingCPU c : cpuSet) { - boolean found = false; - for (final CraftingCPURecord ccr : this.cpus) { - if (ccr.getCpu() == c) { - found = true; - break; - } - } - - final boolean matched = this.cpuMatches(c); - - if (matched) { - matches++; - } - - if (found == !matched) { - changed = true; - } - } - - if (changed || this.cpus.size() != matches) { - this.cpus.clear(); - for (final ICraftingCPU c : cpuSet) { - if (this.cpuMatches(c)) { - this.cpus.add(new CraftingCPURecord(c.getAvailableStorage(), c.getCoProcessors(), c)); - } - } - - this.sendCPUs(); - } - - this.setNoCPU(this.cpus.isEmpty()); + this.cpuCycler.detectAndSendChanges(this.getGrid()); super.detectAndSendChanges(); @@ -277,22 +224,6 @@ public class CraftConfirmContainer extends AEBaseContainer { return c.getAvailableStorage() >= this.getUsedBytes() && !c.isBusy(); } - private void sendCPUs() { - Collections.sort(this.cpus); - - if (this.getSelectedCpu() >= this.cpus.size()) { - this.setSelectedCpu(-1); - this.setCpuAvailableBytes(0); - this.setCpuCoProcessors(0); - this.setName(null); - } else if (this.getSelectedCpu() != -1) { - CraftingCPURecord cpu = this.cpus.get(this.getSelectedCpu()); - this.setName(cpu.getName()); - this.setCpuAvailableBytes(cpu.getSize()); - this.setCpuCoProcessors(cpu.getProcessors()); - } - } - public void startJob() { ContainerType originalGui = null; @@ -315,9 +246,7 @@ public class CraftConfirmContainer extends AEBaseContainer { if (this.result != null && !this.isSimulation()) { final ICraftingGrid cc = this.getGrid().getCache(ICraftingGrid.class); - final ICraftingLink g = cc.submitJob(this.result, null, - this.getSelectedCpu() == -1 ? null : this.cpus.get(this.getSelectedCpu()).getCpu(), true, - this.getActionSrc()); + final ICraftingLink g = cc.submitJob(this.result, null, this.selectedCpu, true, this.getActionSrc()); this.setAutoStart(false); if (g != null && originalGui != null && this.getLocator() != null) { ContainerOpener.openContainer(originalGui, getPlayerInventory().player, getLocator()); @@ -347,6 +276,22 @@ public class CraftConfirmContainer extends AEBaseContainer { } } + private void onCPUSelectionChanged(CraftingCPURecord cpuRecord, boolean cpusAvailable) { + noCPU = !cpusAvailable; + + if (cpuRecord == null) { + cpuBytesAvail = 0; + cpuCoProcessors = 0; + cpuName = null; + selectedCpu = null; + } else { + cpuBytesAvail = cpuRecord.getSize(); + cpuCoProcessors = cpuRecord.getProcessors(); + cpuName = cpuRecord.getName(); + selectedCpu = cpuRecord.getCpu(); + } + } + public World getWorld() { return this.getPlayerInv().player.world; } @@ -371,42 +316,18 @@ public class CraftConfirmContainer extends AEBaseContainer { return this.cpuBytesAvail; } - private void setCpuAvailableBytes(final long cpuBytesAvail) { - this.cpuBytesAvail = cpuBytesAvail; - } - public int getCpuCoProcessors() { return this.cpuCoProcessors; } - private void setCpuCoProcessors(final int cpuCoProcessors) { - this.cpuCoProcessors = cpuCoProcessors; - } - - public int getSelectedCpu() { - return this.selectedCpu; - } - - private void setSelectedCpu(final int selectedCpu) { - this.selectedCpu = selectedCpu; - } - public ITextComponent getName() { - return this.myName; - } - - private void setName(@Nullable final ITextComponent myName) { - this.myName = myName; + return this.cpuName; } public boolean hasNoCPU() { return this.noCPU; } - private void setNoCPU(final boolean noCPU) { - this.noCPU = noCPU; - } - public boolean isSimulation() { return this.simulation; } diff --git a/src/main/java/appeng/container/implementations/CraftingCPUContainer.java b/src/main/java/appeng/container/implementations/CraftingCPUContainer.java index fcccf1b5a..901096a5a 100644 --- a/src/main/java/appeng/container/implementations/CraftingCPUContainer.java +++ b/src/main/java/appeng/container/implementations/CraftingCPUContainer.java @@ -66,7 +66,7 @@ public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorH private final IItemList list = Api.instance().storage().getStorageChannel(IItemStorageChannel.class) .createList(); - private IGrid network; + private final IGrid network; private CraftingCPUCluster monitor = null; @GuiSync(0) @@ -81,7 +81,9 @@ public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorH final IActionHost host = (IActionHost) (te instanceof IActionHost ? te : null); if (host != null && host.getActionableNode() != null) { - this.setNetwork(host.getActionableNode().getGrid()); + this.network = host.getActionableNode().getGrid(); + } else { + this.network = null; } if (te instanceof CraftingTileEntity) { @@ -118,13 +120,13 @@ public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorH } if (c instanceof CraftingCPUCluster) { - this.setMonitor((CraftingCPUCluster) c); + this.monitor = (CraftingCPUCluster) c; this.list.resetStatus(); this.getMonitor().getListOfItem(this.list, CraftingItemList.ALL); this.getMonitor().addListener(this, null); this.setEstimatedTime(0); } else { - this.setMonitor(null); + this.monitor = null; this.setEstimatedTime(-1); } } @@ -232,15 +234,8 @@ public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorH return this.monitor; } - private void setMonitor(final CraftingCPUCluster monitor) { - this.monitor = monitor; - } - IGrid getNetwork() { return this.network; } - private void setNetwork(final IGrid network) { - this.network = network; - } } diff --git a/src/main/java/appeng/container/implementations/CraftingCPUCycler.java b/src/main/java/appeng/container/implementations/CraftingCPUCycler.java new file mode 100644 index 000000000..d0ada4826 --- /dev/null +++ b/src/main/java/appeng/container/implementations/CraftingCPUCycler.java @@ -0,0 +1,131 @@ +package appeng.container.implementations; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.Predicate; + +import com.google.common.collect.ImmutableSet; + +import net.minecraft.util.text.StringTextComponent; + +import appeng.api.networking.IGrid; +import appeng.api.networking.crafting.ICraftingCPU; +import appeng.api.networking.crafting.ICraftingGrid; + +/** + * Utility class for dialogs that can cycle through crafting CPUs + */ +class CraftingCPUCycler { + + @FunctionalInterface + public interface ChangeListener { + void onChange(CraftingCPURecord selectedCpu, boolean cpusAvailable); + } + + private final Predicate cpuFilter; + private final ChangeListener changeListener; + private final List cpus = new ArrayList<>(); + private int selectedCpu = -1; + private boolean initialDataSent = false; + private boolean allowNoSelection; + + public CraftingCPUCycler(Predicate cpuFilter, ChangeListener changeListener) { + this.cpuFilter = cpuFilter; + this.changeListener = changeListener; + } + + public void detectAndSendChanges(IGrid network) { + final ICraftingGrid cc = network.getCache(ICraftingGrid.class); + final ImmutableSet cpuSet = cc.getCpus(); + + int matches = 0; + boolean changed = !initialDataSent; + initialDataSent = true; + for (final ICraftingCPU c : cpuSet) { + boolean found = false; + for (final CraftingCPURecord ccr : this.cpus) { + if (ccr.getCpu() == c) { + found = true; + break; + } + } + + final boolean matched = this.cpuFilter.test(c); + + if (matched) { + matches++; + } + + if (found == !matched) { + changed = true; + } + } + + if (changed || this.cpus.size() != matches) { + this.cpus.clear(); + for (final ICraftingCPU c : cpuSet) { + if (this.cpuFilter.test(c)) { + this.cpus.add(new CraftingCPURecord(c.getAvailableStorage(), c.getCoProcessors(), c)); + } + } + + // Sort and assign numeric IDs in case they have no names + Collections.sort(this.cpus); + for (int i = 0; i < this.cpus.size(); i++) { + CraftingCPURecord cpu = cpus.get(i); + if (cpu.getName() == null) { + cpu.setName(new StringTextComponent("#" + (i + 1))); + } + } + + this.notifyListener(); + } + } + + public void cycleCpu(final boolean next) { + if (next) { + this.selectedCpu++; + } else { + this.selectedCpu--; + } + + // If "no CPU" is a valid selection, then -1 is the first potential item + int lowerLimit = this.allowNoSelection ? -1 : 0; + + if (this.selectedCpu < lowerLimit) { + this.selectedCpu = this.cpus.size() - 1; + } else if (this.selectedCpu >= this.cpus.size()) { + this.selectedCpu = lowerLimit; + } + + this.notifyListener(); + } + + public boolean isAllowNoSelection() { + return allowNoSelection; + } + + public void setAllowNoSelection(boolean allowNoSelection) { + this.allowNoSelection = allowNoSelection; + } + + private void notifyListener() { + if (this.selectedCpu >= this.cpus.size()) { + this.selectedCpu = -1; + } + + // Force the selected CPU to the first available CPU unless no-selection is + // explicitly allowed + if (!this.allowNoSelection && this.selectedCpu == -1 && !this.cpus.isEmpty()) { + this.selectedCpu = 0; + } + + if (this.selectedCpu != -1) { + this.changeListener.onChange(this.cpus.get(this.selectedCpu), true); + } else { + this.changeListener.onChange(null, !this.cpus.isEmpty()); + } + } + +} diff --git a/src/main/java/appeng/container/implementations/CraftingCPUCyclingContainer.java b/src/main/java/appeng/container/implementations/CraftingCPUCyclingContainer.java new file mode 100644 index 000000000..b2877ac9f --- /dev/null +++ b/src/main/java/appeng/container/implementations/CraftingCPUCyclingContainer.java @@ -0,0 +1,12 @@ +package appeng.container.implementations; + +/** + * Implemented on screens that show information about a crafting CPU and allow + * the CPU to be cycled. Is triggered by receiving a config value packet with + * name Terminal.Cpu. + */ +public interface CraftingCPUCyclingContainer { + + void cycleSelectedCPU(boolean forward); + +} diff --git a/src/main/java/appeng/container/implementations/CraftingCPURecord.java b/src/main/java/appeng/container/implementations/CraftingCPURecord.java index d2d0ee459..55dbff264 100644 --- a/src/main/java/appeng/container/implementations/CraftingCPURecord.java +++ b/src/main/java/appeng/container/implementations/CraftingCPURecord.java @@ -25,16 +25,16 @@ import net.minecraft.util.text.ITextComponent; import appeng.api.networking.crafting.ICraftingCPU; public class CraftingCPURecord implements Comparable { - private final ITextComponent myName; private final ICraftingCPU cpu; private final long size; private final int processors; + private ITextComponent name; public CraftingCPURecord(final long size, final int coProcessors, final ICraftingCPU server) { this.size = size; this.processors = coProcessors; this.cpu = server; - this.myName = server.getName(); + this.name = server.getName(); } @Override @@ -50,10 +50,6 @@ public class CraftingCPURecord implements Comparable { return this.cpu; } - ITextComponent getName() { - return this.myName; - } - int getProcessors() { return this.processors; } @@ -61,4 +57,13 @@ public class CraftingCPURecord implements Comparable { long getSize() { return this.size; } + + public ITextComponent getName() { + return name; + } + + public void setName(ITextComponent name) { + this.name = name; + } + } diff --git a/src/main/java/appeng/container/implementations/CraftingStatusContainer.java b/src/main/java/appeng/container/implementations/CraftingStatusContainer.java index dcd1f8406..a1c173661 100644 --- a/src/main/java/appeng/container/implementations/CraftingStatusContainer.java +++ b/src/main/java/appeng/container/implementations/CraftingStatusContainer.java @@ -18,12 +18,6 @@ package appeng.container.implementations; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.google.common.collect.ImmutableSet; - import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.inventory.container.ContainerType; @@ -31,13 +25,13 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.util.text.ITextComponent; import appeng.api.config.SecurityPermissions; +import appeng.api.networking.IGrid; import appeng.api.networking.crafting.ICraftingCPU; -import appeng.api.networking.crafting.ICraftingGrid; import appeng.api.storage.ITerminalHost; import appeng.container.ContainerLocator; import appeng.container.guisync.GuiSync; -public class CraftingStatusContainer extends CraftingCPUContainer { +public class CraftingStatusContainer extends CraftingCPUContainer implements CraftingCPUCyclingContainer { public static ContainerType TYPE; @@ -52,13 +46,13 @@ public class CraftingStatusContainer extends CraftingCPUContainer { return helper.open(player, locator); } - private final List cpus = new ArrayList<>(); - @GuiSync(5) - public int selectedCpu = -1; + private final CraftingCPUCycler cpuCycler = new CraftingCPUCycler(this::cpuMatches, this::onCPUSelectionChanged); + @GuiSync(6) public boolean noCPU = true; + @GuiSync(7) - public ITextComponent myName; + public ITextComponent cpuName; public CraftingStatusContainer(int id, final PlayerInventory ip, final ITerminalHost te) { super(TYPE, id, ip, te); @@ -66,43 +60,9 @@ public class CraftingStatusContainer extends CraftingCPUContainer { @Override public void detectAndSendChanges() { - if (isServer() && this.getNetwork() != null) { - final ICraftingGrid cc = this.getNetwork().getCache(ICraftingGrid.class); - final ImmutableSet cpuSet = cc.getCpus(); - - int matches = 0; - boolean changed = false; - for (final ICraftingCPU c : cpuSet) { - boolean found = false; - for (final CraftingCPURecord ccr : this.cpus) { - if (ccr.getCpu() == c) { - found = true; - } - } - - final boolean matched = this.cpuMatches(c); - - if (matched) { - matches++; - } - - if (found == !matched) { - changed = true; - } - } - - if (changed || this.cpus.size() != matches) { - this.cpus.clear(); - for (final ICraftingCPU c : cpuSet) { - if (this.cpuMatches(c)) { - this.cpus.add(new CraftingCPURecord(c.getAvailableStorage(), c.getCoProcessors(), c)); - } - } - - this.sendCPUs(); - } - - this.noCPU = this.cpus.isEmpty(); + IGrid network = this.getNetwork(); + if (isServer() && network != null) { + cpuCycler.detectAndSendChanges(network); } super.detectAndSendChanges(); @@ -112,52 +72,20 @@ public class CraftingStatusContainer extends CraftingCPUContainer { return c.isBusy(); } - private void sendCPUs() { - Collections.sort(this.cpus); - - if (this.selectedCpu >= this.cpus.size()) { - this.selectedCpu = -1; - this.myName = null; - } else if (this.selectedCpu != -1) { - this.myName = this.cpus.get(this.selectedCpu).getName(); - } - - if (this.selectedCpu == -1 && this.cpus.size() > 0) { - this.selectedCpu = 0; - } - - if (this.selectedCpu != -1) { - if (this.cpus.get(this.selectedCpu).getCpu() != this.getMonitor()) { - this.setCPU(this.cpus.get(this.selectedCpu).getCpu()); - } + private void onCPUSelectionChanged(CraftingCPURecord cpuRecord, boolean cpusAvailable) { + noCPU = !cpusAvailable; + if (cpuRecord == null) { + cpuName = null; + setCPU(null); } else { - this.setCPU(null); + cpuName = cpuRecord.getName(); + setCPU(cpuRecord.getCpu()); } } - public void cycleCpu(final boolean next) { - if (next) { - this.selectedCpu++; - } else { - this.selectedCpu--; - } - - if (this.selectedCpu < -1) { - this.selectedCpu = this.cpus.size() - 1; - } else if (this.selectedCpu >= this.cpus.size()) { - this.selectedCpu = -1; - } - - if (this.selectedCpu == -1 && this.cpus.size() > 0) { - this.selectedCpu = 0; - } - - if (this.selectedCpu == -1) { - this.myName = null; - this.setCPU(null); - } else { - this.myName = this.cpus.get(this.selectedCpu).getName(); - this.setCPU(this.cpus.get(this.selectedCpu).getCpu()); - } + @Override + public void cycleSelectedCPU(boolean forward) { + this.cpuCycler.cycleCpu(forward); } + } diff --git a/src/main/java/appeng/core/sync/packets/ConfigValuePacket.java b/src/main/java/appeng/core/sync/packets/ConfigValuePacket.java index 5a222403b..4ab5bfa90 100644 --- a/src/main/java/appeng/core/sync/packets/ConfigValuePacket.java +++ b/src/main/java/appeng/core/sync/packets/ConfigValuePacket.java @@ -37,7 +37,7 @@ import appeng.container.AEBaseContainer; import appeng.container.implementations.CellWorkbenchContainer; import appeng.container.implementations.CraftConfirmContainer; import appeng.container.implementations.CraftingCPUContainer; -import appeng.container.implementations.CraftingStatusContainer; +import appeng.container.implementations.CraftingCPUCyclingContainer; import appeng.container.implementations.LevelEmitterContainer; import appeng.container.implementations.NetworkToolContainer; import appeng.container.implementations.PatternTermContainer; @@ -98,12 +98,9 @@ public class ConfigValuePacket extends BasePacket { final ItemStack is = player.getHeldItem(hand); final IMouseWheelItem si = (IMouseWheelItem) is.getItem(); si.onWheel(is, this.Value.equals("WheelUp")); - } else if (this.Name.equals("Terminal.Cpu") && c instanceof CraftingStatusContainer) { - final CraftingStatusContainer qk = (CraftingStatusContainer) c; - qk.cycleCpu(this.Value.equals("Next")); - } else if (this.Name.equals("Terminal.Cpu") && c instanceof CraftConfirmContainer) { - final CraftConfirmContainer qk = (CraftConfirmContainer) c; - qk.cycleCpu(this.Value.equals("Next")); + } else if (this.Name.equals("Terminal.Cpu") && c instanceof CraftingCPUCyclingContainer) { + final CraftingCPUCyclingContainer qk = (CraftingCPUCyclingContainer) c; + qk.cycleSelectedCPU(this.Value.equals("Next")); } else if (this.Name.equals("Terminal.Start") && c instanceof CraftConfirmContainer) { final CraftConfirmContainer qk = (CraftConfirmContainer) c; qk.startJob();