mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 15:00:13 +01:00
Registry Modification API
== AT == public net.minecraft.core.MappedRegistry validateWrite(Lnet/minecraft/resources/ResourceKey;)V public net.minecraft.resources.RegistryOps lookupProvider public net.minecraft.resources.RegistryOps$HolderLookupAdapter
This commit is contained in:
parent
463f952cd4
commit
a1b891dd88
35 changed files with 1109 additions and 11 deletions
|
@ -17,3 +17,17 @@
|
|||
private Lifecycle registryLifecycle;
|
||||
private final Map<TagKey<T>, HolderSet.Named<T>> frozenTags = new IdentityHashMap<>();
|
||||
MappedRegistry.TagSet<T> allTags = MappedRegistry.TagSet.unbound();
|
||||
@@ -508,5 +508,13 @@
|
||||
void forEach(BiConsumer<? super TagKey<T>, ? super HolderSet.Named<T>> consumer);
|
||||
|
||||
Stream<HolderSet.Named<T>> getTags();
|
||||
+ }
|
||||
+ // Paper start
|
||||
+ // used to clear intrusive holders from GameEvent, Item, Block, EntityType, and Fluid from unused instances of those types
|
||||
+ public void clearIntrusiveHolder(final T instance) {
|
||||
+ if (this.unregisteredIntrusiveHolders != null) {
|
||||
+ this.unregisteredIntrusiveHolders.remove(instance);
|
||||
+ }
|
||||
}
|
||||
+ // Paper end
|
||||
}
|
||||
|
|
|
@ -1,6 +1,24 @@
|
|||
--- a/net/minecraft/core/registries/BuiltInRegistries.java
|
||||
+++ b/net/minecraft/core/registries/BuiltInRegistries.java
|
||||
@@ -323,14 +323,21 @@
|
||||
@@ -296,6 +296,17 @@
|
||||
public static final Registry<SlotDisplay.Type<?>> SLOT_DISPLAY = registerSimple(Registries.SLOT_DISPLAY, SlotDisplays::bootstrap);
|
||||
public static final Registry<RecipeBookCategory> RECIPE_BOOK_CATEGORY = registerSimple(Registries.RECIPE_BOOK_CATEGORY, RecipeBookCategories::bootstrap);
|
||||
public static final Registry<? extends Registry<?>> REGISTRY = WRITABLE_REGISTRY;
|
||||
+ // Paper start - add built-in registry conversions
|
||||
+ public static final io.papermc.paper.registry.data.util.Conversions BUILT_IN_CONVERSIONS = new io.papermc.paper.registry.data.util.Conversions(new net.minecraft.resources.RegistryOps.RegistryInfoLookup() {
|
||||
+ @Override
|
||||
+ public <T> java.util.Optional<net.minecraft.resources.RegistryOps.RegistryInfo<T>> lookup(final ResourceKey<? extends Registry<? extends T>> registryRef) {
|
||||
+ final Registry<T> registry = net.minecraft.server.RegistryLayer.STATIC_ACCESS.lookupOrThrow(registryRef);
|
||||
+ return java.util.Optional.of(
|
||||
+ new net.minecraft.resources.RegistryOps.RegistryInfo<>(registry, registry, Lifecycle.experimental())
|
||||
+ );
|
||||
+ }
|
||||
+ });
|
||||
+ // Paper end - add built-in registry conversions
|
||||
|
||||
private static <T> Registry<T> registerSimple(ResourceKey<? extends Registry<T>> key, BuiltInRegistries.RegistryBootstrap<T> initializer) {
|
||||
return internalRegister(key, new MappedRegistry<>(key, Lifecycle.stable(), false), initializer);
|
||||
@@ -323,14 +334,22 @@
|
||||
ResourceKey<? extends Registry<T>> key, R registry, BuiltInRegistries.RegistryBootstrap<T> initializer
|
||||
) {
|
||||
Bootstrap.checkBootstrapCalled(() -> "registry " + key.location());
|
||||
|
@ -18,8 +36,17 @@
|
|||
+ }
|
||||
+ public static void bootStrap(Runnable runnable) {
|
||||
+ // Paper end
|
||||
+ REGISTRY.freeze(); // Paper - freeze main registry early
|
||||
createContents();
|
||||
+ runnable.run(); // Paper
|
||||
freeze();
|
||||
validate(REGISTRY);
|
||||
}
|
||||
@@ -348,6 +367,7 @@
|
||||
|
||||
for (Registry<?> registry : REGISTRY) {
|
||||
bindBootstrappedTagsToEmpty(registry);
|
||||
+ io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), BUILT_IN_CONVERSIONS); // Paper
|
||||
registry.freeze();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,65 @@
|
|||
private static final RegistrationInfo NETWORK_REGISTRATION_INFO = new RegistrationInfo(Optional.empty(), Lifecycle.experimental());
|
||||
private static final Function<Optional<KnownPack>, RegistrationInfo> REGISTRATION_INFO_CACHE = Util.memoize(knownPacks -> {
|
||||
Lifecycle lifecycle = knownPacks.map(KnownPack::isVanilla).map(vanilla -> Lifecycle.stable()).orElse(Lifecycle.experimental());
|
||||
@@ -349,6 +349,7 @@
|
||||
@@ -238,13 +238,13 @@
|
||||
}
|
||||
|
||||
private static <E> void loadElementFromResource(
|
||||
- WritableRegistry<E> registry, Decoder<E> decoder, RegistryOps<JsonElement> ops, ResourceKey<E> key, Resource resource, RegistrationInfo entryInfo
|
||||
+ WritableRegistry<E> registry, Decoder<E> decoder, RegistryOps<JsonElement> ops, ResourceKey<E> key, Resource resource, RegistrationInfo entryInfo, io.papermc.paper.registry.data.util.Conversions conversions // Paper - pass conversions
|
||||
) throws IOException {
|
||||
try (Reader reader = resource.openAsReader()) {
|
||||
JsonElement jsonElement = JsonParser.parseReader(reader);
|
||||
DataResult<E> dataResult = decoder.parse(ops, jsonElement);
|
||||
E object = dataResult.getOrThrow();
|
||||
- registry.register(key, object, entryInfo);
|
||||
+ io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.registerWithListeners(registry, key, object, entryInfo, conversions); // Paper - register with listeners
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,6 +258,7 @@
|
||||
FileToIdConverter fileToIdConverter = FileToIdConverter.registry(registry.key());
|
||||
RegistryOps<JsonElement> registryOps = RegistryOps.create(JsonOps.INSTANCE, infoGetter);
|
||||
|
||||
+ final io.papermc.paper.registry.data.util.Conversions conversions = new io.papermc.paper.registry.data.util.Conversions(infoGetter); // Paper - create conversions
|
||||
for (Entry<ResourceLocation, Resource> entry : fileToIdConverter.listMatchingResources(resourceManager).entrySet()) {
|
||||
ResourceLocation resourceLocation = entry.getKey();
|
||||
ResourceKey<E> resourceKey = ResourceKey.create(registry.key(), fileToIdConverter.fileToId(resourceLocation));
|
||||
@@ -265,7 +266,7 @@
|
||||
RegistrationInfo registrationInfo = REGISTRATION_INFO_CACHE.apply(resource.knownPackInfo());
|
||||
|
||||
try {
|
||||
- loadElementFromResource(registry, elementDecoder, registryOps, resourceKey, resource, registrationInfo);
|
||||
+ loadElementFromResource(registry, elementDecoder, registryOps, resourceKey, resource, registrationInfo, conversions); // Paper - pass conversions
|
||||
} catch (Exception var14) {
|
||||
errors.put(
|
||||
resourceKey,
|
||||
@@ -274,6 +275,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), conversions); // Paper - run pre-freeze listeners
|
||||
TagLoader.loadTagsForRegistry(resourceManager, registry);
|
||||
}
|
||||
|
||||
@@ -291,6 +293,7 @@
|
||||
RegistryOps<JsonElement> registryOps2 = RegistryOps.create(JsonOps.INSTANCE, infoGetter);
|
||||
FileToIdConverter fileToIdConverter = FileToIdConverter.registry(registry.key());
|
||||
|
||||
+ final io.papermc.paper.registry.data.util.Conversions conversions = new io.papermc.paper.registry.data.util.Conversions(infoGetter); // Paper - create conversions
|
||||
for (RegistrySynchronization.PackedRegistryEntry packedRegistryEntry : networkedRegistryData.elements) {
|
||||
ResourceKey<E> resourceKey = ResourceKey.create(registry.key(), packedRegistryEntry.id());
|
||||
Optional<Tag> optional = packedRegistryEntry.data();
|
||||
@@ -309,7 +312,7 @@
|
||||
|
||||
try {
|
||||
Resource resource = factory.getResourceOrThrow(resourceLocation);
|
||||
- loadElementFromResource(registry, decoder, registryOps2, resourceKey, resource, NETWORK_REGISTRATION_INFO);
|
||||
+ loadElementFromResource(registry, decoder, registryOps2, resourceKey, resource, NETWORK_REGISTRATION_INFO, conversions); // Paper - pass conversions
|
||||
} catch (Exception var17) {
|
||||
loadingErrors.put(resourceKey, new IllegalStateException("Failed to parse local data", var17));
|
||||
}
|
||||
@@ -349,6 +352,7 @@
|
||||
|
||||
RegistryDataLoader.Loader<T> create(Lifecycle lifecycle, Map<ResourceKey<?>, Exception> errors) {
|
||||
WritableRegistry<T> writableRegistry = new MappedRegistry<>(this.key, lifecycle);
|
||||
|
|
|
@ -1,10 +1,30 @@
|
|||
--- a/net/minecraft/server/ReloadableServerRegistries.java
|
||||
+++ b/net/minecraft/server/ReloadableServerRegistries.java
|
||||
@@ -64,6 +64,7 @@
|
||||
@@ -50,8 +50,9 @@
|
||||
);
|
||||
HolderLookup.Provider provider = HolderLookup.Provider.create(list.stream());
|
||||
RegistryOps<JsonElement> registryOps = provider.createSerializationContext(JsonOps.INSTANCE);
|
||||
+ final io.papermc.paper.registry.data.util.Conversions conversions = new io.papermc.paper.registry.data.util.Conversions(registryOps.lookupProvider); // Paper
|
||||
List<CompletableFuture<WritableRegistry<?>>> list2 = LootDataType.values()
|
||||
- .map(type -> scheduleRegistryLoad((LootDataType<?>)type, registryOps, resourceManager, prepareExecutor))
|
||||
+ .map(type -> scheduleRegistryLoad((LootDataType<?>)type, registryOps, resourceManager, prepareExecutor, conversions)) // Paper
|
||||
.toList();
|
||||
CompletableFuture<List<WritableRegistry<?>>> completableFuture = Util.sequence(list2);
|
||||
return completableFuture.thenApplyAsync(
|
||||
@@ -60,13 +61,14 @@
|
||||
}
|
||||
|
||||
private static <T> CompletableFuture<WritableRegistry<?>> scheduleRegistryLoad(
|
||||
- LootDataType<T> type, RegistryOps<JsonElement> ops, ResourceManager resourceManager, Executor prepareExecutor
|
||||
+ LootDataType<T> type, RegistryOps<JsonElement> ops, ResourceManager resourceManager, Executor prepareExecutor, io.papermc.paper.registry.data.util.Conversions conversions // Paper
|
||||
) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
WritableRegistry<T> writableRegistry = new MappedRegistry<>(type.registryKey(), Lifecycle.experimental());
|
||||
+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerReloadableRegistry(type.registryKey(), writableRegistry); // Paper - register reloadable registry
|
||||
Map<ResourceLocation, T> map = new HashMap<>();
|
||||
SimpleJsonResourceReloadListener.scanDirectory(resourceManager, type.registryKey(), ops, type.codec(), map);
|
||||
map.forEach((id, value) -> writableRegistry.register(ResourceKey.create(type.registryKey(), id), (T)value, DEFAULT_REGISTRATION_INFO));
|
||||
- map.forEach((id, value) -> writableRegistry.register(ResourceKey.create(type.registryKey(), id), (T)value, DEFAULT_REGISTRATION_INFO));
|
||||
+ map.forEach((id, value) -> io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.registerWithListeners(writableRegistry, ResourceKey.create(type.registryKey(), id), value, DEFAULT_REGISTRATION_INFO, conversions)); // Paper - register with listeners
|
||||
TagLoader.loadTagsForRegistry(resourceManager, writableRegistry);
|
||||
return writableRegistry;
|
||||
}, prepareExecutor);
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.papermc.paper.registry;
|
|||
import com.google.common.base.Preconditions;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.registry.entry.RegistryEntry;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
|
@ -148,6 +149,15 @@ public final class PaperRegistries {
|
|||
return ResourceKey.create((ResourceKey<? extends Registry<M>>) PaperRegistries.registryToNms(typedKey.registryKey()), PaperAdventure.asVanilla(typedKey.key()));
|
||||
}
|
||||
|
||||
public static <M, T> TagKey<T> fromNms(final net.minecraft.tags.TagKey<M> tagKey) {
|
||||
return TagKey.create(registryFromNms(tagKey.registry()), CraftNamespacedKey.fromMinecraft(tagKey.location()));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "RedundantCast"})
|
||||
public static <M, T> net.minecraft.tags.TagKey<M> toNms(final TagKey<T> tagKey) {
|
||||
return net.minecraft.tags.TagKey.create((ResourceKey<? extends Registry<M>>) registryToNms(tagKey.registryKey()), PaperAdventure.asVanilla(tagKey.key()));
|
||||
}
|
||||
|
||||
private PaperRegistries() {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,6 +78,14 @@ public class PaperRegistryAccess implements RegistryAccess {
|
|||
return possiblyUnwrap(registryHolder.get());
|
||||
}
|
||||
|
||||
public <M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> WritableCraftRegistry<M, T, B> getWritableRegistry(final RegistryKey<T> key) {
|
||||
final Registry<T> registry = this.getRegistry(key);
|
||||
if (registry instanceof WritableCraftRegistry<?, T, ?>) {
|
||||
return (WritableCraftRegistry<M, T, B>) registry;
|
||||
}
|
||||
throw new IllegalArgumentException(key + " does not point to a writable registry");
|
||||
}
|
||||
|
||||
private static <T extends Keyed> Registry<T> possiblyUnwrap(final Registry<T> registry) {
|
||||
if (registry instanceof final DelayedRegistry<T, ?> delayedRegistry) { // if not coming from legacy, unwrap the delayed registry
|
||||
return delayedRegistry.delegate();
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package io.papermc.paper.registry;
|
||||
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public interface PaperRegistryBuilder<M, T> extends RegistryBuilder<T> {
|
||||
|
||||
M build();
|
||||
|
||||
@FunctionalInterface
|
||||
interface Filler<M, T, B extends PaperRegistryBuilder<M, T>> {
|
||||
|
||||
B fill(Conversions conversions, @Nullable M nms);
|
||||
|
||||
default Factory<M, T, B> asFactory() {
|
||||
return (lookup) -> this.fill(lookup, null);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface Factory<M, T, B extends PaperRegistryBuilder<M, T>> {
|
||||
|
||||
B create(Conversions conversions);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
package io.papermc.paper.registry;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
||||
import io.papermc.paper.plugin.entrypoint.Entrypoint;
|
||||
import io.papermc.paper.plugin.entrypoint.LaunchEntryPointHandler;
|
||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner;
|
||||
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.entry.RegistryEntry;
|
||||
import io.papermc.paper.registry.entry.RegistryEntryInfo;
|
||||
import io.papermc.paper.registry.event.RegistryEntryAddEventImpl;
|
||||
import io.papermc.paper.registry.event.RegistryEventMap;
|
||||
import io.papermc.paper.registry.event.RegistryEventProvider;
|
||||
import io.papermc.paper.registry.event.RegistryFreezeEvent;
|
||||
import io.papermc.paper.registry.event.RegistryFreezeEventImpl;
|
||||
import io.papermc.paper.registry.event.type.RegistryEntryAddEventType;
|
||||
import io.papermc.paper.registry.event.type.RegistryEntryAddEventTypeImpl;
|
||||
import io.papermc.paper.registry.event.type.RegistryLifecycleEventType;
|
||||
import java.util.Optional;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.RegistrationInfo;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.WritableRegistry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.intellij.lang.annotations.Subst;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class PaperRegistryListenerManager {
|
||||
|
||||
public static final PaperRegistryListenerManager INSTANCE = new PaperRegistryListenerManager();
|
||||
|
||||
public final RegistryEventMap valueAddEventTypes = new RegistryEventMap("value add");
|
||||
public final RegistryEventMap freezeEventTypes = new RegistryEventMap("freeze");
|
||||
|
||||
private PaperRegistryListenerManager() {
|
||||
}
|
||||
|
||||
/**
|
||||
* For {@link Registry#register(Registry, String, Object)}
|
||||
*/
|
||||
public <M> M registerWithListeners(final Registry<M> registry, final String id, final M nms) {
|
||||
return this.registerWithListeners(registry, ResourceLocation.withDefaultNamespace(id), nms);
|
||||
}
|
||||
|
||||
/**
|
||||
* For {@link Registry#register(Registry, ResourceLocation, Object)}
|
||||
*/
|
||||
public <M> M registerWithListeners(final Registry<M> registry, final ResourceLocation loc, final M nms) {
|
||||
return this.registerWithListeners(registry, ResourceKey.create(registry.key(), loc), nms);
|
||||
}
|
||||
|
||||
/**
|
||||
* For {@link Registry#register(Registry, ResourceKey, Object)}
|
||||
*/
|
||||
public <M> M registerWithListeners(final Registry<M> registry, final ResourceKey<M> key, final M nms) {
|
||||
return this.registerWithListeners(registry, key, nms, RegistrationInfo.BUILT_IN, PaperRegistryListenerManager::registerWithInstance, BuiltInRegistries.BUILT_IN_CONVERSIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* For {@link Registry#registerForHolder(Registry, ResourceLocation, Object)}
|
||||
*/
|
||||
public <M> Holder.Reference<M> registerForHolderWithListeners(final Registry<M> registry, final ResourceLocation loc, final M nms) {
|
||||
return this.registerForHolderWithListeners(registry, ResourceKey.create(registry.key(), loc), nms);
|
||||
}
|
||||
|
||||
/**
|
||||
* For {@link Registry#registerForHolder(Registry, ResourceKey, Object)}
|
||||
*/
|
||||
public <M> Holder.Reference<M> registerForHolderWithListeners(final Registry<M> registry, final ResourceKey<M> key, final M nms) {
|
||||
return this.registerWithListeners(registry, key, nms, RegistrationInfo.BUILT_IN, WritableRegistry::register, BuiltInRegistries.BUILT_IN_CONVERSIONS);
|
||||
}
|
||||
|
||||
public <M> void registerWithListeners(
|
||||
final Registry<M> registry,
|
||||
final ResourceKey<M> key,
|
||||
final M nms,
|
||||
final RegistrationInfo registrationInfo,
|
||||
final Conversions conversions
|
||||
) {
|
||||
this.registerWithListeners(registry, key, nms, registrationInfo, WritableRegistry::register, conversions);
|
||||
}
|
||||
|
||||
// TODO remove Keyed
|
||||
public <M, T extends org.bukkit.Keyed, B extends PaperRegistryBuilder<M, T>, R> R registerWithListeners(
|
||||
final Registry<M> registry,
|
||||
final ResourceKey<M> key,
|
||||
final M nms,
|
||||
final RegistrationInfo registrationInfo,
|
||||
final RegisterMethod<M, R> registerMethod,
|
||||
final Conversions conversions
|
||||
) {
|
||||
Preconditions.checkState(LaunchEntryPointHandler.INSTANCE.hasEntered(Entrypoint.BOOTSTRAPPER), registry.key() + " tried to run modification listeners before bootstrappers have been called"); // verify that bootstrappers have been called
|
||||
final RegistryEntryInfo<M, T> entry = PaperRegistries.getEntry(registry.key());
|
||||
if (!RegistryEntry.Modifiable.isModifiable(entry) || !this.valueAddEventTypes.hasHandlers(entry.apiKey())) {
|
||||
return registerMethod.register((WritableRegistry<M>) registry, key, nms, registrationInfo);
|
||||
}
|
||||
final RegistryEntry.Modifiable<M, T, B> modifiableEntry = RegistryEntry.Modifiable.asModifiable(entry);
|
||||
@SuppressWarnings("PatternValidation") final TypedKey<T> typedKey = TypedKey.create(entry.apiKey(), Key.key(key.location().getNamespace(), key.location().getPath()));
|
||||
final B builder = modifiableEntry.fillBuilder(conversions, nms);
|
||||
return this.registerWithListeners(registry, modifiableEntry, key, nms, builder, registrationInfo, registerMethod, conversions);
|
||||
}
|
||||
|
||||
<M, T extends org.bukkit.Keyed, B extends PaperRegistryBuilder<M, T>> void registerWithListeners( // TODO remove Keyed
|
||||
final WritableRegistry<M> registry,
|
||||
final RegistryEntryInfo<M, T> entry,
|
||||
final ResourceKey<M> key,
|
||||
final B builder,
|
||||
final RegistrationInfo registrationInfo,
|
||||
final Conversions conversions
|
||||
) {
|
||||
if (!RegistryEntry.Modifiable.isModifiable(entry) || !this.valueAddEventTypes.hasHandlers(entry.apiKey())) {
|
||||
registry.register(key, builder.build(), registrationInfo);
|
||||
return;
|
||||
}
|
||||
this.registerWithListeners(registry, RegistryEntry.Modifiable.asModifiable(entry), key, null, builder, registrationInfo, WritableRegistry::register, conversions);
|
||||
}
|
||||
|
||||
public <M, T extends org.bukkit.Keyed, B extends PaperRegistryBuilder<M, T>, R> R registerWithListeners( // TODO remove Keyed
|
||||
final Registry<M> registry,
|
||||
final RegistryEntry.Modifiable<M, T, B> entry,
|
||||
final ResourceKey<M> key,
|
||||
final @Nullable M oldNms,
|
||||
final B builder,
|
||||
RegistrationInfo registrationInfo,
|
||||
final RegisterMethod<M, R> registerMethod,
|
||||
final Conversions conversions
|
||||
) {
|
||||
@Subst("namespace:key") final ResourceLocation beingAdded = key.location();
|
||||
@SuppressWarnings("PatternValidation") final TypedKey<T> typedKey = TypedKey.create(entry.apiKey(), Key.key(beingAdded.getNamespace(), beingAdded.getPath()));
|
||||
final RegistryEntryAddEventImpl<T, B> event = entry.createEntryAddEvent(typedKey, builder, conversions);
|
||||
LifecycleEventRunner.INSTANCE.callEvent(this.valueAddEventTypes.getEventType(entry.apiKey()), event);
|
||||
if (oldNms != null) {
|
||||
((MappedRegistry<M>) registry).clearIntrusiveHolder(oldNms);
|
||||
}
|
||||
final M newNms = event.builder().build();
|
||||
if (oldNms != null && !newNms.equals(oldNms)) {
|
||||
registrationInfo = new RegistrationInfo(Optional.empty(), Lifecycle.experimental());
|
||||
}
|
||||
return registerMethod.register((WritableRegistry<M>) registry, key, newNms, registrationInfo);
|
||||
}
|
||||
|
||||
private static <M> M registerWithInstance(final WritableRegistry<M> writableRegistry, final ResourceKey<M> key, final M value, final RegistrationInfo registrationInfo) {
|
||||
writableRegistry.register(key, value, registrationInfo);
|
||||
return value;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface RegisterMethod<M, R> {
|
||||
|
||||
R register(WritableRegistry<M> writableRegistry, ResourceKey<M> key, M value, RegistrationInfo registrationInfo);
|
||||
}
|
||||
|
||||
public <M, T extends org.bukkit.Keyed, B extends PaperRegistryBuilder<M, T>> void runFreezeListeners(final ResourceKey<? extends Registry<M>> resourceKey, final Conversions conversions) {
|
||||
final RegistryEntryInfo<M, T> entry = PaperRegistries.getEntry(resourceKey);
|
||||
if (!RegistryEntry.Addable.isAddable(entry) || !this.freezeEventTypes.hasHandlers(entry.apiKey())) {
|
||||
return;
|
||||
}
|
||||
final RegistryEntry.Addable<M, T, B> writableEntry = RegistryEntry.Addable.asAddable(entry);
|
||||
final WritableCraftRegistry<M, T, B> writableRegistry = PaperRegistryAccess.instance().getWritableRegistry(entry.apiKey());
|
||||
final RegistryFreezeEventImpl<T, B> event = writableEntry.createFreezeEvent(writableRegistry, conversions);
|
||||
LifecycleEventRunner.INSTANCE.callEvent(this.freezeEventTypes.getEventType(entry.apiKey()), event);
|
||||
}
|
||||
|
||||
public <T, B extends RegistryBuilder<T>> RegistryEntryAddEventType<T, B> getRegistryValueAddEventType(final RegistryEventProvider<T, B> type) {
|
||||
if (!RegistryEntry.Modifiable.isModifiable(PaperRegistries.getEntry(type.registryKey()))) {
|
||||
throw new IllegalArgumentException(type.registryKey() + " does not support RegistryEntryAddEvent");
|
||||
}
|
||||
return this.valueAddEventTypes.getOrCreate(type.registryKey(), RegistryEntryAddEventTypeImpl::new);
|
||||
}
|
||||
|
||||
public <T, B extends RegistryBuilder<T>> LifecycleEventType.Prioritizable<BootstrapContext, RegistryFreezeEvent<T, B>> getRegistryFreezeEventType(final RegistryEventProvider<T, B> type) {
|
||||
if (!RegistryEntry.Addable.isAddable(PaperRegistries.getEntry(type.registryKey()))) {
|
||||
throw new IllegalArgumentException(type.registryKey() + " does not support RegistryFreezeEvent");
|
||||
}
|
||||
return this.freezeEventTypes.getOrCreate(type.registryKey(), RegistryLifecycleEventType::new);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
package io.papermc.paper.registry;
|
||||
|
||||
import io.papermc.paper.registry.set.NamedRegistryKeySetImpl;
|
||||
import io.papermc.paper.registry.tag.Tag;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import java.util.function.Predicate;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.Particle;
|
||||
|
@ -35,4 +39,16 @@ public class PaperSimpleRegistry<T extends Enum<T> & Keyed, M> extends Registry.
|
|||
super(type, predicate);
|
||||
this.nmsRegistry = nmsRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTag(final TagKey<T> key) {
|
||||
final net.minecraft.tags.TagKey<M> nmsKey = PaperRegistries.toNms(key);
|
||||
return this.nmsRegistry.get(nmsKey).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag<T> getTag(final TagKey<T> key) {
|
||||
final HolderSet.Named<M> namedHolderSet = this.nmsRegistry.get(PaperRegistries.toNms(key)).orElseThrow();
|
||||
return new NamedRegistryKeySetImpl<>(key, namedHolderSet);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
package io.papermc.paper.registry;
|
||||
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.entry.RegistryEntry;
|
||||
import io.papermc.paper.registry.entry.RegistryTypeMapper;
|
||||
import io.papermc.paper.registry.event.WritableRegistry;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.RegistrationInfo;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
|
||||
public class WritableCraftRegistry<M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> extends CraftRegistry<T, M> {
|
||||
|
||||
private static final RegistrationInfo FROM_PLUGIN = new RegistrationInfo(Optional.empty(), Lifecycle.experimental());
|
||||
|
||||
private final RegistryEntry.BuilderHolder<M, T, B> entry;
|
||||
private final MappedRegistry<M> registry;
|
||||
private final PaperRegistryBuilder.Factory<M, T, ? extends B> builderFactory;
|
||||
|
||||
public WritableCraftRegistry(
|
||||
final RegistryEntry.BuilderHolder<M, T, B> entry,
|
||||
final Class<?> classToPreload,
|
||||
final MappedRegistry<M> registry,
|
||||
final BiFunction<NamespacedKey, ApiVersion, NamespacedKey> serializationUpdater,
|
||||
final PaperRegistryBuilder.Factory<M, T, ? extends B> builderFactory,
|
||||
final RegistryTypeMapper<M, T> minecraftToBukkit
|
||||
) {
|
||||
super(classToPreload, registry, minecraftToBukkit, serializationUpdater);
|
||||
this.entry = entry;
|
||||
this.registry = registry;
|
||||
this.builderFactory = builderFactory;
|
||||
}
|
||||
|
||||
public void register(final TypedKey<T> key, final Consumer<? super B> value, final Conversions conversions) {
|
||||
final ResourceKey<M> resourceKey = PaperRegistries.toNms(key);
|
||||
this.registry.validateWrite(resourceKey);
|
||||
final B builder = this.newBuilder(conversions);
|
||||
value.accept(builder);
|
||||
PaperRegistryListenerManager.INSTANCE.registerWithListeners(
|
||||
this.registry,
|
||||
RegistryEntry.Modifiable.asModifiable(this.entry),
|
||||
resourceKey,
|
||||
builder,
|
||||
FROM_PLUGIN,
|
||||
conversions
|
||||
);
|
||||
}
|
||||
|
||||
public WritableRegistry<T, B> createApiWritableRegistry(final Conversions conversions) {
|
||||
return new ApiWritableRegistry(conversions);
|
||||
}
|
||||
|
||||
protected B newBuilder(final Conversions conversions) {
|
||||
return this.builderFactory.create(conversions);
|
||||
}
|
||||
|
||||
public class ApiWritableRegistry implements WritableRegistry<T, B> {
|
||||
|
||||
private final Conversions conversions;
|
||||
|
||||
public ApiWritableRegistry(final Conversions conversions) {
|
||||
this.conversions = conversions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(final TypedKey<T> key, final Consumer<? super B> value) {
|
||||
WritableCraftRegistry.this.register(key, value, this.conversions);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package io.papermc.paper.registry.data.util;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.mojang.serialization.JavaOps;
|
||||
import io.papermc.paper.adventure.WrapperAwareSerializer;
|
||||
import java.util.Optional;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class Conversions {
|
||||
|
||||
private static @Nullable Conversions globalInstance;
|
||||
public static Conversions global() {
|
||||
if (globalInstance == null) {
|
||||
final RegistryAccess globalAccess = CraftRegistry.getMinecraftRegistry();
|
||||
Preconditions.checkState(globalAccess != null, "Global registry access is not available");
|
||||
globalInstance = new Conversions(new RegistryOps.RegistryInfoLookup() {
|
||||
@Override
|
||||
public <T> Optional<RegistryOps.RegistryInfo<T>> lookup(final ResourceKey<? extends Registry<? extends T>> registryRef) {
|
||||
final Registry<T> registry = globalAccess.lookupOrThrow(registryRef);
|
||||
return Optional.of(
|
||||
new RegistryOps.RegistryInfo<>(registry, registry, registry.registryLifecycle())
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
return globalInstance;
|
||||
}
|
||||
|
||||
|
||||
private final RegistryOps.RegistryInfoLookup lookup;
|
||||
private final WrapperAwareSerializer serializer;
|
||||
|
||||
public Conversions(final RegistryOps.RegistryInfoLookup lookup) {
|
||||
this.lookup = lookup;
|
||||
this.serializer = new WrapperAwareSerializer(() -> RegistryOps.create(JavaOps.INSTANCE, lookup));
|
||||
}
|
||||
|
||||
public RegistryOps.RegistryInfoLookup lookup() {
|
||||
return this.lookup;
|
||||
}
|
||||
|
||||
@Contract("null -> null; !null -> !null")
|
||||
public net.minecraft.network.chat.@Nullable Component asVanilla(final @Nullable Component adventure) {
|
||||
if (adventure == null) return null;
|
||||
return this.serializer.serialize(adventure);
|
||||
}
|
||||
|
||||
public Component asAdventure(final net.minecraft.network.chat.@Nullable Component vanilla) {
|
||||
return vanilla == null ? Component.empty() : this.serializer.deserialize(vanilla);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
@NullMarked
|
||||
package io.papermc.paper.registry.data.util;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -0,0 +1,41 @@
|
|||
package io.papermc.paper.registry.entry;
|
||||
|
||||
import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
import io.papermc.paper.registry.RegistryHolder;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.WritableCraftRegistry;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.Keyed;
|
||||
|
||||
public class AddableRegistryEntry<M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> extends CraftRegistryEntry<M, T> implements RegistryEntry.Addable<M, T, B> {
|
||||
|
||||
private final PaperRegistryBuilder.Filler<M, T, B> builderFiller;
|
||||
|
||||
protected AddableRegistryEntry(
|
||||
final ResourceKey<? extends Registry<M>> mcKey,
|
||||
final RegistryKey<T> apiKey,
|
||||
final Class<?> classToPreload,
|
||||
final RegistryTypeMapper<M, T> minecraftToBukkit,
|
||||
final PaperRegistryBuilder.Filler<M, T, B> builderFiller
|
||||
) {
|
||||
super(mcKey, apiKey, classToPreload, minecraftToBukkit);
|
||||
this.builderFiller = builderFiller;
|
||||
}
|
||||
|
||||
private WritableCraftRegistry<M, T, B> createRegistry(final Registry<M> registry) {
|
||||
return new WritableCraftRegistry<>(this, this.classToPreload, (MappedRegistry<M>) registry, this.updater, this.builderFiller.asFactory(), this.minecraftToBukkit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistryHolder<T> createRegistryHolder(final Registry<M> nmsRegistry) {
|
||||
return new RegistryHolder.Memoized<>(() -> this.createRegistry(nmsRegistry));
|
||||
}
|
||||
|
||||
@Override
|
||||
public B fillBuilder(final Conversions conversions, final M nms) {
|
||||
return this.builderFiller.fill(conversions, nms);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package io.papermc.paper.registry.entry;
|
||||
|
||||
import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.Keyed;
|
||||
|
||||
public class ModifiableRegistryEntry<M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> extends CraftRegistryEntry<M, T> implements RegistryEntry.Modifiable<M, T, B> {
|
||||
|
||||
protected final PaperRegistryBuilder.Filler<M, T, B> builderFiller;
|
||||
|
||||
protected ModifiableRegistryEntry(
|
||||
final ResourceKey<? extends Registry<M>> mcKey,
|
||||
final RegistryKey<T> apiKey,
|
||||
final Class<?> toPreload,
|
||||
final RegistryTypeMapper<M, T> minecraftToBukkit,
|
||||
final PaperRegistryBuilder.Filler<M, T, B> builderFiller
|
||||
) {
|
||||
super(mcKey, apiKey, toPreload, minecraftToBukkit);
|
||||
this.builderFiller = builderFiller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public B fillBuilder(final Conversions conversions, final M nms) {
|
||||
return this.builderFiller.fill(conversions, nms);
|
||||
}
|
||||
}
|
|
@ -1,13 +1,20 @@
|
|||
package io.papermc.paper.registry.entry;
|
||||
|
||||
import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
import io.papermc.paper.registry.RegistryHolder;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import io.papermc.paper.registry.WritableCraftRegistry;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.event.RegistryEntryAddEventImpl;
|
||||
import io.papermc.paper.registry.event.RegistryFreezeEventImpl;
|
||||
import io.papermc.paper.registry.legacy.DelayedRegistryEntry;
|
||||
import java.util.function.BiFunction;
|
||||
import net.minecraft.core.Registry;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.craftbukkit.util.ApiVersion;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public interface RegistryEntry<M, B extends Keyed> extends RegistryEntryInfo<M, B> { // TODO remove Keyed
|
||||
|
||||
|
@ -26,4 +33,63 @@ public interface RegistryEntry<M, B extends Keyed> extends RegistryEntryInfo<M,
|
|||
default RegistryEntry<M, B> delayed() {
|
||||
return new DelayedRegistryEntry<>(this);
|
||||
}
|
||||
|
||||
interface BuilderHolder<M, T, B extends PaperRegistryBuilder<M, T>> extends RegistryEntryInfo<M, T> {
|
||||
|
||||
B fillBuilder(Conversions conversions, M nms);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can mutate values being added to the registry
|
||||
*/
|
||||
interface Modifiable<M, T, B extends PaperRegistryBuilder<M, T>> extends BuilderHolder<M, T, B> {
|
||||
|
||||
static boolean isModifiable(final @Nullable RegistryEntryInfo<?, ?> entry) {
|
||||
return entry instanceof RegistryEntry.Modifiable<?, ?, ?> || (entry instanceof final DelayedRegistryEntry<?, ?> delayed && delayed.delegate() instanceof RegistryEntry.Modifiable<?, ?, ?>);
|
||||
}
|
||||
|
||||
static <M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> Modifiable<M, T, B> asModifiable(final RegistryEntryInfo<M, T> entry) { // TODO remove Keyed
|
||||
return (Modifiable<M, T, B>) possiblyUnwrap(entry);
|
||||
}
|
||||
|
||||
default RegistryEntryAddEventImpl<T, B> createEntryAddEvent(final TypedKey<T> key, final B initialBuilder, final Conversions conversions) {
|
||||
return new RegistryEntryAddEventImpl<>(key, initialBuilder, this.apiKey(), conversions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Can only add new values to the registry, not modify any values.
|
||||
*/
|
||||
interface Addable<M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> extends BuilderHolder<M, T, B> { // TODO remove Keyed
|
||||
|
||||
default RegistryFreezeEventImpl<T, B> createFreezeEvent(final WritableCraftRegistry<M, T, B> writableRegistry, final Conversions conversions) {
|
||||
return new RegistryFreezeEventImpl<>(this.apiKey(), writableRegistry.createApiWritableRegistry(conversions), conversions);
|
||||
}
|
||||
|
||||
static boolean isAddable(final @Nullable RegistryEntryInfo<?, ?> entry) {
|
||||
return entry instanceof RegistryEntry.Addable<?, ?, ?> || (entry instanceof final DelayedRegistryEntry<?, ?> delayed && delayed.delegate() instanceof RegistryEntry.Addable<?, ?, ?>);
|
||||
}
|
||||
|
||||
static <M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> Addable<M, T, B> asAddable(final RegistryEntryInfo<M, T> entry) {
|
||||
return (Addable<M, T, B>) possiblyUnwrap(entry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Can mutate values and add new values.
|
||||
*/
|
||||
interface Writable<M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> extends Modifiable<M, T, B>, Addable<M, T, B> { // TODO remove Keyed
|
||||
|
||||
static boolean isWritable(final @Nullable RegistryEntryInfo<?, ?> entry) {
|
||||
return entry instanceof RegistryEntry.Writable<?, ?, ?> || (entry instanceof final DelayedRegistryEntry<?, ?> delayed && delayed.delegate() instanceof RegistryEntry.Writable<?, ?, ?>);
|
||||
}
|
||||
|
||||
static <M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> Writable<M, T, B> asWritable(final RegistryEntryInfo<M, T> entry) { // TODO remove Keyed
|
||||
return (Writable<M, T, B>) possiblyUnwrap(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private static <M, B extends Keyed> RegistryEntryInfo<M, B> possiblyUnwrap(final RegistryEntryInfo<M, B> entry) {
|
||||
return entry instanceof final DelayedRegistryEntry<M, B> delayed ? delayed.delegate() : entry;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.papermc.paper.registry.entry;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
@ -59,5 +60,17 @@ public class RegistryEntryBuilder<M, A extends Keyed> { // TODO remove Keyed
|
|||
public RegistryEntry<M, A> build() {
|
||||
return new CraftRegistryEntry<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit);
|
||||
}
|
||||
|
||||
public <B extends PaperRegistryBuilder<M, A>> RegistryEntry<M, A> modifiable(final PaperRegistryBuilder.Filler<M, A, B> filler) {
|
||||
return new ModifiableRegistryEntry<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit, filler);
|
||||
}
|
||||
|
||||
public <B extends PaperRegistryBuilder<M, A>> RegistryEntry<M, A> addable(final PaperRegistryBuilder.Filler<M, A, B> filler) {
|
||||
return new AddableRegistryEntry<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit, filler);
|
||||
}
|
||||
|
||||
public <B extends PaperRegistryBuilder<M, A>> RegistryEntry<M, A> writable(final PaperRegistryBuilder.Filler<M, A, B> filler) {
|
||||
return new WritableRegistryEntry<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit, filler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package io.papermc.paper.registry.entry;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import io.papermc.paper.registry.PaperRegistryBuilder;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.NamespacedKey;
|
||||
|
||||
public class WritableRegistryEntry<M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> extends AddableRegistryEntry<M, T, B> implements RegistryEntry.Writable<M, T, B> { // TODO remove Keyed
|
||||
|
||||
protected WritableRegistryEntry(
|
||||
final ResourceKey<? extends Registry<M>> mcKey,
|
||||
final RegistryKey<T> apiKey,
|
||||
final Class<?> classToPreload,
|
||||
final RegistryTypeMapper<M, T> minecraftToBukkit,
|
||||
final PaperRegistryBuilder.Filler<M, T, B> builderFiller
|
||||
) {
|
||||
super(mcKey, apiKey, classToPreload, minecraftToBukkit, builderFiller);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package io.papermc.paper.registry.event;
|
||||
|
||||
import io.papermc.paper.plugin.lifecycle.event.PaperLifecycleEvent;
|
||||
import io.papermc.paper.registry.PaperRegistries;
|
||||
import io.papermc.paper.registry.RegistryBuilder;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.set.NamedRegistryKeySetImpl;
|
||||
import io.papermc.paper.registry.tag.Tag;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import org.bukkit.Keyed;
|
||||
|
||||
public record RegistryEntryAddEventImpl<T, B extends RegistryBuilder<T>>(
|
||||
TypedKey<T> key,
|
||||
B builder,
|
||||
RegistryKey<T> registryKey,
|
||||
Conversions conversions
|
||||
) implements RegistryEntryAddEvent<T, B>, PaperLifecycleEvent {
|
||||
|
||||
@Override
|
||||
public <V extends Keyed> Tag<V> getOrCreateTag(final TagKey<V> tagKey) {
|
||||
final RegistryOps.RegistryInfo<Object> registryInfo = this.conversions.lookup().lookup(PaperRegistries.registryToNms(tagKey.registryKey())).orElseThrow();
|
||||
final HolderSet.Named<?> tagSet = registryInfo.getter().getOrThrow(PaperRegistries.toNms(tagKey));
|
||||
return new NamedRegistryKeySetImpl<>(tagKey, tagSet);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package io.papermc.paper.registry.event;
|
||||
|
||||
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner;
|
||||
import io.papermc.paper.plugin.lifecycle.event.types.AbstractLifecycleEventType;
|
||||
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public final class RegistryEventMap {
|
||||
|
||||
private final Map<RegistryKey<?>, LifecycleEventType<BootstrapContext, ? extends LifecycleEvent, ?>> eventTypes = new HashMap<>();
|
||||
private final String name;
|
||||
|
||||
public RegistryEventMap(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, E extends LifecycleEvent, ET extends LifecycleEventType<BootstrapContext, E, ?>> ET getOrCreate(final RegistryKey<T> registryKey, final BiFunction<? super RegistryKey<T>, ? super String, ET> eventTypeCreator) {
|
||||
final ET eventType;
|
||||
if (this.eventTypes.containsKey(registryKey)) {
|
||||
eventType = (ET) this.eventTypes.get(registryKey);
|
||||
} else {
|
||||
eventType = eventTypeCreator.apply(registryKey, this.name);
|
||||
this.eventTypes.put(registryKey, eventType);
|
||||
}
|
||||
return eventType;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, E extends LifecycleEvent> LifecycleEventType<BootstrapContext, E, ?> getEventType(final RegistryKey<T> registryKey) {
|
||||
return (LifecycleEventType<BootstrapContext, E, ?>) Objects.requireNonNull(this.eventTypes.get(registryKey), "No hook for " + registryKey);
|
||||
}
|
||||
|
||||
public boolean hasHandlers(final RegistryKey<?> registryKey) {
|
||||
final AbstractLifecycleEventType<?, ?, ?> type = ((AbstractLifecycleEventType<?, ?, ?>) this.eventTypes.get(registryKey));
|
||||
return type != null && type.hasHandlers();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package io.papermc.paper.registry.event;
|
||||
|
||||
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
||||
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
|
||||
import io.papermc.paper.registry.PaperRegistryListenerManager;
|
||||
import io.papermc.paper.registry.RegistryBuilder;
|
||||
import io.papermc.paper.registry.event.type.RegistryEntryAddEventType;
|
||||
|
||||
public class RegistryEventTypeProviderImpl implements RegistryEventTypeProvider {
|
||||
|
||||
public static RegistryEventTypeProviderImpl instance() {
|
||||
return (RegistryEventTypeProviderImpl) RegistryEventTypeProvider.provider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, B extends RegistryBuilder<T>> RegistryEntryAddEventType<T, B> registryEntryAdd(final RegistryEventProvider<T, B> type) {
|
||||
return PaperRegistryListenerManager.INSTANCE.getRegistryValueAddEventType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, B extends RegistryBuilder<T>> LifecycleEventType.Prioritizable<BootstrapContext, RegistryFreezeEvent<T, B>> registryFreeze(final RegistryEventProvider<T, B> type) {
|
||||
return PaperRegistryListenerManager.INSTANCE.getRegistryFreezeEventType(type);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package io.papermc.paper.registry.event;
|
||||
|
||||
import io.papermc.paper.plugin.lifecycle.event.PaperLifecycleEvent;
|
||||
import io.papermc.paper.registry.PaperRegistries;
|
||||
import io.papermc.paper.registry.RegistryBuilder;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.set.NamedRegistryKeySetImpl;
|
||||
import io.papermc.paper.registry.tag.Tag;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import org.bukkit.Keyed;
|
||||
|
||||
public record RegistryFreezeEventImpl<T, B extends RegistryBuilder<T>>(
|
||||
RegistryKey<T> registryKey,
|
||||
WritableRegistry<T, B> registry,
|
||||
Conversions conversions
|
||||
) implements RegistryFreezeEvent<T, B>, PaperLifecycleEvent {
|
||||
|
||||
@Override
|
||||
public <V extends Keyed> Tag<V> getOrCreateTag(final TagKey<V> tagKey) {
|
||||
final RegistryOps.RegistryInfo<Object> registryInfo = this.conversions.lookup().lookup(PaperRegistries.registryToNms(tagKey.registryKey())).orElseThrow();
|
||||
final HolderSet.Named<?> tagSet = registryInfo.getter().getOrThrow(PaperRegistries.toNms(tagKey));
|
||||
return new NamedRegistryKeySetImpl<>(tagKey, tagSet);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
@NullMarked
|
||||
package io.papermc.paper.registry.event;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -0,0 +1,37 @@
|
|||
package io.papermc.paper.registry.event.type;
|
||||
|
||||
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
||||
import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
import io.papermc.paper.plugin.lifecycle.event.types.PrioritizableLifecycleEventType;
|
||||
import io.papermc.paper.registry.RegistryBuilder;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.event.RegistryEntryAddEvent;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class RegistryEntryAddEventTypeImpl<T, B extends RegistryBuilder<T>> extends PrioritizableLifecycleEventType<BootstrapContext, RegistryEntryAddEvent<T, B>, RegistryEntryAddConfiguration<T>> implements RegistryEntryAddEventType<T, B> {
|
||||
|
||||
public RegistryEntryAddEventTypeImpl(final RegistryKey<T> registryKey, final String eventName) {
|
||||
super(registryKey + " / " + eventName, BootstrapContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean blocksReloading(final BootstrapContext eventOwner) {
|
||||
return false; // only runs once
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistryEntryAddConfiguration<T> newHandler(final LifecycleEventHandler<? super RegistryEntryAddEvent<T, B>> handler) {
|
||||
return new RegistryEntryAddHandlerConfiguration<>(handler, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachHandler(final RegistryEntryAddEvent<T, B> event, final Consumer<RegisteredHandler<BootstrapContext, RegistryEntryAddEvent<T, B>>> consumer, final Predicate<RegisteredHandler<BootstrapContext, RegistryEntryAddEvent<T, B>>> predicate) {
|
||||
super.forEachHandler(event, consumer, predicate.and(handler -> this.matchesTarget(event, handler)));
|
||||
}
|
||||
|
||||
private boolean matchesTarget(final RegistryEntryAddEvent<T, B> event, final RegisteredHandler<BootstrapContext, RegistryEntryAddEvent<T, B>> handler) {
|
||||
final RegistryEntryAddHandlerConfiguration<T, B> config = (RegistryEntryAddHandlerConfiguration<T, B>) handler.config();
|
||||
return config.filter() == null || config.filter().test(event.key());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package io.papermc.paper.registry.event.type;
|
||||
|
||||
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
||||
import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfigurationImpl;
|
||||
import io.papermc.paper.plugin.lifecycle.event.types.AbstractLifecycleEventType;
|
||||
import io.papermc.paper.registry.RegistryBuilder;
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import io.papermc.paper.registry.event.RegistryEntryAddEvent;
|
||||
import java.util.function.Predicate;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class RegistryEntryAddHandlerConfiguration<T, B extends RegistryBuilder<T>> extends PrioritizedLifecycleEventHandlerConfigurationImpl<BootstrapContext, RegistryEntryAddEvent<T, B>> implements RegistryEntryAddConfiguration<T> {
|
||||
|
||||
private @Nullable Predicate<TypedKey<T>> filter;
|
||||
|
||||
public RegistryEntryAddHandlerConfiguration(final LifecycleEventHandler<? super RegistryEntryAddEvent<T, B>> handler, final AbstractLifecycleEventType<BootstrapContext, RegistryEntryAddEvent<T, B>, ?> eventType) {
|
||||
super(handler, eventType);
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
public @Nullable Predicate<TypedKey<T>> filter() {
|
||||
return this.filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistryEntryAddConfiguration<T> filter(final Predicate<TypedKey<T>> filter) {
|
||||
this.filter = filter;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistryEntryAddConfiguration<T> priority(final int priority) {
|
||||
return (RegistryEntryAddConfiguration<T>) super.priority(priority);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistryEntryAddConfiguration<T> monitor() {
|
||||
return (RegistryEntryAddConfiguration<T>) super.monitor();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package io.papermc.paper.registry.event.type;
|
||||
|
||||
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
||||
import io.papermc.paper.plugin.lifecycle.event.types.PrioritizableLifecycleEventType;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.event.RegistryEvent;
|
||||
|
||||
public final class RegistryLifecycleEventType<T, E extends RegistryEvent<T>> extends PrioritizableLifecycleEventType.Simple<BootstrapContext, E> {
|
||||
|
||||
public RegistryLifecycleEventType(final RegistryKey<T> registryKey, final String eventName) {
|
||||
super(registryKey + " / " + eventName, BootstrapContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean blocksReloading(final BootstrapContext eventOwner) {
|
||||
return false; // only runs once
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
@NullMarked
|
||||
package io.papermc.paper.registry.event.type;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -1,11 +1,14 @@
|
|||
package io.papermc.paper.registry.legacy;
|
||||
|
||||
import io.papermc.paper.registry.tag.Tag;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Registry;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
|
@ -54,4 +57,14 @@ public final class DelayedRegistry<T extends Keyed, R extends Registry<T>> imple
|
|||
public @Nullable NamespacedKey getKey(final T value) {
|
||||
return this.delegate().getKey(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTag(final TagKey<T> key) {
|
||||
return this.delegate().hasTag(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Tag<T> getTag(final TagKey<T> key) {
|
||||
return this.delegate().getTag(key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package io.papermc.paper.registry.set;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import io.papermc.paper.registry.PaperRegistries;
|
||||
import io.papermc.paper.registry.RegistryAccess;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import io.papermc.paper.registry.tag.Tag;
|
||||
import io.papermc.paper.registry.tag.TagKey;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@NullMarked
|
||||
public record NamedRegistryKeySetImpl<T extends Keyed, M>( // TODO remove Keyed
|
||||
TagKey<T> tagKey,
|
||||
HolderSet.Named<M> namedSet
|
||||
) implements Tag<T>, org.bukkit.Tag<T> {
|
||||
|
||||
@Override
|
||||
public @Unmodifiable Collection<TypedKey<T>> values() {
|
||||
final ImmutableList.Builder<TypedKey<T>> builder = ImmutableList.builder();
|
||||
for (final Holder<M> holder : this.namedSet) {
|
||||
builder.add(TypedKey.create(this.tagKey.registryKey(), CraftNamespacedKey.fromMinecraft(((Holder.Reference<?>) holder).key().location())));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistryKey<T> registryKey() {
|
||||
return this.tagKey.registryKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(final TypedKey<T> valueKey) {
|
||||
return Iterables.any(this.namedSet, h -> {
|
||||
return PaperRegistries.fromNms(((Holder.Reference<?>) h).key()).equals(valueKey);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Unmodifiable Collection<T> resolve(final Registry<T> registry) {
|
||||
final ImmutableList.Builder<T> builder = ImmutableList.builder();
|
||||
for (final Holder<M> holder : this.namedSet) {
|
||||
builder.add(registry.getOrThrow(CraftNamespacedKey.fromMinecraft(((Holder.Reference<?>) holder).key().location())));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTagged(final T item) {
|
||||
return this.getValues().contains(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<T> getValues() {
|
||||
return Set.copyOf(this.resolve(RegistryAccess.registryAccess().getRegistry(this.registryKey())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespacedKey getKey() {
|
||||
final Key key = this.tagKey().key();
|
||||
return new NamespacedKey(key.namespace(), key.value());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package io.papermc.paper.registry.set;
|
||||
|
||||
import io.papermc.paper.registry.PaperRegistries;
|
||||
import io.papermc.paper.registry.RegistryKey;
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.Keyed;
|
||||
|
||||
public final class PaperRegistrySets {
|
||||
|
||||
public static <A extends Keyed, M> HolderSet<M> convertToNms(final ResourceKey<? extends Registry<M>> resourceKey, final RegistryOps.RegistryInfoLookup lookup, final RegistryKeySet<A> registryKeySet) { // TODO remove Keyed
|
||||
if (registryKeySet instanceof NamedRegistryKeySetImpl<A, ?>) {
|
||||
return ((NamedRegistryKeySetImpl<A, M>) registryKeySet).namedSet();
|
||||
} else {
|
||||
final RegistryOps.RegistryInfo<M> registryInfo = lookup.lookup(resourceKey).orElseThrow();
|
||||
return HolderSet.direct(key -> {
|
||||
return registryInfo.getter().getOrThrow(PaperRegistries.toNms(key));
|
||||
}, registryKeySet.values());
|
||||
}
|
||||
}
|
||||
|
||||
public static <A extends Keyed, M> RegistryKeySet<A> convertToApi(final RegistryKey<A> registryKey, final HolderSet<M> holders) { // TODO remove Keyed
|
||||
if (holders instanceof final HolderSet.Named<M> named) {
|
||||
return new NamedRegistryKeySetImpl<>(PaperRegistries.fromNms(named.key()), named);
|
||||
} else {
|
||||
final List<TypedKey<A>> keys = new ArrayList<>();
|
||||
for (final Holder<M> holder : holders) {
|
||||
if (!(holder instanceof final Holder.Reference<M> reference)) {
|
||||
throw new UnsupportedOperationException("Cannot convert a holder set containing direct holders");
|
||||
}
|
||||
keys.add(PaperRegistries.fromNms(reference.key()));
|
||||
}
|
||||
return RegistrySet.keySet(registryKey, keys);
|
||||
}
|
||||
}
|
||||
|
||||
private PaperRegistrySets() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
@NullMarked
|
||||
package io.papermc.paper.registry.set;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -301,4 +301,17 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
|||
return this.byValue.get(value);
|
||||
}
|
||||
// Paper end - improve Registry
|
||||
|
||||
// Paper start - RegistrySet API
|
||||
@Override
|
||||
public boolean hasTag(final io.papermc.paper.registry.tag.TagKey<B> key) {
|
||||
return this.minecraftRegistry.get(net.minecraft.tags.TagKey.create(this.minecraftRegistry.key(), io.papermc.paper.adventure.PaperAdventure.asVanilla(key.key()))).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public io.papermc.paper.registry.tag.Tag<B> getTag(final io.papermc.paper.registry.tag.TagKey<B> key) {
|
||||
final net.minecraft.core.HolderSet.Named<M> namedHolderSet = this.minecraftRegistry.get(io.papermc.paper.registry.PaperRegistries.toNms(key)).orElseThrow();
|
||||
return new io.papermc.paper.registry.set.NamedRegistryKeySetImpl<>(key, namedHolderSet);
|
||||
}
|
||||
// Paper end - RegistrySet API
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
io.papermc.paper.registry.event.RegistryEventTypeProviderImpl
|
|
@ -0,0 +1,44 @@
|
|||
package io.papermc.paper.registry;
|
||||
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.entry.RegistryEntry;
|
||||
import io.papermc.paper.registry.entry.RegistryEntryInfo;
|
||||
import io.papermc.paper.registry.legacy.DelayedRegistryEntry;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.support.RegistryHelper;
|
||||
import org.bukkit.support.environment.AllFeatures;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@AllFeatures
|
||||
class RegistryBuilderTest {
|
||||
|
||||
static Stream<Arguments> registries() {
|
||||
return PaperRegistries.REGISTRY_ENTRIES.stream()
|
||||
.map(RegistryBuilderTest::possiblyUnwrap)
|
||||
.filter(RegistryEntry.BuilderHolder.class::isInstance)
|
||||
.map(Arguments::arguments);
|
||||
}
|
||||
|
||||
private static <M, B extends Keyed> RegistryEntryInfo<M, B> possiblyUnwrap(final RegistryEntryInfo<M, B> entry) {
|
||||
return entry instanceof final DelayedRegistryEntry<M, B> delayed ? delayed.delegate() : entry;
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("registries")
|
||||
<M, T> void testEquality(final RegistryEntry.BuilderHolder<M, T, ?> registryEntry) {
|
||||
final Registry<M> registry = RegistryHelper.getRegistry().lookupOrThrow(registryEntry.mcKey());
|
||||
for (final Map.Entry<ResourceKey<M>, M> entry : registry.entrySet()) {
|
||||
final M built = registryEntry.fillBuilder(new Conversions(new RegistryOps.HolderLookupAdapter(RegistryHelper.getRegistry())), entry.getValue()).build();
|
||||
assertEquals(entry.getValue(), built);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -111,7 +111,7 @@ public class RegistryClassTest {
|
|||
outsideRequest.clear();
|
||||
MockUtil.resetMock(spyRegistry);
|
||||
doAnswer(invocation -> {
|
||||
Keyed item = realRegistry.get(invocation.getArgument(0));
|
||||
Keyed item = realRegistry.get((NamespacedKey) invocation.getArgument(0)); // Paper - registry modification api - specifically call namespaced key overload
|
||||
|
||||
if (item == null) {
|
||||
nullValue.add(invocation.getArgument(0));
|
||||
|
@ -120,10 +120,10 @@ public class RegistryClassTest {
|
|||
nullAble.add(invocation.getArgument(0));
|
||||
|
||||
return item;
|
||||
}).when(spyRegistry).get(any());
|
||||
}).when(spyRegistry).get((NamespacedKey) any()); // Paper - registry modification api - specifically call namespaced key overload
|
||||
|
||||
doAnswer(invocation -> {
|
||||
Keyed item = realRegistry.get(invocation.getArgument(0));
|
||||
Keyed item = realRegistry.get((NamespacedKey) invocation.getArgument(0)); // Paper - registry modification api - specifically call namespaced key overload
|
||||
|
||||
if (item == null) {
|
||||
nullValue.add(invocation.getArgument(0));
|
||||
|
@ -138,7 +138,7 @@ public class RegistryClassTest {
|
|||
notNullAble.add(invocation.getArgument(0));
|
||||
|
||||
return item;
|
||||
}).when(spyRegistry).getOrThrow(any());
|
||||
}).when(spyRegistry).getOrThrow((NamespacedKey) any()); // Paper - registry modification api - specifically call namespaced key overload
|
||||
|
||||
// Load class
|
||||
try {
|
||||
|
@ -171,13 +171,13 @@ public class RegistryClassTest {
|
|||
outsideRequest
|
||||
.computeIfAbsent(type, ty -> new ArrayList<>()).add(invocation.getArgument(0));
|
||||
return mock(type);
|
||||
}).when(spyRegistry).get(any());
|
||||
}).when(spyRegistry).get((NamespacedKey) any()); // Paper - registry modification api - specifically call namespaced key overload
|
||||
|
||||
doAnswer(invocation -> {
|
||||
outsideRequest
|
||||
.computeIfAbsent(type, ty -> new ArrayList<>()).add(invocation.getArgument(0));
|
||||
return mock(type);
|
||||
}).when(spyRegistry).getOrThrow(any());
|
||||
}).when(spyRegistry).getOrThrow((NamespacedKey) any()); // Paper - registry modification api - specifically call namespaced key overload
|
||||
}
|
||||
|
||||
private static void initFieldDataCache() {
|
||||
|
|
|
@ -62,7 +62,7 @@ public class NormalExtension extends BaseExtension {
|
|||
|
||||
doAnswer(invocation ->
|
||||
mocks.computeIfAbsent(invocation.getArgument(0), k -> mock(RegistryHelper.updateClass(keyed, invocation.getArgument(0)), withSettings().stubOnly().defaultAnswer(DEFAULT_ANSWER)))
|
||||
).when(registry).get(any()); // Allow static classes to fill there fields, so that it does not error out, just by loading them
|
||||
).when(registry).get((NamespacedKey) any()); // Allow static classes to fill there fields, so that it does not error out, just by loading them // Paper - registry modification api - specifically call namespaced key overload
|
||||
|
||||
return registry;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue