Add container syncing helper + Rename slot builder methods

An example of the new syncing system can be found in the ChargeBench
This commit is contained in:
Ourten 2017-01-07 02:46:46 +01:00
parent b688fe72e4
commit 9f74feabff
7 changed files with 170 additions and 12 deletions

View file

@ -79,8 +79,8 @@ public class GuiHandler implements IGuiHandler {
return new ContainerQuantumTank((TileQuantumTank) world.getTileEntity(new BlockPos(x, y, z)), player); return new ContainerQuantumTank((TileQuantumTank) world.getTileEntity(new BlockPos(x, y, z)), player);
} else if (ID == GuiHandler.digitalChestID || ID == GuiHandler.quantumChestID) { } else if (ID == GuiHandler.digitalChestID || ID == GuiHandler.quantumChestID) {
return new ContainerBuilder().player(player.inventory).inventory().hotbar().addInventory() return new ContainerBuilder().player(player.inventory).inventory().hotbar().addInventory()
.tile((IInventory) world.getTileEntity(new BlockPos(x, y, z))).slot(0, 80, 17).output(1, 80, 53) .tile((IInventory) world.getTileEntity(new BlockPos(x, y, z))).slot(0, 80, 17).outputSlot(1, 80, 53)
.fake(2, 59, 42).addInventory().create(); .fakeSlot(2, 59, 42).addInventory().create();
} else if (ID == GuiHandler.centrifugeID) { } else if (ID == GuiHandler.centrifugeID) {
container = new ContainerCentrifuge(player, (TileCentrifuge) world.getTileEntity(new BlockPos(x, y, z))); container = new ContainerCentrifuge(player, (TileCentrifuge) world.getTileEntity(new BlockPos(x, y, z)));
} else if (ID == rollingMachineID) { } else if (ID == rollingMachineID) {
@ -132,9 +132,13 @@ public class GuiHandler implements IGuiHandler {
player); player);
} else if (ID == GuiHandler.chargeBench) { } else if (ID == GuiHandler.chargeBench) {
return new ContainerBuilder().player(player.inventory).inventory().hotbar().addInventory() return new ContainerBuilder().player(player.inventory).inventory().hotbar().addInventory()
.tile((IInventory) world.getTileEntity(new BlockPos(x, y, z))) .tile((IInventory) world.getTileEntity(new BlockPos(x, y, z))).energySlot(0, 62, 21)
.energy(0, 62, 21).energy(1, 80, 21).energy(2, 98, 21).energy(3, 62, 39).energy(4, 80, 39) .energySlot(1, 80, 21).energySlot(2, 98, 21).energySlot(3, 62, 39).energySlot(4, 80, 39)
.energy(5, 98, 39).addInventory().create(); .energySlot(5, 98, 39)
.syncIntegerValue(
() -> (int) ((TileChargeBench) world.getTileEntity(new BlockPos(x, y, z))).getEnergy(),
((TileChargeBench) world.getTileEntity(new BlockPos(x, y, z)))::setEnergy)
.addInventory().create();
} else if (ID == vacuumFreezerID) { } else if (ID == vacuumFreezerID) {
return new ContainerVacuumFreezer((TileVacuumFreezer) world.getTileEntity(new BlockPos(x, y, z)), player); return new ContainerVacuumFreezer((TileVacuumFreezer) world.getTileEntity(new BlockPos(x, y, z)), player);
} else if (ID == grinderID) { } else if (ID == grinderID) {

View file

@ -1,15 +1,23 @@
package techreborn.client.container.builder; package techreborn.client.container.builder;
import org.apache.commons.lang3.Range; import org.apache.commons.lang3.Range;
import org.apache.commons.lang3.tuple.MutableTriple;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container; import net.minecraft.inventory.Container;
import net.minecraft.inventory.IContainerListener;
import net.minecraft.inventory.Slot; import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import reborncore.common.util.ItemUtils; import reborncore.common.util.ItemUtils;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.IntConsumer;
import java.util.function.IntSupplier;
import java.util.function.Predicate; import java.util.function.Predicate;
final class BuiltContainer extends Container { final class BuiltContainer extends Container {
@ -18,12 +26,34 @@ final class BuiltContainer extends Container {
private final List<Range<Integer>> playerSlotRanges; private final List<Range<Integer>> playerSlotRanges;
private final List<Range<Integer>> tileSlotRanges; private final List<Range<Integer>> tileSlotRanges;
private final ArrayList<MutableTriple<IntSupplier, IntConsumer, Short>> shortValues;
private final ArrayList<MutableTriple<IntSupplier, IntConsumer, Integer>> integerValues;
private Integer[] integerParts;
public BuiltContainer(final Predicate<EntityPlayer> canInteract, final List<Range<Integer>> playerSlotRange, public BuiltContainer(final Predicate<EntityPlayer> canInteract, final List<Range<Integer>> playerSlotRange,
final List<Range<Integer>> tileSlotRange) { final List<Range<Integer>> tileSlotRange) {
this.canInteract = canInteract; this.canInteract = canInteract;
this.playerSlotRanges = playerSlotRange; this.playerSlotRanges = playerSlotRange;
this.tileSlotRanges = tileSlotRange; this.tileSlotRanges = tileSlotRange;
this.shortValues = new ArrayList<>();
this.integerValues = new ArrayList<>();
}
public void addShortSync(final List<Pair<IntSupplier, IntConsumer>> syncables) {
for (final Pair<IntSupplier, IntConsumer> syncable : syncables)
this.shortValues.add(MutableTriple.of(syncable.getLeft(), syncable.getRight(), (short) 0));
this.shortValues.trimToSize();
}
public void addIntegerSync(final List<Pair<IntSupplier, IntConsumer>> syncables) {
for (final Pair<IntSupplier, IntConsumer> syncable : syncables)
this.integerValues.add(MutableTriple.of(syncable.getLeft(), syncable.getRight(), 0));
this.integerValues.trimToSize();
this.integerParts = new Integer[this.integerValues.size()];
} }
public void addSlot(final Slot slot) { public void addSlot(final Slot slot) {
@ -35,6 +65,86 @@ final class BuiltContainer extends Container {
return this.canInteract.test(playerIn); return this.canInteract.test(playerIn);
} }
@Override
public void detectAndSendChanges() {
super.detectAndSendChanges();
for (final IContainerListener listener : this.listeners) {
int i = 0;
if (!this.shortValues.isEmpty())
for (final MutableTriple<IntSupplier, IntConsumer, Short> value : this.shortValues) {
final short supplied = (short) value.getLeft().getAsInt();
if (supplied != value.getRight()) {
listener.sendProgressBarUpdate(this, i, supplied);
value.setRight(supplied);
}
i++;
}
if (!this.integerValues.isEmpty())
for (final MutableTriple<IntSupplier, IntConsumer, Integer> value : this.integerValues) {
final int supplied = value.getLeft().getAsInt();
if (supplied != value.getRight()) {
listener.sendProgressBarUpdate(this, i, supplied >> 16);
listener.sendProgressBarUpdate(this, i + 1, (short) (supplied & 0xFFFF));
value.setRight(supplied);
}
i += 2;
}
}
}
@Override
public void addListener(final IContainerListener listener) {
super.addListener(listener);
int i = 0;
if (!this.shortValues.isEmpty())
for (final MutableTriple<IntSupplier, IntConsumer, Short> value : this.shortValues) {
final short supplied = (short) value.getLeft().getAsInt();
listener.sendProgressBarUpdate(this, i, supplied);
value.setRight(supplied);
i++;
}
if (!this.integerValues.isEmpty())
for (final MutableTriple<IntSupplier, IntConsumer, Integer> value : this.integerValues) {
final int supplied = value.getLeft().getAsInt();
listener.sendProgressBarUpdate(this, i, supplied >> 16);
listener.sendProgressBarUpdate(this, i + 1, (short) (supplied & 0xFFFF));
value.setRight(supplied);
i += 2;
}
}
@SideOnly(Side.CLIENT)
@Override
public void updateProgressBar(final int id, final int value) {
if(id < this.shortValues.size())
{
this.shortValues.get(id).getMiddle().accept((short) value);
this.shortValues.get(id).setRight((short) value);
}
else if (id - this.shortValues.size() < this.integerValues.size() * 2)
{
if ((id - this.shortValues.size()) % 2 == 0)
this.integerParts[(id - this.shortValues.size()) / 2] = value;
else
{
this.integerValues.get((id - this.shortValues.size()) / 2).getMiddle().accept(
(this.integerParts[(id - this.shortValues.size()) / 2] & 0xFFFF) << 16 | value & 0xFFFF);
}
}
}
@Override @Override
public ItemStack transferStackInSlot(final EntityPlayer player, final int index) { public ItemStack transferStackInSlot(final EntityPlayer player, final int index) {

View file

@ -1,6 +1,7 @@
package techreborn.client.container.builder; package techreborn.client.container.builder;
import org.apache.commons.lang3.Range; import org.apache.commons.lang3.Range;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
@ -9,6 +10,8 @@ import net.minecraft.inventory.Slot;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.IntConsumer;
import java.util.function.IntSupplier;
import java.util.function.Predicate; import java.util.function.Predicate;
public class ContainerBuilder { public class ContainerBuilder {
@ -17,10 +20,16 @@ public class ContainerBuilder {
final List<Slot> slots; final List<Slot> slots;
final List<Range<Integer>> playerInventoryRanges, tileInventoryRanges; final List<Range<Integer>> playerInventoryRanges, tileInventoryRanges;
final List<Pair<IntSupplier, IntConsumer>> shortValues;
final List<Pair<IntSupplier, IntConsumer>> integerValues;
public ContainerBuilder() { public ContainerBuilder() {
this.slots = new ArrayList<>(); this.slots = new ArrayList<>();
this.playerInventoryRanges = new ArrayList<>(); this.playerInventoryRanges = new ArrayList<>();
this.tileInventoryRanges = new ArrayList<>(); this.tileInventoryRanges = new ArrayList<>();
this.shortValues = new ArrayList<>();
this.integerValues = new ArrayList<>();
} }
public ContainerBuilder interact(final Predicate<EntityPlayer> canInteract) { public ContainerBuilder interact(final Predicate<EntityPlayer> canInteract) {
@ -47,6 +56,10 @@ public class ContainerBuilder {
public BuiltContainer create() { public BuiltContainer create() {
final BuiltContainer built = new BuiltContainer(this.canInteract, this.playerInventoryRanges, final BuiltContainer built = new BuiltContainer(this.canInteract, this.playerInventoryRanges,
this.tileInventoryRanges); this.tileInventoryRanges);
if (!this.shortValues.isEmpty())
built.addShortSync(this.shortValues);
if (!this.integerValues.isEmpty())
built.addIntegerSync(this.integerValues);
this.slots.forEach(built::addSlot); this.slots.forEach(built::addSlot);

View file

@ -1,6 +1,7 @@
package techreborn.client.container.builder; package techreborn.client.container.builder;
import org.apache.commons.lang3.Range; import org.apache.commons.lang3.Range;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.inventory.IInventory; import net.minecraft.inventory.IInventory;
@ -10,6 +11,9 @@ import reborncore.client.gui.slots.SlotOutput;
import techreborn.client.container.builder.slot.EnergyChargeSlot; import techreborn.client.container.builder.slot.EnergyChargeSlot;
import java.util.function.IntConsumer;
import java.util.function.IntSupplier;
public class ContainerTileInventoryBuilder { public class ContainerTileInventoryBuilder {
private final IInventory tile; private final IInventory tile;
@ -27,21 +31,47 @@ public class ContainerTileInventoryBuilder {
return this; return this;
} }
public ContainerTileInventoryBuilder output(final int index, final int x, final int y) { public ContainerTileInventoryBuilder outputSlot(final int index, final int x, final int y) {
this.parent.slots.add(new SlotOutput(this.tile, index, x, y)); this.parent.slots.add(new SlotOutput(this.tile, index, x, y));
return this; return this;
} }
public ContainerTileInventoryBuilder fake(final int index, final int x, final int y) { public ContainerTileInventoryBuilder fakeSlot(final int index, final int x, final int y) {
this.parent.slots.add(new SlotFake(this.tile, index, x, y, false, false, Integer.MAX_VALUE)); this.parent.slots.add(new SlotFake(this.tile, index, x, y, false, false, Integer.MAX_VALUE));
return this; return this;
} }
public ContainerTileInventoryBuilder energy(final int index, final int x, final int y) { public ContainerTileInventoryBuilder energySlot(final int index, final int x, final int y) {
this.parent.slots.add(new EnergyChargeSlot(this.tile, index, x, y)); this.parent.slots.add(new EnergyChargeSlot(this.tile, index, x, y));
return this; return this;
} }
/**
*
* @param supplier
* The supplier must supply a variable holding inside a Short, it
* will be truncated by force.
* @param setter
* The setter to call when the variable has been updated.
*/
public ContainerTileInventoryBuilder syncShortValue(final IntSupplier supplier, final IntConsumer setter) {
this.parent.shortValues.add(Pair.of(supplier, setter));
return this;
}
/**
*
* @param supplier
* The supplier it can supply a variable holding in an Integer it
* will be split inside multiples shorts.
* @param setter
* The setter to call when the variable has been updated.
*/
public ContainerTileInventoryBuilder syncIntegerValue(final IntSupplier supplier, final IntConsumer setter) {
this.parent.integerValues.add(Pair.of(supplier, setter));
return this;
}
public ContainerBuilder addInventory() { public ContainerBuilder addInventory() {
this.parent.tileInventoryRanges.add(Range.between(this.rangeStart, this.parent.slots.size() - 1)); this.parent.tileInventoryRanges.add(Range.between(this.rangeStart, this.parent.slots.size() - 1));
return this.parent; return this.parent;

View file

@ -16,8 +16,9 @@ public class GuiChargeBench extends GuiContainer {
public GuiChargeBench(final EntityPlayer player, final TileChargeBench tile) { public GuiChargeBench(final EntityPlayer player, final TileChargeBench tile) {
super(new ContainerBuilder().player(player.inventory).inventory(true).hotbar(true).addInventory().tile(tile) super(new ContainerBuilder().player(player.inventory).inventory(true).hotbar(true).addInventory().tile(tile)
.energy(0, 62, 21).energy(1, 80, 21).energy(2, 98, 21).energy(3, 62, 39).energy(4, 80, 39) .energySlot(0, 62, 21).energySlot(1, 80, 21).energySlot(2, 98, 21).energySlot(3, 62, 39).energySlot(4, 80, 39)
.energy(5, 98, 39).addInventory().create()); .energySlot(5, 98, 39).syncIntegerValue(() -> (int) tile.getEnergy(), tile::setEnergy).addInventory()
.create());
this.xSize = 176; this.xSize = 176;
this.ySize = 167; this.ySize = 167;
chargebench = tile; chargebench = tile;

View file

@ -10,7 +10,7 @@ public class GuiDigitalChest extends GuiBase {
TileDigitalChest tile; TileDigitalChest tile;
public GuiDigitalChest(final EntityPlayer player, final TileDigitalChest tile) { public GuiDigitalChest(final EntityPlayer player, final TileDigitalChest tile) {
super(player, tile, new ContainerBuilder().player(player.inventory).inventory().hotbar().addInventory().tile(tile).slot(0, 80, 20).output(1, 80, 70).fake(2, 80, 45).addInventory().create()); super(player, tile, new ContainerBuilder().player(player.inventory).inventory().hotbar().addInventory().tile(tile).slot(0, 80, 20).outputSlot(1, 80, 70).fakeSlot(2, 80, 45).addInventory().create());
this.tile = tile; this.tile = tile;
} }

View file

@ -20,7 +20,7 @@ public class GuiQuantumChest extends GuiContainer {
public GuiQuantumChest(final EntityPlayer player, final TileQuantumChest tile) { public GuiQuantumChest(final EntityPlayer player, final TileQuantumChest tile) {
super(new ContainerBuilder().player(player.inventory).inventory(true).hotbar(true).addInventory().tile(tile) super(new ContainerBuilder().player(player.inventory).inventory(true).hotbar(true).addInventory().tile(tile)
.slot(0, 80, 17).output(1, 80, 53).fake(2, 59, 42).addInventory().create()); .slot(0, 80, 17).outputSlot(1, 80, 53).fakeSlot(2, 59, 42).addInventory().create());
this.xSize = 176; this.xSize = 176;
this.ySize = 167; this.ySize = 167;
this.tile = tile; this.tile = tile;