mirror of
https://github.com/architectury/architectury-api.git
synced 2026-03-28 03:56:59 -05:00
Add Dynamic (DataPack, WorldGen) registries support (#462)
Signed-off-by: Sergey Shatunov <me@aur.rocks>
This commit is contained in:
@@ -19,12 +19,14 @@
|
||||
|
||||
package dev.architectury.registry.registries;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -76,6 +78,59 @@ public final class RegistrarManager {
|
||||
return this.provider.builder((Class<T>) typeGetter.getClass().getComponentType(), registryId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a non-synced dynamic registry.
|
||||
*
|
||||
* <p>The entries of the registry will be loaded from data packs at the file path
|
||||
* {@code data/<entry namespace>/<registry namespace>/<registry path>/<entry path>.json}.
|
||||
*
|
||||
* @param key the key of the registry
|
||||
* @param codec the codec used to load registry entries from data packs
|
||||
* @param <T> the type of registry entry
|
||||
*/
|
||||
public <T> void dynamicRegistry(ResourceKey<Registry<T>> key, @NotNull Codec<T> codec) {
|
||||
this.provider.registerDynamicRegistry(key, codec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a synced dynamic registry.
|
||||
*
|
||||
* <p>The entries of the registry will be loaded from data packs at the file path
|
||||
* {@code data/<entry namespace>/<registry namespace>/<registry path>/<entry path>.json}.
|
||||
*
|
||||
* <p>The registry will be synced from the server to players' clients using the same codec
|
||||
* that is used to load the registry.
|
||||
*
|
||||
* <p>If the object contained in the registry is complex and contains a lot of data
|
||||
* that is not relevant on the client, another codec for networking can be specified with
|
||||
* {@link #dynamicRegistrySynced(ResourceKey, Codec, Codec)}.
|
||||
*
|
||||
* @param key the key of the registry
|
||||
* @param codec the codec used to load registry entries from data packs and the network
|
||||
* @param <T> the type of registry entry
|
||||
*/
|
||||
public <T> void dynamicRegistrySynced(ResourceKey<Registry<T>> key, @NotNull Codec<T> codec) {
|
||||
this.provider.registerDynamicRegistrySynced(key, codec, codec);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Registers a synced dynamic registry.
|
||||
*
|
||||
* <p>The entries of the registry will be loaded from data packs at the file path
|
||||
* {@code data/<entry namespace>/<registry namespace>/<registry path>/<entry path>.json}
|
||||
*
|
||||
* <p>The registry will be synced from the server to players' clients using the given network codec.
|
||||
*
|
||||
* @param key the key of the registry
|
||||
* @param dataCodec the codec used to load registry entries from data packs
|
||||
* @param networkCodec the codec used to load registry entries from the network
|
||||
* @param <T> the type of registry entry
|
||||
*/
|
||||
public <T> void dynamicRegistrySynced(ResourceKey<Registry<T>> key, @NotNull Codec<T> dataCodec, @NotNull Codec<T> networkCodec) {
|
||||
this.provider.registerDynamicRegistrySynced(key, dataCodec, networkCodec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forge: If the object is {@code IForgeRegistryEntry}, use `getRegistryName`, else null
|
||||
* Fabric: Use registry
|
||||
@@ -118,5 +173,9 @@ public final class RegistrarManager {
|
||||
<T> void forRegistry(ResourceKey<Registry<T>> key, Consumer<Registrar<T>> consumer);
|
||||
|
||||
<T> RegistrarBuilder<T> builder(Class<T> type, ResourceLocation registryId);
|
||||
|
||||
<T> void registerDynamicRegistry(ResourceKey<Registry<T>> key, Codec<T> dataCodec);
|
||||
|
||||
<T> void registerDynamicRegistrySynced(ResourceKey<Registry<T>> key, Codec<T> dataCodec, Codec<T> networkCodec);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.google.common.base.Objects;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.mojang.serialization.Codec;
|
||||
import dev.architectury.impl.RegistrySupplierImpl;
|
||||
import dev.architectury.registry.registries.Registrar;
|
||||
import dev.architectury.registry.registries.RegistrarBuilder;
|
||||
@@ -30,6 +31,7 @@ import dev.architectury.registry.registries.RegistrarManager;
|
||||
import dev.architectury.registry.registries.RegistrySupplier;
|
||||
import dev.architectury.registry.registries.options.RegistrarOption;
|
||||
import dev.architectury.registry.registries.options.StandardRegistrarOption;
|
||||
import net.fabricmc.fabric.api.event.registry.DynamicRegistries;
|
||||
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryAttribute;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
@@ -94,6 +96,16 @@ public class RegistrarManagerImpl {
|
||||
public <T> RegistrarBuilder<T> builder(Class<T> type, ResourceLocation registryId) {
|
||||
return new RegistrarBuilderWrapper<>(modId, FabricRegistryBuilder.createSimple(type, registryId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void registerDynamicRegistry(ResourceKey<Registry<T>> key, Codec<T> dataCodec) {
|
||||
DynamicRegistries.register(key, dataCodec);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void registerDynamicRegistrySynced(ResourceKey<Registry<T>> key, Codec<T> dataCodec, Codec<T> networkCodec) {
|
||||
DynamicRegistries.registerSynced(key, dataCodec, networkCodec);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RegistryEntryId<T> {
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.google.common.base.Objects;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.mojang.serialization.Codec;
|
||||
import dev.architectury.impl.RegistrySupplierImpl;
|
||||
import dev.architectury.platform.hooks.EventBusesHooks;
|
||||
import dev.architectury.registry.registries.Registrar;
|
||||
@@ -122,6 +123,9 @@ public class RegistrarManagerImpl {
|
||||
@Nullable
|
||||
private List<RegistryBuilderEntry> builders = new ArrayList<>();
|
||||
|
||||
@Nullable
|
||||
private List<DynamicRegistryData<?>> newDynamicRegistries = new ArrayList<>();
|
||||
|
||||
public RegistryProviderImpl(String modId) {
|
||||
this.modId = modId;
|
||||
this.eventBus = Suppliers.memoize(() -> {
|
||||
@@ -177,6 +181,36 @@ public class RegistrarManagerImpl {
|
||||
.setName(registryId), registryId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void registerDynamicRegistry(ResourceKey<Registry<T>> key, Codec<T> dataCodec) {
|
||||
if (newDynamicRegistries == null) {
|
||||
throw new IllegalStateException("Cannot create registries when registries are already aggregated!");
|
||||
}
|
||||
newDynamicRegistries.add(new DynamicRegistryData<>(key, dataCodec, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void registerDynamicRegistrySynced(ResourceKey<Registry<T>> key, Codec<T> dataCodec, Codec<T> networkCodec) {
|
||||
if (newDynamicRegistries == null) {
|
||||
throw new IllegalStateException("Cannot create registries when registries are already aggregated!");
|
||||
}
|
||||
newDynamicRegistries.add(new DynamicRegistryData<>(key, dataCodec, networkCodec));
|
||||
}
|
||||
|
||||
private record DynamicRegistryData<T>(
|
||||
ResourceKey<Registry<T>> key,
|
||||
Codec<T> dataCodec,
|
||||
@Nullable Codec<T> networkCodec) {
|
||||
public void register(DataPackRegistryEvent.NewRegistry event) {
|
||||
if (networkCodec != null) {
|
||||
event.dataPackRegistry(key, dataCodec, networkCodec);
|
||||
} else {
|
||||
event.dataPackRegistry(key, dataCodec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class EventListener {
|
||||
@SubscribeEvent
|
||||
public void handleEvent(RegisterEvent event) {
|
||||
@@ -266,6 +300,16 @@ public class RegistrarManagerImpl {
|
||||
builders = null;
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void handleEvent(DataPackRegistryEvent.NewRegistry event) {
|
||||
if (newDynamicRegistries != null) {
|
||||
for (DynamicRegistryData<?> data : newDynamicRegistries) {
|
||||
data.register(event);
|
||||
}
|
||||
newDynamicRegistries = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.google.common.base.Objects;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.mojang.serialization.Codec;
|
||||
import dev.architectury.impl.RegistrySupplierImpl;
|
||||
import dev.architectury.platform.hooks.forge.EventBusesHooksImpl;
|
||||
import dev.architectury.registry.registries.Registrar;
|
||||
@@ -38,6 +39,7 @@ import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.neoforged.bus.api.EventPriority;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.neoforge.registries.DataPackRegistryEvent;
|
||||
import net.neoforged.neoforge.registries.NewRegistryEvent;
|
||||
import net.neoforged.neoforge.registries.RegisterEvent;
|
||||
import net.neoforged.neoforge.registries.RegistryBuilder;
|
||||
@@ -106,6 +108,9 @@ public class RegistrarManagerImpl {
|
||||
@Nullable
|
||||
private List<Registry<?>> newRegistries = new ArrayList<>();
|
||||
|
||||
@Nullable
|
||||
private List<DynamicRegistryData<?>> newDynamicRegistries = new ArrayList<>();
|
||||
|
||||
public RegistryProviderImpl(String modId) {
|
||||
this.modId = modId;
|
||||
EventBusesHooksImpl.getModEventBus(modId).get().register(new EventListener());
|
||||
@@ -138,6 +143,35 @@ public class RegistrarManagerImpl {
|
||||
return new RegistryBuilderWrapper<>(this, new RegistryBuilder<>(ResourceKey.createRegistryKey(registryId)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void registerDynamicRegistry(ResourceKey<Registry<T>> key, Codec<T> dataCodec) {
|
||||
if (newDynamicRegistries == null) {
|
||||
throw new IllegalStateException("Cannot create registries when registries are already aggregated!");
|
||||
}
|
||||
newDynamicRegistries.add(new DynamicRegistryData<>(key, dataCodec, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void registerDynamicRegistrySynced(ResourceKey<Registry<T>> key, Codec<T> dataCodec, Codec<T> networkCodec) {
|
||||
if (newDynamicRegistries == null) {
|
||||
throw new IllegalStateException("Cannot create registries when registries are already aggregated!");
|
||||
}
|
||||
newDynamicRegistries.add(new DynamicRegistryData<>(key, dataCodec, networkCodec));
|
||||
}
|
||||
|
||||
private record DynamicRegistryData<T>(
|
||||
ResourceKey<Registry<T>> key,
|
||||
Codec<T> dataCodec,
|
||||
@Nullable Codec<T> networkCodec) {
|
||||
public void register(DataPackRegistryEvent.NewRegistry event) {
|
||||
if (networkCodec != null) {
|
||||
event.dataPackRegistry(key, dataCodec, networkCodec);
|
||||
} else {
|
||||
event.dataPackRegistry(key, dataCodec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EventListener {
|
||||
@SubscribeEvent
|
||||
public void handleEvent(RegisterEvent event) {
|
||||
@@ -210,6 +244,16 @@ public class RegistrarManagerImpl {
|
||||
newRegistries = null;
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void handleEvent(DataPackRegistryEvent.NewRegistry event) {
|
||||
if (newDynamicRegistries != null) {
|
||||
for (DynamicRegistryData<?> data : newDynamicRegistries) {
|
||||
data.register(event);
|
||||
}
|
||||
newDynamicRegistries = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user