From eb8fe02a5ed96184ef47cfa50f00d5d4d2949a5f Mon Sep 17 00:00:00 2001 From: LexManos Date: Wed, 13 Apr 2022 23:04:04 -0700 Subject: [PATCH] Fix intrusive handlers on dummy objects. --- .../registries/ForgeRegistry.java | 25 +++++++++++++++++-- .../minecraftforge/registries/GameData.java | 2 +- .../registries/NamespacedHolderHelper.java | 12 ++++++++- .../registries/RegistryManager.java | 13 +++++++--- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java index 3239ce03e8..657273679b 100644 --- a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java @@ -876,6 +876,29 @@ public class ForgeRegistry> implements IForgeRe if (this.dummyFactory == null) return false; + ForgeRegistry active = RegistryManager.ACTIVE.getRegistry(getRegistryKey()); + Optional> holders = active.getHolderHelper(); + if (holders.isPresent() && holders.get().isIntrusive() && holders.get().isFrozen()) + { + try + { + // We have to unfreeze the ACTIVE registry because a lot of vanilla objects use intrusive handlers in object init. + holders.get().unfreeze(); + createAndAddDummy(key, id); + } + finally + { + holders.get().freeze(); + } + } + else + createAndAddDummy(key, id); + + return true; + } + + private void createAndAddDummy(ResourceLocation key, int id) + { V dummy = this.dummyFactory.createDummy(key); LOGGER.debug(REGISTRIES,"Registry {} Dummy Add: {} {} -> {}", this.name, key, id, dummy); @@ -906,8 +929,6 @@ public class ForgeRegistry> implements IForgeRe if (realId != id) LOGGER.warn(REGISTRIES,"Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.name, key, id, realId); this.dummies.add(key); - - return true; } //Public for tests diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/src/main/java/net/minecraftforge/registries/GameData.java index 9dd1632316..f58f39eb1b 100644 --- a/src/main/java/net/minecraftforge/registries/GameData.java +++ b/src/main/java/net/minecraftforge/registries/GameData.java @@ -737,7 +737,7 @@ public class GameData } } - RegistryManager STAGING = new RegistryManager("STAGING"); + RegistryManager STAGING = new RegistryManager(); final Map> remaps = Maps.newHashMap(); final LinkedHashMap> missing = Maps.newLinkedHashMap(); diff --git a/src/main/java/net/minecraftforge/registries/NamespacedHolderHelper.java b/src/main/java/net/minecraftforge/registries/NamespacedHolderHelper.java index c913272853..5c54bb3a1b 100644 --- a/src/main/java/net/minecraftforge/registries/NamespacedHolderHelper.java +++ b/src/main/java/net/minecraftforge/registries/NamespacedHolderHelper.java @@ -236,10 +236,20 @@ class NamespacedHolderHelper> this.frozen = false; } + boolean isFrozen() + { + return this.frozen; + } + + boolean isIntrusive() + { + return this.holderLookup != null; + } + @Nullable Holder onAdded(RegistryManager stage, int id, T newValue, T oldValue) { - if (stage != RegistryManager.ACTIVE) + if (stage != RegistryManager.ACTIVE && (this.holderLookup == null || !stage.isStaging())) // Intrusive handlers need updating in staging. return null; // Only do holder shit on the active registries, not pending or snapshots. ResourceKey key = ResourceKey.create(this.self.key(), newValue.getRegistryName()); diff --git a/src/main/java/net/minecraftforge/registries/RegistryManager.java b/src/main/java/net/minecraftforge/registries/RegistryManager.java index 5d0f455b94..486b0fb405 100644 --- a/src/main/java/net/minecraftforge/registries/RegistryManager.java +++ b/src/main/java/net/minecraftforge/registries/RegistryManager.java @@ -7,13 +7,11 @@ package net.minecraftforge.registries; import java.util.Collections; import java.util.HashMap; -import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; -import java.util.function.Function; import java.util.stream.Collectors; import com.google.common.collect.BiMap; @@ -28,7 +26,6 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.core.Registry; import net.minecraftforge.fml.IModStateTransition; -import net.minecraftforge.fml.ModContainer; import net.minecraftforge.network.HandshakeMessages; import net.minecraftforge.registries.ForgeRegistry.Snapshot; import org.apache.commons.lang3.tuple.Pair; @@ -50,6 +47,11 @@ public class RegistryManager private Map legacyNames = new HashMap<>(); private final String name; + RegistryManager() + { + this("STAGING"); + } + public RegistryManager(String name) { this.name = name; @@ -60,6 +62,11 @@ public class RegistryManager return this.name; } + boolean isStaging() + { + return "STAGING".equals(this.name); + } + @SuppressWarnings("unchecked") public > Class getSuperType(ResourceLocation key) {