Pass DynamicRegistryView to DynamicRegistrySetupCallback ()

* Pass DynamicRegistryView to DynamicRegistrySetupCallback

* Update fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/DynamicRegistryViewImpl.java

Co-authored-by: Juuz <6596629+Juuxel@users.noreply.github.com>

Co-authored-by: Juuz <6596629+Juuxel@users.noreply.github.com>
This commit is contained in:
apple502j 2022-11-27 05:00:04 +09:00 committed by GitHub
parent 65e415cb4c
commit 2608564621
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 180 additions and 49 deletions
fabric-registry-sync-v0/src
main/java/net/fabricmc/fabric
testmod/java/net/fabricmc/fabric/test/registry/sync

View file

@ -16,44 +16,36 @@
package net.fabricmc.fabric.api.event.registry;
import net.minecraft.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.
* This event gets triggered before a dynamic registry is being loaded.
* 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.
* For example, the following code is used to register a callback that gets triggered for any registered Biome:
*
* <pre>
* {@code
* DynamicRegistrySetupCallback.EVENT.register(registryManager -> {
* registryManager.getOptional(Registry.BIOME_KEY).ifPresent(biomes -> {
* RegistryEntryAddedCallback.event(biomes).register((rawId, id, object) -> {
* // Do something
* });
* DynamicRegistrySetupCallback.EVENT.register(registryView -> {
* registryView.registerEntryAdded(RegistryKeys.BIOME, (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 DynamicRegistryView
* @see net.minecraft.registry.ServerDynamicRegistryType
*/
@FunctionalInterface
public interface DynamicRegistrySetupCallback {
void onRegistrySetup(DynamicRegistryManager registryManager);
void onRegistrySetup(DynamicRegistryView registryView);
Event<DynamicRegistrySetupCallback> EVENT = EventFactory.createArrayBacked(
DynamicRegistrySetupCallback.class,
callbacks -> registryManager -> {
callbacks -> registryView -> {
for (DynamicRegistrySetupCallback callback : callbacks) {
callback.onRegistrySetup(registryManager);
callback.onRegistrySetup(registryView);
}
}
);

View file

@ -0,0 +1,72 @@
/*
* 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 java.util.Optional;
import java.util.stream.Stream;
import org.jetbrains.annotations.ApiStatus;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
/**
* A view providing access to the registries that are currently being loaded. This is passed to
* the {@link DynamicRegistrySetupCallback} event.
*
* @apiNote This might not contain all the registry, as the event is invoked for each layer of
* the combined registry manager, and each layer holds different registries. For example, the biome
* registry is not loaded in the {@link net.minecraft.registry.ServerDynamicRegistryType#DIMENSIONS}
* layer.
*/
@ApiStatus.NonExtendable
public interface DynamicRegistryView {
/**
* @return an {@link DynamicRegistryManager} instance representing the registry view
*/
DynamicRegistryManager asDynamicRegistryManager();
/**
* @return the stream of registries that are currently being loaded
*/
Stream<Registry<?>> stream();
/**
* Returns the registry identified by the registry key. This returns an empty optional if
* the key does not refer to a registry, or if the current combined registry layer being loaded
* does not contain the registry.
*
* @param registryRef the registry key of the registry to get
* @return the registry, or {@link Optional#empty()} if the registry is not currently being loaded
*/
<T> Optional<Registry<T>> getOptional(RegistryKey<? extends Registry<? extends T>> registryRef);
/**
* A shortcut to register {@link RegistryEntryAddedCallback}.
* @param registryRef the registry key of the registry to register the event to
* @param callback the callback of the event
*/
<T> void registerEntryAdded(RegistryKey<? extends Registry<? extends T>> registryRef, RegistryEntryAddedCallback<T> callback);
/**
* A shortcut to register {@link RegistryEntryRemovedCallback}.
* @param registryRef the registry key of the registry to register the event to
* @param callback the callback of the event
*/
<T> void registerEntryRemoved(RegistryKey<? extends Registry<? extends T>> registryRef, RegistryEntryRemovedCallback<T> callback);
}

View file

@ -0,0 +1,91 @@
/*
* 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.impl.registry.sync;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.fabricmc.fabric.api.event.registry.DynamicRegistryView;
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
import net.fabricmc.fabric.api.event.registry.RegistryEntryRemovedCallback;
public final class DynamicRegistryViewImpl implements DynamicRegistryView {
private final Map<RegistryKey<? extends Registry<?>>, Registry<?>> registries;
public DynamicRegistryViewImpl(Map<RegistryKey<? extends Registry<?>>, Registry<?>> registries) {
this.registries = registries;
}
@Override
public DynamicRegistryManager asDynamicRegistryManager() {
return new DynamicRegistryManager.Immutable() {
@SuppressWarnings("unchecked")
public <T> Optional<Registry<T>> getOptional(RegistryKey<? extends Registry<? extends T>> key) {
return Optional.ofNullable((Registry<T>) DynamicRegistryViewImpl.this.registries.get(key));
}
public Stream<Entry<?>> streamAllRegistries() {
return DynamicRegistryViewImpl.this.stream()
.map(this::entry);
}
private <T> Entry<T> entry(Registry<T> registry) {
return new Entry<>(registry.getKey(), registry);
}
public Immutable toImmutable() {
return this;
}
};
}
@Override
public Stream<Registry<?>> stream() {
return this.registries.values().stream();
}
@Override
@SuppressWarnings("unchecked")
public <T> Optional<Registry<T>> getOptional(RegistryKey<? extends Registry<? extends T>> registryRef) {
return Optional.ofNullable((Registry<T>) this.registries.get(registryRef));
}
@Override
@SuppressWarnings("unchecked")
public <T> void registerEntryAdded(RegistryKey<? extends Registry<? extends T>> registryRef, RegistryEntryAddedCallback<T> callback) {
Registry<T> registry = (Registry<T>) this.registries.get(registryRef);
if (registry != null) {
RegistryEntryAddedCallback.event(registry).register(callback);
}
}
@Override
@SuppressWarnings("unchecked")
public <T> void registerEntryRemoved(RegistryKey<? extends Registry<? extends T>> registryRef, RegistryEntryRemovedCallback<T> callback) {
Registry<T> registry = (Registry<T>) this.registries.get(registryRef);
if (registry != null) {
RegistryEntryRemovedCallback.event(registry).register(callback);
}
}
}

View file

@ -19,8 +19,6 @@ package net.fabricmc.fabric.mixin.registry.sync;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
import com.mojang.datafixers.util.Pair;
import org.spongepowered.asm.mixin.Mixin;
@ -29,15 +27,16 @@ 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.resource.ResourceManager;
import net.minecraft.registry.RegistryOps;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.MutableRegistry;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryLoader;
import net.minecraft.registry.RegistryOps;
import net.minecraft.resource.ResourceManager;
import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback;
import net.fabricmc.fabric.impl.registry.sync.DynamicRegistryViewImpl;
@Mixin(RegistryLoader.class)
public class RegistryLoaderMixin {
@ -57,26 +56,6 @@ public class RegistryLoaderMixin {
registries.put(pair.getFirst().getKey(), pair.getFirst());
}
DynamicRegistryManager drm = new DynamicRegistryManager.Immutable() {
@SuppressWarnings("unchecked")
public <T> Optional<Registry<T>> getOptional(RegistryKey<? extends Registry<? extends T>> key) {
return Optional.ofNullable((Registry<T>) registries.get(key));
}
public Stream<Entry<?>> streamAllRegistries() {
return registries.values().stream()
.map(this::entry);
}
private <T> Entry<T> entry(Registry<T> registry) {
return new Entry<>(registry.getKey(), registry);
}
public Immutable toImmutable() {
return this;
}
};
DynamicRegistrySetupCallback.EVENT.invoker().onRegistrySetup(drm);
DynamicRegistrySetupCallback.EVENT.invoker().onRegistrySetup(new DynamicRegistryViewImpl(registries));
}
}

View file

@ -27,13 +27,13 @@ import org.slf4j.Logger;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.Material;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.util.Identifier;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.SimpleRegistry;
import net.minecraft.util.Identifier;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
@ -41,7 +41,6 @@ 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;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.fabricmc.fabric.impl.registry.sync.RegistrySyncManager;
@ -114,10 +113,8 @@ public class RegistrySyncTest implements ModInitializer {
DynamicRegistrySetupCallback.EVENT.register(registryManager -> {
setupCalled.set(true);
registryManager.getOptional(RegistryKeys.BIOME).ifPresent(registry -> {
RegistryEntryAddedCallback.event(registry).register((rawId, id, object) -> {
LOGGER.info("Biome added: {}", id);
});
registryManager.registerEntryAdded(RegistryKeys.BIOME, (rawId, id, object) -> {
LOGGER.info("Biome added: {}", id);
});
});