From 28518eb816628e41b245ffeffda0a313f66d4baf Mon Sep 17 00:00:00 2001 From: Andrei Laiff Date: Thu, 12 Oct 2023 12:40:27 +0300 Subject: [PATCH] api: Add `LevelTerminalRegistry` functionality --- .../glodblock/github/api/FluidCraftAPI.java | 8 ++ .../glodblock/github/api/IFluidCraftAPI.java | 7 ++ .../java/com/glodblock/github/api/ISide.java | 8 ++ .../registries/ILevelTerminalRegistry.java | 20 ++++ .../github/api/registries/ILevelViewable.java | 53 +++++++++ .../api/registries/ILevelViewableAdapter.java | 8 ++ .../registries/LevelTerminalRegistry.java | 71 ++++++++++++ .../PartFluidLevelEmitterAdapter.java | 88 ++++++++++++++ .../adapters/PartLevelEmitterAdapter.java | 109 ++++++++++++++++++ 9 files changed, 372 insertions(+) create mode 100644 src/main/java/com/glodblock/github/api/ISide.java create mode 100644 src/main/java/com/glodblock/github/api/registries/ILevelTerminalRegistry.java create mode 100644 src/main/java/com/glodblock/github/api/registries/ILevelViewable.java create mode 100644 src/main/java/com/glodblock/github/api/registries/ILevelViewableAdapter.java create mode 100644 src/main/java/com/glodblock/github/coremod/registries/LevelTerminalRegistry.java create mode 100644 src/main/java/com/glodblock/github/coremod/registries/adapters/PartFluidLevelEmitterAdapter.java create mode 100644 src/main/java/com/glodblock/github/coremod/registries/adapters/PartLevelEmitterAdapter.java diff --git a/src/main/java/com/glodblock/github/api/FluidCraftAPI.java b/src/main/java/com/glodblock/github/api/FluidCraftAPI.java index fc2ea89c..00396424 100644 --- a/src/main/java/com/glodblock/github/api/FluidCraftAPI.java +++ b/src/main/java/com/glodblock/github/api/FluidCraftAPI.java @@ -5,6 +5,9 @@ import java.util.Set; import net.minecraftforge.fluids.Fluid; +import com.glodblock.github.api.registries.ILevelTerminalRegistry; +import com.glodblock.github.coremod.registries.LevelTerminalRegistry; + public final class FluidCraftAPI implements IFluidCraftAPI { private static final FluidCraftAPI API = new FluidCraftAPI(); @@ -42,4 +45,9 @@ public final class FluidCraftAPI implements IFluidCraftAPI { public boolean isBlacklistedInDisplay(Class fluid) { return blacklistedDispFluids.contains(fluid); } + + @Override + public ILevelTerminalRegistry levelTerminalRegistry() { + return LevelTerminalRegistry.instance(); + } } diff --git a/src/main/java/com/glodblock/github/api/IFluidCraftAPI.java b/src/main/java/com/glodblock/github/api/IFluidCraftAPI.java index fbf9e47d..07b0126f 100644 --- a/src/main/java/com/glodblock/github/api/IFluidCraftAPI.java +++ b/src/main/java/com/glodblock/github/api/IFluidCraftAPI.java @@ -2,6 +2,8 @@ package com.glodblock.github.api; import net.minecraftforge.fluids.Fluid; +import com.glodblock.github.api.registries.ILevelTerminalRegistry; + @SuppressWarnings("unused") public interface IFluidCraftAPI { @@ -24,4 +26,9 @@ public interface IFluidCraftAPI { * Mostly for internal use; queries whether the fluid is blacklisted from being displayed. */ boolean isBlacklistedInDisplay(Class fluid); + + /** + * Get instance of `ILevelTerminalRegistry` to add new supported machines into terminal + */ + ILevelTerminalRegistry levelTerminalRegistry(); } diff --git a/src/main/java/com/glodblock/github/api/ISide.java b/src/main/java/com/glodblock/github/api/ISide.java new file mode 100644 index 00000000..3fade747 --- /dev/null +++ b/src/main/java/com/glodblock/github/api/ISide.java @@ -0,0 +1,8 @@ +package com.glodblock.github.api; + +import net.minecraftforge.common.util.ForgeDirection; + +public interface ISide { + + ForgeDirection getSide(); +} diff --git a/src/main/java/com/glodblock/github/api/registries/ILevelTerminalRegistry.java b/src/main/java/com/glodblock/github/api/registries/ILevelTerminalRegistry.java new file mode 100644 index 00000000..d00c4d16 --- /dev/null +++ b/src/main/java/com/glodblock/github/api/registries/ILevelTerminalRegistry.java @@ -0,0 +1,20 @@ +package com.glodblock.github.api.registries; + +import java.util.Set; + +import appeng.api.networking.IGridHost; + +public interface ILevelTerminalRegistry { + + void register(Class clazz); + + void register(Class aeClass, ILevelViewableAdapter adapter); + + Set> getSupportedClasses(); + + boolean isAdopted(Class clazz); + + Class getAdopted(Class clazz); + + ILevelViewableAdapter getAdapter(Class clazz); +} diff --git a/src/main/java/com/glodblock/github/api/registries/ILevelViewable.java b/src/main/java/com/glodblock/github/api/registries/ILevelViewable.java new file mode 100644 index 00000000..2f192602 --- /dev/null +++ b/src/main/java/com/glodblock/github/api/registries/ILevelViewable.java @@ -0,0 +1,53 @@ +package com.glodblock.github.api.registries; + +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; + +import com.glodblock.github.api.ISide; + +import appeng.api.implementations.tiles.ISegmentedInventory; +import appeng.api.networking.IGridHost; +import appeng.api.util.DimensionalCoord; +import appeng.helpers.ICustomNameObject; + +public interface ILevelViewable extends IGridHost, ISide, ISegmentedInventory, ICustomNameObject { + + DimensionalCoord getLocation(); + + TileEntity getTile(); + + default long getSortValue() { + TileEntity te = getTile(); + return ((long) te.zCoord << 24) ^ ((long) te.xCoord << 8) ^ te.yCoord; + } + + default boolean shouldDisplay() { + return true; + } + + /** + * Number of rows to expect. This is used with {@link #rowSize()} to determine how to render the slots. + */ + default int rows() { + return 1; + }; + + /** + * Number of slots per row. + */ + default int rowSize() { + return 1; + }; + + default ItemStack getSelfItemStack() { + return null; + } + + /** + * "Target" Display representation + */ + default ItemStack getDisplayItemStack() { + return null; + } + +} diff --git a/src/main/java/com/glodblock/github/api/registries/ILevelViewableAdapter.java b/src/main/java/com/glodblock/github/api/registries/ILevelViewableAdapter.java new file mode 100644 index 00000000..890b3f77 --- /dev/null +++ b/src/main/java/com/glodblock/github/api/registries/ILevelViewableAdapter.java @@ -0,0 +1,8 @@ +package com.glodblock.github.api.registries; + +import appeng.api.networking.IGridHost; + +public interface ILevelViewableAdapter extends ILevelViewable { + + ILevelViewable adapt(IGridHost gridHost); +} diff --git a/src/main/java/com/glodblock/github/coremod/registries/LevelTerminalRegistry.java b/src/main/java/com/glodblock/github/coremod/registries/LevelTerminalRegistry.java new file mode 100644 index 00000000..326cda9d --- /dev/null +++ b/src/main/java/com/glodblock/github/coremod/registries/LevelTerminalRegistry.java @@ -0,0 +1,71 @@ +package com.glodblock.github.coremod.registries; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; + +import com.glodblock.github.api.registries.ILevelTerminalRegistry; +import com.glodblock.github.api.registries.ILevelViewable; +import com.glodblock.github.api.registries.ILevelViewableAdapter; +import com.glodblock.github.common.parts.PartFluidLevelEmitter; +import com.glodblock.github.common.tile.TileLevelMaintainer; +import com.glodblock.github.coremod.registries.adapters.PartFluidLevelEmitterAdapter; +import com.glodblock.github.coremod.registries.adapters.PartLevelEmitterAdapter; + +import appeng.api.networking.IGridHost; +import appeng.parts.automation.PartLevelEmitter; + +public class LevelTerminalRegistry implements ILevelTerminalRegistry { + + private final Set> supportedClasses = new HashSet<>(); + private final Map, Class> adapterMap = new WeakHashMap<>(); + private final Map, ILevelViewableAdapter> adapterInstanceMap = new WeakHashMap<>(); + + private static class Singleton { + + private static final ILevelTerminalRegistry INSTANCE = new LevelTerminalRegistry(); + } + + { + this.register(TileLevelMaintainer.class); + this.register(PartFluidLevelEmitter.class, new PartFluidLevelEmitterAdapter()); + this.register(PartLevelEmitter.class, new PartLevelEmitterAdapter()); + } + + public Set> getSupportedClasses() { + return supportedClasses; + } + + @Override + public boolean isAdopted(Class clazz) { + return adapterMap.containsKey(clazz); + } + + @Override + public Class getAdopted(Class clazz) { + return adapterMap.getOrDefault(clazz, null); + } + + @Override + public ILevelViewableAdapter getAdapter(Class clazz) { + return adapterInstanceMap.getOrDefault(clazz, null); + } + + public static ILevelTerminalRegistry instance() { + return Singleton.INSTANCE; + } + + @Override + public void register(Class clazz) { + supportedClasses.add(clazz); + } + + @Override + public void register(Class aeClass, ILevelViewableAdapter adapter) { + var aClass = adapter.getClass(); + supportedClasses.add(aClass); + adapterMap.put(aClass, aeClass); + adapterInstanceMap.put(aClass, adapter); + } +} diff --git a/src/main/java/com/glodblock/github/coremod/registries/adapters/PartFluidLevelEmitterAdapter.java b/src/main/java/com/glodblock/github/coremod/registries/adapters/PartFluidLevelEmitterAdapter.java new file mode 100644 index 00000000..b8aad794 --- /dev/null +++ b/src/main/java/com/glodblock/github/coremod/registries/adapters/PartFluidLevelEmitterAdapter.java @@ -0,0 +1,88 @@ +package com.glodblock.github.coremod.registries.adapters; + +import static com.glodblock.github.coremod.registries.adapters.PartLevelEmitterAdapter.getPatchedInventory; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.ForgeDirection; + +import com.glodblock.github.api.registries.ILevelViewable; +import com.glodblock.github.api.registries.ILevelViewableAdapter; +import com.glodblock.github.common.parts.PartFluidLevelEmitter; +import com.glodblock.github.common.tile.TileLevelMaintainer.State; + +import appeng.api.networking.IGridHost; +import appeng.api.networking.IGridNode; +import appeng.api.util.AECableType; +import appeng.api.util.DimensionalCoord; + +public class PartFluidLevelEmitterAdapter implements ILevelViewable, ILevelViewableAdapter { + + private PartFluidLevelEmitter delegate; + + public PartFluidLevelEmitterAdapter() {} + + public ILevelViewable adapt(IGridHost gridHost) { + if (gridHost instanceof PartFluidLevelEmitter levelEmitter) this.delegate = levelEmitter; + return this; + }; + + @Override + public DimensionalCoord getLocation() { + return delegate.getLocation(); + } + + @Override + public TileEntity getTile() { + return delegate.getTile(); + } + + @Override + public ForgeDirection getSide() { + return delegate.getSide(); + } + + @Override + public IInventory getInventoryByName(String name) { + long value = delegate.getReportingValue(); + State state = delegate.isProvidingStrongPower() > 0 ? State.Craft : State.Idle; + + return getPatchedInventory(delegate.getInventoryByName(name), value, state); + } + + @Override + public IGridNode getGridNode(ForgeDirection dir) { + return delegate.getGridNode(dir); + } + + @Override + public AECableType getCableConnectionType(ForgeDirection dir) { + return delegate.getCableConnectionType(dir); + } + + @Override + public void securityBreak() { + delegate.securityBreak(); + } + + @Override + public String getCustomName() { + return delegate.getCustomName(); + } + + @Override + public boolean hasCustomName() { + return delegate.hasCustomName(); + } + + @Override + public void setCustomName(String name) { + delegate.hasCustomName(); + } + + @Override + public ItemStack getSelfItemStack() { + return delegate.getItemStack(); + } +} diff --git a/src/main/java/com/glodblock/github/coremod/registries/adapters/PartLevelEmitterAdapter.java b/src/main/java/com/glodblock/github/coremod/registries/adapters/PartLevelEmitterAdapter.java new file mode 100644 index 00000000..a8bdb45d --- /dev/null +++ b/src/main/java/com/glodblock/github/coremod/registries/adapters/PartLevelEmitterAdapter.java @@ -0,0 +1,109 @@ +package com.glodblock.github.coremod.registries.adapters; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.ForgeDirection; + +import org.jetbrains.annotations.NotNull; + +import com.glodblock.github.api.registries.ILevelViewable; +import com.glodblock.github.api.registries.ILevelViewableAdapter; +import com.glodblock.github.common.tile.TileLevelMaintainer.State; +import com.glodblock.github.common.tile.TileLevelMaintainer.TLMTags; + +import appeng.api.networking.IGridHost; +import appeng.api.networking.IGridNode; +import appeng.api.util.AECableType; +import appeng.api.util.DimensionalCoord; +import appeng.parts.automation.PartLevelEmitter; + +public class PartLevelEmitterAdapter implements ILevelViewable, ILevelViewableAdapter { + + private PartLevelEmitter delegate; + + private static final int SLOT_IN = 0; + + public PartLevelEmitterAdapter() {} + + public ILevelViewable adapt(IGridHost gridHost) { + if (gridHost instanceof PartLevelEmitter levelEmitter) this.delegate = levelEmitter; + return this; + }; + + @NotNull + static public IInventory getPatchedInventory(IInventory inventory, long value, State state) { + ItemStack itemStack = inventory.getStackInSlot(SLOT_IN).copy(); + NBTTagCompound data = !itemStack.hasTagCompound() ? new NBTTagCompound() : itemStack.getTagCompound(); + data.setLong(TLMTags.Quantity.tagName, value); + data.setInteger(TLMTags.State.tagName, state.ordinal()); + itemStack.setTagCompound(data); + inventory.setInventorySlotContents(SLOT_IN, itemStack); + + return inventory; + } + + @Override + public DimensionalCoord getLocation() { + return delegate.getLocation(); + } + + @Override + public TileEntity getTile() { + return delegate.getTile(); + } + + @Override + public IInventory getInventoryByName(String name) { + long value = delegate.getReportingValue(); + State state = delegate.isProvidingStrongPower() > 0 ? State.Craft : State.Idle; + + return getPatchedInventory(delegate.getInventoryByName(name), value, state); + } + + @Override + public IGridNode getGridNode(ForgeDirection dir) { + return delegate.getGridNode(dir); + } + + @Override + public AECableType getCableConnectionType(ForgeDirection dir) { + return delegate.getCableConnectionType(dir); + } + + @Override + public ForgeDirection getSide() { + return delegate.getSide(); + } + + @Override + public void securityBreak() { + delegate.securityBreak(); + } + + @Override + public String getCustomName() { + return delegate.getCustomName(); + } + + @Override + public boolean hasCustomName() { + return delegate.hasCustomName(); + } + + @Override + public void setCustomName(String name) { + delegate.hasCustomName(); + } + + @Override + public ItemStack getSelfItemStack() { + return delegate.getItemStack(); + } + + @Override + public ItemStack getDisplayItemStack() { + return delegate.getCrafterIcon(); + } +}