Remove Non-HolderLookup methods from INBTSerializeable and mark it as deprecated in favor of using Vanilla's new Component system. Closes #9998

This commit is contained in:
LexManos committed 2024-06-13 13:17:03 -07:00
1 parent 4a2db246e0
commit 387441c045
11 files changed
+97 -214

No files matched your search

@@ -16,6 +16,7 @@ import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.common.util.LazyOptional;
@@ -33,42 +34,36 @@ import org.jetbrains.annotations.Nullable;
*/
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public final class CapabilityDispatcher implements INBTSerializable<CompoundTag>, ICapabilityProvider
{
@SuppressWarnings("deprecation")
public final class CapabilityDispatcher implements INBTSerializable<CompoundTag>, ICapabilityProvider {
private final ICapabilityProvider[] caps;
private final INBTSerializable<Tag>[] writers;
private final String[] names;
private final List<Runnable> listeners;
public CapabilityDispatcher(Map<ResourceLocation, ICapabilityProvider> list, List<Runnable> listeners)
{
public CapabilityDispatcher(Map<ResourceLocation, ICapabilityProvider> list, List<Runnable> listeners) {
this(list, listeners, null);
}
@SuppressWarnings("unchecked")
public CapabilityDispatcher(Map<ResourceLocation, ICapabilityProvider> list, List<Runnable> listeners, @Nullable ICapabilityProvider parent)
{
public CapabilityDispatcher(Map<ResourceLocation, ICapabilityProvider> list, List<Runnable> listeners, @Nullable ICapabilityProvider parent) {
List<ICapabilityProvider> lstCaps = new ArrayList<>();
List<INBTSerializable<Tag>> lstWriters = new ArrayList<>();
List<String> lstNames = new ArrayList<>();
this.listeners = listeners;
if (parent != null) // Parents go first!
{
if (parent != null) { // Parents go first!
lstCaps.add(parent);
if (parent instanceof INBTSerializable)
{
if (parent instanceof INBTSerializable) {
lstWriters.add((INBTSerializable<Tag>)parent);
lstNames.add("Parent");
}
}
for (Map.Entry<ResourceLocation, ICapabilityProvider> entry : list.entrySet())
{
for (var entry : list.entrySet()) {
ICapabilityProvider prov = entry.getValue();
lstCaps.add(prov);
if (prov instanceof INBTSerializable)
{
if (prov instanceof INBTSerializable) {
lstWriters.add((INBTSerializable<Tag>)prov);
lstNames.add(entry.getKey().toString());
}
@@ -81,14 +76,11 @@ public final class CapabilityDispatcher implements INBTSerializable<CompoundTag>
@Override
public <T> LazyOptional<T> getCapability(Capability<T> cap, @Nullable Direction side)
{
for (ICapabilityProvider c : caps)
{
public <T> LazyOptional<T> getCapability(Capability<T> cap, @Nullable Direction side) {
for (ICapabilityProvider c : caps) {
LazyOptional<T> ret = c.getCapability(cap, side);
//noinspection ConstantConditions
if (ret == null)
{
if (ret == null) {
throw new RuntimeException(
String.format(
Locale.ENGLISH,
@@ -97,46 +89,31 @@ public final class CapabilityDispatcher implements INBTSerializable<CompoundTag>
)
);
}
if (ret.isPresent())
{
return ret;
}
}
return LazyOptional.empty();
}
@Override
public CompoundTag serializeNBT()
{
public CompoundTag serializeNBT(HolderLookup.Provider registryAccess) {
CompoundTag nbt = new CompoundTag();
for (int x = 0; x < writers.length; x++)
{
nbt.put(names[x], writers[x].serializeNBT());
}
nbt.put(names[x], writers[x].serializeNBT(registryAccess));
return nbt;
}
@Override
public void deserializeNBT(CompoundTag nbt)
{
for (int x = 0; x < writers.length; x++)
{
public void deserializeNBT(HolderLookup.Provider registryAccess, CompoundTag nbt) {
for (int x = 0; x < writers.length; x++) {
if (nbt.contains(names[x]))
{
writers[x].deserializeNBT(nbt.get(names[x]));
}
writers[x].deserializeNBT(registryAccess, nbt.get(names[x]));
}
}
public boolean areCompatible(@Nullable CapabilityDispatcher other) //Called from ItemStack to compare equality.
{ // Only compares serializeable caps.
if (other == null) return this.writers.length == 0; // Done this way so we can do some pre-checks before doing the costly NBT serialization and compare
if (this.writers.length == 0) return other.writers.length == 0;
return this.serializeNBT().equals(other.serializeNBT());
}
public void invalidate()
{
public void invalidate() {
this.listeners.forEach(Runnable::run);
}
}
@@ -10,6 +10,7 @@ import javax.annotation.ParametersAreNonnullByDefault;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.event.ForgeEventFactory;
@@ -21,8 +22,7 @@ import java.util.function.Supplier;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public abstract class CapabilityProvider<B extends ICapabilityProviderImpl<B>> implements ICapabilityProviderImpl<B>
{
public abstract class CapabilityProvider<B extends ICapabilityProviderImpl<B>> implements ICapabilityProviderImpl<B> {
@VisibleForTesting
static boolean SUPPORTS_LAZY_CAPABILITIES = true;
@@ -33,33 +33,28 @@ public abstract class CapabilityProvider<B extends ICapabilityProviderImpl<B>> i
private boolean isLazy = false;
private Supplier<ICapabilityProvider> lazyParentSupplier = null;
private CompoundTag lazyData = null;
private HolderLookup.Provider registryAccess = null;
private boolean initialized = false;
protected CapabilityProvider(Class<B> baseClass)
{
protected CapabilityProvider(Class<B> baseClass) {
this(baseClass, false);
}
protected CapabilityProvider(final Class<B> baseClass, final boolean isLazy)
{
protected CapabilityProvider(final Class<B> baseClass, final boolean isLazy) {
this.baseClass = baseClass;
this.isLazy = SUPPORTS_LAZY_CAPABILITIES && isLazy;
}
protected final void gatherCapabilities()
{
protected final void gatherCapabilities() {
gatherCapabilities(() -> null);
}
protected final void gatherCapabilities(@Nullable ICapabilityProvider parent)
{
protected final void gatherCapabilities(@Nullable ICapabilityProvider parent) {
gatherCapabilities(() -> parent);
}
protected final void gatherCapabilities(@Nullable Supplier<ICapabilityProvider> parent)
{
if (isLazy && !initialized)
{
protected final void gatherCapabilities(@Nullable Supplier<ICapabilityProvider> parent) {
if (isLazy && !initialized) {
lazyParentSupplier = parent == null ? () -> null : parent;
return;
}
@@ -67,86 +62,51 @@ public abstract class CapabilityProvider<B extends ICapabilityProviderImpl<B>> i
doGatherCapabilities(parent == null ? null : parent.get());
}
private void doGatherCapabilities(@Nullable ICapabilityProvider parent)
{
private void doGatherCapabilities(@Nullable ICapabilityProvider parent) {
this.capabilities = ForgeEventFactory.gatherCapabilities(baseClass, getProvider(), parent);
this.initialized = true;
}
@SuppressWarnings("unchecked")
@NotNull
B getProvider()
{
B getProvider() {
return (B)this;
}
protected final @Nullable CapabilityDispatcher getCapabilities()
{
if (isLazy && !initialized)
{
protected final @Nullable CapabilityDispatcher getCapabilities() {
if (isLazy && !initialized) {
doGatherCapabilities(lazyParentSupplier == null ? null : lazyParentSupplier.get());
if (lazyData != null)
{
deserializeCaps(lazyData);
}
deserializeCaps(registryAccess, lazyData);
}
return capabilities;
}
public final boolean areCapsCompatible(CapabilityProvider<B> other)
{
return areCapsCompatible(other.getCapabilities());
}
public final boolean areCapsCompatible(@Nullable CapabilityDispatcher other)
{
final CapabilityDispatcher disp = getCapabilities();
if (disp == null)
{
if (other == null)
{
return true;
}
else
{
return other.areCompatible(null);
}
}
else
{
return disp.areCompatible(other);
}
}
protected final @Nullable CompoundTag serializeCaps()
{
protected final @Nullable CompoundTag serializeCaps(HolderLookup.Provider registryAccess) {
if (isLazy && !initialized)
{
return lazyData;
}
final CapabilityDispatcher disp = getCapabilities();
var disp = getCapabilities();
if (disp != null)
{
return disp.serializeNBT();
}
return disp.serializeNBT(registryAccess);
return null;
}
protected final void deserializeCaps(CompoundTag tag)
{
if (isLazy && !initialized)
{
lazyData = tag;
protected final void deserializeCaps(HolderLookup.Provider registryAccess, CompoundTag tag) {
if (isLazy && !initialized) {
this.lazyData = tag;
this.registryAccess = registryAccess;
return;
}
final CapabilityDispatcher disp = getCapabilities();
var disp = getCapabilities();
if (disp != null)
{
disp.deserializeNBT(tag);
}
disp.deserializeNBT(registryAccess, tag);
this.lazyData = null;
this.registryAccess = null;
}
/*
@@ -157,8 +117,7 @@ public abstract class CapabilityProvider<B extends ICapabilityProviderImpl<B>> i
* when they are finished.
* Be sure to make your invalidate callbaks recursion safe.
*/
public void invalidateCaps()
{
public void invalidateCaps() {
this.valid = false;
final CapabilityDispatcher disp = getCapabilities();
if (disp != null)
@@ -170,15 +129,13 @@ public abstract class CapabilityProvider<B extends ICapabilityProviderImpl<B>> i
* Modders can use this if they need to copy caps from one removed provider to a new one.
* It is expected the modders who call this function, then call invalidateCaps() to invalidate the provider again.
*/
public void reviveCaps()
{
public void reviveCaps() {
this.valid = true; //Stupid players don't copy the entity when transporting across worlds.
}
@Override
@NotNull
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side)
{
public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
final CapabilityDispatcher disp = getCapabilities();
return !valid || disp == null ? LazyOptional.empty() : disp.getCapability(cap, side);
}
@@ -187,42 +144,35 @@ public abstract class CapabilityProvider<B extends ICapabilityProviderImpl<B>> i
* Special implementation for cases which have a superclass and can't extend CapabilityProvider directly.
* See {@link LevelChunk}
*/
public static class AsField<B extends ICapabilityProviderImpl<B>> extends CapabilityProvider<B>
{
public static class AsField<B extends ICapabilityProviderImpl<B>> extends CapabilityProvider<B> {
private final B owner;
public AsField(Class<B> baseClass, B owner)
{
public AsField(Class<B> baseClass, B owner) {
super(baseClass);
this.owner = owner;
}
public AsField(Class<B> baseClass, B owner, boolean isLazy)
{
public AsField(Class<B> baseClass, B owner, boolean isLazy) {
super(baseClass, isLazy);
this.owner = owner;
}
public void initInternal()
{
public void initInternal() {
gatherCapabilities();
}
@Nullable
public CompoundTag serializeInternal()
{
return serializeCaps();
public CompoundTag serializeInternal(HolderLookup.Provider registryAccess) {
return serializeCaps(registryAccess);
}
public void deserializeInternal(CompoundTag tag)
{
deserializeCaps(tag);
public void deserializeInternal(HolderLookup.Provider registryAccess, CompoundTag tag) {
deserializeCaps(registryAccess, tag);
}
@Override
@NotNull
B getProvider()
{
B getProvider() {
return owner;
}
};
@@ -6,13 +6,9 @@
package net.minecraftforge.common.capabilities;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
@ApiStatus.Internal // Modders should use ICapabilityProvider, this is for Forge
public interface ICapabilityProviderImpl<B extends ICapabilityProviderImpl<B>> extends ICapabilityProvider
{
boolean areCapsCompatible(CapabilityProvider<B> other);
boolean areCapsCompatible(@Nullable CapabilityDispatcher other);
public interface ICapabilityProviderImpl<B extends ICapabilityProviderImpl<B>> extends ICapabilityProvider {
void invalidateCaps();
void reviveCaps();
}
@@ -20,6 +20,7 @@ import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.HitResult;
import net.minecraftforge.common.ForgeSpawnEggItem;
@@ -34,11 +35,13 @@ public interface IForgeEntity extends ICapabilitySerializable<CompoundTag> {
return (Entity)this;
}
default void deserializeNBT(CompoundTag nbt) {
@Override
default void deserializeNBT(HolderLookup.Provider registryAccess, CompoundTag nbt) {
self().load(nbt);
}
default CompoundTag serializeNBT() {
@Override
default CompoundTag serializeNBT(HolderLookup.Provider registryAccess) {
var ret = new CompoundTag();
var id = self().getEncodeId();
if (id != null)
@@ -13,14 +13,10 @@ import net.minecraft.nbt.Tag;
* code base that can be serialized to and from a NBT tag.
*
* @deprecated // Mojang has switched most things to Codecs and registry context, probably worth deleting this.
*
* Most cases this is used for Capabilities, and should use Components attached to the object that the cap is attached to.
*/
public interface INBTSerializable<T extends Tag> {
default T serializeNBT() { return null; }
default T serializeNBT(HolderLookup.Provider registryAccess) {
return serializeNBT();
}
default void deserializeNBT(T nbt) { }
default void deserializeNBT(HolderLookup.Provider registryAccess, T nbt) {
deserializeNBT(nbt);
}
T serializeNBT(HolderLookup.Provider registryAccess);
void deserializeNBT(HolderLookup.Provider registryAccess, T nbt);
}
@@ -6,7 +6,6 @@
package net.minecraftforge.common.util;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.HolderLookup.Provider;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.saveddata.SavedData;
import net.minecraft.world.level.storage.DimensionDataStorage;
@@ -23,18 +22,10 @@ public class LevelCapabilityData extends SavedData {
this.serializable = serializable;
}
public void read(CompoundTag nbt) {
this.capNBT = nbt;
if (serializable != null) {
serializable.deserializeNBT(this.capNBT);
this.capNBT = null;
}
}
@Override
public CompoundTag save(CompoundTag nbt, HolderLookup.Provider provider) {
if (serializable != null)
nbt = serializable.serializeNBT();
nbt = serializable.serializeNBT(provider);
return nbt;
}
@@ -43,27 +34,18 @@ public class LevelCapabilityData extends SavedData {
return true;
}
public void setCapabilities(INBTSerializable<CompoundTag> capabilities) {
this.serializable = capabilities;
if (this.capNBT != null && serializable != null) {
serializable.deserializeNBT(this.capNBT);
this.capNBT = null;
}
}
public static LevelCapabilityData compute(DimensionDataStorage data, @Nullable INBTSerializable<CompoundTag> caps) {
var factory = new Factory<>(
() -> new LevelCapabilityData(caps),
(tag, lookup) -> {
var ret = new LevelCapabilityData(caps);
ret.read(tag);
if (caps != null)
caps.deserializeNBT(lookup, tag);
return ret;
},
null
);
var ret = data.computeIfAbsent(factory, ID);
ret.setCapabilities(caps);
return ret;
return data.computeIfAbsent(factory, ID);
}
}
@@ -5,6 +5,7 @@
package net.minecraftforge.energy;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.IntTag;
import net.minecraft.nbt.Tag;
import net.minecraftforge.common.util.INBTSerializable;
@@ -15,30 +16,25 @@ import net.minecraftforge.common.util.INBTSerializable;
* Derived from the Redstone Flux power system designed by King Lemming and originally utilized in Thermal Expansion and related mods.
* Created with consent and permission of King Lemming and Team CoFH. Released with permission under LGPL 2.1 when bundled with Forge.
*/
public class EnergyStorage implements IEnergyStorage, INBTSerializable<Tag>
{
public class EnergyStorage implements IEnergyStorage, INBTSerializable<Tag> {
protected int energy;
protected int capacity;
protected int maxReceive;
protected int maxExtract;
public EnergyStorage(int capacity)
{
public EnergyStorage(int capacity) {
this(capacity, capacity, capacity, 0);
}
public EnergyStorage(int capacity, int maxTransfer)
{
public EnergyStorage(int capacity, int maxTransfer) {
this(capacity, maxTransfer, maxTransfer, 0);
}
public EnergyStorage(int capacity, int maxReceive, int maxExtract)
{
public EnergyStorage(int capacity, int maxReceive, int maxExtract) {
this(capacity, maxReceive, maxExtract, 0);
}
public EnergyStorage(int capacity, int maxReceive, int maxExtract, int energy)
{
public EnergyStorage(int capacity, int maxReceive, int maxExtract, int energy) {
this.capacity = capacity;
this.maxReceive = maxReceive;
this.maxExtract = maxExtract;
@@ -46,8 +42,7 @@ public class EnergyStorage implements IEnergyStorage, INBTSerializable<Tag>
}
@Override
public int receiveEnergy(int maxReceive, boolean simulate)
{
public int receiveEnergy(int maxReceive, boolean simulate) {
if (!canReceive())
return 0;
@@ -58,8 +53,7 @@ public class EnergyStorage implements IEnergyStorage, INBTSerializable<Tag>
}
@Override
public int extractEnergy(int maxExtract, boolean simulate)
{
public int extractEnergy(int maxExtract, boolean simulate) {
if (!canExtract())
return 0;
@@ -70,20 +64,17 @@ public class EnergyStorage implements IEnergyStorage, INBTSerializable<Tag>
}
@Override
public int getEnergyStored()
{
public int getEnergyStored() {
return energy;
}
@Override
public int getMaxEnergyStored()
{
public int getMaxEnergyStored() {
return capacity;
}
@Override
public boolean canExtract()
{
public boolean canExtract() {
return this.maxExtract > 0;
}
@@ -94,14 +85,12 @@ public class EnergyStorage implements IEnergyStorage, INBTSerializable<Tag>
}
@Override
public Tag serializeNBT()
{
public Tag serializeNBT(HolderLookup.Provider registryAccess) {
return IntTag.valueOf(this.getEnergyStored());
}
@Override
public void deserializeNBT(Tag nbt)
{
public void deserializeNBT(HolderLookup.Provider registryAccess, Tag nbt) {
if (!(nbt instanceof IntTag intNbt))
throw new IllegalArgumentException("Can not deserialize to an instance that isn't the default implementation");
this.energy = intNbt.getAsInt();