Finish moving over to Holderable (#12646)

This commit is contained in:
Jake Potrebic
2025-06-10 16:29:10 -07:00
committed by GitHub
parent 519e4224b1
commit ba7fb23ddd
17 changed files with 171 additions and 723 deletions

View File

@@ -1,14 +1,13 @@
package io.papermc.paper.datacomponent;
import java.util.function.Function;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.util.NullOps;
import net.minecraft.util.Unit;
import org.bukkit.craftbukkit.CraftRegistry;
public record DataComponentAdapter<NMS, API>(
DataComponentType<NMS> type,
Function<API, NMS> apiToVanilla,
Function<NMS, API> vanillaToApi,
boolean codecValidation
@@ -27,11 +26,11 @@ public record DataComponentAdapter<NMS, API>(
return this.apiToVanilla == API_TO_UNIMPLEMENTED_CONVERTER;
}
public NMS toVanilla(final API value) {
public NMS toVanilla(final API value, final Holder<? extends DataComponentType<NMS>> type) {
final NMS nms = this.apiToVanilla.apply(value);
if (this.codecValidation) {
this.type.codecOrThrow().encodeStart(CraftRegistry.getMinecraftRegistry().createSerializationContext(NullOps.INSTANCE), nms).ifError(error -> {
throw new IllegalArgumentException("Failed to encode data component %s (%s)".formatted(BuiltInRegistries.DATA_COMPONENT_TYPE.getKey(this.type), error.message()));
if (this.codecValidation && !type.value().isTransient()) {
type.value().codecOrThrow().encodeStart(CraftRegistry.getMinecraftRegistry().createSerializationContext(NullOps.INSTANCE), nms).ifError(error -> {
throw new IllegalArgumentException("Failed to encode data component %s (%s)".formatted(type.unwrapKey().orElseThrow(), error.message()));
});
}

View File

@@ -40,10 +40,10 @@ import io.papermc.paper.datacomponent.item.PaperUseRemainder;
import io.papermc.paper.datacomponent.item.PaperWeapon;
import io.papermc.paper.datacomponent.item.PaperWritableBookContent;
import io.papermc.paper.datacomponent.item.PaperWrittenBookContent;
import io.papermc.paper.registry.PaperRegistries;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import io.papermc.paper.registry.PaperRegistries;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.BuiltInRegistries;
@@ -147,7 +147,8 @@ public final class DataComponentAdapters {
register(DataComponents.OMINOUS_BOTTLE_AMPLIFIER, PaperOminousBottleAmplifier::new);
register(DataComponents.JUKEBOX_PLAYABLE, PaperJukeboxPlayable::new);
register(DataComponents.PROVIDES_BANNER_PATTERNS, PaperRegistries::fromNms, PaperRegistries::toNms);
register(DataComponents.RECIPES,
register(
DataComponents.RECIPES,
nms -> transformUnmodifiable(nms, PaperAdventure::asAdventureKey),
api -> transformUnmodifiable(api, key -> PaperAdventure.asVanilla(Registries.RECIPE, key))
);
@@ -164,7 +165,7 @@ public final class DataComponentAdapters {
// bees
// register(DataComponents.LOCK, PaperLockCode::new);
register(DataComponents.CONTAINER_LOOT, PaperSeededContainerLoot::new);
register(DataComponents.BREAK_SOUND, nms -> PaperAdventure.asAdventure(nms.value().location()), PaperAdventure::resolveSound);
register(DataComponents.BREAK_SOUND, nms -> PaperAdventure.asAdventure(nms.value().location()), PaperAdventure::resolveSound);
register(DataComponents.TOOLTIP_DISPLAY, PaperTooltipDisplay::new);
register(DataComponents.WEAPON, PaperWeapon::new);
register(DataComponents.BLOCKS_ATTACKS, PaperBlocksAttacks::new);
@@ -195,38 +196,42 @@ public final class DataComponentAdapters {
register(DataComponents.SHEEP_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
register(DataComponents.SHULKER_COLOR, nms -> DyeColor.getByWoolData((byte) nms.getId()), api -> net.minecraft.world.item.DyeColor.byId(api.getWoolData()));
for (final Map.Entry<ResourceKey<DataComponentType<?>>, DataComponentType<?>> componentType : BuiltInRegistries.DATA_COMPONENT_TYPE.entrySet()) {
if (!ADAPTERS.containsKey(componentType.getKey())) {
registerUnimplemented(componentType.getValue());
for (final ResourceKey<DataComponentType<?>> key : BuiltInRegistries.DATA_COMPONENT_TYPE.registryKeySet()) {
if (!ADAPTERS.containsKey(key)) {
registerUnimplemented(key);
}
}
}
private static <NMS> ResourceKey<DataComponentType<?>> getKey(final DataComponentType<NMS> type) {
return BuiltInRegistries.DATA_COMPONENT_TYPE.getResourceKey(type).orElseThrow();
}
public static void registerUntyped(final DataComponentType<Unit> type) {
registerInternal(type, UNIT_TO_API_CONVERTER, DataComponentAdapter.API_TO_UNIT_CONVERTER, false);
registerInternal(getKey(type), UNIT_TO_API_CONVERTER, DataComponentAdapter.API_TO_UNIT_CONVERTER, false);
}
private static <COMMON> void registerIdentity(final DataComponentType<COMMON> type) {
registerInternal(type, Function.identity(), Function.identity(), true);
registerInternal(getKey(type), Function.identity(), Function.identity(), true);
}
public static <NMS> void registerUnimplemented(final DataComponentType<NMS> type) {
registerInternal(type, UNIMPLEMENTED_TO_API_CONVERTER, DataComponentAdapter.API_TO_UNIMPLEMENTED_CONVERTER, false);
@SuppressWarnings("unchecked")
public static void registerUnimplemented(final ResourceKey<DataComponentType<?>> key) {
registerInternal(key, UNIMPLEMENTED_TO_API_CONVERTER, DataComponentAdapter.API_TO_UNIMPLEMENTED_CONVERTER, false);
}
private static <NMS, API extends Handleable<NMS>> void register(final DataComponentType<NMS> type, final Function<NMS, API> vanillaToApi) {
registerInternal(type, vanillaToApi, Handleable::getHandle, false);
registerInternal(getKey(type), vanillaToApi, Handleable::getHandle, false);
}
private static <NMS, API> void register(final DataComponentType<NMS> type, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla) {
registerInternal(type, vanillaToApi, apiToVanilla, false);
registerInternal(getKey(type), vanillaToApi, apiToVanilla, false);
}
private static <NMS, API> void registerInternal(final DataComponentType<NMS> type, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla, final boolean codecValidation) {
final ResourceKey<DataComponentType<?>> key = BuiltInRegistries.DATA_COMPONENT_TYPE.getResourceKey(type).orElseThrow();
private static <NMS, API> void registerInternal(final ResourceKey<DataComponentType<?>> key, final Function<NMS, API> vanillaToApi, final Function<API, NMS> apiToVanilla, final boolean codecValidation) {
if (ADAPTERS.containsKey(key)) {
throw new IllegalStateException("Duplicate adapter registration for " + key);
}
ADAPTERS.put(key, new DataComponentAdapter<>(type, apiToVanilla, vanillaToApi, codecValidation && !type.isTransient()));
ADAPTERS.put(key, new DataComponentAdapter<>(apiToVanilla, vanillaToApi, codecValidation));
}
}

View File

@@ -1,17 +1,16 @@
package io.papermc.paper.datacomponent;
import io.papermc.paper.registry.HolderableBase;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import org.bukkit.NamespacedKey;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.util.Handleable;
import org.jspecify.annotations.Nullable;
public abstract class PaperDataComponentType<T, NMS> implements DataComponentType, Handleable<net.minecraft.core.component.DataComponentType<NMS>> {
public abstract class PaperDataComponentType<T, NMS> extends HolderableBase<net.minecraft.core.component.DataComponentType<NMS>> implements DataComponentType {
static {
DataComponentAdapters.bootstrap();
@@ -42,80 +41,64 @@ public abstract class PaperDataComponentType<T, NMS> implements DataComponentTyp
return type.getAdapter().fromVanilla(nmsValue);
}
private final NamespacedKey key;
private final net.minecraft.core.component.DataComponentType<NMS> type;
private final DataComponentAdapter<NMS, T> adapter;
public PaperDataComponentType(final NamespacedKey key, final net.minecraft.core.component.DataComponentType<NMS> type, final DataComponentAdapter<NMS, T> adapter) {
this.key = key;
this.type = type;
private PaperDataComponentType(final Holder<net.minecraft.core.component.DataComponentType<NMS>> holder, final DataComponentAdapter<NMS, T> adapter) {
super(holder);
this.adapter = adapter;
}
@Override
public NamespacedKey getKey() {
return this.key;
}
@Override
public boolean isPersistent() {
return !this.type.isTransient();
return !this.getHandle().isTransient();
}
public DataComponentAdapter<NMS, T> getAdapter() {
return this.adapter;
}
@Override
public net.minecraft.core.component.DataComponentType<NMS> getHandle() {
return this.type;
}
@SuppressWarnings("unchecked")
public static <NMS> DataComponentType of(final NamespacedKey key, final net.minecraft.core.component.DataComponentType<NMS> type) {
final DataComponentAdapter<NMS, ?> adapter = (DataComponentAdapter<NMS, ?>) DataComponentAdapters.ADAPTERS.get(BuiltInRegistries.DATA_COMPONENT_TYPE.getResourceKey(type).orElseThrow());
@SuppressWarnings({"unchecked"})
public static <NMS> DataComponentType of(final Holder<?> holder) {
final DataComponentAdapter<NMS, ?> adapter = (DataComponentAdapter<NMS, ?>) DataComponentAdapters.ADAPTERS.get(holder.unwrapKey().orElseThrow());
if (adapter == null) {
throw new IllegalArgumentException("No adapter found for " + key);
throw new IllegalArgumentException("No adapter found for " + holder);
}
if (adapter.isUnimplemented()) {
return new Unimplemented<>(key, type, adapter);
return new Unimplemented<>((Holder<net.minecraft.core.component.DataComponentType<NMS>>) holder, adapter);
} else if (adapter.isValued()) {
return new ValuedImpl<>(key, type, adapter);
return new ValuedImpl<>((Holder<net.minecraft.core.component.DataComponentType<NMS>>) holder, adapter);
} else {
return new NonValuedImpl<>(key, type, adapter);
return new NonValuedImpl<>((Holder<net.minecraft.core.component.DataComponentType<NMS>>) holder, adapter);
}
}
public static final class NonValuedImpl<T, NMS> extends PaperDataComponentType<T, NMS> implements NonValued {
NonValuedImpl(
final NamespacedKey key,
final net.minecraft.core.component.DataComponentType<NMS> type,
final Holder<net.minecraft.core.component.DataComponentType<NMS>> holder,
final DataComponentAdapter<NMS, T> adapter
) {
super(key, type, adapter);
super(holder, adapter);
}
}
public static final class ValuedImpl<T, NMS> extends PaperDataComponentType<T, NMS> implements Valued<T> {
ValuedImpl(
final NamespacedKey key,
final net.minecraft.core.component.DataComponentType<NMS> type,
final Holder<net.minecraft.core.component.DataComponentType<NMS>> holder,
final DataComponentAdapter<NMS, T> adapter
) {
super(key, type, adapter);
super(holder, adapter);
}
}
public static final class Unimplemented<T, NMS> extends PaperDataComponentType<T, NMS> {
public Unimplemented(
final NamespacedKey key,
final net.minecraft.core.component.DataComponentType<NMS> type,
final Holder<net.minecraft.core.component.DataComponentType<NMS>> holder,
final DataComponentAdapter<NMS, T> adapter
) {
super(key, type, adapter);
super(holder, adapter);
}
}
}

View File

@@ -12,11 +12,17 @@ public abstract class HolderableBase<M> implements Holderable<M> {
this.holder = holder;
}
// methods below are overridden to make final
@Override
public final Holder<M> getHolder() {
return this.holder;
}
@Override
public final M getHandle() {
return Holderable.super.getHandle();
}
@Override
public final int hashCode() {
return Holderable.super.implHashCode();
@@ -28,7 +34,7 @@ public abstract class HolderableBase<M> implements Holderable<M> {
}
@Override
public final String toString() {
public String toString() {
return Holderable.super.implToString();
}

View File

@@ -1,6 +1,7 @@
package io.papermc.paper.util;
import com.google.common.base.Preconditions;
import io.papermc.paper.registry.HolderableBase;
import java.util.Locale;
import net.minecraft.core.Holder;
import org.bukkit.Keyed;
@@ -12,14 +13,13 @@ import org.jspecify.annotations.Nullable;
@SuppressWarnings({"removal", "DeprecatedIsStillUsed"})
@Deprecated
@NullMarked
public abstract class OldEnumHolderable<A extends OldEnum<A>, M> implements Holderable<M>, OldEnum<A>, Keyed {
public abstract class OldEnumHolderable<A extends OldEnum<A>, M> extends HolderableBase<M> implements Holderable<M>, OldEnum<A>, Keyed {
private final Holder<M> holder;
private final int ordinal;
private final @Nullable String name;
protected OldEnumHolderable(final Holder<M> holder, final int ordinal) {
this.holder = holder;
super(holder);
this.ordinal = ordinal;
if (holder instanceof final Holder.Reference<M> reference) {
// For backwards compatibility, minecraft values will stile return the uppercase name without the namespace,
@@ -36,11 +36,6 @@ public abstract class OldEnumHolderable<A extends OldEnum<A>, M> implements Hold
}
}
@Override
public Holder<M> getHolder() {
return this.holder;
}
@Override
@Deprecated
public int compareTo(final A other) {
@@ -66,21 +61,6 @@ public abstract class OldEnumHolderable<A extends OldEnum<A>, M> implements Hold
Preconditions.checkState(this.holder.kind() == Holder.Kind.REFERENCE, "Cannot call method for this registry item, because it is not registered.");
}
@Override
public NamespacedKey getKey() {
return MCUtil.fromResourceKey(this.holder.unwrapKey().orElseThrow(() -> new IllegalStateException("Cannot get key for this registry item, because it is not registered.")));
}
@Override
public boolean equals(final Object obj) {
return this.implEquals(obj);
}
@Override
public int hashCode() {
return this.implHashCode();
}
@Override
public String toString() {
if (this.name != null) {