From c700b4ea9d7aebb09890c84175fb302755c40b3a Mon Sep 17 00:00:00 2001 From: LexManos Date: Sun, 12 May 2024 10:53:10 -0700 Subject: [PATCH] Make RegistryObject.getHolder lazy, Should help cases where vanilla registries use holders from other vanilla registries. Closes #9961 --- .../minecraft/core/MappedRegistry.java.patch | 6 +- .../registries/NamespacedWrapper.java | 3 +- .../registries/NewRegistryEvent.java | 30 ++--- .../registries/RegistryObject.java | 123 ++++++++---------- 4 files changed, 68 insertions(+), 94 deletions(-) diff --git a/patches/minecraft/net/minecraft/core/MappedRegistry.java.patch b/patches/minecraft/net/minecraft/core/MappedRegistry.java.patch index 0cb2f1385d..6ce918debd 100644 --- a/patches/minecraft/net/minecraft/core/MappedRegistry.java.patch +++ b/patches/minecraft/net/minecraft/core/MappedRegistry.java.patch @@ -35,12 +35,16 @@ } return this; -@@ -435,5 +_,20 @@ +@@ -435,5 +_,24 @@ @Override public HolderLookup.RegistryLookup asLookup() { return this.lookup; + } + ++ public boolean isIntrusive() { ++ return this.unregisteredIntrusiveHolders != null; ++ } ++ + private static final Set KNOWN = new java.util.LinkedHashSet<>(); + public static Set getKnownRegistries() { + return java.util.Collections.unmodifiableSet(KNOWN); diff --git a/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java b/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java index b57e58d975..45479c678b 100644 --- a/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java +++ b/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java @@ -377,7 +377,8 @@ class NamespacedWrapper extends MappedRegistry implements ILockableRegistr return this.frozen; } - boolean isIntrusive() { + @Override + public boolean isIntrusive() { return this.intrusiveHolderCallback != null && this.stage == RegistryManager.ACTIVE; } diff --git a/src/main/java/net/minecraftforge/registries/NewRegistryEvent.java b/src/main/java/net/minecraftforge/registries/NewRegistryEvent.java index e958149dc4..2e56cc60f9 100644 --- a/src/main/java/net/minecraftforge/registries/NewRegistryEvent.java +++ b/src/main/java/net/minecraftforge/registries/NewRegistryEvent.java @@ -22,8 +22,7 @@ import org.slf4j.Logger; /** * Register new registries when you receive this event through {@link RegistryBuilder} and {@link #create(RegistryBuilder)}. */ -public class NewRegistryEvent extends Event implements IModBusEvent -{ +public class NewRegistryEvent extends Event implements IModBusEvent { private static final Logger LOGGER = LogUtils.getLogger(); private final List> registries = new ArrayList<>(); @@ -35,8 +34,7 @@ public class NewRegistryEvent extends Event implements IModBusEvent * @param builder The builder to turn into a {@link IForgeRegistry} * @return A supplier of the {@link IForgeRegistry} created by the builder. Resolving too early will return null. */ - public Supplier> create(RegistryBuilder builder) - { + public Supplier> create(RegistryBuilder builder) { return create(builder, null); } @@ -47,8 +45,7 @@ public class NewRegistryEvent extends Event implements IModBusEvent * @param onFill Called when the returned supplier is filled with the registry * @return a supplier of the {@link IForgeRegistry} created by the builder. Resolving too early will return null. */ - public Supplier> create(RegistryBuilder builder, @Nullable Consumer> onFill) - { + public Supplier> create(RegistryBuilder builder, @Nullable Consumer> onFill) { RegistryHolder registryHolder = new RegistryHolder<>(); registries.add(new RegistryData<>(builder, registryHolder, onFill)); @@ -57,20 +54,17 @@ public class NewRegistryEvent extends Event implements IModBusEvent } @SuppressWarnings("deprecation") - void fill() - { + void fill() { RuntimeException aggregate = new RuntimeException(); Map, IForgeRegistry> builtRegistries = new IdentityHashMap<>(); if (BuiltInRegistries.REGISTRY instanceof MappedRegistry rootRegistry) rootRegistry.unfreeze(); - for (RegistryData data : this.registries) - { + for (RegistryData data : this.registries) { try { buildRegistry(builtRegistries, data); - } catch (Throwable t) - { + } catch (Throwable t) { aggregate.addSuppressed(t); return; } @@ -83,8 +77,7 @@ public class NewRegistryEvent extends Event implements IModBusEvent LOGGER.error(LogUtils.FATAL_MARKER, "Failed to create some forge registries, see suppressed exceptions for details", aggregate); } - private void buildRegistry(Map, IForgeRegistry> builtRegistries, RegistryData data) - { + private void buildRegistry(Map, IForgeRegistry> builtRegistries, RegistryData data) { RegistryBuilder builder = data.builder; IForgeRegistry registry = builder.create(); @@ -104,20 +97,17 @@ public class NewRegistryEvent extends Event implements IModBusEvent Consumer> onFill ) {} - private static class RegistryHolder implements Supplier> - { + private static class RegistryHolder implements Supplier> { IForgeRegistry registry = null; @Override - public IForgeRegistry get() - { + public IForgeRegistry get() { return this.registry; } } @Override - public String toString() - { + public String toString() { return "RegistryEvent.NewRegistry"; } } diff --git a/src/main/java/net/minecraftforge/registries/RegistryObject.java b/src/main/java/net/minecraftforge/registries/RegistryObject.java index 6d5a82ffcc..29f7767401 100644 --- a/src/main/java/net/minecraftforge/registries/RegistryObject.java +++ b/src/main/java/net/minecraftforge/registries/RegistryObject.java @@ -6,6 +6,7 @@ package net.minecraftforge.registries; import net.minecraft.core.Holder; +import net.minecraft.core.MappedRegistry; import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceKey; @@ -21,8 +22,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Stream; -public final class RegistryObject implements Supplier -{ +public final class RegistryObject implements Supplier { @Nullable private final ResourceLocation name; @Nullable @@ -31,7 +31,7 @@ public final class RegistryObject implements Supplier @Nullable private T value; @Nullable - private Holder holder; + private Supplier> holder; /** * Factory for a {@link RegistryObject} that stores the value of an object from the provided forge registry once it is ready. @@ -40,8 +40,7 @@ public final class RegistryObject implements Supplier * @param registry the forge registry * @return a {@link RegistryObject} that stores the value of an object from the provided forge registry once it is ready */ - public static RegistryObject create(final ResourceLocation name, IForgeRegistry registry) - { + public static RegistryObject create(final ResourceLocation name, IForgeRegistry registry) { return new RegistryObject(name, registry); } @@ -59,8 +58,7 @@ public final class RegistryObject implements Supplier * @see #create(ResourceLocation, IForgeRegistry) * @see #create(ResourceLocation, ResourceLocation, String) */ - public static RegistryObject create(final ResourceLocation name, final ResourceKey> registryKey, String modid) - { + public static RegistryObject create(final ResourceLocation name, final ResourceKey> registryKey, String modid) { return new RegistryObject<>(name, registryKey.location(), modid, false); } @@ -79,9 +77,7 @@ public final class RegistryObject implements Supplier * @see #create(ResourceLocation, IForgeRegistry) * @see #create(ResourceLocation, ResourceLocation, String) */ - public static RegistryObject createOptional(final ResourceLocation name, final ResourceKey> registryKey, - String modid) - { + public static RegistryObject createOptional(final ResourceLocation name, final ResourceKey> registryKey, String modid) { return new RegistryObject<>(name, registryKey.location(), modid, true); } @@ -99,8 +95,7 @@ public final class RegistryObject implements Supplier * @see #create(ResourceLocation, IForgeRegistry) * @see #create(ResourceLocation, ResourceKey, String) */ - public static RegistryObject create(final ResourceLocation name, final ResourceLocation registryName, String modid) - { + public static RegistryObject create(final ResourceLocation name, final ResourceLocation registryName, String modid) { return new RegistryObject<>(name, registryName, modid, false); } @@ -119,8 +114,7 @@ public final class RegistryObject implements Supplier * @see #create(ResourceLocation, IForgeRegistry) * @see #create(ResourceLocation, ResourceKey, String) */ - public static RegistryObject createOptional(final ResourceLocation name, final ResourceLocation registryName, String modid) - { + public static RegistryObject createOptional(final ResourceLocation name, final ResourceLocation registryName, String modid) { return new RegistryObject<>(name, registryName, modid, true); } @@ -139,47 +133,41 @@ public final class RegistryObject implements Supplier } @SuppressWarnings("unchecked") - private RegistryObject(ResourceLocation name, IForgeRegistry registry) - { + private RegistryObject(ResourceLocation name, IForgeRegistry registry) { if (registry == null) throw new IllegalArgumentException("Invalid registry argument, must not be null"); this.name = name; this.key = (ResourceKey) ResourceKey.create(registry.getRegistryKey(), name); this.optionalRegistry = false; - ObjectHolderRegistry.addHandler(pred -> - { + ObjectHolderRegistry.addHandler(pred -> { if (pred.test(registry.getRegistryName())) this.updateReference((IForgeRegistry) registry); }); this.updateReference((IForgeRegistry) registry); } - private RegistryObject(final ResourceLocation name, final ResourceLocation registryName, final String modid, boolean optionalRegistry) - { + private RegistryObject(final ResourceLocation name, final ResourceLocation registryName, final String modid, boolean optionalRegistry) { this.name = name; this.key = ResourceKey.create(ResourceKey.createRegistryKey(registryName), name); this.optionalRegistry = optionalRegistry; final Throwable callerStack = new Throwable("Calling Site from mod: " + modid); - ObjectHolderRegistry.addHandler(new Consumer<>() - { + ObjectHolderRegistry.addHandler(new Consumer<>() { private boolean registryExists = false; private boolean invalidRegistry = false; @Override - public void accept(Predicate pred) - { + public void accept(Predicate pred) { if (invalidRegistry) return; - if (!RegistryObject.this.optionalRegistry && !registryExists) - { - if (!registryExists(registryName)) - { + + if (!RegistryObject.this.optionalRegistry && !registryExists) { + if (!registryExists(registryName)) { invalidRegistry = true; - registryExists(registryName); throw new IllegalStateException("Unable to find registry with key " + registryName + " for mod \"" + modid + "\". Check the 'caused by' to see further stack.", callerStack); } registryExists = true; } + if (pred.test(registryName)) RegistryObject.this.updateReference(registryName); } @@ -199,62 +187,61 @@ public final class RegistryObject implements Supplier */ @NotNull @Override - public T get() - { + public T get() { T ret = this.value; Objects.requireNonNull(ret, () -> "Registry Object not present: " + this.name); return ret; } @SuppressWarnings("unchecked") - void updateReference(IForgeRegistry registry) - { + void updateReference(IForgeRegistry registry) { if (this.name == null || this.key == null) return; - if (registry.containsKey(this.name)) - { + + var wrapper = registry instanceof ForgeRegistry forge ? forge.getWrapper() : null; + if (registry.containsKey(this.name)) { this.value = registry.getValue(this.name); - this.holder = (Holder) registry.getHolder(this.name).orElse(null); - } - else - { + this.holder = () -> (Holder)registry.getHolder(this.name).orElse(null); + } else if (wrapper != null && !wrapper.isIntrusive()) { + this.value = null; + this.holder = () -> wrapper.createRegistrationLookup().getOrThrow(this.key); + } else { this.value = null; this.holder = null; } } @SuppressWarnings("unchecked") - void updateReference(Registry registry) - { + void updateReference(Registry registry) { if (this.name == null || this.key == null) return; - if (registry.containsKey(this.name)) - { + + var mapped = registry instanceof MappedRegistry m ? m : null; + if (registry.containsKey(this.name)) { this.value = registry.get(this.name); - this.holder = ((Registry) registry).getHolder(this.key).orElse(null); - } - else - { + this.holder = () -> ((Registry)registry).getHolder(this.key).orElse(null); + } else if (mapped != null && !mapped.isIntrusive()) { + this.value = null; + this.holder = () -> mapped.createRegistrationLookup().getOrThrow(this.key); + } else { this.value = null; this.holder = null; } } @SuppressWarnings("unchecked") - void updateReference(ResourceLocation registryName) - { + void updateReference(ResourceLocation registryName) { if (this.name == null) return; + IForgeRegistry forgeRegistry = RegistryManager.ACTIVE.getRegistry(registryName); - if (forgeRegistry != null) - { + if (forgeRegistry != null) { updateReference(forgeRegistry); return; } Registry vanillaRegistry = (Registry) BuiltInRegistries.REGISTRY.get(registryName); - if (vanillaRegistry != null) - { + if (vanillaRegistry != null) { updateReference(vanillaRegistry); return; } @@ -263,11 +250,9 @@ public final class RegistryObject implements Supplier this.holder = null; } - void updateReference(RegisterEvent event) - { + void updateReference(RegisterEvent event) { IForgeRegistry forgeRegistry = event.getForgeRegistry(); - if (forgeRegistry != null) - { + if (forgeRegistry != null) { updateReference(forgeRegistry); return; } @@ -279,14 +264,12 @@ public final class RegistryObject implements Supplier this.value = null; } - private static boolean registryExists(ResourceLocation registryName) - { + private static boolean registryExists(ResourceLocation registryName) { return RegistryManager.ACTIVE.getRegistry(registryName) != null || BuiltInRegistries.REGISTRY.containsKey(registryName); } - public ResourceLocation getId() - { + public ResourceLocation getId() { return this.name; } @@ -297,8 +280,7 @@ public final class RegistryObject implements Supplier * @return the resource key that points to the registry and name of this registry object */ @Nullable - public ResourceKey getKey() - { + public ResourceKey getKey() { return this.key; } @@ -477,24 +459,21 @@ public final class RegistryObject implements Supplier * @return an optional {@link Holder} instance pointing to this RegistryObject's name and value */ @NotNull - public Optional> getHolder() - { - return Optional.ofNullable(this.holder); + public Optional> getHolder() { + return Optional.ofNullable(this.holder == null ? null : this.holder.get()); } @Override - public boolean equals(Object obj) - { + public boolean equals(Object obj) { if (this == obj) return true; - if (obj instanceof RegistryObject) { - return Objects.equals(((RegistryObject)obj).name, name); + if (obj instanceof RegistryObject o) { + return Objects.equals(o.name, name); } return false; } @Override - public int hashCode() - { + public int hashCode() { return Objects.hashCode(name); } }