From b1a1b4e62aeb6c86859d65c3227252cd513c328a Mon Sep 17 00:00:00 2001 From: malte0811 Date: Sat, 17 Jun 2017 17:22:44 +0200 Subject: [PATCH] Allowed multiple components on the same panel network to modify the same RS signal Cleaned up RS output code for panel components (Back-port from 1.11) --- .../controlpanel/TileEntityRSPanelConn.java | 51 +++++++++++++++++-- .../controlpanel/LightedButton.java | 22 ++------ .../industrialWires/controlpanel/Lock.java | 24 +++------ .../controlpanel/PanelComponent.java | 19 ++++--- .../industrialWires/controlpanel/Slider.java | 26 +++------- .../controlpanel/ToggleSwitch.java | 22 ++------ .../industrialWires/controlpanel/Variac.java | 26 +++------- .../industrialWires/util/TriConsumer.java | 23 +++++++++ .../assets/industrialwires/lang/en_US.lang | 2 +- 9 files changed, 114 insertions(+), 101 deletions(-) create mode 100644 src/main/java/malte0811/industrialWires/util/TriConsumer.java diff --git a/src/main/java/malte0811/industrialWires/blocks/controlpanel/TileEntityRSPanelConn.java b/src/main/java/malte0811/industrialWires/blocks/controlpanel/TileEntityRSPanelConn.java index 0331f2b..54661d6 100644 --- a/src/main/java/malte0811/industrialWires/blocks/controlpanel/TileEntityRSPanelConn.java +++ b/src/main/java/malte0811/industrialWires/blocks/controlpanel/TileEntityRSPanelConn.java @@ -30,6 +30,7 @@ import malte0811.industrialWires.blocks.IBlockBoundsIW; import malte0811.industrialWires.blocks.INetGUI; import malte0811.industrialWires.controlpanel.PanelComponent; import malte0811.industrialWires.controlpanel.PanelUtils; +import malte0811.industrialWires.util.TriConsumer; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; @@ -44,8 +45,8 @@ import net.minecraft.world.World; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.lang.ref.WeakReference; import java.util.*; -import java.util.function.BiConsumer; import java.util.function.Consumer; public class TileEntityRSPanelConn extends TileEntityImmersiveConnectable implements IRedstoneConnector, ITickable, INetGUI, IEBlockInterfaces.IDirectionalTile, IBlockBoundsIW { @@ -109,13 +110,55 @@ public class TileEntityRSPanelConn extends TileEntityImmersiveConnectable implem aabb = null; } - private BiConsumer rsOut = (channel, value) -> { - if (value != out[channel]) { + private final Map outputs = new HashMap<>(); + private TriConsumer rsOut = (channel, value, pc) -> { + PCWrapper wrapper = new PCWrapper(pc); + if (!outputs.containsKey(wrapper)) { + outputs.put(wrapper, new byte[16]); + } + if (outputs.get(wrapper)[channel] != value) { + outputs.get(wrapper)[channel] = value; + byte max = 0; + Iterator> it = outputs.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry curr = it.next(); + if (curr.getKey().pc.get() == null) { + it.remove(); + continue; + } + if (curr.getValue()[channel] > max) { + max = curr.getValue()[channel]; + } + } dirty = true; - out[channel] = value; + out[channel] = max; } }; + private class PCWrapper { + @Nonnull + private final WeakReference pc; + + public PCWrapper(@Nonnull PanelComponent pc) { + this.pc = new WeakReference<>(pc); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PCWrapper pcWrapper = (PCWrapper) o; + + return pcWrapper.pc.get() == pc.get(); + } + + @Override + public int hashCode() { + return System.identityHashCode(pc.get()); + } + } + public void registerPanel(TileEntityPanel panel) { PropertyComponents.PanelRenderProperties p = panel.getComponents(); for (PanelComponent pc : p) { diff --git a/src/main/java/malte0811/industrialWires/controlpanel/LightedButton.java b/src/main/java/malte0811/industrialWires/controlpanel/LightedButton.java index c3c82e9..32991e8 100644 --- a/src/main/java/malte0811/industrialWires/controlpanel/LightedButton.java +++ b/src/main/java/malte0811/industrialWires/controlpanel/LightedButton.java @@ -22,6 +22,7 @@ import malte0811.industrialWires.IndustrialWires; import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel; import malte0811.industrialWires.client.RawQuad; import malte0811.industrialWires.client.gui.GuiPanelCreator; +import malte0811.industrialWires.util.TriConsumer; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTBase; @@ -34,10 +35,7 @@ import org.lwjgl.util.vector.Vector3f; import javax.annotation.Nonnull; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.function.BiConsumer; public class LightedButton extends PanelComponent implements IConfigurableComponent { public int color = 0xFF0000; @@ -46,7 +44,6 @@ public class LightedButton extends PanelComponent implements IConfigurableCompon public int rsOutputId; public int rsOutputChannel; private int ticksTillOff; - private Set> rsOut = new HashSet<>(); public LightedButton() { super("lighted_button"); @@ -144,17 +141,10 @@ public class LightedButton extends PanelComponent implements IConfigurableCompon } @Override - public void registerRSOutput(int id, @Nonnull BiConsumer out) { + public void registerRSOutput(int id, @Nonnull TriConsumer out) { if (id == rsOutputId) { - rsOut.add(out); - out.accept(rsOutputChannel, (byte) (active ? 15 : 0)); - } - } - - @Override - public void unregisterRSOutput(int id, @Nonnull BiConsumer out) { - if (id == rsOutputId) { - rsOut.remove(out); + super.registerRSOutput(id, out); + out.accept(rsOutputChannel, (byte) (active ? 15 : 0), this); } } @@ -177,9 +167,7 @@ public class LightedButton extends PanelComponent implements IConfigurableCompon active = on; tile.markDirty(); tile.triggerRenderUpdate(); - for (BiConsumer rs : rsOut) { - rs.accept(rsOutputChannel, (byte) (active ? 15 : 0)); - } + setOut(rsOutputChannel, active ? 15 : 0); } @Override diff --git a/src/main/java/malte0811/industrialWires/controlpanel/Lock.java b/src/main/java/malte0811/industrialWires/controlpanel/Lock.java index 7e85965..d78f185 100644 --- a/src/main/java/malte0811/industrialWires/controlpanel/Lock.java +++ b/src/main/java/malte0811/industrialWires/controlpanel/Lock.java @@ -24,6 +24,7 @@ import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel; import malte0811.industrialWires.client.RawQuad; import malte0811.industrialWires.client.gui.GuiPanelCreator; import malte0811.industrialWires.items.ItemKey; +import malte0811.industrialWires.util.TriConsumer; import net.minecraft.block.Block; import net.minecraft.client.gui.Gui; import net.minecraft.client.resources.I18n; @@ -41,8 +42,9 @@ import org.lwjgl.util.vector.Vector3f; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.*; -import java.util.function.BiConsumer; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; public class Lock extends PanelComponent implements IConfigurableComponent { private final static Random rand = new Random(); @@ -54,7 +56,6 @@ public class Lock extends PanelComponent implements IConfigurableComponent { private int rsOutputChannel; private int ticksTillOff; private int lockID; - private Set> rsOut = new HashSet<>(); public Lock() { super("lock"); @@ -214,17 +215,10 @@ public class Lock extends PanelComponent implements IConfigurableComponent { } @Override - public void registerRSOutput(int id, @Nonnull BiConsumer out) { + public void registerRSOutput(int id, @Nonnull TriConsumer out) { if (id == rsOutputId) { - rsOut.add(out); - out.accept(rsOutputChannel, (byte) (turned ? 15 : 0)); - } - } - - @Override - public void unregisterRSOutput(int id, @Nonnull BiConsumer out) { - if (id == rsOutputId) { - rsOut.remove(out); + super.registerRSOutput(id, out); + out.accept(rsOutputChannel, (byte) (turned ? 15 : 0), this); } } @@ -252,9 +246,7 @@ public class Lock extends PanelComponent implements IConfigurableComponent { private void setOut(TileEntityPanel tile) { tile.markDirty(); tile.triggerRenderUpdate(); - for (BiConsumer rs : rsOut) { - rs.accept(rsOutputChannel, (byte) (turned ? 15 : 0)); - } + setOut(rsOutputChannel, turned ? 15 : 0); } @Override diff --git a/src/main/java/malte0811/industrialWires/controlpanel/PanelComponent.java b/src/main/java/malte0811/industrialWires/controlpanel/PanelComponent.java index 32daee1..52582ca 100644 --- a/src/main/java/malte0811/industrialWires/controlpanel/PanelComponent.java +++ b/src/main/java/malte0811/industrialWires/controlpanel/PanelComponent.java @@ -22,6 +22,7 @@ import blusunrize.immersiveengineering.common.util.IELogger; import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel; import malte0811.industrialWires.client.RawQuad; import malte0811.industrialWires.client.gui.GuiPanelCreator; +import malte0811.industrialWires.util.TriConsumer; import net.minecraft.client.gui.Gui; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.RenderGlobal; @@ -33,10 +34,7 @@ import net.minecraft.util.math.Vec3d; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.BiConsumer; +import java.util.*; import java.util.function.Consumer; import java.util.function.Supplier; @@ -47,6 +45,7 @@ public abstract class PanelComponent { private final String type; protected final static float[] GRAY = {.8F, .8F, .8F}; protected final static int GRAY_INT = 0xFFD0D0D0; + private Set> outputs = new HashSet<>(); protected PanelComponent(String type) { this.type = type; @@ -97,10 +96,12 @@ public abstract class PanelComponent { return null; } - public void registerRSOutput(int id, @Nonnull BiConsumer out) { + public void registerRSOutput(int id, @Nonnull TriConsumer out) { + outputs.add(out); } - public void unregisterRSOutput(int id, @Nonnull BiConsumer out) { + public void unregisterRSOutput(int id, @Nonnull TriConsumer out) { + outputs.remove(out); } public void dropItems(TileEntityPanel te) { @@ -208,6 +209,12 @@ public abstract class PanelComponent { return true; } + void setOut(int channel, int level) { + for (TriConsumer out : outputs) { + out.accept(channel, (byte) level, this); + } + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/malte0811/industrialWires/controlpanel/Slider.java b/src/main/java/malte0811/industrialWires/controlpanel/Slider.java index 7463be7..46b849f 100644 --- a/src/main/java/malte0811/industrialWires/controlpanel/Slider.java +++ b/src/main/java/malte0811/industrialWires/controlpanel/Slider.java @@ -22,6 +22,7 @@ import malte0811.industrialWires.IndustrialWires; import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel; import malte0811.industrialWires.client.RawQuad; import malte0811.industrialWires.client.gui.GuiPanelCreator; +import malte0811.industrialWires.util.TriConsumer; import net.minecraft.client.gui.Gui; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayerMP; @@ -33,10 +34,7 @@ import org.lwjgl.util.vector.Vector3f; import javax.annotation.Nonnull; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.function.BiConsumer; public class Slider extends PanelComponent implements IConfigurableComponent { private static final float WIDTH = .0625F; @@ -46,7 +44,6 @@ public class Slider extends PanelComponent implements IConfigurableComponent { private byte out; private byte rsChannel; private int rsId; - private Set> outputs = new HashSet<>(); public Slider(float length, int color, boolean horizontal, int rsId, byte rsChannel) { this(); @@ -135,9 +132,7 @@ public class Slider extends PanelComponent implements IConfigurableComponent { double pos = horizontal ? hitRelative.xCoord : (length - hitRelative.zCoord); byte newLevel = (byte) (Math.min(pos * 16 / length, 15)); if (newLevel != out) { - for (BiConsumer output : outputs) { - output.accept((int) rsChannel, newLevel); - } + setOut(rsChannel, newLevel); out = newLevel; tile.markDirty(); tile.triggerRenderUpdate(); @@ -145,17 +140,10 @@ public class Slider extends PanelComponent implements IConfigurableComponent { } @Override - public void registerRSOutput(int id, @Nonnull BiConsumer out) { + public void registerRSOutput(int id, @Nonnull TriConsumer out) { if (id == rsId) { - outputs.add(out); - out.accept((int) rsChannel, this.out); - } - } - - @Override - public void unregisterRSOutput(int id, @Nonnull BiConsumer out) { - if (id == rsId) { - outputs.remove(out); + super.registerRSOutput(id, out); + out.accept((int) rsChannel, this.out, this); } } @@ -183,9 +171,7 @@ public class Slider extends PanelComponent implements IConfigurableComponent { @Override public void invalidate(TileEntityPanel te) { - for (BiConsumer out : outputs) { - out.accept((int) rsChannel, (byte) 0); - } + setOut(rsChannel, 0); } @Override diff --git a/src/main/java/malte0811/industrialWires/controlpanel/ToggleSwitch.java b/src/main/java/malte0811/industrialWires/controlpanel/ToggleSwitch.java index 2f99bb8..25b1fa1 100644 --- a/src/main/java/malte0811/industrialWires/controlpanel/ToggleSwitch.java +++ b/src/main/java/malte0811/industrialWires/controlpanel/ToggleSwitch.java @@ -23,6 +23,7 @@ import malte0811.industrialWires.IndustrialWires; import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel; import malte0811.industrialWires.client.RawQuad; import malte0811.industrialWires.client.gui.GuiPanelCreator; +import malte0811.industrialWires.util.TriConsumer; import net.minecraft.client.gui.Gui; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayerMP; @@ -37,16 +38,12 @@ import org.lwjgl.util.vector.Vector3f; import javax.annotation.Nonnull; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.function.BiConsumer; public class ToggleSwitch extends PanelComponent implements IConfigurableComponent { public boolean active; public int rsOutputId; public byte rsOutputChannel; - private Set> rsOut = new HashSet<>(); public ToggleSwitch() { super("toggle_switch"); @@ -132,17 +129,10 @@ public class ToggleSwitch extends PanelComponent implements IConfigurableCompone } @Override - public void registerRSOutput(int id, @Nonnull BiConsumer out) { + public void registerRSOutput(int id, @Nonnull TriConsumer out) { if (id == rsOutputId) { - rsOut.add(out); - out.accept((int) rsOutputChannel, (byte) (active ? 15 : 0)); - } - } - - @Override - public void unregisterRSOutput(int id, @Nonnull BiConsumer out) { - if (id == rsOutputId) { - rsOut.remove(out); + super.registerRSOutput(id, out); + out.accept((int) rsOutputChannel, (byte) (active ? 15 : 0), this); } } @@ -178,9 +168,7 @@ public class ToggleSwitch extends PanelComponent implements IConfigurableCompone active = on; tile.markDirty(); tile.triggerRenderUpdate(); - for (BiConsumer rs : rsOut) { - rs.accept((int) rsOutputChannel, (byte) (active ? 15 : 0)); - } + setOut(rsOutputChannel, active ? 15 : 0); } @Override diff --git a/src/main/java/malte0811/industrialWires/controlpanel/Variac.java b/src/main/java/malte0811/industrialWires/controlpanel/Variac.java index 16d0a6a..f9396e6 100644 --- a/src/main/java/malte0811/industrialWires/controlpanel/Variac.java +++ b/src/main/java/malte0811/industrialWires/controlpanel/Variac.java @@ -23,6 +23,7 @@ import malte0811.industrialWires.IndustrialWires; import malte0811.industrialWires.blocks.controlpanel.TileEntityPanel; import malte0811.industrialWires.client.RawQuad; import malte0811.industrialWires.client.gui.GuiPanelCreator; +import malte0811.industrialWires.util.TriConsumer; import net.minecraft.client.gui.Gui; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.resources.I18n; @@ -38,10 +39,7 @@ import org.lwjgl.util.vector.Vector3f; import javax.annotation.Nonnull; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.function.BiConsumer; public class Variac extends PanelComponent implements IConfigurableComponent { private static final float SIZE = 3 / 16F; @@ -56,7 +54,6 @@ public class Variac extends PanelComponent implements IConfigurableComponent { private byte out; private byte rsChannel; private int rsId; - private Set> outputs = new HashSet<>(); public Variac(int rsId, byte rsChannel) { this(); @@ -153,9 +150,7 @@ public class Variac extends PanelComponent implements IConfigurableComponent { } newLevel = (byte) Math.max(0, Math.min(newLevel, 15)); if (newLevel != out) { - for (BiConsumer output : outputs) { - output.accept((int) rsChannel, newLevel); - } + setOut(rsChannel, newLevel); out = newLevel; tile.markDirty(); tile.triggerRenderUpdate(); @@ -163,17 +158,10 @@ public class Variac extends PanelComponent implements IConfigurableComponent { } @Override - public void registerRSOutput(int id, @Nonnull BiConsumer out) { + public void registerRSOutput(int id, @Nonnull TriConsumer out) { if (id == rsId) { - outputs.add(out); - out.accept((int) rsChannel, this.out); - } - } - - @Override - public void unregisterRSOutput(int id, @Nonnull BiConsumer out) { - if (id == rsId) { - outputs.remove(out); + super.registerRSOutput(id, out); + out.accept((int) rsChannel, this.out, this); } } @@ -208,9 +196,7 @@ public class Variac extends PanelComponent implements IConfigurableComponent { @Override public void invalidate(TileEntityPanel te) { - for (BiConsumer out : outputs) { - out.accept((int) rsChannel, (byte) 0); - } + setOut(rsChannel, 0); } @Override diff --git a/src/main/java/malte0811/industrialWires/util/TriConsumer.java b/src/main/java/malte0811/industrialWires/util/TriConsumer.java new file mode 100644 index 0000000..01fa81d --- /dev/null +++ b/src/main/java/malte0811/industrialWires/util/TriConsumer.java @@ -0,0 +1,23 @@ +/* + * This file is part of Industrial Wires. + * Copyright (C) 2016-2017 malte0811 + * + * Industrial Wires is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Industrial Wires is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Industrial Wires. If not, see . + */ + +package malte0811.industrialWires.util; + +public interface TriConsumer { + void accept(A a, B b, C c); +} diff --git a/src/main/resources/assets/industrialwires/lang/en_US.lang b/src/main/resources/assets/industrialwires/lang/en_US.lang index c38e795..e805f98 100644 --- a/src/main/resources/assets/industrialwires/lang/en_US.lang +++ b/src/main/resources/assets/industrialwires/lang/en_US.lang @@ -109,7 +109,7 @@ ie.manual.entry.industrialWires.intro.subtext= ie.manual.entry.industrialWires.intro0=Control Panels allow you to monitor and control a large amount of redstone signals using only a few blocks. Those signals can currently be connected using redstone wires and connectors.
Buttons, switches, indicator lights and other things that can be placed on a control panel are called §l(Panel) Components§r
To create a control panel you will need a Panel Creator, the individual components and a basic machine casing as the enclosure of the panel. Each ie.manual.entry.industrialWires.intro1=component is described in the entry "Panel Components". Right-clicking with a panel component opens up a GUI in which the properties of the component, like the redstone channel and ID or the color, can be configured. ie.manual.entry.industrialWires.intro2=A §l(panel) network§r is formed by panel blocks connected to each other, directly or through other panel blocks. Panel blocks include the control panel itself, the panel connector and the Redstone Wire Controller. If multiple components in one network are configured to modify the same -ie.manual.entry.industrialWires.intro3=redstone signal, the resulting behavior is undefined (but won't crash the game). Having multiple components accepting the same signal on a network is valid though. +ie.manual.entry.industrialWires.intro3=redstone signal, the resulting signal will be the highest of the individual signals. Having multiple components accepting the same signal on a network is valid as well. ie.manual.entry.industrialWires.panel_creator.name=Panel Creator ie.manual.entry.industrialWires.panel_creator.subtext=