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:
modmuss50 2020-10-11 21:15:25 +01:00 committed by GitHub
commit c29304db6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 106 additions and 8 deletions

View file

@ -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);
}
}
);
}

View file

@ -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);
}
}

View file

@ -45,8 +45,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.SimpleRegistry;
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.EventFactory;
@ -132,8 +132,8 @@ public abstract class MixinIdRegistry<T> extends Registry<T> implements Remappab
@Unique
private boolean fabric_isObjectNew = false;
@Inject(method = "set", at = @At("HEAD"))
public void setPre(int id, RegistryKey<T> registryId, T object, Lifecycle lifecycle, CallbackInfoReturnable<T> info) {
@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, boolean checkDuplicateKeys, CallbackInfoReturnable<T> info) {
int indexedEntriesId = entryToRawId.getInt(object);
if (indexedEntriesId >= 0) {
@ -148,7 +148,7 @@ public abstract class MixinIdRegistry<T> extends Registry<T> implements Remappab
if (oldObject != null && oldObject != object) {
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()!");
}
@ -160,8 +160,8 @@ public abstract class MixinIdRegistry<T> extends Registry<T> implements Remappab
}
}
@Inject(method = "set", at = @At("RETURN"))
public void setPost(int id, RegistryKey<T> registryId, T object, Lifecycle lifecycle, CallbackInfoReturnable<T> info) {
@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, boolean checkDuplicateKeys, CallbackInfoReturnable<T> info) {
if (fabric_isObjectNew) {
fabric_addObjectEvent.invoker().onEntryAdded(id, registryId.getValue(), object);
}

View file

@ -11,7 +11,8 @@
"MixinPlayerManager",
"MixinLevelStorageSession",
"MixinRegistry",
"MixinSimpleRegistry"
"MixinSimpleRegistry",
"DynamicRegistryManagerMixin"
],
"client": [
"client.MixinBlockColorMap",

View file

@ -16,7 +16,7 @@
"FabricMC"
],
"depends": {
"fabricloader": ">=0.4.0",
"fabricloader": ">=0.9.2",
"fabric-api-base": "*",
"fabric-networking-v0": "*"
},

View file

@ -34,9 +34,11 @@ 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.registry.DynamicRegistrySetupCallback;
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
import net.fabricmc.fabric.api.event.registry.RegistryAttribute;
import net.fabricmc.fabric.api.event.registry.RegistryAttributeHolder;
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
public class RegistrySyncTest implements ModInitializer {
/**
@ -73,9 +75,17 @@ public class RegistrySyncTest implements ModInitializer {
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.SYNCED));
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);
});
});
}
/**