mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 16:27:47 +00:00
Make RegistryObject.getHolder lazy, Should help cases where vanilla registries use holders from other vanilla registries. Closes #9961
This commit is contained in:
4 files changed
+68
-94
No files matched your search
@@ -377,7 +377,8 @@ class NamespacedWrapper<T> extends MappedRegistry<T> implements ILockableRegistr
|
||||
return this.frozen;
|
||||
}
|
||||
|
||||
boolean isIntrusive() {
|
||||
@Override
|
||||
public boolean isIntrusive() {
|
||||
return this.intrusiveHolderCallback != null && this.stage == RegistryManager.ACTIVE;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<RegistryData<?>> 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 <V> Supplier<IForgeRegistry<V>> create(RegistryBuilder<V> builder)
|
||||
{
|
||||
public <V> Supplier<IForgeRegistry<V>> create(RegistryBuilder<V> 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 <V> Supplier<IForgeRegistry<V>> create(RegistryBuilder<V> builder, @Nullable Consumer<IForgeRegistry<V>> onFill)
|
||||
{
|
||||
public <V> Supplier<IForgeRegistry<V>> create(RegistryBuilder<V> builder, @Nullable Consumer<IForgeRegistry<V>> onFill) {
|
||||
RegistryHolder<V> 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<RegistryBuilder<?>, 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 <T> void buildRegistry(Map<RegistryBuilder<?>, IForgeRegistry<?>> builtRegistries, RegistryData<T> data)
|
||||
{
|
||||
private <T> void buildRegistry(Map<RegistryBuilder<?>, IForgeRegistry<?>> builtRegistries, RegistryData<T> data) {
|
||||
RegistryBuilder<T> builder = data.builder;
|
||||
IForgeRegistry<T> registry = builder.create();
|
||||
|
||||
@@ -104,20 +97,17 @@ public class NewRegistryEvent extends Event implements IModBusEvent
|
||||
Consumer<IForgeRegistry<V>> onFill
|
||||
) {}
|
||||
|
||||
private static class RegistryHolder<V> implements Supplier<IForgeRegistry<V>>
|
||||
{
|
||||
private static class RegistryHolder<V> implements Supplier<IForgeRegistry<V>> {
|
||||
IForgeRegistry<V> registry = null;
|
||||
|
||||
@Override
|
||||
public IForgeRegistry<V> get()
|
||||
{
|
||||
public IForgeRegistry<V> get() {
|
||||
return this.registry;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
public String toString() {
|
||||
return "RegistryEvent.NewRegistry";
|
||||
}
|
||||
}
|
||||
@@ -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<T> implements Supplier<T>
|
||||
{
|
||||
public final class RegistryObject<T> implements Supplier<T> {
|
||||
@Nullable
|
||||
private final ResourceLocation name;
|
||||
@Nullable
|
||||
@@ -31,7 +31,7 @@ public final class RegistryObject<T> implements Supplier<T>
|
||||
@Nullable
|
||||
private T value;
|
||||
@Nullable
|
||||
private Holder<T> holder;
|
||||
private Supplier<Holder<T>> 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<T> implements Supplier<T>
|
||||
* @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 <T, U extends T> RegistryObject<U> create(final ResourceLocation name, IForgeRegistry<T> registry)
|
||||
{
|
||||
public static <T, U extends T> RegistryObject<U> create(final ResourceLocation name, IForgeRegistry<T> registry) {
|
||||
return new RegistryObject<U>(name, registry);
|
||||
}
|
||||
|
||||
@@ -59,8 +58,7 @@ public final class RegistryObject<T> implements Supplier<T>
|
||||
* @see #create(ResourceLocation, IForgeRegistry)
|
||||
* @see #create(ResourceLocation, ResourceLocation, String)
|
||||
*/
|
||||
public static <T, U extends T> RegistryObject<U> create(final ResourceLocation name, final ResourceKey<? extends Registry<T>> registryKey, String modid)
|
||||
{
|
||||
public static <T, U extends T> RegistryObject<U> create(final ResourceLocation name, final ResourceKey<? extends Registry<T>> registryKey, String modid) {
|
||||
return new RegistryObject<>(name, registryKey.location(), modid, false);
|
||||
}
|
||||
|
||||
@@ -79,9 +77,7 @@ public final class RegistryObject<T> implements Supplier<T>
|
||||
* @see #create(ResourceLocation, IForgeRegistry)
|
||||
* @see #create(ResourceLocation, ResourceLocation, String)
|
||||
*/
|
||||
public static <T, U extends T> RegistryObject<U> createOptional(final ResourceLocation name, final ResourceKey<? extends Registry<T>> registryKey,
|
||||
String modid)
|
||||
{
|
||||
public static <T, U extends T> RegistryObject<U> createOptional(final ResourceLocation name, final ResourceKey<? extends Registry<T>> registryKey, String modid) {
|
||||
return new RegistryObject<>(name, registryKey.location(), modid, true);
|
||||
}
|
||||
|
||||
@@ -99,8 +95,7 @@ public final class RegistryObject<T> implements Supplier<T>
|
||||
* @see #create(ResourceLocation, IForgeRegistry)
|
||||
* @see #create(ResourceLocation, ResourceKey, String)
|
||||
*/
|
||||
public static <T, U extends T> RegistryObject<U> create(final ResourceLocation name, final ResourceLocation registryName, String modid)
|
||||
{
|
||||
public static <T, U extends T> RegistryObject<U> create(final ResourceLocation name, final ResourceLocation registryName, String modid) {
|
||||
return new RegistryObject<>(name, registryName, modid, false);
|
||||
}
|
||||
|
||||
@@ -119,8 +114,7 @@ public final class RegistryObject<T> implements Supplier<T>
|
||||
* @see #create(ResourceLocation, IForgeRegistry)
|
||||
* @see #create(ResourceLocation, ResourceKey, String)
|
||||
*/
|
||||
public static <T, U extends T> RegistryObject<U> createOptional(final ResourceLocation name, final ResourceLocation registryName, String modid)
|
||||
{
|
||||
public static <T, U extends T> RegistryObject<U> createOptional(final ResourceLocation name, final ResourceLocation registryName, String modid) {
|
||||
return new RegistryObject<>(name, registryName, modid, true);
|
||||
}
|
||||
|
||||
@@ -139,47 +133,41 @@ public final class RegistryObject<T> implements Supplier<T>
|
||||
}
|
||||
|
||||
@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<T>) ResourceKey.create(registry.getRegistryKey(), name);
|
||||
this.optionalRegistry = false;
|
||||
ObjectHolderRegistry.addHandler(pred ->
|
||||
{
|
||||
ObjectHolderRegistry.addHandler(pred -> {
|
||||
if (pred.test(registry.getRegistryName()))
|
||||
this.updateReference((IForgeRegistry<? extends T>) registry);
|
||||
});
|
||||
this.updateReference((IForgeRegistry<? extends T>) 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<ResourceLocation> pred)
|
||||
{
|
||||
public void accept(Predicate<ResourceLocation> 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<T> implements Supplier<T>
|
||||
*/
|
||||
@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<? extends T> registry)
|
||||
{
|
||||
void updateReference(IForgeRegistry<? extends T> 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<T>) registry.getHolder(this.name).orElse(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.holder = () -> (Holder<T>)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<? extends T> registry)
|
||||
{
|
||||
void updateReference(Registry<? extends T> 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<T>) registry).getHolder(this.key).orElse(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.holder = () -> ((Registry<T>)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<? extends T> forgeRegistry = RegistryManager.ACTIVE.getRegistry(registryName);
|
||||
if (forgeRegistry != null)
|
||||
{
|
||||
if (forgeRegistry != null) {
|
||||
updateReference(forgeRegistry);
|
||||
return;
|
||||
}
|
||||
|
||||
Registry<? extends T> vanillaRegistry = (Registry<? extends T>) BuiltInRegistries.REGISTRY.get(registryName);
|
||||
if (vanillaRegistry != null)
|
||||
{
|
||||
if (vanillaRegistry != null) {
|
||||
updateReference(vanillaRegistry);
|
||||
return;
|
||||
}
|
||||
@@ -263,11 +250,9 @@ public final class RegistryObject<T> implements Supplier<T>
|
||||
this.holder = null;
|
||||
}
|
||||
|
||||
void updateReference(RegisterEvent event)
|
||||
{
|
||||
void updateReference(RegisterEvent event) {
|
||||
IForgeRegistry<? extends T> forgeRegistry = event.getForgeRegistry();
|
||||
if (forgeRegistry != null)
|
||||
{
|
||||
if (forgeRegistry != null) {
|
||||
updateReference(forgeRegistry);
|
||||
return;
|
||||
}
|
||||
@@ -279,14 +264,12 @@ public final class RegistryObject<T> implements Supplier<T>
|
||||
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<T> implements Supplier<T>
|
||||
* @return the resource key that points to the registry and name of this registry object
|
||||
*/
|
||||
@Nullable
|
||||
public ResourceKey<T> getKey()
|
||||
{
|
||||
public ResourceKey<T> getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
@@ -477,24 +459,21 @@ public final class RegistryObject<T> implements Supplier<T>
|
||||
* @return an optional {@link Holder} instance pointing to this RegistryObject's name and value
|
||||
*/
|
||||
@NotNull
|
||||
public Optional<Holder<T>> getHolder()
|
||||
{
|
||||
return Optional.ofNullable(this.holder);
|
||||
public Optional<Holder<T>> 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);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user