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.ContainerOpenContext;
|
||||
import appeng.container.implementations.*;
|
||||
import appeng.container.interfaces.IInventorySlotAware;
|
||||
import appeng.fluids.container.*;
|
||||
import appeng.fluids.helper.IFluidInterfaceHost;
|
||||
import appeng.fluids.parts.PartFluidFormationPlane;
|
||||
@@ -59,11 +58,20 @@ import appeng.parts.automation.PartFormationPlane;
|
||||
import appeng.parts.automation.PartLevelEmitter;
|
||||
import appeng.parts.misc.PartOreDicStorageBus;
|
||||
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.TileMolecularAssembler;
|
||||
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.qnb.TileQuantumBridge;
|
||||
import appeng.tile.spatial.TileSpatialIOPort;
|
||||
@@ -185,6 +193,7 @@ public enum GuiBridge implements IGuiHandler {
|
||||
private Class guiClass;
|
||||
private GuiHostType type;
|
||||
private SecurityPermissions requiredPermission;
|
||||
private GuiWrapper.IExternalGui externalGui = null;
|
||||
|
||||
GuiBridge() {
|
||||
this.tileClass = null;
|
||||
@@ -192,6 +201,16 @@ public enum GuiBridge implements IGuiHandler {
|
||||
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) {
|
||||
this.requiredPermission = requiredPermission;
|
||||
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.sync.GuiBridge;
|
||||
import appeng.core.sync.GuiHostType;
|
||||
import appeng.core.sync.GuiWrapper;
|
||||
import appeng.fluids.util.AEFluidStack;
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.integration.Integrations;
|
||||
@@ -323,6 +324,20 @@ public class Platform {
|
||||
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 y = 0;
|
||||
int z = Integer.MIN_VALUE;
|
||||
@@ -360,6 +375,20 @@ public class Platform {
|
||||
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()) {
|
||||
p.openGui(AppEng.instance(), type.ordinal() << 4, p.getEntityWorld(), slot, isBauble ? 1 : 0, Integer.MIN_VALUE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user