mirror of
https://github.com/FabricMC/fabric.git
synced 2025-02-17 04:01:46 -05:00
DynamicRegistryEvents (#1029)
* Added DynamicRegistryEntryAddedCallback * bumbed loader version, finalized DynamicRegistryEvents * Fixed some generics * Changed the event to a more generic one * Added some javadoc and the license header * increased gradle memory in the hope it fixes the github action fail * Added DynamicRegistryEntryAddedCallback * bumbed loader version, finalized DynamicRegistryEvents * Fixed some generics * Changed the event to a more generic one * reverted memory change * updated mixin for new mappings * removed redundant supressions * renamed event method
This commit is contained in:
commit
c29304db6a
6 changed files with 106 additions and 8 deletions
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* 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.api.event.registry;
|
||||||
|
|
||||||
|
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.event.Event;
|
||||||
|
import net.fabricmc.fabric.api.event.EventFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This event gets triggered when a new {@link DynamicRegistryManager} gets created, but before it gets filled.
|
||||||
|
* Therefore, this is the ideal place to register callbacks to dynamic registries.
|
||||||
|
* For example, the following code is used to register a callback that gets triggered for any registered Biome, both JSON and code defined.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* {@code
|
||||||
|
* DynamicRegistrySetupCallback.EVENT.register(registryManager -> {
|
||||||
|
* Registry<Biome> biomes = registryManager.get(Registry.BIOME_KEY);
|
||||||
|
* RegistryEntryAddedCallback.event(biomes).register((rawId, id, object) -> {
|
||||||
|
* // Do something
|
||||||
|
* });
|
||||||
|
* });
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface DynamicRegistrySetupCallback {
|
||||||
|
void onRegistrySetup(DynamicRegistryManager registryManager);
|
||||||
|
|
||||||
|
Event<DynamicRegistrySetupCallback> EVENT = EventFactory.createArrayBacked(
|
||||||
|
DynamicRegistrySetupCallback.class,
|
||||||
|
callbacks -> registryManager -> {
|
||||||
|
for (DynamicRegistrySetupCallback callback : callbacks) {
|
||||||
|
callback.onRegistrySetup(registryManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* 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 org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback;
|
||||||
|
|
||||||
|
@Mixin(DynamicRegistryManager.class)
|
||||||
|
public class DynamicRegistryManagerMixin {
|
||||||
|
@Inject(method = "create", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/dynamic/RegistryOps$class_5506$class_5507;<init>()V"), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||||
|
private static void onCreateImpl(CallbackInfoReturnable<DynamicRegistryManager.Impl> cir, DynamicRegistryManager.Impl registryManager) {
|
||||||
|
DynamicRegistrySetupCallback.EVENT.invoker().onRegistrySetup(registryManager);
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,8 +45,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
import net.minecraft.util.registry.SimpleRegistry;
|
|
||||||
import net.minecraft.util.registry.RegistryKey;
|
import net.minecraft.util.registry.RegistryKey;
|
||||||
|
import net.minecraft.util.registry.SimpleRegistry;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.event.Event;
|
import net.fabricmc.fabric.api.event.Event;
|
||||||
import net.fabricmc.fabric.api.event.EventFactory;
|
import net.fabricmc.fabric.api.event.EventFactory;
|
||||||
|
@ -132,8 +132,8 @@ public abstract class MixinIdRegistry<T> extends Registry<T> implements Remappab
|
||||||
@Unique
|
@Unique
|
||||||
private boolean fabric_isObjectNew = false;
|
private boolean fabric_isObjectNew = false;
|
||||||
|
|
||||||
@Inject(method = "set", at = @At("HEAD"))
|
@Inject(method = "set(ILnet/minecraft/util/registry/RegistryKey;Ljava/lang/Object;Lcom/mojang/serialization/Lifecycle;Z)Ljava/lang/Object;", at = @At("HEAD"))
|
||||||
public void setPre(int id, RegistryKey<T> registryId, T object, Lifecycle lifecycle, CallbackInfoReturnable<T> info) {
|
public void setPre(int id, RegistryKey<T> registryId, T object, Lifecycle lifecycle, boolean checkDuplicateKeys, CallbackInfoReturnable<T> info) {
|
||||||
int indexedEntriesId = entryToRawId.getInt(object);
|
int indexedEntriesId = entryToRawId.getInt(object);
|
||||||
|
|
||||||
if (indexedEntriesId >= 0) {
|
if (indexedEntriesId >= 0) {
|
||||||
|
@ -148,7 +148,7 @@ public abstract class MixinIdRegistry<T> extends Registry<T> implements Remappab
|
||||||
if (oldObject != null && oldObject != object) {
|
if (oldObject != null && oldObject != object) {
|
||||||
int oldId = entryToRawId.getInt(oldObject);
|
int oldId = entryToRawId.getInt(oldObject);
|
||||||
|
|
||||||
if (oldId != id) {
|
if (oldId != id && checkDuplicateKeys) {
|
||||||
throw new RuntimeException("Attempted to register ID " + registryId + " at different raw IDs (" + oldId + ", " + id + ")! If you're trying to override an item, use .set(), not .register()!");
|
throw new RuntimeException("Attempted to register ID " + registryId + " at different raw IDs (" + oldId + ", " + id + ")! If you're trying to override an item, use .set(), not .register()!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,8 +160,8 @@ public abstract class MixinIdRegistry<T> extends Registry<T> implements Remappab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "set", at = @At("RETURN"))
|
@Inject(method = "set(ILnet/minecraft/util/registry/RegistryKey;Ljava/lang/Object;Lcom/mojang/serialization/Lifecycle;Z)Ljava/lang/Object;", at = @At("RETURN"))
|
||||||
public void setPost(int id, RegistryKey<T> registryId, T object, Lifecycle lifecycle, CallbackInfoReturnable<T> info) {
|
public void setPost(int id, RegistryKey<T> registryId, T object, Lifecycle lifecycle, boolean checkDuplicateKeys, CallbackInfoReturnable<T> info) {
|
||||||
if (fabric_isObjectNew) {
|
if (fabric_isObjectNew) {
|
||||||
fabric_addObjectEvent.invoker().onEntryAdded(id, registryId.getValue(), object);
|
fabric_addObjectEvent.invoker().onEntryAdded(id, registryId.getValue(), object);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
"MixinPlayerManager",
|
"MixinPlayerManager",
|
||||||
"MixinLevelStorageSession",
|
"MixinLevelStorageSession",
|
||||||
"MixinRegistry",
|
"MixinRegistry",
|
||||||
"MixinSimpleRegistry"
|
"MixinSimpleRegistry",
|
||||||
|
"DynamicRegistryManagerMixin"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"client.MixinBlockColorMap",
|
"client.MixinBlockColorMap",
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
"FabricMC"
|
"FabricMC"
|
||||||
],
|
],
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=0.4.0",
|
"fabricloader": ">=0.9.2",
|
||||||
"fabric-api-base": "*",
|
"fabric-api-base": "*",
|
||||||
"fabric-networking-v0": "*"
|
"fabric-networking-v0": "*"
|
||||||
},
|
},
|
||||||
|
|
|
@ -34,9 +34,11 @@ import net.minecraft.world.gen.feature.DefaultFeatureConfig;
|
||||||
import net.minecraft.world.gen.feature.Feature;
|
import net.minecraft.world.gen.feature.Feature;
|
||||||
|
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback;
|
||||||
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
||||||
import net.fabricmc.fabric.api.event.registry.RegistryAttribute;
|
import net.fabricmc.fabric.api.event.registry.RegistryAttribute;
|
||||||
import net.fabricmc.fabric.api.event.registry.RegistryAttributeHolder;
|
import net.fabricmc.fabric.api.event.registry.RegistryAttributeHolder;
|
||||||
|
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||||
|
|
||||||
public class RegistrySyncTest implements ModInitializer {
|
public class RegistrySyncTest implements ModInitializer {
|
||||||
/**
|
/**
|
||||||
|
@ -73,9 +75,17 @@ public class RegistrySyncTest implements ModInitializer {
|
||||||
|
|
||||||
Registry.register(fabricRegistry, new Identifier("registry_sync", "test"), "test");
|
Registry.register(fabricRegistry, new Identifier("registry_sync", "test"), "test");
|
||||||
|
|
||||||
|
Validate.isTrue(Registry.REGISTRIES.getIds().contains(new Identifier("registry_sync", "fabric_registry")));
|
||||||
|
|
||||||
Validate.isTrue(RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.MODDED));
|
Validate.isTrue(RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.MODDED));
|
||||||
Validate.isTrue(RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.SYNCED));
|
Validate.isTrue(RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.SYNCED));
|
||||||
Validate.isTrue(!RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.PERSISTED));
|
Validate.isTrue(!RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.PERSISTED));
|
||||||
|
|
||||||
|
DynamicRegistrySetupCallback.EVENT.register(registryManager -> {
|
||||||
|
RegistryEntryAddedCallback.event(registryManager.get(Registry.BIOME_KEY)).register((rawId, id, object) -> {
|
||||||
|
System.out.println(id);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue