diff --git a/loader-common/src/main/java/org/cyclops/cyclopscore/config/DeferredHolderCommon.java b/loader-common/src/main/java/org/cyclops/cyclopscore/config/DeferredHolderCommon.java index a493287fd53..7f11a9f0f73 100644 --- a/loader-common/src/main/java/org/cyclops/cyclopscore/config/DeferredHolderCommon.java +++ b/loader-common/src/main/java/org/cyclops/cyclopscore/config/DeferredHolderCommon.java @@ -144,18 +144,19 @@ protected Registry getRegistry() { protected final void bind(boolean throwOnMissingRegistry) { if (this.holder != null) return; - // Check if we have an override for specific mod loaders - if (DeferredHolderCommon.BIND_OVERRIDE != null) { - this.holder = (Holder) DeferredHolderCommon.BIND_OVERRIDE.apply(this.key); - if (this.holder != null) { - return; - } - } - + // Bind via the registry first, as that gives us a Holder.Reference, which is required by delegates. Registry registry = getRegistry(); if (registry != null) { this.holder = registry.get(this.key).orElse(null); - } else if (throwOnMissingRegistry) { + } + + // Check if we have an override for specific mod loaders, + // for entries that are not present in a regular registry. + if (this.holder == null && DeferredHolderCommon.BIND_OVERRIDE != null) { + this.holder = (Holder) DeferredHolderCommon.BIND_OVERRIDE.apply(this.key); + } + + if (this.holder == null && registry == null && throwOnMissingRegistry) { throw new IllegalStateException("Registry not present for " + this + ": " + this.key.registry()); } } diff --git a/loader-common/src/main/java/org/cyclops/cyclopscore/gametest/DeferredHolderCommonTest.java b/loader-common/src/main/java/org/cyclops/cyclopscore/gametest/DeferredHolderCommonTest.java new file mode 100644 index 00000000000..19fb2a4353f --- /dev/null +++ b/loader-common/src/main/java/org/cyclops/cyclopscore/gametest/DeferredHolderCommonTest.java @@ -0,0 +1,36 @@ +package org.cyclops.cyclopscore.gametest; + +import com.google.gson.JsonElement; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.JsonOps; +import net.minecraft.core.Holder; +import net.minecraft.core.particles.ParticleType; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.gametest.framework.GameTestHelper; +import org.cyclops.cyclopscore.RegistryEntriesCommon; +import org.cyclops.cyclopscore.config.DeferredHolderCommon; + +/** + * Tests for {@link DeferredHolderCommon}. + * @author rubensworks + */ +public class DeferredHolderCommonTest { + + // Registry#safeCastToReference only accepts Holder.Reference, so delegates must resolve to one. + @GameTest + public void testDelegateIsReference(GameTestHelper helper) { + Holder> delegate = RegistryEntriesCommon.PARTICLE_BLUR.getDelegate(); + helper.assertTrue(delegate instanceof Holder.Reference, + "Expected a Holder.Reference delegate, but got " + delegate); + helper.succeed(); + } + + @GameTest + public void testHolderCodecEncoding(GameTestHelper helper) { + DataResult result = BuiltInRegistries.PARTICLE_TYPE.holderByNameCodec() + .encodeStart(JsonOps.INSTANCE, RegistryEntriesCommon.PARTICLE_BLUR); + helper.assertTrue(result.result().isPresent(), "Expected a successful encoding, but got " + result); + helper.succeed(); + } + +} diff --git a/loader-fabric/src/main/java/org/cyclops/cyclopscore/CyclopsCoreFabric.java b/loader-fabric/src/main/java/org/cyclops/cyclopscore/CyclopsCoreFabric.java index b92806fdcfb..dc0f8886ea3 100644 --- a/loader-fabric/src/main/java/org/cyclops/cyclopscore/CyclopsCoreFabric.java +++ b/loader-fabric/src/main/java/org/cyclops/cyclopscore/CyclopsCoreFabric.java @@ -17,6 +17,7 @@ import org.cyclops.cyclopscore.component.DataComponentCapacityConfig; import org.cyclops.cyclopscore.component.DataComponentEnergyStorageConfig; import org.cyclops.cyclopscore.config.ConfigHandlerCommon; +import org.cyclops.cyclopscore.gametest.DeferredHolderCommonTest; import org.cyclops.cyclopscore.gametest.MethodGameTestInstanceConfig; import org.cyclops.cyclopscore.gametest.StartupTestFabric; import org.cyclops.cyclopscore.helper.CyclopsCoreInstance; @@ -112,6 +113,6 @@ protected void onConfigsRegister(ConfigHandlerCommon configHandler) { @Override public Class[] getGameTestClasses() { - return new Class[]{ StartupTestFabric.class }; + return new Class[]{ StartupTestFabric.class, DeferredHolderCommonTest.class }; } } diff --git a/loader-forge/src/main/java/org/cyclops/cyclopscore/CyclopsCoreForge.java b/loader-forge/src/main/java/org/cyclops/cyclopscore/CyclopsCoreForge.java index 319be0b7fa7..98c99af3cc8 100644 --- a/loader-forge/src/main/java/org/cyclops/cyclopscore/CyclopsCoreForge.java +++ b/loader-forge/src/main/java/org/cyclops/cyclopscore/CyclopsCoreForge.java @@ -25,6 +25,7 @@ import org.cyclops.cyclopscore.config.ConfigHandlerCommon; import org.cyclops.cyclopscore.config.ConfigurableTypesForge; import org.cyclops.cyclopscore.config.DeferredHolderCommon; +import org.cyclops.cyclopscore.gametest.DeferredHolderCommonTest; import org.cyclops.cyclopscore.gametest.MethodGameTestInstanceConfig; import org.cyclops.cyclopscore.gametest.StartupTestForge; import org.cyclops.cyclopscore.helper.CyclopsCoreInstance; @@ -37,6 +38,8 @@ import org.cyclops.cyclopscore.proxy.ICommonProxyCommon; import org.cyclops.cyclopscore.tracking.ImportantUsers; +import java.util.Optional; + /** * The main mod class of CyclopsCore. * @author rubensworks @@ -62,6 +65,11 @@ public CyclopsCoreForge(FMLJavaModLoadingContext context) { DeferredHolderCommon.BIND_OVERRIDE = (key) -> { ForgeRegistry registry = RegistryManager.ACTIVE.getRegistry(key.registry()); if (registry != null) { + // Prefer the registry's delegate, as only Holder.Reference can be serialized. + Optional> delegate = registry.getDelegate(key.identifier()); + if (delegate.isPresent()) { + return delegate.get(); + } Object value = registry.getValue(key.identifier()); if (value != null) { return Holder.direct(value); @@ -141,6 +149,6 @@ protected void onConfigsRegister(ConfigHandlerCommon configHandler) { @Override public Class[] getGameTestClasses() { - return new Class[]{ StartupTestForge.class }; + return new Class[]{ StartupTestForge.class, DeferredHolderCommonTest.class }; } } diff --git a/loader-neoforge/src/main/java/org/cyclops/cyclopscore/CyclopsCoreNeoForge.java b/loader-neoforge/src/main/java/org/cyclops/cyclopscore/CyclopsCoreNeoForge.java index c588a30c4ac..b841c1bc0a3 100644 --- a/loader-neoforge/src/main/java/org/cyclops/cyclopscore/CyclopsCoreNeoForge.java +++ b/loader-neoforge/src/main/java/org/cyclops/cyclopscore/CyclopsCoreNeoForge.java @@ -22,6 +22,7 @@ import org.cyclops.cyclopscore.component.DataComponentFluidContentConfig; import org.cyclops.cyclopscore.component.DataComponentInventoryConfig; import org.cyclops.cyclopscore.config.ConfigHandlerCommon; +import org.cyclops.cyclopscore.gametest.DeferredHolderCommonTest; import org.cyclops.cyclopscore.gametest.MethodGameTestInstanceConfig; import org.cyclops.cyclopscore.gametest.StartupTestNeoForge; import org.cyclops.cyclopscore.helper.CyclopsCoreInstance; @@ -177,7 +178,7 @@ public void onConfigsRegister(ConfigHandlerCommon configHandler) { @Override public Class[] getGameTestClasses() { - return new Class[] { StartupTestNeoForge.class }; + return new Class[] { StartupTestNeoForge.class, DeferredHolderCommonTest.class }; } private void loadComplete(FMLLoadCompleteEvent event) {