From 15f941decc8dc85de64e7c1c52ba0c86760af053 Mon Sep 17 00:00:00 2001 From: Alex Emelyanov Date: Sun, 31 Mar 2024 15:33:02 +0300 Subject: [PATCH 1/6] Refactoring after lib update --- .../energy/EnergyConnectorSettings.java | 2 +- .../mcjty/xnet/apiimpl/enums/InsExtMode.java | 2 +- .../xnet/apiimpl/items/enums/ExtractMode.java | 2 +- .../xnet/apiimpl/items/enums/StackMode.java | 2 +- .../apiimpl/logic/LogicConnectorSettings.java | 6 +- .../mcjty/xnet/apiimpl/logic/RSOutput.java | 4 +- .../mcjty/xnet/apiimpl/logic/RSSensor.java | 2 +- .../xnet/apiimpl/logic/enums/LogicFilter.java | 2 +- .../xnet/apiimpl/logic/enums/LogicMode.java | 2 +- .../xnet/apiimpl/logic/enums/SensorMode.java | 2 +- .../facade/blocks/FacadeBlockItem.java | 2 +- .../java/mcjty/xnet/utils/ChoiceEvent.java | 5 - .../mcjty/xnet/utils/EnumChoiceLabel.java | 203 ------------------ .../mcjty/xnet/utils/ITranslatableEnum.java | 11 - 14 files changed, 13 insertions(+), 234 deletions(-) delete mode 100644 src/main/java/mcjty/xnet/utils/ChoiceEvent.java delete mode 100644 src/main/java/mcjty/xnet/utils/EnumChoiceLabel.java delete mode 100644 src/main/java/mcjty/xnet/utils/ITranslatableEnum.java diff --git a/src/main/java/mcjty/xnet/apiimpl/energy/EnergyConnectorSettings.java b/src/main/java/mcjty/xnet/apiimpl/energy/EnergyConnectorSettings.java index 47a603a0..68c8c59b 100644 --- a/src/main/java/mcjty/xnet/apiimpl/energy/EnergyConnectorSettings.java +++ b/src/main/java/mcjty/xnet/apiimpl/energy/EnergyConnectorSettings.java @@ -94,7 +94,7 @@ public void createGui(IEditorGui gui) { colorsGui(gui); redstoneGui(gui); gui.nl(); - ((ConnectorEditorPanel) gui).translatableChoices(TAG_MODE, energyMode, InsExtMode.values());// TODO: 09.03.2024 remove ConnectorEditorPanel cast after rftoolbase update + gui.translatableChoices(TAG_MODE, energyMode, InsExtMode.values()); gui.nl() .label(PRIORITY_LABEL.i18n()).integer(TAG_PRIORITY, PRIORITY_TOOLTIP.i18n(), priority, 30).nl() diff --git a/src/main/java/mcjty/xnet/apiimpl/enums/InsExtMode.java b/src/main/java/mcjty/xnet/apiimpl/enums/InsExtMode.java index 26e581c5..8399b855 100644 --- a/src/main/java/mcjty/xnet/apiimpl/enums/InsExtMode.java +++ b/src/main/java/mcjty/xnet/apiimpl/enums/InsExtMode.java @@ -1,8 +1,8 @@ package mcjty.xnet.apiimpl.enums; import mcjty.lib.varia.ComponentFactory; +import mcjty.lib.gui.ITranslatableEnum; import mcjty.xnet.utils.I18nUtils; -import mcjty.xnet.utils.ITranslatableEnum; public enum InsExtMode implements ITranslatableEnum { INS("xnet.enum.insextmode.ins"), diff --git a/src/main/java/mcjty/xnet/apiimpl/items/enums/ExtractMode.java b/src/main/java/mcjty/xnet/apiimpl/items/enums/ExtractMode.java index 8dbafdfa..5c1c6004 100644 --- a/src/main/java/mcjty/xnet/apiimpl/items/enums/ExtractMode.java +++ b/src/main/java/mcjty/xnet/apiimpl/items/enums/ExtractMode.java @@ -1,8 +1,8 @@ package mcjty.xnet.apiimpl.items.enums; import mcjty.lib.varia.ComponentFactory; +import mcjty.lib.gui.ITranslatableEnum; import mcjty.xnet.utils.I18nUtils; -import mcjty.xnet.utils.ITranslatableEnum; public enum ExtractMode implements ITranslatableEnum { FIRST("xnet.enum.items.extractmode.first"), diff --git a/src/main/java/mcjty/xnet/apiimpl/items/enums/StackMode.java b/src/main/java/mcjty/xnet/apiimpl/items/enums/StackMode.java index 2944b02e..b784b01b 100644 --- a/src/main/java/mcjty/xnet/apiimpl/items/enums/StackMode.java +++ b/src/main/java/mcjty/xnet/apiimpl/items/enums/StackMode.java @@ -1,8 +1,8 @@ package mcjty.xnet.apiimpl.items.enums; import mcjty.lib.varia.ComponentFactory; +import mcjty.lib.gui.ITranslatableEnum; import mcjty.xnet.utils.I18nUtils; -import mcjty.xnet.utils.ITranslatableEnum; public enum StackMode implements ITranslatableEnum { SINGLE("xnet.enum.items.stackmode.single"), diff --git a/src/main/java/mcjty/xnet/apiimpl/logic/LogicConnectorSettings.java b/src/main/java/mcjty/xnet/apiimpl/logic/LogicConnectorSettings.java index 0974a66e..f1d8b1bc 100644 --- a/src/main/java/mcjty/xnet/apiimpl/logic/LogicConnectorSettings.java +++ b/src/main/java/mcjty/xnet/apiimpl/logic/LogicConnectorSettings.java @@ -131,15 +131,13 @@ public void createGui(IEditorGui gui) { sideGui(gui); colorsGui(gui); redstoneGui(gui); - gui.nl(); - ((ConnectorEditorPanel)gui).translatableChoices(TAG_MODE, logicMode, LogicMode.values());// TODO: 09.03.2024 remove ConnectorEditorPanel cast after rftoolbase update - gui.nl(); + gui.nl().translatableChoices(TAG_MODE, logicMode, LogicMode.values()).nl(); if (logicMode == LogicMode.SENSOR) { for (RSSensor sensor : sensors) { sensor.createGui(gui); } } else { - output.createGui((ConnectorEditorPanel) gui); // TODO: 06.03.2024 remove ConnectorEditorPanel cast after rftoolbase update + output.createGui(gui); } } diff --git a/src/main/java/mcjty/xnet/apiimpl/logic/RSOutput.java b/src/main/java/mcjty/xnet/apiimpl/logic/RSOutput.java index 3bc01db2..bcbf6b9f 100644 --- a/src/main/java/mcjty/xnet/apiimpl/logic/RSOutput.java +++ b/src/main/java/mcjty/xnet/apiimpl/logic/RSOutput.java @@ -1,8 +1,8 @@ package mcjty.xnet.apiimpl.logic; import mcjty.rftoolsbase.api.xnet.channels.Color; +import mcjty.rftoolsbase.api.xnet.gui.IEditorGui; import mcjty.xnet.apiimpl.logic.enums.LogicFilter; -import mcjty.xnet.modules.controller.client.ConnectorEditorPanel; import mcjty.xnet.utils.CastTools; import net.minecraft.nbt.CompoundTag; @@ -135,7 +135,7 @@ public void setRedstoneOut(int redstoneOut) { this.redstoneOut = redstoneOut; } - public void createGui(ConnectorEditorPanel gui) {// TODO: 09.03.2024 remove ConnectorEditorPanel cast after rftoolbase update + public void createGui(IEditorGui gui) { if (gui.isAdvanced()) { gui.translatableChoices(TAG_RS_FILTER, logicFilter, LogicFilter.values()); switch (logicFilter) { diff --git a/src/main/java/mcjty/xnet/apiimpl/logic/RSSensor.java b/src/main/java/mcjty/xnet/apiimpl/logic/RSSensor.java index 566fd80a..5a59916b 100644 --- a/src/main/java/mcjty/xnet/apiimpl/logic/RSSensor.java +++ b/src/main/java/mcjty/xnet/apiimpl/logic/RSSensor.java @@ -112,7 +112,7 @@ public boolean isEnabled(String tag) { } public void createGui(IEditorGui gui) { - ((AbstractEditorPanel)gui).translatableChoices(TAG_MODE + index, sensorMode, SensorMode.values()); + gui.translatableChoices(TAG_MODE + index, sensorMode, SensorMode.values()); gui .choices(TAG_OP + index, LOGIC_SENSOR_OPERATOR_TOOLTIP.i18n(), operator, Operator.values()) .integer(TAG_AMOUNT + index, LOGIC_SENSOR_AMOUNT_TOOLTIP.i18n(), amount, 46) diff --git a/src/main/java/mcjty/xnet/apiimpl/logic/enums/LogicFilter.java b/src/main/java/mcjty/xnet/apiimpl/logic/enums/LogicFilter.java index 2d56e899..b581efef 100644 --- a/src/main/java/mcjty/xnet/apiimpl/logic/enums/LogicFilter.java +++ b/src/main/java/mcjty/xnet/apiimpl/logic/enums/LogicFilter.java @@ -1,7 +1,7 @@ package mcjty.xnet.apiimpl.logic.enums; +import mcjty.lib.gui.ITranslatableEnum; import mcjty.xnet.utils.I18nUtils; -import mcjty.xnet.utils.ITranslatableEnum; import org.apache.commons.lang3.StringUtils; public enum LogicFilter implements ITranslatableEnum { diff --git a/src/main/java/mcjty/xnet/apiimpl/logic/enums/LogicMode.java b/src/main/java/mcjty/xnet/apiimpl/logic/enums/LogicMode.java index ddacc86c..96abb21b 100644 --- a/src/main/java/mcjty/xnet/apiimpl/logic/enums/LogicMode.java +++ b/src/main/java/mcjty/xnet/apiimpl/logic/enums/LogicMode.java @@ -2,8 +2,8 @@ import mcjty.lib.varia.ComponentFactory; +import mcjty.lib.gui.ITranslatableEnum; import mcjty.xnet.utils.I18nUtils; -import mcjty.xnet.utils.ITranslatableEnum; public enum LogicMode implements ITranslatableEnum { diff --git a/src/main/java/mcjty/xnet/apiimpl/logic/enums/SensorMode.java b/src/main/java/mcjty/xnet/apiimpl/logic/enums/SensorMode.java index 9259d06c..9bf21dd4 100644 --- a/src/main/java/mcjty/xnet/apiimpl/logic/enums/SensorMode.java +++ b/src/main/java/mcjty/xnet/apiimpl/logic/enums/SensorMode.java @@ -1,8 +1,8 @@ package mcjty.xnet.apiimpl.logic.enums; import mcjty.lib.varia.ComponentFactory; +import mcjty.lib.gui.ITranslatableEnum; import mcjty.xnet.utils.I18nUtils; -import mcjty.xnet.utils.ITranslatableEnum; public enum SensorMode implements ITranslatableEnum { OFF("xnet.enum.logic.sensormode.off"), diff --git a/src/main/java/mcjty/xnet/modules/facade/blocks/FacadeBlockItem.java b/src/main/java/mcjty/xnet/modules/facade/blocks/FacadeBlockItem.java index 5a7dd003..c41305fa 100644 --- a/src/main/java/mcjty/xnet/modules/facade/blocks/FacadeBlockItem.java +++ b/src/main/java/mcjty/xnet/modules/facade/blocks/FacadeBlockItem.java @@ -86,7 +86,7 @@ private static void userSetMimicBlock(@Nonnull ItemStack item, BlockState mimicB setMimicBlock(item, mimicBlock); if (world.isClientSide) { player.displayClientMessage(ComponentFactory.literal( - String.format(FACADE_CURRENT_MIMIC_FORMATTED.i18n(), mimicBlock.getBlock().getDescriptionId())), + FACADE_CURRENT_MIMIC_FORMATTED.i18n(mimicBlock.getBlock().getDescriptionId())), false ); } diff --git a/src/main/java/mcjty/xnet/utils/ChoiceEvent.java b/src/main/java/mcjty/xnet/utils/ChoiceEvent.java deleted file mode 100644 index 24138020..00000000 --- a/src/main/java/mcjty/xnet/utils/ChoiceEvent.java +++ /dev/null @@ -1,5 +0,0 @@ -package mcjty.xnet.utils; - -public interface ChoiceEvent { - void choiceChanged(T newChoice); -} diff --git a/src/main/java/mcjty/xnet/utils/EnumChoiceLabel.java b/src/main/java/mcjty/xnet/utils/EnumChoiceLabel.java deleted file mode 100644 index 7c31d184..00000000 --- a/src/main/java/mcjty/xnet/utils/EnumChoiceLabel.java +++ /dev/null @@ -1,203 +0,0 @@ -package mcjty.xnet.utils; - -import com.mojang.blaze3d.vertex.PoseStack; -import mcjty.lib.base.StyleConfig; -import mcjty.lib.client.RenderHelper; -import mcjty.lib.gui.GuiParser; -import mcjty.lib.gui.Window; -import mcjty.lib.gui.widgets.AbstractLabel; -import mcjty.lib.gui.widgets.Widget; -import mcjty.lib.typed.Key; -import mcjty.lib.typed.Type; -import mcjty.lib.typed.TypedMap; -import mcjty.lib.varia.SafeClientTools; -import net.minecraft.client.gui.screens.Screen; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -public class EnumChoiceLabel extends AbstractLabel { - - public static final String TYPE_ENUM_CHOICE_LABEL = "enumchoicelabel"; - public static final Key PARAM_CHOICE = new Key<>("choice", Type.INTEGER); - public static final Key PARAM_CHOICE_IDX = new Key<>("choiceIdx", Type.INTEGER); - - private Integer choiceIndex = null; - private ITranslatableEnum[] enumChoices = null; - private final Map, List> tooltipMap = new HashMap<>(); - private List>> choiceEvents = null; - - public EnumChoiceLabel() { - text(""); - } - - private void setCurrentChoice(ITranslatableEnum enumChoice) { - this.choiceIndex = enumChoice.ordinal(); - } - - public EnumChoiceLabel choices(ITranslatableEnum[] choices) { - enumChoices = choices; - if (choiceIndex == null) { - choiceIndex = choices[0].ordinal(); - text(choices[0].getI18n()); - fireChoiceEvents(choices[0]); - } - if (tooltipMap.isEmpty()) { - for (ITranslatableEnum choice : choices) { - setChoiceTooltip(choice); - } - } - - return this; - } - - public EnumChoiceLabel setChoiceTooltip(ITranslatableEnum choice) { - tooltipMap.put(choice, Arrays.asList(choice.getI18nSplitedTooltip())); - return this; - } - - public EnumChoiceLabel choice(ITranslatableEnum choice) { - if (Objects.equals(choiceIndex, choice.ordinal())) { - return this; - } - choiceIndex = choice.ordinal(); - text(choice.getI18n()); - return this; - } - - @Override - public List getTooltips() { - List tooltips = tooltipMap.get(enumChoices[choiceIndex]); - if (tooltips == null) { - return super.getTooltips(); - } else { - return tooltips; - } - } - - @Override - public void draw(Screen gui, PoseStack matrixStack, int x, int y) { - if (!visible) { - return; - } - int xx = x + bounds.x; - int yy = y + bounds.y; - - if (isEnabled()) { - if (isHovering()) { - drawStyledBoxHovering(window, matrixStack, xx, yy, xx + bounds.width - 1, yy + bounds.height - 1); - } else { - drawStyledBoxNormal(window, matrixStack, xx, yy, xx + bounds.width - 1, yy + bounds.height - 1); - } - RenderHelper.drawLeftTriangle(matrixStack, xx + bounds.width - 10, yy + bounds.height / 2, StyleConfig.colorCycleButtonTriangleNormal); - RenderHelper.drawRightTriangle(matrixStack, xx + bounds.width - 4, yy + bounds.height / 2, StyleConfig.colorCycleButtonTriangleNormal); - } else { - drawStyledBoxDisabled(window, matrixStack, xx, yy, xx + bounds.width - 1, yy + bounds.height - 1); - RenderHelper.drawLeftTriangle(matrixStack, xx + bounds.width - 10, yy + bounds.height / 2, StyleConfig.colorCycleButtonTriangleDisabled); - RenderHelper.drawRightTriangle(matrixStack, xx + bounds.width - 4, yy + bounds.height / 2, StyleConfig.colorCycleButtonTriangleDisabled); - } - - super.drawOffset(gui, matrixStack, x, y, -3, 1); - } - - @Override - public Widget mouseClick(double x, double y, int button) { - if (isEnabledAndVisible()) { - if (enumChoices.length == 0) { - return null; - } - if (button == 1 || SafeClientTools.isSneaking()) { - choiceIndex--; - if (choiceIndex < 0) { - choiceIndex = enumChoices.length - 1; - } - } else { - choiceIndex++; - if (choiceIndex >= enumChoices.length) { - choiceIndex = 0; - } - } - - text(enumChoices[choiceIndex].getI18n()); - fireChoiceEvents(enumChoices[choiceIndex]); - } - return null; - } - - public EnumChoiceLabel event(ChoiceEvent> event) { - if (choiceEvents == null) { - choiceEvents = new ArrayList<>(); - } - choiceEvents.add(event); - return this; - } - - public void removeChoiceEvent(ChoiceEvent> event) { - if (choiceEvents != null) { - choiceEvents.remove(event); - } - } - - private void fireChoiceEvents(ITranslatableEnum choice) { - - fireChannelEvents(TypedMap.builder() - .put(Window.PARAM_ID, "choice") - .put(PARAM_CHOICE, choice.ordinal()) - .put(PARAM_CHOICE_IDX, choice.ordinal()) - .build()); - - if (choiceEvents != null) { - for (ChoiceEvent> event : choiceEvents) { - event.choiceChanged(choice); - } - } - } - - @Override - public void readFromGuiCommand(GuiParser.GuiCommand command) { - System.out.println("readFromGuiCommand"); - super.readFromGuiCommand(command); - command.findCommand("choices").ifPresent(cmd -> { - cmd.commands().forEach(choiceCmd -> { - Integer enumIndex = choiceCmd.getOptionalPar(0, 0); - -// Arrays.fill(enumChoices, choice); - choiceCmd.findCommand("tooltips") - .ifPresent(tooltipsCmd -> tooltipMap.put(enumChoices[enumIndex], tooltipsCmd.parameters() - .map(Object::toString) - .collect(Collectors.toList()))); - }); - }); - } - - @Override - public void fillGuiCommand(GuiParser.GuiCommand command) { - System.out.println("fillGuiCommand"); - super.fillGuiCommand(command); - command.removeParameter(1); // We don't need the name as set by the label - GuiParser.GuiCommand choicesCmd = new GuiParser.GuiCommand("choices"); - for (ITranslatableEnum s : enumChoices) { - GuiParser.GuiCommand choiceCmd = new GuiParser.GuiCommand("choice").parameter(s.ordinal()); - choicesCmd.command(choiceCmd); - List tooltips = tooltipMap.get(s); - if (tooltips != null && !tooltips.isEmpty()) { - GuiParser.GuiCommand tooltipsCmd = new GuiParser.GuiCommand("tooltips"); - choiceCmd.command(tooltipsCmd); - for (String tt : tooltips) { - tooltipsCmd.parameter(tt); - } - } - } - command.command(choicesCmd); - } - - @Override - public GuiParser.GuiCommand createGuiCommand() { - return new GuiParser.GuiCommand(TYPE_ENUM_CHOICE_LABEL); - } -} diff --git a/src/main/java/mcjty/xnet/utils/ITranslatableEnum.java b/src/main/java/mcjty/xnet/utils/ITranslatableEnum.java deleted file mode 100644 index 813f9879..00000000 --- a/src/main/java/mcjty/xnet/utils/ITranslatableEnum.java +++ /dev/null @@ -1,11 +0,0 @@ -package mcjty.xnet.utils; - -public interface ITranslatableEnum> { - - String name(); - int ordinal(); - String toString(); - - String getI18n(); - String[] getI18nSplitedTooltip(); -} From 6bd6a554ffa1acc96642d901f4976abaf48b7c0b Mon Sep 17 00:00:00 2001 From: Alex Emelyanov Date: Sat, 6 Apr 2024 13:37:54 +0300 Subject: [PATCH 2/6] Refactoring after lib update --- .../mcjty/xnet/apiimpl/enums/ChannelMode.java | 2 +- .../fluids/FluidConnectorSettings.java | 9 ++++--- .../apiimpl/items/ItemConnectorSettings.java | 16 ++++------- .../client/AbstractEditorPanel.java | 27 ++++++++++++++----- .../mcjty/xnet/utils/ChannelChoiceLabel.java | 8 +++--- .../java/mcjty/xnet/utils/I18nConstants.java | 4 --- src/main/java/mcjty/xnet/utils/TagUtils.java | 8 ++++++ 7 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/main/java/mcjty/xnet/apiimpl/enums/ChannelMode.java b/src/main/java/mcjty/xnet/apiimpl/enums/ChannelMode.java index 95fe343b..67e16ebd 100644 --- a/src/main/java/mcjty/xnet/apiimpl/enums/ChannelMode.java +++ b/src/main/java/mcjty/xnet/apiimpl/enums/ChannelMode.java @@ -1,8 +1,8 @@ package mcjty.xnet.apiimpl.enums; import mcjty.lib.varia.ComponentFactory; +import mcjty.lib.gui.ITranslatableEnum; import mcjty.xnet.utils.I18nUtils; -import mcjty.xnet.utils.ITranslatableEnum; public enum ChannelMode implements ITranslatableEnum { PRIORITY("xnet.enum.channelmode.priority"), diff --git a/src/main/java/mcjty/xnet/apiimpl/fluids/FluidConnectorSettings.java b/src/main/java/mcjty/xnet/apiimpl/fluids/FluidConnectorSettings.java index f01be798..3379665c 100644 --- a/src/main/java/mcjty/xnet/apiimpl/fluids/FluidConnectorSettings.java +++ b/src/main/java/mcjty/xnet/apiimpl/fluids/FluidConnectorSettings.java @@ -12,7 +12,6 @@ import mcjty.xnet.apiimpl.Constants; import mcjty.xnet.apiimpl.EnumStringTranslators; import mcjty.xnet.apiimpl.enums.InsExtMode; -import mcjty.xnet.modules.controller.client.AbstractEditorPanel; import mcjty.xnet.setup.Config; import mcjty.xnet.utils.CastTools; import mcjty.xnet.utils.TagUtils; @@ -24,6 +23,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.Arrays; import java.util.Map; import java.util.Set; @@ -120,14 +120,15 @@ private String getMinMaxTooltip() { @Override public void createGui(IEditorGui gui) { advanced = gui.isAdvanced(); - String[] speeds = advanced ? Constants.ADVANCED_SPEEDS : Constants.SPEEDS; + String[] speeds = Arrays.stream(advanced ? Constants.ADVANCED_SPEEDS : Constants.SPEEDS) + .map(s -> String.valueOf(Integer.parseInt(s) * 2)).toArray(String[]::new); int maxrate = Config.getMaxFluidRate(advanced); sideGui(gui); colorsGui(gui); redstoneGui(gui); gui.nl(); - ((AbstractEditorPanel)gui).translatableChoices(TAG_MODE, fluidMode, InsExtMode.values())// TODO: 09.03.2024 remove AbstractEditorPanel cast after rftoolbase update + gui.translatableChoices(TAG_MODE, fluidMode, InsExtMode.values()) .choices(TAG_SPEED, SPEED_TOOLTIP.i18n(), Integer.toString(speed * 10), speeds) .nl() @@ -226,7 +227,7 @@ public void readFromNBT(CompoundTag tag) { priority = TagUtils.getIntOrNull(tag, TAG_PRIORITY); rate = TagUtils.getIntOrNull(tag, TAG_RATE); minmax = TagUtils.getIntOrNull(tag, TAG_MINMAX); - setSpeed(TagUtils.getIntOrNull(tag, TAG_SPEED)); + speed = TagUtils.getIntOrValue(tag, TAG_SPEED, 2); if (tag.contains(TAG_FLT)) { CompoundTag itemTag = tag.getCompound(TAG_FLT); filter = ItemStack.of(itemTag); diff --git a/src/main/java/mcjty/xnet/apiimpl/items/ItemConnectorSettings.java b/src/main/java/mcjty/xnet/apiimpl/items/ItemConnectorSettings.java index 61a62c38..74f55dae 100644 --- a/src/main/java/mcjty/xnet/apiimpl/items/ItemConnectorSettings.java +++ b/src/main/java/mcjty/xnet/apiimpl/items/ItemConnectorSettings.java @@ -15,7 +15,6 @@ import mcjty.xnet.apiimpl.enums.InsExtMode; import mcjty.xnet.apiimpl.items.enums.ExtractMode; import mcjty.xnet.apiimpl.items.enums.StackMode; -import mcjty.xnet.modules.controller.client.AbstractEditorPanel; import mcjty.xnet.utils.CastTools; import mcjty.xnet.utils.TagUtils; import net.minecraft.core.Direction; @@ -133,26 +132,21 @@ public void createGui(IEditorGui gui) { colorsGui(gui); redstoneGui(gui); gui.nl(); - ((AbstractEditorPanel)gui).translatableChoices(TAG_MODE, itemMode, InsExtMode.values())// TODO: 09.03.2024 remove AbstractEditorPanel cast after rftoolbase update - .shift(5); - ((AbstractEditorPanel)gui).translatableChoices(TAG_STACK, stackMode, StackMode.values());// TODO: 09.03.2024 remove AbstractEditorPanel cast after rftoolbase update + gui.translatableChoices(TAG_MODE, itemMode, InsExtMode.values()).shift(5); + gui.translatableChoices(TAG_STACK, stackMode, StackMode.values()); if (stackMode == StackMode.COUNT && itemMode == InsExtMode.EXT) { gui.integer(TAG_EXTRACT_AMOUNT, ITEM_EXT_COUNT_TOOLTIP.i18n(), extractAmount, 30, 64); } - gui - .shift(10) - .choices(TAG_SPEED, SPEED_TOOLTIP.i18n(), Integer.toString(speed * 5), speeds); + gui.shift(10).choices(TAG_SPEED, SPEED_TOOLTIP.i18n(), Integer.toString(speed * 5), speeds); gui.nl(); gui .label(PRIORITY_LABEL.i18n()).integer(TAG_PRIORITY, PRIORITY_TOOLTIP.i18n(), priority, 36).shift(5) - .label("#") - .integer(TAG_COUNT, getMinMaxTooltip(), count, 30); + .label("#").integer(TAG_COUNT, getMinMaxTooltip(), count, 30); if (itemMode == InsExtMode.EXT) { - gui.shift(5); - ((AbstractEditorPanel)gui).translatableChoices(TAG_EXTRACT, extractMode, ExtractMode.values());// TODO: 09.03.2024 remove AbstractEditorPanel cast after rftoolbase update + gui.shift(5).translatableChoices(TAG_EXTRACT, extractMode, ExtractMode.values()); } gui.nl(); diff --git a/src/main/java/mcjty/xnet/modules/controller/client/AbstractEditorPanel.java b/src/main/java/mcjty/xnet/modules/controller/client/AbstractEditorPanel.java index 5ee3c331..05ceac1c 100644 --- a/src/main/java/mcjty/xnet/modules/controller/client/AbstractEditorPanel.java +++ b/src/main/java/mcjty/xnet/modules/controller/client/AbstractEditorPanel.java @@ -1,10 +1,12 @@ package mcjty.xnet.modules.controller.client; import mcjty.lib.blockcommands.Command; +import mcjty.lib.gui.ITranslatableEnum; import mcjty.lib.gui.events.BlockRenderEvent; import mcjty.lib.gui.widgets.BlockRender; import mcjty.lib.gui.widgets.ChoiceLabel; import mcjty.lib.gui.widgets.ColorChoiceLabel; +import mcjty.lib.gui.widgets.EnumChoiceLabel; import mcjty.lib.gui.widgets.ImageChoiceLabel; import mcjty.lib.gui.widgets.Label; import mcjty.lib.gui.widgets.Panel; @@ -19,8 +21,6 @@ import mcjty.rftoolsbase.api.xnet.gui.IEditorGui; import mcjty.xnet.XNet; import mcjty.xnet.setup.XNetMessages; -import mcjty.xnet.utils.EnumChoiceLabel; -import mcjty.xnet.utils.ITranslatableEnum; import net.minecraft.client.Minecraft; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; @@ -162,7 +162,20 @@ private Integer validate(String i, Integer maximum, Integer minimum) { @Override public IEditorGui integer(String tag, String tooltip, Integer value, int width) { - return integer(tag, tooltip, value, width, Integer.MAX_VALUE, 0); + fitWidth(width); + TextField text = textfield(x, y, width, 14).text(value == null ? "" : value.toString()) + .tooltips(parseTooltips(tooltip)); + data.put(tag, value); + text.addTextEnterEvent((newText) -> update(tag, validate(newText, null, null))); + gui.getWindow().addFocusEvent((textFocus) -> { + if (textFocus == null) { + update(tag, validate(text.getText(), null, null)); + } + }); + panel.children(text); + components.put(tag, text); + x += width; + return this; } @Override @@ -170,7 +183,7 @@ public IEditorGui integer(String tag, String tooltip, Integer value, int width, return integer(tag, tooltip, value, width, maximum, 0); } - // TODO: 06.03.2024 override IEditorGUI after rftoolbase update + @Override public IEditorGui integer(String tag, String tooltip, Integer value, int width, int maximum, int minimum) { fitWidth(width); TextField text = textfield(x, y, width, 14).text(value == null ? String.valueOf(minimum) : value.toString()) @@ -288,15 +301,15 @@ public > IEditorGui choices(String tag, String tooltip, T curr return choices(tag, tooltip, StringUtils.capitalize(current.toString().toLowerCase()), strings); } - public IEditorGui translatableChoices(String tag, ITranslatableEnum current, ITranslatableEnum... values) {// TODO: 09.03.2024 move to rftoolsbase + @Override + public IEditorGui translatableChoices(String tag, ITranslatableEnum current, ITranslatableEnum... values) { int w = 10; for (ITranslatableEnum s : values) { w = Math.max(w, mc.font.width(s.getI18n()) + 14); } fitWidth(w); - EnumChoiceLabel choice = new EnumChoiceLabel().choices(values).choice(current) - .hint(x, y, w, 14); + EnumChoiceLabel choice = new EnumChoiceLabel().choices(values).choice(current).hint(x, y, w, 14); data.put(tag, current.ordinal()); choice.event((newChoice) -> update(tag, newChoice.ordinal())); panel.children(choice); diff --git a/src/main/java/mcjty/xnet/utils/ChannelChoiceLabel.java b/src/main/java/mcjty/xnet/utils/ChannelChoiceLabel.java index ff771fb7..08b27546 100644 --- a/src/main/java/mcjty/xnet/utils/ChannelChoiceLabel.java +++ b/src/main/java/mcjty/xnet/utils/ChannelChoiceLabel.java @@ -4,7 +4,9 @@ import mcjty.lib.base.StyleConfig; import mcjty.lib.client.RenderHelper; import mcjty.lib.gui.GuiParser; +import mcjty.lib.gui.ITranslatableEnum; import mcjty.lib.gui.Window; +import mcjty.lib.gui.events.ChoiceEvent; import mcjty.lib.gui.widgets.AbstractLabel; import mcjty.lib.gui.widgets.Widget; import mcjty.lib.typed.Key; @@ -26,7 +28,7 @@ public class ChannelChoiceLabel extends AbstractLabel { - public static final String TYPE_ENUM_CHOICE_LABEL = "enumchoicelabel"; + public static final String TYPE_CHANNEL_CHOICE_LABEL = "channelchoicelabel"; public static final Key PARAM_CHOICE = new Key<>("choice", Type.STRING); public static final Key PARAM_CHOICE_IDX = new Key<>("choiceIdx", Type.INTEGER); @@ -169,7 +171,6 @@ private void fireChoiceEvents(String choice) { @Override public void readFromGuiCommand(GuiParser.GuiCommand command) { - System.out.println("readFromGuiCommand"); super.readFromGuiCommand(command); command.findCommand("choices").ifPresent(cmd -> { cmd.commands().forEach(choiceCmd -> { @@ -186,7 +187,6 @@ public void readFromGuiCommand(GuiParser.GuiCommand command) { @Override public void fillGuiCommand(GuiParser.GuiCommand command) { - System.out.println("fillGuiCommand"); super.fillGuiCommand(command); command.removeParameter(1); // We don't need the name as set by the label GuiParser.GuiCommand choicesCmd = new GuiParser.GuiCommand("choices"); @@ -207,6 +207,6 @@ public void fillGuiCommand(GuiParser.GuiCommand command) { @Override public GuiParser.GuiCommand createGuiCommand() { - return new GuiParser.GuiCommand(TYPE_ENUM_CHOICE_LABEL); + return new GuiParser.GuiCommand(TYPE_CHANNEL_CHOICE_LABEL); } } diff --git a/src/main/java/mcjty/xnet/utils/I18nConstants.java b/src/main/java/mcjty/xnet/utils/I18nConstants.java index 30fc41e4..b46a026a 100644 --- a/src/main/java/mcjty/xnet/utils/I18nConstants.java +++ b/src/main/java/mcjty/xnet/utils/I18nConstants.java @@ -105,10 +105,6 @@ public enum I18nConstants { I18nConstants(String langKey) {this.langKey = langKey;} -// public String i18n() { -// -// } - public String i18n(Object... formatArgs) { if (formatArgs == null) { return ComponentFactory.translatable(this.langKey).getString(); diff --git a/src/main/java/mcjty/xnet/utils/TagUtils.java b/src/main/java/mcjty/xnet/utils/TagUtils.java index ca27982f..b5d4f2ff 100644 --- a/src/main/java/mcjty/xnet/utils/TagUtils.java +++ b/src/main/java/mcjty/xnet/utils/TagUtils.java @@ -12,6 +12,14 @@ public static Integer getIntOrNull(CompoundTag tag, String key) { } } + public static Integer getIntOrValue(CompoundTag tag, String key, int value) { + if (key == null || key.isEmpty() || !tag.contains(key)) { + return value; + } else { + return tag.getInt(key); + } + } + public static String getStringOrNull(CompoundTag tag, String key) { if (key == null || key.isEmpty() || !tag.contains(key)) { return null; From d778ba6e03fa1f2e2c3f44571438b1fe50049d54 Mon Sep 17 00:00:00 2001 From: Alex Emelyanov Date: Sat, 6 Apr 2024 13:40:46 +0300 Subject: [PATCH 3/6] New connector gui features, translate controller gui, #551 fix --- .../modules/cables/client/GuiConnector.java | 72 +++++++++++++++---- .../controller/client/GuiController.java | 45 ++++++++++-- .../java/mcjty/xnet/utils/I18nConstants.java | 5 +- .../resources/assets/xnet/lang/en_us.json | 5 +- .../resources/assets/xnet/lang/ru_ru.json | 12 ++-- 5 files changed, 113 insertions(+), 26 deletions(-) diff --git a/src/main/java/mcjty/xnet/modules/cables/client/GuiConnector.java b/src/main/java/mcjty/xnet/modules/cables/client/GuiConnector.java index da6a930c..f7b257f2 100644 --- a/src/main/java/mcjty/xnet/modules/cables/client/GuiConnector.java +++ b/src/main/java/mcjty/xnet/modules/cables/client/GuiConnector.java @@ -4,16 +4,28 @@ import mcjty.lib.container.GenericContainer; import mcjty.lib.gui.GenericGuiContainer; import mcjty.lib.gui.Window; +import mcjty.lib.gui.layout.HorizontalAlignment; +import mcjty.lib.gui.layout.VerticalAlignment; +import mcjty.lib.gui.widgets.BlockRender; +import mcjty.lib.gui.widgets.Label; import mcjty.lib.gui.widgets.Panel; import mcjty.lib.gui.widgets.TextField; import mcjty.lib.gui.widgets.ToggleButton; +import mcjty.lib.network.PacketRequestDataFromServer; import mcjty.lib.typed.TypedMap; import mcjty.lib.varia.OrientationTools; import mcjty.xnet.modules.cables.CableModule; +import mcjty.xnet.modules.cables.ConnectorType; import mcjty.xnet.modules.cables.blocks.ConnectorTileEntity; import mcjty.xnet.setup.XNetMessages; +import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.EnumProperty; import javax.annotation.Nonnull; @@ -22,6 +34,7 @@ import static mcjty.lib.gui.widgets.Widgets.vertical; import static mcjty.xnet.apiimpl.Constants.TAG_NAME; import static mcjty.xnet.modules.cables.blocks.ConnectorTileEntity.CMD_ENABLE; +import static mcjty.xnet.modules.cables.blocks.ConnectorTileEntity.CMD_GET_NAME; import static mcjty.xnet.modules.cables.blocks.ConnectorTileEntity.PARAM_ENABLED; import static mcjty.xnet.modules.cables.blocks.ConnectorTileEntity.PARAM_FACING; import static mcjty.xnet.utils.I18nConstants.CONNECTOR_NAME_TOOLTIP; @@ -30,10 +43,11 @@ public class GuiConnector extends GenericGuiContainer { - public static final int WIDTH = 220; - public static final int HEIGHT = 50; + public static final int WIDTH = 230; + public static final int HEIGHT = 60; private final ToggleButton[] toggleButtons = new ToggleButton[6]; + private final BlockRender[] connectedBlockRenders = new BlockRender[6]; // public GuiConnector(AdvancedConnectorTileEntity te, EmptyContainer container, PlayerInventory inventory) { // this((ConnectorTileEntity) te, container, inventory); @@ -41,7 +55,11 @@ public class GuiConnector extends GenericGuiContainer { sendServerCommandTyped(XNetMessages.INSTANCE, CMD_ENABLE, TypedMap.builder() @@ -72,14 +116,16 @@ public void init() { .put(PARAM_ENABLED, toggleButtons[facing.ordinal()].isPressed()) .build()); }); - toggleButtons[facing.ordinal()].pressed(tileEntity.isEnabled(facing)); - togglePanel.children(toggleButtons[facing.ordinal()]); + boolean isEnabled = !tileEntity.getBlockState().getValue(EnumProperty.create(facing.getName(), ConnectorType.class)).equals(ConnectorType.NONE); + toggleButtons[facing.ordinal()].pressed(isEnabled); + directionNamesPanel.children(toggleButtons[facing.ordinal()]); } - toplevel.children(togglePanel); - + directionBlocksPanel.children(connectedBlockRenders); + directionValuesPanel.children(directionBlocksPanel, directionNamesPanel); + directionsPanel.children(directionValuesPanel); + toplevel.children(directionsPanel); toplevel.bounds(leftPos, topPos, WIDTH, HEIGHT); window = new Window(this, toplevel); - window.bind(XNetMessages.INSTANCE, TAG_NAME, tileEntity, TAG_NAME); } diff --git a/src/main/java/mcjty/xnet/modules/controller/client/GuiController.java b/src/main/java/mcjty/xnet/modules/controller/client/GuiController.java index 66e22f47..86d9014a 100644 --- a/src/main/java/mcjty/xnet/modules/controller/client/GuiController.java +++ b/src/main/java/mcjty/xnet/modules/controller/client/GuiController.java @@ -35,6 +35,7 @@ import mcjty.xnet.client.ChannelClientInfo; import mcjty.xnet.client.ConnectedBlockClientInfo; import mcjty.xnet.client.ConnectorClientInfo; +import mcjty.xnet.modules.controller.ChannelInfo; import mcjty.xnet.modules.controller.ControllerModule; import mcjty.xnet.modules.controller.blocks.TileEntityController; import mcjty.xnet.setup.Config; @@ -101,6 +102,8 @@ import static mcjty.xnet.utils.I18nConstants.CONNECTOR_REMOVE_TOOLTIP; import static mcjty.xnet.utils.I18nConstants.CREATE_LABEL; import static mcjty.xnet.utils.I18nConstants.DOUBLE_CLICK_HIGHLIGHT; +import static mcjty.xnet.utils.I18nConstants.EDIT_CHANNEL_TOOLTIP_EXIST_FORMATTED; +import static mcjty.xnet.utils.I18nConstants.EDIT_CHANNEL_TOOLTIP_NOT_EXIST_FORMATTED; import static mcjty.xnet.utils.I18nConstants.ERROR_COPY; import static mcjty.xnet.utils.I18nConstants.ERROR_LARGE_COPY; import static mcjty.xnet.utils.I18nConstants.ERROR_NOTHING_SELECTED; @@ -195,9 +198,18 @@ public void doubleClick(int index) { } }); + ChannelInfo[] channels = tileEntity.getChannels(); for (int i = 0 ; i < MAX_CHANNELS ; i++) { String name = TAG_CHANNEL + (i+1); channelButtons[i] = window.findChild(name); + if (channels[i] == null) { + channelButtons[i].tooltips(EDIT_CHANNEL_TOOLTIP_NOT_EXIST_FORMATTED.i18n(i + 1)); + } else { + channelButtons[i] + .tooltips(I18nUtils.getSplitedTooltip( + EDIT_CHANNEL_TOOLTIP_EXIST_FORMATTED.i18n(i + 1, channels[i].getType().getName())) + ); + } } energyBar = window.findChild(WIDGET_ENERGY_BAR); @@ -321,23 +333,40 @@ private void createConnector(SidedPos sidedPos) { } private void removeChannel() { + int selectedChannel = getSelectedChannel(); + if (selectedChannel == -1) { + return; + } showMessage(minecraft, this, getWindowManager(), 50, 50, - ChatFormatting.RED + String.format(MESSAGE_CONFIRM_REMOVE_CHANNEL_FORMATTED.i18n(), (getSelectedChannel() + 1)), + ChatFormatting.RED + MESSAGE_CONFIRM_REMOVE_CHANNEL_FORMATTED.i18n((selectedChannel + 1)), () -> { sendServerCommandTyped(XNetMessages.INSTANCE, TileEntityController.CMD_REMOVECHANNEL, TypedMap.builder() - .put(PARAM_INDEX, getSelectedChannel()) + .put(PARAM_INDEX, selectedChannel) .build()); + + channelButtons[selectedChannel].tooltips(EDIT_CHANNEL_TOOLTIP_NOT_EXIST_FORMATTED.i18n(selectedChannel + 1)); refresh(); }); } private void createChannel(String typeId) { + int selectedChannel = getSelectedChannel(); + if (selectedChannel == -1) { + return; + } sendServerCommandTyped(XNetMessages.INSTANCE, TileEntityController.CMD_CREATECHANNEL, TypedMap.builder() - .put(PARAM_INDEX, getSelectedChannel()) + .put(PARAM_INDEX, selectedChannel) .put(PARAM_TYPE, typeId) .build()); + IChannelType type = XNet.xNetApi.findType(typeId); + if (type != null) { + channelButtons[selectedChannel].tooltips(I18nUtils.getSplitedTooltip( + EDIT_CHANNEL_TOOLTIP_EXIST_FORMATTED.i18n((selectedChannel + 1), type.getName())) + ); + } + refresh(); } @@ -370,7 +399,7 @@ private void refreshChannelEditor() { ChannelClientInfo info = tileEntity.clientChannels.get(editingChannel); if (info != null) { ChannelEditorPanel editor = new ChannelEditorPanel(channelEditPanel, minecraft, this, editingChannel); - editor.label(String.format(CHANNEL_LABEL_FORMATTED.i18n(), (editingChannel + 1))) + editor.label(CHANNEL_LABEL_FORMATTED.i18n(editingChannel + 1)) .shift(5) .toggle(TAG_ENABLED, CHANNEL_ENABLE_TOOLTIP.i18n(), info.isEnabled()) .shift(5) @@ -492,7 +521,7 @@ private void pasteConnector() { String type = root.get(TAG_TYPE).getAsString(); IChannelType channelType = XNet.xNetApi.findType(type); if (channelType == null) { - showMessage(minecraft, this, getWindowManager(), 50, 50, ChatFormatting.RED + String.format(ERROR_UNS_CH_FORMATTED.i18n(), type)); + showMessage(minecraft, this, getWindowManager(), 50, 50, ChatFormatting.RED + ERROR_UNS_CH_FORMATTED.i18n(type)); return; } @@ -527,7 +556,7 @@ private void pasteChannel() { String type = root.get(TAG_TYPE).getAsString(); IChannelType channelType = XNet.xNetApi.findType(type); if (channelType == null) { - showMessage(minecraft, this, getWindowManager(), 50, 50, ChatFormatting.RED + String.format(ERROR_UNS_CH_FORMATTED.i18n(), type)); + showMessage(minecraft, this, getWindowManager(), 50, 50, ChatFormatting.RED + ERROR_UNS_CH_FORMATTED.i18n(type)); return; } PacketServerCommandTyped packet = new PacketServerCommandTyped(tileEntity.getBlockPos(), tileEntity.getDimension(), CMD_PASTECHANNEL.name(), TypedMap.builder() @@ -736,6 +765,10 @@ protected void renderBg(@Nonnull PoseStack matrixStack, float v, int x1, int x2) String channel = String.valueOf(i + 1); ChannelClientInfo info = tileEntity.clientChannels.get(i); if (info != null) { + channelButtons[i] + .tooltips(I18nUtils.getSplitedTooltip( + EDIT_CHANNEL_TOOLTIP_EXIST_FORMATTED.i18n((i + 1), info.getType().getName())) + ); IndicatorIcon icon = info.getChannelSettings().getIndicatorIcon(); if (icon != null) { channelButtons[i].image(icon.getImage(), icon.getU(), icon.getV(), icon.getIw(), icon.getIh()); diff --git a/src/main/java/mcjty/xnet/utils/I18nConstants.java b/src/main/java/mcjty/xnet/utils/I18nConstants.java index b46a026a..0cd435da 100644 --- a/src/main/java/mcjty/xnet/utils/I18nConstants.java +++ b/src/main/java/mcjty/xnet/utils/I18nConstants.java @@ -98,7 +98,10 @@ public enum I18nConstants { ERROR_COPY("xnet.error.copy"), ERROR_READ_COPY("xnet.error.read.copy"), ERROR_LARGE_COPY("xnet.error.large.copy"), - ERROR_UNS_CH_FORMATTED("xnet.uns.ch.formatted"); + ERROR_UNS_CH_FORMATTED("xnet.uns.ch.formatted"), + + EDIT_CHANNEL_TOOLTIP_EXIST_FORMATTED("xnet.channel.edit.tooltip.exist"), + EDIT_CHANNEL_TOOLTIP_NOT_EXIST_FORMATTED("xnet.channel.edit.tooltip.notexist"); private final String langKey; diff --git a/src/main/resources/assets/xnet/lang/en_us.json b/src/main/resources/assets/xnet/lang/en_us.json index d024b43d..a84c38b1 100644 --- a/src/main/resources/assets/xnet/lang/en_us.json +++ b/src/main/resources/assets/xnet/lang/en_us.json @@ -211,5 +211,8 @@ "xnet.connector.upgrade": "Sneak right click this on a|normal connector to upgrade it|to an advanced connector", "xnet.connector.was.upgraded": "Connector was upgraded", "xnet.connector.already.advanced": "This connector is already advanced!", - "xnet.connector.use.it.to.upgrade": "Use this item on a connector to upgrade it!" + "xnet.connector.use.it.to.upgrade": "Use this item on a connector to upgrade it!", + + "xnet.channel.edit.tooltip.exist": "Edit channel %d|Type: %s", + "xnet.channel.edit.tooltip.notexist": "Edit channel %d" } \ No newline at end of file diff --git a/src/main/resources/assets/xnet/lang/ru_ru.json b/src/main/resources/assets/xnet/lang/ru_ru.json index feeef8d1..f0b629c5 100644 --- a/src/main/resources/assets/xnet/lang/ru_ru.json +++ b/src/main/resources/assets/xnet/lang/ru_ru.json @@ -77,7 +77,7 @@ "message.xnet.redstone_proxy_upd.gold": "Эта версия обновляет блок!", "xnet.channel.energy": "Энергия", - "xnet.channel.fluid": "Жидкость", + "xnet.channel.fluid": "Жидкости", "xnet.channel.item": "Предметы", "xnet.channel.logic": "Редстоун", "xnet.min": "Мин", @@ -144,9 +144,9 @@ "xnet.index.label": "Индекс", "xnet.double.click.highlight": "(двойной клик для выделения)", "xnet.enum.channelmode.priority": "Приоритет", - "xnet.enum.channelmode.priority.tooltip": "Режим распределения предметов|По приоритету(выше-раньше)", - "xnet.enum.channelmode.roundrobin": "Круговой", - "xnet.enum.channelmode.roundrobin.tooltip": "Режим распределения предметов|Круговое распределение", + "xnet.enum.channelmode.priority.tooltip": "Режим распределения предметов|По приоритету (выше-раньше)", + "xnet.enum.channelmode.roundrobin": "Равномерно", + "xnet.enum.channelmode.roundrobin.tooltip": "Режим распределения предметов|Равномерное распределение", "xnet.enum.insextmode.ins": "Помещать", "xnet.enum.insextmode.ins.tooltip": "Помещать в подключенный блок", "xnet.enum.insextmode.ext": "Извлекать", @@ -199,5 +199,7 @@ "xnet.connector.upgrade": "ПКМ сидя по коннектору|чтобы улучшить его|до продвинутого", "xnet.connector.was.upgraded": "Коннектор улучшен", "xnet.connector.already.advanced": "Коннектор уже улучшен!", - "xnet.connector.use.it.to.upgrade": "Используйте этот предмет, чтобы улучшить коннектор!" + "xnet.connector.use.it.to.upgrade": "Используйте этот предмет, чтобы улучшить коннектор!", + "xnet.channel.edit.tooltip.exist": "Настроить канал %d|Тип: %s", + "xnet.channel.edit.tooltip.notexist": "Настроить канал %d" } From 472da694bc3a13ec1cdb226263137db73bfc785f Mon Sep 17 00:00:00 2001 From: Alex Emelyanov Date: Sat, 6 Apr 2024 13:41:23 +0300 Subject: [PATCH 4/6] New connector gui features, translate controller gui, #551 fix --- .../xnet/modules/cables/blocks/ConnectorTileEntity.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/mcjty/xnet/modules/cables/blocks/ConnectorTileEntity.java b/src/main/java/mcjty/xnet/modules/cables/blocks/ConnectorTileEntity.java index e7a076ca..e4b95343 100644 --- a/src/main/java/mcjty/xnet/modules/cables/blocks/ConnectorTileEntity.java +++ b/src/main/java/mcjty/xnet/modules/cables/blocks/ConnectorTileEntity.java @@ -3,6 +3,7 @@ import mcjty.lib.api.container.DefaultContainerProvider; import mcjty.lib.bindings.GuiValue; import mcjty.lib.blockcommands.Command; +import mcjty.lib.blockcommands.ResultCommand; import mcjty.lib.blockcommands.ServerCommand; import mcjty.lib.container.GenericContainer; import mcjty.lib.tileentity.Cap; @@ -10,6 +11,7 @@ import mcjty.lib.tileentity.GenericTileEntity; import mcjty.lib.typed.Key; import mcjty.lib.typed.Type; +import mcjty.lib.typed.TypedMap; import mcjty.lib.varia.OrientationTools; import mcjty.rftoolsbase.api.xnet.tiles.IConnectorTile; import mcjty.xnet.modules.cables.CableModule; @@ -303,6 +305,8 @@ public ModelData getModelData() { public static final Key PARAM_FACING = new Key<>(TAG_FACING, Type.INTEGER); public static final Key PARAM_ENABLED = new Key<>(TAG_ENABLED, Type.BOOLEAN); + public static final Key PARAM_NAME = new Key<>(TAG_NAME, Type.STRING); + @ServerCommand public static final Command CMD_ENABLE = Command.create("connector.enable", (te, playerEntity, params) -> { @@ -310,6 +314,10 @@ public ModelData getModelData() { boolean e = params.get(PARAM_ENABLED); te.setEnabled(OrientationTools.DIRECTION_VALUES[f], e); }); + @ServerCommand + public static final ResultCommand CMD_GET_NAME = ResultCommand.create("xnet.connector.name", + (te, player, params) -> TypedMap.builder().put(PARAM_NAME, te.getConnectorName()).build(), + (te, player, params) -> te.setConnectorName(params.get(PARAM_NAME))); @Nonnull @Override From 7842c7b51da45566bfb144c54c9c04773073623d Mon Sep 17 00:00:00 2001 From: Alex Emelyanov Date: Sat, 6 Apr 2024 13:43:13 +0300 Subject: [PATCH 5/6] Huge optimisation patch for multiplayer --- .../mcjty/xnet/apiimpl/ConnectedBlock.java | 7 + .../apiimpl/energy/EnergyChannelSettings.java | 225 +++++----- .../apiimpl/energy/EnergyConnectedBlock.java | 7 + .../apiimpl/fluids/FluidChannelSettings.java | 264 +++++------ .../apiimpl/items/ItemChannelSettings.java | 416 +++++++++--------- .../apiimpl/logic/LogicChannelSettings.java | 63 +-- .../mcjty/xnet/compat/RFToolsSupport.java | 50 +-- 7 files changed, 495 insertions(+), 537 deletions(-) create mode 100644 src/main/java/mcjty/xnet/apiimpl/ConnectedBlock.java create mode 100644 src/main/java/mcjty/xnet/apiimpl/energy/EnergyConnectedBlock.java diff --git a/src/main/java/mcjty/xnet/apiimpl/ConnectedBlock.java b/src/main/java/mcjty/xnet/apiimpl/ConnectedBlock.java new file mode 100644 index 00000000..98b2724d --- /dev/null +++ b/src/main/java/mcjty/xnet/apiimpl/ConnectedBlock.java @@ -0,0 +1,7 @@ +package mcjty.xnet.apiimpl; + +import mcjty.rftoolsbase.api.xnet.keys.SidedConsumer; +import net.minecraft.core.BlockPos; + +public record ConnectedBlock(SidedConsumer sidedConsumer, T settings, BlockPos connectorPos){ +} diff --git a/src/main/java/mcjty/xnet/apiimpl/energy/EnergyChannelSettings.java b/src/main/java/mcjty/xnet/apiimpl/energy/EnergyChannelSettings.java index d17c6a88..f3f3a363 100644 --- a/src/main/java/mcjty/xnet/apiimpl/energy/EnergyChannelSettings.java +++ b/src/main/java/mcjty/xnet/apiimpl/energy/EnergyChannelSettings.java @@ -37,8 +37,9 @@ public class EnergyChannelSettings extends DefaultChannelSettings implements ICh public static final ResourceLocation iconGuiElements = new ResourceLocation(XNet.MODID, "textures/gui/guielements.png"); // Cache data - private List> energyExtractors = null; - private List> energyConsumers = null; + private List energyExtractors = null; + private List energyConsumers = null; + private long maxConsume = 0; // Maximum RF that all consumers can accept per tick @Override public JsonObject writeToJson() { @@ -65,87 +66,84 @@ public int getColors() { @Override public void tick(int channel, IControllerContext context) { + if (!context.checkAndConsumeRF(Config.controllerOperationRFT.get())) { + return; // Not enough energy for this operation + } updateCache(channel, context); Level world = context.getControllerWorld(); // First find out how much energy we have to distribute in total - int totalToDistribute = 0; - // Keep track of the connectors we already got energy from and how much energy we - // got from it + long totalToDistribute = 0; + // Keep track of the connectors we already got energy from and how much energy we got from it Map alreadyHandled = new HashMap<>(); List> energyProducers = new ArrayList<>(); - for (Pair entry : energyExtractors) { - BlockPos connectorPos = context.findConsumerPosition(entry.getKey().consumerId()); - if (connectorPos != null) { + for (EnergyConnectedBlock extractor : energyExtractors) { + BlockPos connectorPos = extractor.connectorPos(); + if (connectorPos == null) { + continue; + } - Direction side = entry.getKey().side(); - BlockPos energyPos = connectorPos.relative(side); - if (!LevelTools.isLoaded(world, energyPos)) { + Direction side = extractor.sidedConsumer().side(); + BlockPos energyPos = connectorPos.relative(side); + if (!LevelTools.isLoaded(world, energyPos)) { + continue; + } + + BlockEntity te = world.getBlockEntity(energyPos); + // @todo report error somewhere? + if (!isEnergyTE(te, side.getOpposite())) { + continue; + } + EnergyConnectorSettings settings = extractor.settings(); + ConnectorTileEntity connectorTE = (ConnectorTileEntity) world.getBlockEntity(connectorPos); + if (connectorTE == null) { + continue; + } + + if (checkRedstone(world, settings, connectorPos) || !context.matchColor(settings.getColorsMask())) { + continue; + } + + Integer count = settings.getMinmax(); + if (count != null) { + int level = getEnergyLevel(te, side.getOpposite()); + if (level < count) { continue; } + } + + int rate = extractor.rate(); + connectorTE.setEnergyInputFrom(side, rate); + + if (!alreadyHandled.containsKey(connectorPos)) { + // We did not handle this connector yet. Remember the amount of energy in it + alreadyHandled.put(connectorPos, connectorTE.getEnergy()); + } - BlockEntity te = world.getBlockEntity(energyPos); - // @todo report error somewhere? - if (isEnergyTE(te, side.getOpposite())) { - EnergyConnectorSettings settings = entry.getValue(); - ConnectorTileEntity connectorTE = (ConnectorTileEntity) world.getBlockEntity(connectorPos); - - if (checkRedstone(world, settings, connectorPos)) { - continue; - } - if (!context.matchColor(settings.getColorsMask())) { - continue; - } - - Integer count = settings.getMinmax(); - if (count != null) { - int level = getEnergyLevel(te, side.getOpposite()); - if (level < count) { - continue; - } - } - - Integer rate = settings.getRate(); - if (rate == null) { - boolean advanced = ConnectorBlock.isAdvancedConnector(world, connectorPos); - rate = advanced ? Config.maxRfRateAdvanced.get() : Config.maxRfRateNormal.get(); - } - connectorTE.setEnergyInputFrom(side, rate); - - if (!alreadyHandled.containsKey(connectorPos)) { - // We did not handle this connector yet. Remember the amount of energy in it - alreadyHandled.put(connectorPos, connectorTE.getEnergy()); - } - - // Check how much energy we can still send from that connector - int connectorEnergy = alreadyHandled.get(connectorPos); - int tosend = Math.min(rate, connectorEnergy); - if (tosend > 0) { - // Decrease the energy from our temporary datastructure - alreadyHandled.put(connectorPos, connectorEnergy - tosend); - totalToDistribute += tosend; - energyProducers.add(Pair.of(connectorTE, tosend)); - } + // Check how much energy we can still send from that connector + int connectorEnergy = alreadyHandled.get(connectorPos); + int tosend = Math.min(rate, connectorEnergy); + if (tosend > 0) { + // Decrease the energy from our temporary datastructure + alreadyHandled.put(connectorPos, connectorEnergy - tosend); + totalToDistribute += tosend; + energyProducers.add(Pair.of(connectorTE, tosend)); + if (totalToDistribute >= maxConsume) { + break; // We have enough to fill all consumers } } } if (totalToDistribute <= 0) { - // Nothing to do - return; + return; // Nothing to do } - if (!context.checkAndConsumeRF(Config.controllerOperationRFT.get())) { - // Not enough energy for this operation - return; - } - int actuallyConsumed = insertEnergy(context, totalToDistribute); + long actuallyConsumed = insertEnergy(context, totalToDistribute); if (actuallyConsumed <= 0) { - // Nothing was done - return; + return; // Nothing was done } // Now we need to actually fetch the energy from the producers @@ -153,8 +151,8 @@ public void tick(int channel, IControllerContext context) { ConnectorTileEntity connectorTE = entry.getKey(); int amount = entry.getValue(); - int actuallySpent = Math.min(amount, actuallyConsumed); - connectorTE.setEnergy(connectorTE.getEnergy() - actuallySpent); + long actuallySpent = Math.min(amount, actuallyConsumed); + connectorTE.setEnergy((int) (connectorTE.getEnergy() - actuallySpent)); actuallyConsumed -= actuallySpent; if (actuallyConsumed <= 0) { break; @@ -162,50 +160,40 @@ public void tick(int channel, IControllerContext context) { } } - private int insertEnergy(@Nonnull IControllerContext context, int energy) { - int total = 0; + private long insertEnergy(@Nonnull IControllerContext context, long energy) { + long total = 0; Level world = context.getControllerWorld(); - for (Pair entry : energyConsumers) { - EnergyConnectorSettings settings = entry.getValue(); - BlockPos extractorPos = context.findConsumerPosition(entry.getKey().consumerId()); - if (extractorPos != null) { - Direction side = entry.getKey().side(); - BlockPos pos = extractorPos.relative(side); - if (!LevelTools.isLoaded(world, pos)) { + for (EnergyConnectedBlock consumer : energyConsumers) { + EnergyConnectorSettings settings = consumer.settings(); + BlockPos connectorPos = consumer.connectorPos(); + if (connectorPos == null) { + continue; + } + Direction side = consumer.sidedConsumer().side(); + BlockPos connectedBlockPos = connectorPos.relative(side); + if (!LevelTools.isLoaded(world, connectedBlockPos)) { + continue; + } + BlockEntity te = world.getBlockEntity(connectedBlockPos); + // @todo report error somewhere? + if (!isEnergyTE(te, settings.getFacing()) || checkRedstone(world, settings, connectorPos) || !context.matchColor(settings.getColorsMask())) { + continue; + } + + Integer count = settings.getMinmax(); + if (count != null) { + int level = getEnergyLevel(te, settings.getFacing()); + if (level >= count) { continue; } - BlockEntity te = world.getBlockEntity(pos); - // @todo report error somewhere? - if (isEnergyTE(te, settings.getFacing())) { - - if (checkRedstone(world, settings, extractorPos)) { - continue; - } - if (!context.matchColor(settings.getColorsMask())) { - continue; - } - - Integer count = settings.getMinmax(); - if (count != null) { - int level = getEnergyLevel(te, settings.getFacing()); - if (level >= count) { - continue; - } - } - - Integer rate = settings.getRate(); - if (rate == null) { - boolean advanced = ConnectorBlock.isAdvancedConnector(world, extractorPos); - rate = advanced ? Config.maxRfRateAdvanced.get() : Config.maxRfRateNormal.get(); - } - int totransfer = Math.min(rate, energy); - long e = EnergyTools.receiveEnergy(te, settings.getFacing(), totransfer); - energy -= e; - total += e; - if (energy <= 0) { - return total; - } - } + } + + long totransfer = Math.min(consumer.rate(), energy); + long e = EnergyTools.receiveEnergy(te, settings.getFacing(), totransfer); + energy -= e; + total += e; + if (energy <= 0) { + return total; } } return total; @@ -233,6 +221,7 @@ public static int getEnergyLevel(BlockEntity tileEntity, @Nonnull Direction side public void cleanCache() { energyExtractors = null; energyConsumers = null; + maxConsume = 0; } private void updateCache(int channel, IControllerContext context) { @@ -240,26 +229,42 @@ private void updateCache(int channel, IControllerContext context) { energyExtractors = new ArrayList<>(); energyConsumers = new ArrayList<>(); Map connectors = context.getConnectors(channel); + Level world = context.getControllerWorld(); for (var entry : connectors.entrySet()) { EnergyConnectorSettings con = (EnergyConnectorSettings) entry.getValue(); + BlockPos connectorPos = context.findConsumerPosition(entry.getKey().consumerId()); + Integer rate = getRateOrMax(con, connectorPos, world); if (con.getEnergyMode() == InsExtMode.EXT) { - energyExtractors.add(Pair.of(entry.getKey(), con)); + energyExtractors.add(new EnergyConnectedBlock(entry.getKey(), con, connectorPos, rate)); } else { - energyConsumers.add(Pair.of(entry.getKey(), con)); + energyConsumers.add(new EnergyConnectedBlock(entry.getKey(), con, connectorPos, rate)); + maxConsume += rate; } } connectors = context.getRoutedConnectors(channel); for (var entry : connectors.entrySet()) { EnergyConnectorSettings con = (EnergyConnectorSettings) entry.getValue(); + BlockPos connectorPos = context.findConsumerPosition(entry.getKey().consumerId()); + Integer rate = getRateOrMax(con, connectorPos, world); if (con.getEnergyMode() == InsExtMode.INS) { - energyConsumers.add(Pair.of(entry.getKey(), con)); + energyConsumers.add(new EnergyConnectedBlock(entry.getKey(), con, connectorPos, rate)); + maxConsume += rate; } } - energyExtractors.sort((o1, o2) -> o2.getRight().getPriority().compareTo(o1.getRight().getPriority())); - energyConsumers.sort((o1, o2) -> o2.getRight().getPriority().compareTo(o1.getRight().getPriority())); + energyExtractors.sort((o1, o2) -> o2.settings().getPriority().compareTo(o1.settings().getPriority())); + energyConsumers.sort((o1, o2) -> o2.settings().getPriority().compareTo(o1.settings().getPriority())); + } + } + + private static Integer getRateOrMax(EnergyConnectorSettings con, BlockPos connectorPos, Level world) { + Integer rate = con.getRate(); + if (rate == null) { + boolean advanced = ConnectorBlock.isAdvancedConnector(world, connectorPos); + rate = advanced ? Config.maxRfRateAdvanced.get() : Config.maxRfRateNormal.get(); } + return rate; } @Override diff --git a/src/main/java/mcjty/xnet/apiimpl/energy/EnergyConnectedBlock.java b/src/main/java/mcjty/xnet/apiimpl/energy/EnergyConnectedBlock.java new file mode 100644 index 00000000..a8a16687 --- /dev/null +++ b/src/main/java/mcjty/xnet/apiimpl/energy/EnergyConnectedBlock.java @@ -0,0 +1,7 @@ +package mcjty.xnet.apiimpl.energy; + +import mcjty.rftoolsbase.api.xnet.keys.SidedConsumer; +import net.minecraft.core.BlockPos; + +public record EnergyConnectedBlock (SidedConsumer sidedConsumer, EnergyConnectorSettings settings, BlockPos connectorPos, int rate) { +} diff --git a/src/main/java/mcjty/xnet/apiimpl/fluids/FluidChannelSettings.java b/src/main/java/mcjty/xnet/apiimpl/fluids/FluidChannelSettings.java index 74ee0f69..e37275e3 100644 --- a/src/main/java/mcjty/xnet/apiimpl/fluids/FluidChannelSettings.java +++ b/src/main/java/mcjty/xnet/apiimpl/fluids/FluidChannelSettings.java @@ -11,10 +11,10 @@ import mcjty.rftoolsbase.api.xnet.helper.DefaultChannelSettings; import mcjty.rftoolsbase.api.xnet.keys.SidedConsumer; import mcjty.xnet.XNet; +import mcjty.xnet.apiimpl.ConnectedBlock; import mcjty.xnet.apiimpl.EnumStringTranslators; import mcjty.xnet.apiimpl.enums.ChannelMode; import mcjty.xnet.apiimpl.enums.InsExtMode; -import mcjty.xnet.modules.controller.client.AbstractEditorPanel; import mcjty.xnet.setup.Config; import mcjty.xnet.utils.CastTools; import net.minecraft.core.BlockPos; @@ -27,12 +27,10 @@ import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; -import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -48,8 +46,8 @@ public class FluidChannelSettings extends DefaultChannelSettings implements ICha private int roundRobinOffset = 0; // Cache data - private Map fluidExtractors = null; - private List> fluidConsumers = null; + private List> fluidExtractors = null; + private List> fluidConsumers = null; public ChannelMode getChannelMode() { return channelMode; @@ -86,88 +84,86 @@ public void writeToNBT(CompoundTag tag) { public void tick(int channel, IControllerContext context) { delay--; if (delay <= 0) { - delay = 200*6; // Multiply of the different speeds we have + delay = 200 * 6; // Multiply of the different speeds we have } if (delay % 10 != 0) { return; } - int d = delay/10; + int d = delay / 10; updateCache(channel, context); - // @todo optimize + Level world = context.getControllerWorld(); - extractorsLoop: - for (Map.Entry entry : fluidExtractors.entrySet()) { - FluidConnectorSettings settings = entry.getValue(); + for (ConnectedBlock extractor : fluidExtractors) { + FluidConnectorSettings settings = extractor.settings(); if (d % settings.getSpeed() != 0) { continue; } - BlockPos extractorPos = context.findConsumerPosition(entry.getKey().consumerId()); - if (extractorPos != null) { - Direction side = entry.getKey().side(); - BlockPos pos = extractorPos.relative(side); - if (!LevelTools.isLoaded(world, pos)) { - continue; - } + BlockPos extractorPos = extractor.connectorPos(); + if (extractorPos == null) { + continue; + } - BlockEntity te = world.getBlockEntity(pos); - // @todo ugly code! - IFluidHandler handler = getFluidHandlerAt(te, settings.getFacing()).map(h -> h).orElse(null); - // @todo report error somewhere? - if (handler != null) { - if (checkRedstone(world, settings, extractorPos)) { - continue; - } - if (!context.matchColor(settings.getColorsMask())) { - continue; - } - - FluidStack extractMatcher = settings.getMatcher(); - - int toextract = settings.getRate(); - - Integer count = settings.getMinmax(); - if (count != null) { - int amount = countFluid(handler, extractMatcher); - int canextract = amount-count; - if (canextract <= 0) { - continue; - } - toextract = Math.min(toextract, canextract); - } - - List> inserted = new ArrayList<>(); - int remaining; - do { - // Imagine the pathological case where we're extracting from a container that works in 13mB - // increments and inserting into a container that works in 17mB increments. We should end up - // with toextract = 884 at the end of this loop, given that it started at 1000. - FluidStack stack = fetchFluid(handler, true, extractMatcher, toextract); - if (stack.isEmpty()) { - continue extractorsLoop; - } - toextract = stack.getAmount(); - inserted.clear(); - remaining = insertFluidSimulate(inserted, context, stack); - toextract -= remaining; - if (inserted.isEmpty() || toextract <= 0) { - continue extractorsLoop; - } - } while(remaining > 0); - if (context.checkAndConsumeRF(Config.controllerOperationRFT.get())) { - FluidStack stack = fetchFluid(handler, false, extractMatcher, toextract); - if (stack.isEmpty()) { - throw new NullPointerException(handler.getClass().getName() + " misbehaved! handler.drain(" + toextract + ", true) returned null, even though handler.drain(" + toextract + ", false) did not"); - } - insertFluidReal(context, inserted, stack); - } - } + Direction side = extractor.sidedConsumer().side(); + BlockPos pos = extractorPos.relative(side); + if (!LevelTools.isLoaded(world, pos)) { + continue; + } + + BlockEntity te = world.getBlockEntity(pos); + // @todo ugly code! + IFluidHandler handler = getFluidHandlerAt(te, settings.getFacing()).resolve().orElse(null); + // @todo report error somewhere? + if (handler == null) { + continue; + } + + if (checkRedstone(world, settings, extractorPos)) { + continue; + } + if (!context.matchColor(settings.getColorsMask())) { + continue; } + + tickFluidHandler(context, settings, handler); } } + private void tickFluidHandler(IControllerContext context, FluidConnectorSettings settings, IFluidHandler handler) { + if (!context.checkAndConsumeRF(Config.controllerOperationRFT.get())) { + return; + } + FluidStack extractMatcher = settings.getMatcher(); + + int toextract = settings.getRate(); + + Integer count = settings.getMinmax(); + if (count != null) { + int amount = countFluid(handler, extractMatcher); + int canextract = amount-count; + if (canextract <= 0) { + return; + } + toextract = Math.min(toextract, canextract); + } + + while (true) { + FluidStack stack = fetchFluid(handler, true, extractMatcher, toextract); + if (stack.isEmpty()) { + return; + } + toextract = stack.getAmount(); + int remaining = insertFluid(context, stack); + toextract -= remaining; + if (remaining != toextract) { + fetchFluid(handler, false, extractMatcher, toextract); + return; + } + } + } + @Override public void cleanCache() { @@ -187,8 +183,7 @@ private FluidStack fetchFluid(IFluidHandler handler, boolean simulate, @Nullable } } - // Returns what could not be filled - private int insertFluidSimulate(@Nonnull List> inserted, @Nonnull IControllerContext context, @Nonnull FluidStack stack) { + private int insertFluid(@Nonnull IControllerContext context, @Nonnull FluidStack stack) { Level world = context.getControllerWorld(); if (channelMode == ChannelMode.PRIORITY) { roundRobinOffset = 0; // Always start at 0 @@ -196,87 +191,35 @@ private int insertFluidSimulate(@Nonnull List h).orElse(null); - // @todo report error somewhere? - if (handler != null) { - int toinsert = Math.min(settings.getRate(), amount); - - Integer count = settings.getMinmax(); - if (count != null) { - int a = countFluid(handler, settings.getMatcher()); - int caninsert = count-a; - if (caninsert <= 0) { - continue; - } - toinsert = Math.min(toinsert, caninsert); - } - - FluidStack copy = stack.copy(); - copy.setAmount(toinsert); - - int filled = handler.fill(copy, IFluidHandler.FluidAction.SIMULATE); - if (filled > 0) { - inserted.add(entry); - amount -= filled; - if (amount <= 0) { - return 0; - } - } - } - } + ConnectedBlock consumer = fluidConsumers.get(i); + FluidConnectorSettings settings = consumer.settings(); + BlockPos consumerPos = consumer.connectorPos(); + Direction side = consumer.sidedConsumer().side(); + BlockPos connectedBlockPos = consumerPos.relative(side); + if (!LevelTools.isLoaded(world, connectedBlockPos)) { + continue; } - } - return amount; - } - - private int countFluid(IFluidHandler handler, @Nullable FluidStack matcher) { - int cnt = 0; - for (int i = 0 ; i < handler.getTanks() ; i++) { - if (!handler.getFluidInTank(i).isEmpty() && (matcher == null || matcher.equals(handler.getFluidInTank(i)))) { - cnt += handler.getFluidInTank(i).getAmount(); + BlockEntity te = world.getBlockEntity(connectedBlockPos); + IFluidHandler destination = getFluidHandlerAt(te, settings.getFacing()).resolve().orElse(null); + // @todo report error somewhere? + if (destination == null) { + continue; + } + FluidStack matcher = settings.getMatcher(); + if (matcher != null && !matcher.equals(stack)) { + continue; + } + if (checkRedstone(world, settings, consumerPos) || !context.matchColor(settings.getColorsMask())) { + continue; } - } - return cnt; - } - - private void insertFluidReal(@Nonnull IControllerContext context, @Nonnull List> inserted, @Nonnull FluidStack stack) { - int amount = stack.getAmount(); - for (var pair : inserted) { - BlockPos consumerPosition = context.findConsumerPosition(pair.getKey().consumerId()); - Direction side = pair.getKey().side(); - FluidConnectorSettings settings = pair.getValue(); - BlockPos pos = consumerPosition.relative(side); - BlockEntity te = context.getControllerWorld().getBlockEntity(pos); // @todo ugly code! - IFluidHandler handler = getFluidHandlerAt(te, settings.getFacing()).map(h -> h).orElse(null); - int toinsert = Math.min(settings.getRate(), amount); Integer count = settings.getMinmax(); if (count != null) { - int a = countFluid(handler, settings.getMatcher()); - int caninsert = count-a; + int a = countFluid(destination, settings.getMatcher()); + int caninsert = count - a; if (caninsert <= 0) { continue; } @@ -286,30 +229,40 @@ private void insertFluidReal(@Nonnull IControllerContext context, @Nonnull List< FluidStack copy = stack.copy(); copy.setAmount(toinsert); - int filled = handler.fill(copy, IFluidHandler.FluidAction.EXECUTE); + int filled = destination.fill(copy, IFluidHandler.FluidAction.EXECUTE); if (filled > 0) { - roundRobinOffset = (roundRobinOffset+1) % fluidConsumers.size(); + roundRobinOffset = (roundRobinOffset + 1) % fluidConsumers.size(); amount -= filled; if (amount <= 0) { - return; + return 0; } } } + return amount; } - + private int countFluid(IFluidHandler handler, @Nullable FluidStack matcher) { + int cnt = 0; + for (int i = 0 ; i < handler.getTanks() ; i++) { + if (!handler.getFluidInTank(i).isEmpty() && (matcher == null || matcher.equals(handler.getFluidInTank(i)))) { + cnt += handler.getFluidInTank(i).getAmount(); + } + } + return cnt; + } private void updateCache(int channel, IControllerContext context) { if (fluidExtractors == null) { - fluidExtractors = new HashMap<>(); + fluidExtractors = new ArrayList<>(); fluidConsumers = new ArrayList<>(); Map connectors = context.getConnectors(channel); for (var entry : connectors.entrySet()) { FluidConnectorSettings con = (FluidConnectorSettings) entry.getValue(); + BlockPos connectorPos = context.findConsumerPosition(entry.getKey().consumerId()); if (con.getFluidMode() == InsExtMode.EXT) { - fluidExtractors.put(entry.getKey(), con); + fluidExtractors.add(new ConnectedBlock<>(entry.getKey(), con, connectorPos)); } else { - fluidConsumers.add(Pair.of(entry.getKey(), con)); + fluidConsumers.add(new ConnectedBlock<>(entry.getKey(), con, connectorPos)); } } @@ -317,11 +270,12 @@ private void updateCache(int channel, IControllerContext context) { for (var entry : connectors.entrySet()) { FluidConnectorSettings con = (FluidConnectorSettings) entry.getValue(); if (con.getFluidMode() == InsExtMode.INS) { - fluidConsumers.add(Pair.of(entry.getKey(), con)); + BlockPos connectorPos = context.findConsumerPosition(entry.getKey().consumerId()); + fluidConsumers.add(new ConnectedBlock<>(entry.getKey(), con, connectorPos)); } } - fluidConsumers.sort((o1, o2) -> o2.getRight().getPriority().compareTo(o1.getRight().getPriority())); + fluidConsumers.sort((o1, o2) -> o2.settings().getPriority().compareTo(o1.settings().getPriority())); } } @@ -345,7 +299,7 @@ public String getIndicator() { @Override public void createGui(IEditorGui gui) { gui.nl(); - ((AbstractEditorPanel)gui).translatableChoices(TAG_MODE, channelMode, ChannelMode.values());// TODO: 09.03.2024 remove AbstractEditorPanel cast after rftoolbase update + gui.translatableChoices(TAG_MODE, channelMode, ChannelMode.values()); } @Override diff --git a/src/main/java/mcjty/xnet/apiimpl/items/ItemChannelSettings.java b/src/main/java/mcjty/xnet/apiimpl/items/ItemChannelSettings.java index 22d60147..f8ffa19c 100644 --- a/src/main/java/mcjty/xnet/apiimpl/items/ItemChannelSettings.java +++ b/src/main/java/mcjty/xnet/apiimpl/items/ItemChannelSettings.java @@ -12,12 +12,12 @@ import mcjty.rftoolsbase.api.xnet.keys.ConsumerId; import mcjty.rftoolsbase.api.xnet.keys.SidedConsumer; import mcjty.xnet.XNet; +import mcjty.xnet.apiimpl.ConnectedBlock; import mcjty.xnet.apiimpl.EnumStringTranslators; import mcjty.xnet.apiimpl.enums.ChannelMode; import mcjty.xnet.apiimpl.enums.InsExtMode; import mcjty.xnet.apiimpl.items.enums.StackMode; import mcjty.xnet.compat.RFToolsSupport; -import mcjty.xnet.modules.controller.client.AbstractEditorPanel; import mcjty.xnet.setup.Config; import mcjty.xnet.utils.CastTools; import net.minecraft.core.BlockPos; @@ -31,7 +31,6 @@ import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemHandlerHelper; -import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -53,9 +52,9 @@ public class ItemChannelSettings extends DefaultChannelSettings implements IChan // Cache data - private Map itemExtractors = null; - private List> itemConsumers = null; - + private List> itemExtractors = null; + private List> itemConsumers = null; + private boolean[] consumerFull; // rray of filled consumers in which you don't have to try to insert private ChannelMode channelMode = ChannelMode.PRIORITY; private int delay = 0; private int roundRobinOffset = 0; @@ -160,41 +159,44 @@ public void tick(int channel, IControllerContext context) { updateCache(channel, context); Level world = context.getControllerWorld(); - for (Map.Entry entry : itemExtractors.entrySet()) { - ItemConnectorSettings settings = entry.getValue(); + consumerFull = new boolean[itemConsumers.size()]; + for (ConnectedBlock extractor : itemExtractors) { + ItemConnectorSettings settings = extractor.settings(); if (d % settings.getSpeed() != 0) { continue; } - ConsumerId consumerId = entry.getKey().consumerId(); - BlockPos extractorPos = context.findConsumerPosition(consumerId); - if (extractorPos != null) { - Direction side = entry.getKey().side(); - BlockPos pos = extractorPos.relative(side); - if (!LevelTools.isLoaded(world, pos)) { - continue; - } + ConsumerId consumerId = extractor.sidedConsumer().consumerId(); + BlockPos extractorPos = extractor.connectorPos(); + if (extractorPos == null) { + continue; + } - if (checkRedstone(world, settings, extractorPos)) { - continue; - } - if (!context.matchColor(settings.getColorsMask())) { - continue; - } + Direction side = extractor.sidedConsumer().side(); + BlockPos pos = extractorPos.relative(side); + if (!LevelTools.isLoaded(world, pos)) { + continue; + } - BlockEntity te = world.getBlockEntity(pos); + if (checkRedstone(world, settings, extractorPos)) { + continue; + } + if (!context.matchColor(settings.getColorsMask())) { + continue; + } - if (RFToolsSupport.isStorageScanner(te)) { - RFToolsSupport.tickStorageScanner(context, settings, te, this); - } else { - getItemHandlerAt(te, settings.getFacing()).ifPresent(handler -> { - int idx = getStartExtractIndex(settings, consumerId, handler); - idx = tickItemHandler(context, settings, handler, idx); - if (handler.getSlots() > 0) { - rememberExtractIndex(consumerId, (idx + 1) % handler.getSlots()); - } - }); - } + BlockEntity te = world.getBlockEntity(pos); + + if (RFToolsSupport.isStorageScanner(te)) { + RFToolsSupport.tickStorageScanner(context, settings, te, this, world); + } else { + getItemHandlerAt(te, settings.getFacing()).ifPresent(handler -> { + int idx = getStartExtractIndex(settings, consumerId, handler); + idx = tickItemHandler(context, settings, handler, world, idx); + if (handler.getSlots() > 0) { + rememberExtractIndex(consumerId, (idx + 1) % handler.getSlots()); + } + }); } } } @@ -233,7 +235,8 @@ private int getStartExtractIndex(ItemConnectorSettings settings, ConsumerId cons } - private int tickItemHandler(IControllerContext context, ItemConnectorSettings settings, IItemHandler handler, int startIdx) { + private int tickItemHandler(@Nonnull IControllerContext context, @Nonnull ItemConnectorSettings settings, + @Nonnull IItemHandler handler, @Nonnull Level world, int startIdx) { Predicate extractMatcher = settings.getMatcher(context); Integer count = settings.getCount(); @@ -247,34 +250,38 @@ private int tickItemHandler(IControllerContext context, ItemConnectorSettings se MInteger index = new MInteger(startIdx); while (true) { - ItemStack stack = fetchItem(handler, true, extractMatcher, settings.getStackMode(), settings.getExtractAmount(), 64, index, startIdx); - if (!stack.isEmpty()) { - // Now that we have a stack we first reduce the amount of the stack if we want to keep a certain - // number of items - int toextract = stack.getCount(); - if (count != null) { - int canextract = amount - count; - if (canextract <= 0) { - index.inc(); - continue; - } - if (canextract < toextract) { - toextract = canextract; - stack = stack.copy(); - stack.setCount(toextract); - } + ItemStack stack = fetchItem(handler, true, extractMatcher, settings.getStackMode(), + settings.getExtractAmount(), 64, index, startIdx); + if (stack.isEmpty()) { + break; + } + + // Now that we have a stack we first reduce the amount of the stack if we want to keep a certain + // number of items + int toextract = stack.getCount(); + if (count != null) { + int canextract = amount - count; + if (canextract <= 0) { + index.inc(); + continue; } + if (canextract < toextract) { + toextract = canextract; + stack = stack.copy(); + stack.setCount(toextract); + } + } - List> inserted = new ArrayList<>(); - int remaining = insertStackSimulate(inserted, context, stack); - if (!inserted.isEmpty()) { - if (context.checkAndConsumeRF(Config.controllerOperationRFT.get())) { - insertStackReal(context, inserted, fetchItem(handler, false, extractMatcher, settings.getStackMode(), settings.getExtractAmount(), toextract - remaining, index, startIdx)); - } + if (context.checkAndConsumeRF(Config.controllerOperationRFT.get())) { + int remaining = insertStackNew(context, stack, world); + if (remaining != toextract) { + fetchItem(handler, false, extractMatcher, settings.getStackMode(), + settings.getExtractAmount(), toextract - remaining, index, startIdx); break; } else { index.inc(); } + } else { break; } @@ -282,191 +289,170 @@ private int tickItemHandler(IControllerContext context, ItemConnectorSettings se return index.getSafe(handler.getSlots()); } - // Returns what could not be inserted - public int insertStackSimulate(@Nonnull List> inserted, @Nonnull IControllerContext context, @Nonnull ItemStack stack) { - Level world = context.getControllerWorld(); + public int insertStackNew(@Nonnull IControllerContext context, @Nonnull ItemStack source, @Nonnull Level world) { if (channelMode == ChannelMode.PRIORITY) { roundRobinOffset = 0; // Always start at 0 } - int total = stack.getCount(); - for (int j = 0; j < itemConsumers.size(); j++) { - int i = (j + roundRobinOffset) % itemConsumers.size(); - Pair entry = itemConsumers.get(i); - ItemConnectorSettings settings = entry.getValue(); - - if (settings.getMatcher(context).test(stack)) { - BlockPos consumerPos = context.findConsumerPosition(entry.getKey().consumerId()); - if (consumerPos != null) { - if (!LevelTools.isLoaded(world, consumerPos)) { - continue; - } + int total = source.getCount(); + int consumersSize = itemConsumers.size(); + int extractorsSize = itemExtractors.size(); + for (int j = 0; j < consumersSize; j++) { + int i = (j + roundRobinOffset) % consumersSize; + if (consumerFull[i]) { + continue; + } + ConnectedBlock consumer = itemConsumers.get(i); + ItemConnectorSettings settings = consumer.settings(); - if (checkRedstone(world, settings, consumerPos)) { - continue; - } - if (!context.matchColor(settings.getColorsMask())) { - continue; - } + BlockPos connectorPos = consumer.connectorPos(); + Direction side = consumer.sidedConsumer().side(); + BlockPos connectedBlockPos = connectorPos.relative(side); + if (!LevelTools.isLoaded(world, connectedBlockPos)) { + continue; + } - Direction side = entry.getKey().side(); - BlockPos pos = consumerPos.relative(side); - BlockEntity te = world.getBlockEntity(pos); - int actuallyinserted; - int toinsert = total; - ItemStack remaining; - Integer count = settings.getCount(); - - if (RFToolsSupport.isStorageScanner(te)) { - if (count != null) { - int amount = RFToolsSupport.countItems(te, settings.getMatcher(context), count); - int caninsert = count - amount; - if (caninsert <= 0) { - continue; - } - toinsert = Math.min(toinsert, caninsert); - stack = stack.copy(); - stack.setCount(Math.max(toinsert, 0)); - } - remaining = RFToolsSupport.insertItem(te, stack, true); - } else { - LazyOptional itemHandler = getItemHandlerAt(te, settings.getFacing()); - if (itemHandler.isPresent()) { - if (count != null) { - int amount = countItems(itemHandler, settings.getMatcher(context)); - int caninsert = count - amount; - if (caninsert <= 0) { - continue; - } - toinsert = Math.min(toinsert, caninsert); - stack = stack.copy(); - stack.setCount(Math.max(toinsert, 0)); - } - ItemStack finalStack = stack; - remaining = itemHandler.map(h -> ItemHandlerHelper.insertItem(h, finalStack, true)).orElse(ItemStack.EMPTY); - } else { - continue; - } - } + BlockEntity te = world.getBlockEntity(connectedBlockPos); + ItemStack remaining; - actuallyinserted = toinsert - remaining.getCount(); - if (count == null) { - // If we are not using a count then we restore 'stack' here as that is what - // we actually have to keep inserting until it is empty. If we are using a count - // then we don't do this as we don't want to risk stack getting null (on 1.10.2) - // from the insertItem() and then not being able to set stacksize a few lines - // above this - stack = remaining; - } - if (actuallyinserted > 0) { - inserted.add(entry); - total -= actuallyinserted; - if (total <= 0) { - return 0; - } - } + IItemHandler destination = getItemHandlerAt(te, settings.getFacing()).resolve().orElse(null); + if (destination == null) { + continue; + } + + Predicate matcher = settings.getMatcher(context); + if (!matcher.test(source) || checkRedstone(world, settings, connectorPos) || !context.matchColor(settings.getColorsMask())) { + continue; + } + + int toinsert = total; + Integer count = settings.getCount(); + if (count != null) { + int amount = countItems(destination, matcher); + int caninsert = count - amount; + if (caninsert <= 0) { + continue; + } + toinsert = Math.min(toinsert, caninsert); + source = source.copy(); + source.setCount(toinsert); + } + + remaining = ItemHandlerHelper.insertItem(destination, source, false); + + int actuallyinserted = toinsert - remaining.getCount(); + if (count == null) { + // If we are not using a count then we restore 'stack' here as that is what + // we actually have to keep inserting until it is empty. If we are using a count + // then we don't do this as we don't want to risk stack getting null (on 1.10.2) + // from the insertItem() and then not being able to set stacksize a few lines + // above this + source = remaining; + } + if (actuallyinserted > 0) { + roundRobinOffset = (roundRobinOffset + 1) % consumersSize; + total -= actuallyinserted; + if (total <= 0) { + return 0; + } + } else if (extractorsSize > 1 && (j == 0 || j == consumersSize / 2 - 1)) { + // If we have more than 1 extractor it would be useful to cache full consumer inventories + // to avoid useless processing. + // It will be enough to do it twice: at the beginning and in the middle of processing + if (isFull(destination)) { + consumerFull[i] = true;// We will ignore this consumer for next extractor (if any) } } } return total; } - public void insertStackReal(@Nonnull IControllerContext context, @Nonnull List> inserted, @Nonnull ItemStack stack) { - int total = stack.getCount(); - for (Pair entry : inserted) { - BlockPos consumerPosition = context.findConsumerPosition(entry.getKey().consumerId()); - Direction side = entry.getKey().side(); - ItemConnectorSettings settings = entry.getValue(); - BlockPos pos = consumerPosition.relative(side); - BlockEntity te = context.getControllerWorld().getBlockEntity(pos); - if (RFToolsSupport.isStorageScanner(te)) { - int toinsert = total; - Integer count = settings.getCount(); - if (count != null) { - int amount = RFToolsSupport.countItems(te, settings.getMatcher(context), count); - int caninsert = count - amount; - if (caninsert <= 0) { - continue; - } - toinsert = Math.min(toinsert, caninsert); - stack = stack.copy(); - stack.setCount(Math.max(toinsert, 0)); - } - ItemStack remaining = RFToolsSupport.insertItem(te, stack, false); - int actuallyinserted = toinsert - remaining.getCount(); - if (count == null) { - // If we are not using a count then we restore 'stack' here as that is what - // we actually have to keep inserting until it is empty. If we are using a count - // then we don't do this as we don't want to risk stack getting null (on 1.10.2) - // from the insertItem() and then not being able to set stacksize a few lines - // above this - stack = remaining; - } - if (actuallyinserted > 0) { - roundRobinOffset = (roundRobinOffset + 1) % itemConsumers.size(); - total -= actuallyinserted; - if (total <= 0) { - return; - } - } + public int insertStackToStorageScanner(@Nonnull IControllerContext context, @Nonnull ItemStack source, @Nonnull Level world) { + if (channelMode == ChannelMode.PRIORITY) { + roundRobinOffset = 0; // Always start at 0 + } + int total = source.getCount(); + int consumersSize = itemConsumers.size(); + for (int j = 0; j < consumersSize; j++) { + int i = (j + roundRobinOffset) % consumersSize; + ConnectedBlock consumer = itemConsumers.get(i); + ItemConnectorSettings settings = consumer.settings(); + + BlockPos connectorPos = consumer.connectorPos(); + Direction side = consumer.sidedConsumer().side(); + BlockPos connectedBlockPos = connectorPos.relative(side); + if (!LevelTools.isLoaded(world, connectedBlockPos)) { + continue; + } - } else { - LazyOptional handler = getItemHandlerAt(te, settings.getFacing()); - - int toinsert = total; - Integer count = settings.getCount(); - if (count != null) { - int amount = countItems(handler, settings.getMatcher(context)); - int caninsert = count - amount; - if (caninsert <= 0) { - continue; - } - toinsert = Math.min(toinsert, caninsert); - stack = stack.copy(); - stack.setCount(Math.max(toinsert, 0)); - } - ItemStack finalStack = stack; - ItemStack remaining = handler.map(h -> ItemHandlerHelper.insertItem(h, finalStack, false)).orElse(ItemStack.EMPTY); - int actuallyinserted = toinsert - remaining.getCount(); - if (count == null) { - // If we are not using a count then we restore 'stack' here as that is what - // we actually have to keep inserting until it is empty. If we are using a count - // then we don't do this as we don't want to risk stack getting null (on 1.10.2) - // from the insertItem() and then not being able to set stacksize a few lines - // above this - stack = remaining; + BlockEntity te = world.getBlockEntity(connectedBlockPos); + ItemStack remaining; + + Predicate matcher = settings.getMatcher(context); + if (!matcher.test(source) || checkRedstone(world, settings, connectorPos) || !context.matchColor(settings.getColorsMask())) { + continue; + } + + int toinsert = total; + Integer count = settings.getCount(); + if (count != null) { + int amount = RFToolsSupport.countItems(te, matcher, count); + int caninsert = count - amount; + if (caninsert <= 0) { + continue; } + toinsert = Math.min(toinsert, caninsert); + source = source.copy(); + source.setCount(toinsert); + } - if (actuallyinserted > 0) { - roundRobinOffset = (roundRobinOffset + 1) % itemConsumers.size(); - total -= actuallyinserted; - if (total <= 0) { - return; - } + remaining = RFToolsSupport.insertItem(te, source, false); + + int actuallyinserted = toinsert - remaining.getCount(); + if (count == null) { + // If we are not using a count then we restore 'stack' here as that is what + // we actually have to keep inserting until it is empty. If we are using a count + // then we don't do this as we don't want to risk stack getting null (on 1.10.2) + // from the insertItem() and then not being able to set stacksize a few lines + // above this + source = remaining; + } + if (actuallyinserted > 0) { + roundRobinOffset = (roundRobinOffset + 1) % consumersSize; + total -= actuallyinserted; + if (total <= 0) { + return 0; } } } + return total; } - private int countItems(LazyOptional handler, Predicate matcher) { - return handler.map(h -> countItems(h, matcher)).orElse(0); + private boolean isFull(IItemHandler itemHandler) { + for (int i = 0; i < itemHandler.getSlots(); i++) { + ItemStack stackInSlot = itemHandler.getStackInSlot(i); + if (stackInSlot.getCount() < itemHandler.getSlotLimit(i) + && stackInSlot.getCount() < stackInSlot.getMaxStackSize()) { + return false; + } + } + return true; } private Integer countItems(IItemHandler h, Predicate matcher) { int cnt = 0; for (int i = 0; i < h.getSlots(); i++) { ItemStack s = h.getStackInSlot(i); - if (!s.isEmpty()) { - if (matcher.test(s)) { - cnt += s.getCount(); - } + if (!s.isEmpty() && matcher.test(s)) { + cnt += s.getCount(); } } return cnt; } - private ItemStack fetchItem(IItemHandler handler, boolean simulate, Predicate matcher, StackMode stackMode, int extractAmount, int maxamount, MInteger index, int startIdx) { + private ItemStack fetchItem(IItemHandler handler, boolean simulate, Predicate matcher, + StackMode stackMode, int extractAmount, int maxamount, MInteger index, int startIdx) { if (handler.getSlots() <= 0) { return ItemStack.EMPTY; } @@ -493,26 +479,28 @@ private ItemStack fetchItem(IItemHandler handler, boolean simulate, Predicate(); + itemExtractors = new ArrayList<>(); itemConsumers = new ArrayList<>(); Map connectors = context.getConnectors(channel); for (Map.Entry entry : connectors.entrySet()) { ItemConnectorSettings con = (ItemConnectorSettings) entry.getValue(); + BlockPos connectorPos = context.findConsumerPosition(entry.getKey().consumerId()); if (con.getItemMode() == InsExtMode.EXT) { - itemExtractors.put(entry.getKey(), con); + itemExtractors.add(new ConnectedBlock<>(entry.getKey(), con, connectorPos)); } else { - itemConsumers.add(Pair.of(entry.getKey(), con)); + itemConsumers.add(new ConnectedBlock<>(entry.getKey(), con, connectorPos)); } } connectors = context.getRoutedConnectors(channel); for (Map.Entry entry : connectors.entrySet()) { ItemConnectorSettings con = (ItemConnectorSettings) entry.getValue(); if (con.getItemMode() == InsExtMode.INS) { - itemConsumers.add(Pair.of(entry.getKey(), con)); + BlockPos connectorPos = context.findConsumerPosition(entry.getKey().consumerId()); + itemConsumers.add(new ConnectedBlock<>(entry.getKey(), con, connectorPos)); } } - itemConsumers.sort((o1, o2) -> o2.getRight().getPriority().compareTo(o1.getRight().getPriority())); + itemConsumers.sort((o1, o2) -> o2.settings().getPriority().compareTo(o1.settings().getPriority())); } } @@ -542,7 +530,7 @@ public String getIndicator() { @Override public void createGui(IEditorGui gui) { gui.nl(); - ((AbstractEditorPanel)gui).translatableChoices(TAG_MODE, channelMode, ChannelMode.values());// TODO: 09.03.2024 remove AbstractEditorPanel cast after rftoolbase update + gui.translatableChoices(TAG_MODE, channelMode, ChannelMode.values()); } @Override diff --git a/src/main/java/mcjty/xnet/apiimpl/logic/LogicChannelSettings.java b/src/main/java/mcjty/xnet/apiimpl/logic/LogicChannelSettings.java index 27461db0..f3ad6369 100644 --- a/src/main/java/mcjty/xnet/apiimpl/logic/LogicChannelSettings.java +++ b/src/main/java/mcjty/xnet/apiimpl/logic/LogicChannelSettings.java @@ -10,6 +10,7 @@ import mcjty.rftoolsbase.api.xnet.helper.DefaultChannelSettings; import mcjty.rftoolsbase.api.xnet.keys.SidedConsumer; import mcjty.xnet.XNet; +import mcjty.xnet.apiimpl.ConnectedBlock; import mcjty.xnet.apiimpl.logic.enums.LogicMode; import mcjty.xnet.logic.LogicOperations; import mcjty.xnet.logic.LogicTools; @@ -20,7 +21,6 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nullable; import java.util.ArrayList; @@ -33,8 +33,8 @@ public class LogicChannelSettings extends DefaultChannelSettings implements ICha public static final ResourceLocation iconGuiElements = new ResourceLocation(XNet.MODID, "textures/gui/guielements.png"); private int colors = 0; // Colors for this channel - private List> sensors = null; - private List> outputs = null; + private List> sensors = null; + private List> outputs = null; @Override public JsonObject writeToJson() { @@ -67,12 +67,12 @@ public void tick(int channel, IControllerContext context) { Level world = context.getControllerWorld(); colors = 0; - for (Pair entry : sensors) { - LogicConnectorSettings settings = entry.getValue(); + for (ConnectedBlock connector : sensors) { + LogicConnectorSettings settings = connector.settings(); int sensorColors = 0; - BlockPos connectorPos = context.findConsumerPosition(entry.getKey().consumerId()); + BlockPos connectorPos = connector.connectorPos(); if (connectorPos != null) { - Direction side = entry.getKey().side(); + Direction side = connector.sidedConsumer().side(); BlockPos pos = connectorPos.relative(side); if (!LevelTools.isLoaded(world, pos)) { // If it is not chunkloaded we just use the color settings as we last remembered it @@ -100,27 +100,28 @@ public void tick(int channel, IControllerContext context) { colors |= sensorColors; } - for (Pair entry : outputs) { - LogicConnectorSettings settings = entry.getValue(); - - BlockPos connectorPos = context.findConsumerPosition(entry.getKey().consumerId()); - if (LevelTools.isLoaded(world, connectorPos)) { - - Direction side = entry.getKey().side(); - BlockEntity te = world.getBlockEntity(connectorPos); - if (te instanceof ConnectorTileEntity connectorTE) { - int powerOut; - if (checkRedstone(world, settings, connectorPos) || !context.matchColor(settings.getColorsMask())) { - powerOut = 0; - } else { - RSOutput output = settings.getOutput(); - boolean[] colorsArray = LogicTools.intToBinary(colors); - boolean input1 = colorsArray[output.getInputChannel1().ordinal()]; - boolean input2 = colorsArray[output.getInputChannel2().ordinal()]; - powerOut = LogicOperations.applyFilter(output, input1, input2) ? output.getRedstoneOut() : 0; - } - connectorTE.setPowerOut(side, powerOut); + for (ConnectedBlock connector : outputs) { + LogicConnectorSettings settings = connector.settings(); + + BlockPos connectorPos = connector.connectorPos(); + if (!LevelTools.isLoaded(world, connectorPos)) { + continue; + } + + Direction side = connector.sidedConsumer().side(); + BlockEntity te = world.getBlockEntity(connectorPos); + if (te instanceof ConnectorTileEntity connectorTE) { + int powerOut; + if (checkRedstone(world, settings, connectorPos) || !context.matchColor(settings.getColorsMask())) { + powerOut = 0; + } else { + RSOutput output = settings.getOutput(); + boolean[] colorsArray = LogicTools.intToBinary(colors); + boolean input1 = colorsArray[output.getInputChannel1().ordinal()]; + boolean input2 = colorsArray[output.getInputChannel2().ordinal()]; + powerOut = LogicOperations.applyFilter(output, input1, input2) ? output.getRedstoneOut() : 0; } + connectorTE.setPowerOut(side, powerOut); } } } @@ -132,10 +133,11 @@ private void updateCache(int channel, IControllerContext context) { Map connectors = context.getConnectors(channel); for (Map.Entry entry : connectors.entrySet()) { LogicConnectorSettings con = (LogicConnectorSettings) entry.getValue(); + BlockPos connectorPos = context.findConsumerPosition(entry.getKey().consumerId()); if (con.getLogicMode() == LogicMode.SENSOR) { - sensors.add(Pair.of(entry.getKey(), con)); + sensors.add(new ConnectedBlock<>(entry.getKey(), con, connectorPos)); } else { - outputs.add(Pair.of(entry.getKey(), con)); + outputs.add(new ConnectedBlock<>(entry.getKey(), con, connectorPos)); } } @@ -143,7 +145,8 @@ private void updateCache(int channel, IControllerContext context) { for (Map.Entry entry : connectors.entrySet()) { LogicConnectorSettings con = (LogicConnectorSettings) entry.getValue(); if (con.getLogicMode() == LogicMode.OUTPUT) { - outputs.add(Pair.of(entry.getKey(), con)); + BlockPos connectorPos = context.findConsumerPosition(entry.getKey().consumerId()); + outputs.add(new ConnectedBlock<>(entry.getKey(), con, connectorPos)); } } } diff --git a/src/main/java/mcjty/xnet/compat/RFToolsSupport.java b/src/main/java/mcjty/xnet/compat/RFToolsSupport.java index b316b273..ad5d399f 100644 --- a/src/main/java/mcjty/xnet/compat/RFToolsSupport.java +++ b/src/main/java/mcjty/xnet/compat/RFToolsSupport.java @@ -2,16 +2,13 @@ import mcjty.rftoolsbase.api.storage.IStorageScanner; import mcjty.rftoolsbase.api.xnet.channels.IControllerContext; -import mcjty.rftoolsbase.api.xnet.keys.SidedConsumer; import mcjty.xnet.apiimpl.items.ItemChannelSettings; import mcjty.xnet.apiimpl.items.ItemConnectorSettings; import mcjty.xnet.setup.Config; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -import org.apache.commons.lang3.tuple.Pair; -import java.util.ArrayList; -import java.util.List; import java.util.function.Predicate; public class RFToolsSupport { @@ -20,7 +17,8 @@ public static boolean isStorageScanner(BlockEntity te) { return te instanceof IStorageScanner; } - public static void tickStorageScanner(IControllerContext context, ItemConnectorSettings settings, BlockEntity te, ItemChannelSettings channelSettings) { + public static void tickStorageScanner(IControllerContext context, ItemConnectorSettings settings, BlockEntity te, + ItemChannelSettings channelSettings, Level world) { IStorageScanner scanner = (IStorageScanner) te; Predicate extractMatcher = settings.getMatcher(context); @@ -38,31 +36,27 @@ public static void tickStorageScanner(IControllerContext context, ItemConnectorS case COUNT -> settings.getExtractAmount(); }; ItemStack stack = scanner.requestItem(extractMatcher, true, cnt, true); - if (!stack.isEmpty()) { - // Now that we have a stack we first reduce the amount of the stack if we want to keep a certain - // number of items - int toextract = stack.getCount(); - if (count != null) { - int canextract = amount-count; - if (canextract <= 0) { - return; - } - if (canextract < toextract) { - toextract = canextract; - if (toextract <= 0) { - stack.setCount(0); - } else { - stack.setCount(toextract); - } - } + if (stack.isEmpty()) { + return; + } + // Now that we have a stack we first reduce the amount of the stack if we want to keep a certain + // number of items + int toextract = stack.getCount(); + if (count != null) { + int canextract = amount-count; + if (canextract <= 0) { + return; } + if (canextract < toextract) { + toextract = canextract; + stack.setCount(toextract); + } + } - List> inserted = new ArrayList<>(); - int remaining = channelSettings.insertStackSimulate(inserted, context, stack); - if (!inserted.isEmpty()) { - if (context.checkAndConsumeRF(Config.controllerOperationRFT.get())) { - channelSettings.insertStackReal(context, inserted, scanner.requestItem(extractMatcher, false, toextract - remaining, true)); - } + if (context.checkAndConsumeRF(Config.controllerOperationRFT.get())) { + int remaining = channelSettings.insertStackToStorageScanner(context, stack, world); + if (remaining != toextract) { + scanner.requestItem(extractMatcher, false, toextract - remaining, true); } } } From f6f5cd87a0c03a696d741d22e2085b4f43e077f2 Mon Sep 17 00:00:00 2001 From: Alex Emelyanov Date: Sat, 6 Apr 2024 14:40:26 +0300 Subject: [PATCH 6/6] Huge optimisation patch for multiplayer --- .../apiimpl/items/ItemChannelSettings.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main/java/mcjty/xnet/apiimpl/items/ItemChannelSettings.java b/src/main/java/mcjty/xnet/apiimpl/items/ItemChannelSettings.java index f8ffa19c..65294365 100644 --- a/src/main/java/mcjty/xnet/apiimpl/items/ItemChannelSettings.java +++ b/src/main/java/mcjty/xnet/apiimpl/items/ItemChannelSettings.java @@ -38,6 +38,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Random; import java.util.function.Predicate; @@ -160,7 +161,8 @@ public void tick(int channel, IControllerContext context) { updateCache(channel, context); Level world = context.getControllerWorld(); consumerFull = new boolean[itemConsumers.size()]; - for (ConnectedBlock extractor : itemExtractors) { + for (int i = 0; i < itemExtractors.size(); i++) { + ConnectedBlock extractor = itemExtractors.get(i); ItemConnectorSettings settings = extractor.settings(); if (d % settings.getSpeed() != 0) { continue; @@ -190,13 +192,15 @@ public void tick(int channel, IControllerContext context) { if (RFToolsSupport.isStorageScanner(te)) { RFToolsSupport.tickStorageScanner(context, settings, te, this, world); } else { - getItemHandlerAt(te, settings.getFacing()).ifPresent(handler -> { + Optional lazyHandler = getItemHandlerAt(te, settings.getFacing()).resolve(); + if (lazyHandler.isPresent()) { + IItemHandler handler = lazyHandler.get(); int idx = getStartExtractIndex(settings, consumerId, handler); - idx = tickItemHandler(context, settings, handler, world, idx); + idx = tickItemHandler(context, settings, handler, world, idx, i); if (handler.getSlots() > 0) { rememberExtractIndex(consumerId, (idx + 1) % handler.getSlots()); } - }); + } } } } @@ -236,7 +240,7 @@ private int getStartExtractIndex(ItemConnectorSettings settings, ConsumerId cons private int tickItemHandler(@Nonnull IControllerContext context, @Nonnull ItemConnectorSettings settings, - @Nonnull IItemHandler handler, @Nonnull Level world, int startIdx) { + @Nonnull IItemHandler handler, @Nonnull Level world, int startIdx, int extractorIdx) { Predicate extractMatcher = settings.getMatcher(context); Integer count = settings.getCount(); @@ -273,7 +277,7 @@ private int tickItemHandler(@Nonnull IControllerContext context, @Nonnull ItemCo } if (context.checkAndConsumeRF(Config.controllerOperationRFT.get())) { - int remaining = insertStackNew(context, stack, world); + int remaining = insertStack(context, stack, world, extractorIdx); if (remaining != toextract) { fetchItem(handler, false, extractMatcher, settings.getStackMode(), settings.getExtractAmount(), toextract - remaining, index, startIdx); @@ -289,7 +293,7 @@ private int tickItemHandler(@Nonnull IControllerContext context, @Nonnull ItemCo return index.getSafe(handler.getSlots()); } - public int insertStackNew(@Nonnull IControllerContext context, @Nonnull ItemStack source, @Nonnull Level world) { + public int insertStack(@Nonnull IControllerContext context, @Nonnull ItemStack source, @Nonnull Level world, int extractorIdx) { if (channelMode == ChannelMode.PRIORITY) { roundRobinOffset = 0; // Always start at 0 } @@ -354,7 +358,7 @@ public int insertStackNew(@Nonnull IControllerContext context, @Nonnull ItemStac if (total <= 0) { return 0; } - } else if (extractorsSize > 1 && (j == 0 || j == consumersSize / 2 - 1)) { + } else if (extractorsSize > 2 && (extractorIdx == 0 || extractorIdx == extractorsSize / 2 - 1)) { // If we have more than 1 extractor it would be useful to cache full consumer inventories // to avoid useless processing. // It will be enough to do it twice: at the beginning and in the middle of processing