mirror of
https://github.com/FabricMC/fabric.git
synced 2025-04-11 22:45:38 -04:00
22w42a RegSync changes (#2608)
* Fix DynamicRegistrySetupCallback, add EndDynamicRegistrySetupCallback `DynamicRegistrySetupCallback` did not work as intended because the injection was too late. This moves the injection point to `RegistryLoader`, just before it is loaded. `EndDynamicRegistrySetupCallback` is a new event triggered when the loading is finished. This has access to the combined DRM, allowing context-aware modification. This also replaces `System.out.println` use in testmod. * Remove useless force-init of BiomeKeys * Remove now-unnecessary DynamicRegistryManagerMixin * Fix crash in testmod This caveat needs proper documentation. * Add note to javadoc * Mark impl as internal * Remove EndDynamicRegistrySetupCallback * Fix testmod checkstyle issues * Add automated event call check * Fix test * Update javadoc * Add `@see` * Re-run actions
This commit is contained in:
parent
11ba9c3b22
commit
33c37e23ce
12 changed files with 132 additions and 61 deletions
fabric-registry-sync-v0
build.gradle
src
main
java/net/fabricmc/fabric
resources
testmod/java/net/fabricmc/fabric/test/registry/sync
|
@ -9,3 +9,7 @@ moduleDependencies(project, [
|
|||
'fabric-api-base',
|
||||
'fabric-networking-api-v1'
|
||||
])
|
||||
|
||||
testDependencies(project, [
|
||||
':fabric-lifecycle-events-v1'
|
||||
])
|
||||
|
|
|
@ -29,13 +29,21 @@ import net.fabricmc.fabric.api.event.EventFactory;
|
|||
* <pre>
|
||||
* {@code
|
||||
* DynamicRegistrySetupCallback.EVENT.register(registryManager -> {
|
||||
* Registry<Biome> biomes = registryManager.get(Registry.BIOME_KEY);
|
||||
* RegistryEntryAddedCallback.event(biomes).register((rawId, id, object) -> {
|
||||
* // Do something
|
||||
* registryManager.getOptional(Registry.BIOME_KEY).ifPresent(biomes -> {
|
||||
* RegistryEntryAddedCallback.event(biomes).register((rawId, id, object) -> {
|
||||
* // Do something
|
||||
* });
|
||||
* });
|
||||
* });
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p><strong>Important Note</strong>: The passed dynamic registry manager might not
|
||||
* contain the registry, as this event is invoked for each layer of
|
||||
* the combined registry manager, and each layer holds different registries.
|
||||
* Use {@link DynamicRegistryManager#getOptional} to prevent crashes.
|
||||
*
|
||||
* @see net.minecraft.util.registry.ServerDynamicRegistryType
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface DynamicRegistrySetupCallback {
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the Registry Sync implementation.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
package net.fabricmc.fabric.impl.registry.sync;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains packet handlers used by Registry Sync.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
package net.fabricmc.fabric.impl.registry.sync.packet;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains remap state trackers.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
package net.fabricmc.fabric.impl.registry.sync.trackers;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
|
@ -18,6 +18,8 @@ package net.fabricmc.fabric.impl.registry.sync.trackers.vanilla;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
@ -27,6 +29,7 @@ import net.minecraft.util.registry.Registry;
|
|||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
import net.fabricmc.fabric.mixin.registry.sync.DebugChunkGeneratorAccessor;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public final class BlockInitTracker implements RegistryEntryAddedCallback<Block> {
|
||||
private final Registry<Block> registry;
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.registry.sync.trackers.vanilla;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
@ -23,6 +25,7 @@ import net.minecraft.util.registry.Registry;
|
|||
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public final class BlockItemTracker implements RegistryEntryAddedCallback<Item> {
|
||||
private BlockItemTracker() { }
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ import net.minecraft.fluid.Fluid;
|
|||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.biome.BiomeKeys;
|
||||
|
||||
import net.fabricmc.fabric.impl.registry.sync.RegistrySyncManager;
|
||||
import net.fabricmc.fabric.impl.registry.sync.trackers.StateIdTracker;
|
||||
|
@ -44,7 +43,6 @@ public class BootstrapMixin {
|
|||
// static initializer is called, to register vanilla-provided blocks
|
||||
// and items from the respective classes - otherwise, they would
|
||||
// duplicate our calls from below.
|
||||
Object oBiome = BiomeKeys.THE_END;
|
||||
Object oBlock = Blocks.AIR;
|
||||
Object oFluid = Fluids.EMPTY;
|
||||
Object oItem = Items.AIR;
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.registry.sync;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
|
||||
@Mixin(DynamicRegistryManager.class)
|
||||
public interface DynamicRegistryManagerMixin {
|
||||
/**
|
||||
* Ensures that any registrations made into {@link net.minecraft.util.registry.BuiltinRegistries} after
|
||||
* {@link DynamicRegistryManager} has been class-loaded are still propagated.
|
||||
*/
|
||||
/* TODO 22w42a not needed?
|
||||
@Inject(method = "method_40327", at = @At(value = "RETURN"))
|
||||
private static void setupBuiltInSync(CallbackInfoReturnable<DynamicRegistryManager.Immutable> cir) {
|
||||
DynamicRegistrySync.setupSync(cir.getReturnValue());
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -17,27 +17,32 @@
|
|||
package net.fabricmc.fabric.mixin.registry.sync;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import net.minecraft.util.registry.CombinedDynamicRegistries;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
import net.minecraft.util.registry.RegistryLoader;
|
||||
|
||||
import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback;
|
||||
|
||||
@Mixin(CombinedDynamicRegistries.class)
|
||||
public class CombinedDynamicRegistriesMixin {
|
||||
@Shadow
|
||||
@Final
|
||||
private DynamicRegistryManager.Immutable combinedRegistryManager;
|
||||
|
||||
@Inject(method = "<init>(Ljava/util/List;Ljava/util/List;)V", at = @At("RETURN"))
|
||||
private void init(List list, List list2, CallbackInfo ci) {
|
||||
DynamicRegistrySetupCallback.EVENT.invoker().onRegistrySetup(this.combinedRegistryManager);
|
||||
@Mixin(RegistryLoader.class)
|
||||
public class RegistryLoaderMixin {
|
||||
@Inject(
|
||||
method = "load(Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/util/registry/DynamicRegistryManager;Ljava/util/List;)Lnet/minecraft/util/registry/DynamicRegistryManager$Immutable;",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V",
|
||||
ordinal = 0
|
||||
),
|
||||
locals = LocalCapture.CAPTURE_FAILHARD
|
||||
)
|
||||
private static void beforeLoad(ResourceManager resourceManager, DynamicRegistryManager baseRegistryManager, List<RegistryLoader.Entry<?>> entries, CallbackInfoReturnable<DynamicRegistryManager.Immutable> cir, Map a, List b, DynamicRegistryManager registryManager) {
|
||||
DynamicRegistrySetupCallback.EVENT.invoker().onRegistrySetup(registryManager);
|
||||
}
|
||||
}
|
|
@ -3,17 +3,16 @@
|
|||
"package": "net.fabricmc.fabric.mixin.registry.sync",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
"DebugChunkGeneratorAccessor",
|
||||
"RegistryAccessor",
|
||||
"BootstrapMixin",
|
||||
"BuiltinRegistriesMixin",
|
||||
"ChunkSerializerMixin",
|
||||
"DynamicRegistryManagerMixin",
|
||||
"DebugChunkGeneratorAccessor",
|
||||
"IdListMixin",
|
||||
"SimpleRegistryMixin",
|
||||
"LevelStorageSessionMixin",
|
||||
"RegistryMixin",
|
||||
"MinecraftServerMixin",
|
||||
"RegistryAccessor",
|
||||
"RegistryLoaderMixin",
|
||||
"RegistryMixin",
|
||||
"SimpleRegistryMixin",
|
||||
"StructuresToConfiguredStructuresFixMixin"
|
||||
],
|
||||
|
|
|
@ -17,9 +17,12 @@
|
|||
package net.fabricmc.fabric.test.registry.sync;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.Block;
|
||||
|
@ -36,6 +39,7 @@ import net.minecraft.world.gen.feature.DefaultFeatureConfig;
|
|||
import net.minecraft.world.gen.feature.Feature;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryAttribute;
|
||||
|
@ -49,6 +53,8 @@ import net.fabricmc.fabric.impl.registry.sync.packet.NbtRegistryPacketHandler;
|
|||
import net.fabricmc.fabric.impl.registry.sync.packet.RegistryPacketHandler;
|
||||
|
||||
public class RegistrySyncTest implements ModInitializer {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
/**
|
||||
* These are system property's as it allows for easier testing with different run configurations.
|
||||
*/
|
||||
|
@ -109,12 +115,23 @@ public class RegistrySyncTest implements ModInitializer {
|
|||
Validate.isTrue(RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.SYNCED));
|
||||
Validate.isTrue(!RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.PERSISTED));
|
||||
|
||||
final AtomicBoolean setupCalled = new AtomicBoolean(false);
|
||||
|
||||
DynamicRegistrySetupCallback.EVENT.register(registryManager -> {
|
||||
RegistryEntryAddedCallback.event(registryManager.get(Registry.BIOME_KEY)).register((rawId, id, object) -> {
|
||||
System.out.println(id);
|
||||
setupCalled.set(true);
|
||||
registryManager.getOptional(Registry.BIOME_KEY).ifPresent(registry -> {
|
||||
RegistryEntryAddedCallback.event(registry).register((rawId, id, object) -> {
|
||||
LOGGER.info("Biome added: {}", id);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTING.register(server -> {
|
||||
if (!setupCalled.get()) {
|
||||
throw new IllegalStateException("DRM setup was not called before startup!");
|
||||
}
|
||||
});
|
||||
|
||||
// Vanilla status effects don't have an entry for the int id 0, test we can handle this.
|
||||
RegistryAttributeHolder.get(Registry.STATUS_EFFECT).addAttribute(RegistryAttribute.MODDED);
|
||||
}
|
||||
|
@ -136,7 +153,7 @@ public class RegistrySyncTest implements ModInitializer {
|
|||
* class-loaded.
|
||||
*/
|
||||
private void testBuiltInRegistrySync() {
|
||||
System.out.println("Checking built-in registry sync...");
|
||||
LOGGER.info("Checking built-in registry sync...");
|
||||
|
||||
// Register a configured feature before force-loading the dynamic registry manager
|
||||
ConfiguredFeature<DefaultFeatureConfig, ?> cf1 = new ConfiguredFeature<>(Feature.BASALT_PILLAR, DefaultFeatureConfig.INSTANCE);
|
||||
|
|
Loading…
Add table
Reference in a new issue