Allow third-party addons to register custom GUIs via GuiBridge (#402)
This commit is contained in:
@@ -43,7 +43,6 @@ import appeng.container.AEBaseContainer;
|
|||||||
import appeng.container.ContainerNull;
|
import appeng.container.ContainerNull;
|
||||||
import appeng.container.ContainerOpenContext;
|
import appeng.container.ContainerOpenContext;
|
||||||
import appeng.container.implementations.*;
|
import appeng.container.implementations.*;
|
||||||
import appeng.container.interfaces.IInventorySlotAware;
|
|
||||||
import appeng.fluids.container.*;
|
import appeng.fluids.container.*;
|
||||||
import appeng.fluids.helper.IFluidInterfaceHost;
|
import appeng.fluids.helper.IFluidInterfaceHost;
|
||||||
import appeng.fluids.parts.PartFluidFormationPlane;
|
import appeng.fluids.parts.PartFluidFormationPlane;
|
||||||
@@ -59,11 +58,20 @@ import appeng.parts.automation.PartFormationPlane;
|
|||||||
import appeng.parts.automation.PartLevelEmitter;
|
import appeng.parts.automation.PartLevelEmitter;
|
||||||
import appeng.parts.misc.PartOreDicStorageBus;
|
import appeng.parts.misc.PartOreDicStorageBus;
|
||||||
import appeng.parts.misc.PartStorageBus;
|
import appeng.parts.misc.PartStorageBus;
|
||||||
import appeng.parts.reporting.*;
|
import appeng.parts.reporting.PartCraftingTerminal;
|
||||||
|
import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
|
||||||
|
import appeng.parts.reporting.PartFluidInterfaceConfigurationTerminal;
|
||||||
|
import appeng.parts.reporting.PartInterfaceConfigurationTerminal;
|
||||||
|
import appeng.parts.reporting.PartInterfaceTerminal;
|
||||||
|
import appeng.parts.reporting.PartPatternTerminal;
|
||||||
import appeng.tile.crafting.TileCraftingTile;
|
import appeng.tile.crafting.TileCraftingTile;
|
||||||
import appeng.tile.crafting.TileMolecularAssembler;
|
import appeng.tile.crafting.TileMolecularAssembler;
|
||||||
import appeng.tile.grindstone.TileGrinder;
|
import appeng.tile.grindstone.TileGrinder;
|
||||||
import appeng.tile.misc.*;
|
import appeng.tile.misc.TileCellWorkbench;
|
||||||
|
import appeng.tile.misc.TileCondenser;
|
||||||
|
import appeng.tile.misc.TileInscriber;
|
||||||
|
import appeng.tile.misc.TileSecurityStation;
|
||||||
|
import appeng.tile.misc.TileVibrationChamber;
|
||||||
import appeng.tile.networking.TileWireless;
|
import appeng.tile.networking.TileWireless;
|
||||||
import appeng.tile.qnb.TileQuantumBridge;
|
import appeng.tile.qnb.TileQuantumBridge;
|
||||||
import appeng.tile.spatial.TileSpatialIOPort;
|
import appeng.tile.spatial.TileSpatialIOPort;
|
||||||
@@ -185,6 +193,7 @@ public enum GuiBridge implements IGuiHandler {
|
|||||||
private Class guiClass;
|
private Class guiClass;
|
||||||
private GuiHostType type;
|
private GuiHostType type;
|
||||||
private SecurityPermissions requiredPermission;
|
private SecurityPermissions requiredPermission;
|
||||||
|
private GuiWrapper.IExternalGui externalGui = null;
|
||||||
|
|
||||||
GuiBridge() {
|
GuiBridge() {
|
||||||
this.tileClass = null;
|
this.tileClass = null;
|
||||||
@@ -192,6 +201,16 @@ public enum GuiBridge implements IGuiHandler {
|
|||||||
this.containerClass = null;
|
this.containerClass = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GuiBridge(GuiWrapper.IExternalGui obj) {
|
||||||
|
this.tileClass = null;
|
||||||
|
this.containerClass = null;
|
||||||
|
this.externalGui = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GuiWrapper.IExternalGui getExternalGui() {
|
||||||
|
return this.externalGui;
|
||||||
|
}
|
||||||
|
|
||||||
GuiBridge(final Class containerClass, final SecurityPermissions requiredPermission) {
|
GuiBridge(final Class containerClass, final SecurityPermissions requiredPermission) {
|
||||||
this.requiredPermission = requiredPermission;
|
this.requiredPermission = requiredPermission;
|
||||||
this.containerClass = containerClass;
|
this.containerClass = containerClass;
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package appeng.core.sync;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.Hash;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.common.util.EnumHelper;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow to register custom GuiBridge from third-party
|
||||||
|
*/
|
||||||
|
public class GuiWrapper {
|
||||||
|
|
||||||
|
public static final GuiWrapper INSTANCE = new GuiWrapper();
|
||||||
|
|
||||||
|
private GuiWrapper() {
|
||||||
|
// NO-OP
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Object2ObjectMap<ResourceLocation, Opener> openers = new Object2ObjectOpenHashMap<>();
|
||||||
|
private final Object2ObjectMap<IExternalGui, GuiBridge> externalGuis = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy<IExternalGui>() {
|
||||||
|
@Override
|
||||||
|
public int hashCode(IExternalGui o) {
|
||||||
|
return o.getID().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable IExternalGui a, @Nullable IExternalGui b) {
|
||||||
|
return a == b || (a != null && b != null && a.getID().equals(b.getID()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
public synchronized void registerExternalGuiHandler(@Nonnull ResourceLocation id, @Nonnull Opener opener) {
|
||||||
|
openers.put(id, opener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Opener getOpener(ResourceLocation id) {
|
||||||
|
return openers.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GuiBridge wrap(IExternalGui obj) {
|
||||||
|
return externalGuis.computeIfAbsent(obj, this::create);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GuiBridge create(IExternalGui obj) {
|
||||||
|
return EnumHelper.addEnum(GuiBridge.class, obj.getID().toString(), new Class<?>[] {IExternalGui.class}, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Opener {
|
||||||
|
|
||||||
|
<T extends IExternalGui> void open(T obj, GuiContext context);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IExternalGui {
|
||||||
|
|
||||||
|
ResourceLocation getID();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GuiContext {
|
||||||
|
|
||||||
|
public final World world;
|
||||||
|
public final EntityPlayer player;
|
||||||
|
public final BlockPos pos;
|
||||||
|
public final EnumFacing facing;
|
||||||
|
public final NBTTagCompound extra;
|
||||||
|
|
||||||
|
public GuiContext(World world, EntityPlayer player, BlockPos pos, EnumFacing face, NBTTagCompound extra) {
|
||||||
|
this.world = world;
|
||||||
|
this.player = player;
|
||||||
|
this.pos = pos;
|
||||||
|
this.facing = face;
|
||||||
|
this.extra = extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -53,6 +53,7 @@ import appeng.core.features.AEFeature;
|
|||||||
import appeng.core.stats.Stats;
|
import appeng.core.stats.Stats;
|
||||||
import appeng.core.sync.GuiBridge;
|
import appeng.core.sync.GuiBridge;
|
||||||
import appeng.core.sync.GuiHostType;
|
import appeng.core.sync.GuiHostType;
|
||||||
|
import appeng.core.sync.GuiWrapper;
|
||||||
import appeng.fluids.util.AEFluidStack;
|
import appeng.fluids.util.AEFluidStack;
|
||||||
import appeng.hooks.TickHandler;
|
import appeng.hooks.TickHandler;
|
||||||
import appeng.integration.Integrations;
|
import appeng.integration.Integrations;
|
||||||
@@ -323,6 +324,20 @@ public class Platform {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type.getExternalGui() != null) {
|
||||||
|
GuiWrapper.IExternalGui obj = type.getExternalGui();
|
||||||
|
GuiWrapper.Opener opener = GuiWrapper.INSTANCE.getOpener(obj.getID());
|
||||||
|
if (opener == null) {
|
||||||
|
AELog.warn("External Gui with ID: %s is missing a opener.", obj.getID());
|
||||||
|
} else {
|
||||||
|
World world = tile == null ? p.world : tile.getWorld();
|
||||||
|
BlockPos pos = tile == null ? null : tile.getPos();
|
||||||
|
EnumFacing face = side == null ? null : side.getFacing();
|
||||||
|
opener.open(obj, new GuiWrapper.GuiContext(world, p, pos, face, null));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
int z = Integer.MIN_VALUE;
|
int z = Integer.MIN_VALUE;
|
||||||
@@ -360,6 +375,20 @@ public class Platform {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type.getExternalGui() != null) {
|
||||||
|
GuiWrapper.IExternalGui obj = type.getExternalGui();
|
||||||
|
GuiWrapper.Opener opener = GuiWrapper.INSTANCE.getOpener(obj.getID());
|
||||||
|
if (opener == null) {
|
||||||
|
AELog.warn("External Gui with ID: %s is missing a opener.", obj.getID());
|
||||||
|
} else {
|
||||||
|
NBTTagCompound extra = new NBTTagCompound();
|
||||||
|
extra.setInteger("slot", slot);
|
||||||
|
extra.setBoolean("isBauble", isBauble);
|
||||||
|
opener.open(obj, new GuiWrapper.GuiContext(p.world, p, null, null, extra));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (type.getType().isItem()) {
|
if (type.getType().isItem()) {
|
||||||
p.openGui(AppEng.instance(), type.ordinal() << 4, p.getEntityWorld(), slot, isBauble ? 1 : 0, Integer.MIN_VALUE);
|
p.openGui(AppEng.instance(), type.ordinal() << 4, p.getEntityWorld(), slot, isBauble ? 1 : 0, Integer.MIN_VALUE);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user