diff --git a/common/src/main/java/dev/architectury/registry/registries/Registries.java b/common/src/main/java/dev/architectury/registry/registries/Registries.java index 9b9f6dab..d1c397f8 100644 --- a/common/src/main/java/dev/architectury/registry/registries/Registries.java +++ b/common/src/main/java/dev/architectury/registry/registries/Registries.java @@ -28,6 +28,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; /** * Platform-agnostic wrapper of minecraft registries, should be used to register content. @@ -55,6 +56,19 @@ public final class Registries { return this.provider.get(registry); } + /** + * Listen to registry registration, the callback is called when content should be registered. + * On forge, this is invoked after {@code RegistryEvent.Register}. + * On fabric, this is invoked immediately. + * + * @param key the key of the registry + * @param callback the callback to be invoked + * @param the type of registry entry + */ + public void forRegistry(ResourceKey> key, Consumer> callback) { + this.provider.forRegistry(key, callback); + } + @SafeVarargs public final RegistrarBuilder builder(ResourceLocation registryId, T... typeGetter) { if (typeGetter.length != 0) throw new IllegalStateException("array must be empty!"); @@ -108,6 +122,8 @@ public final class Registries { @Deprecated Registrar get(Registry registry); + void forRegistry(ResourceKey> key, Consumer> consumer); + RegistrarBuilder builder(Class type, ResourceLocation registryId); } } diff --git a/fabric/src/main/java/dev/architectury/registry/registries/fabric/RegistriesImpl.java b/fabric/src/main/java/dev/architectury/registry/registries/fabric/RegistriesImpl.java index 6f76d1c6..4e3ebd1c 100644 --- a/fabric/src/main/java/dev/architectury/registry/registries/fabric/RegistriesImpl.java +++ b/fabric/src/main/java/dev/architectury/registry/registries/fabric/RegistriesImpl.java @@ -40,6 +40,7 @@ import java.util.Iterator; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; import java.util.function.Supplier; public class RegistriesImpl { @@ -72,6 +73,11 @@ public class RegistriesImpl { return new RegistrarImpl<>(registry); } + @Override + public void forRegistry(ResourceKey> key, Consumer> consumer) { + consumer.accept(get(key)); + } + @Override @NotNull public RegistrarBuilder builder(Class type, ResourceLocation registryId) { diff --git a/forge/src/main/java/dev/architectury/registry/registries/forge/RegistriesImpl.java b/forge/src/main/java/dev/architectury/registry/registries/forge/RegistriesImpl.java index 3f172c5d..ba8d80c9 100644 --- a/forge/src/main/java/dev/architectury/registry/registries/forge/RegistriesImpl.java +++ b/forge/src/main/java/dev/architectury/registry/registries/forge/RegistriesImpl.java @@ -22,6 +22,8 @@ package dev.architectury.registry.registries.forge; import com.google.common.base.Objects; import com.google.common.base.Suppliers; import com.google.common.collect.HashBasedTable; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; import com.google.common.collect.Table; import dev.architectury.platform.forge.EventBuses; import dev.architectury.registry.registries.Registrar; @@ -30,6 +32,7 @@ import dev.architectury.registry.registries.Registries; import dev.architectury.registry.registries.RegistrySupplier; import dev.architectury.registry.registries.options.RegistrarOption; import dev.architectury.registry.registries.options.StandardRegistrarOption; +import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.event.RegistryEvent; @@ -48,6 +51,7 @@ import java.util.Iterator; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; import java.util.function.Supplier; public class RegistriesImpl { @@ -69,29 +73,49 @@ public class RegistriesImpl { public static class RegistryProviderImpl implements Registries.RegistryProvider { private final String modId; - private final IEventBus eventBus; + private final Supplier eventBus; private final Table, Supplier>> registry = HashBasedTable.create(); + private final Multimap>, Consumer>> listeners = HashMultimap.create(); public RegistryProviderImpl(String modId) { this.modId = modId; - this.eventBus = EventBuses.getModEventBus(modId).orElseThrow(() -> new IllegalStateException("Can't get event bus for mod '" + modId + "' because it was not registered!")); - this.eventBus.register(new EventListener()); + this.eventBus = Suppliers.memoize(() -> { + IEventBus eventBus = EventBuses.getModEventBus(modId).orElseThrow(() -> new IllegalStateException("Can't get event bus for mod '" + modId + "' because it was not registered!")); + eventBus.register(new EventListener()); + return eventBus; + }); + } + + private void updateEventBus() { + synchronized (eventBus) { + // Make sure that the eventbus is setup + this.eventBus.get(); + } } @Override public Registrar get(ResourceKey> registryKey) { + updateEventBus(); return get(RegistryManager.ACTIVE.getRegistry(registryKey.location())); } public Registrar get(IForgeRegistry registry) { + updateEventBus(); return new ForgeBackedRegistryImpl<>(this.registry, registry); } @Override public Registrar get(net.minecraft.core.Registry registry) { + updateEventBus(); return new VanillaBackedRegistryImpl<>(registry); } + @Override + public void forRegistry(ResourceKey> key, Consumer> consumer) { + this.listeners.put((ResourceKey>) (ResourceKey>) key, + (Consumer>) (Consumer>) consumer); + } + @Override public RegistrarBuilder builder(Class type, ResourceLocation registryId) { return new RegistryBuilderWrapper<>(this, new net.minecraftforge.registries.RegistryBuilder<>() @@ -103,6 +127,7 @@ public class RegistriesImpl { @SubscribeEvent public void handleEvent(RegistryEvent.Register event) { IForgeRegistry registry = event.getRegistry(); + Registrar archRegistry = get(registry); for (Map.Entry, Supplier>>> row : RegistryProviderImpl.this.registry.rowMap().entrySet()) { if (row.getKey() == event.getGenericType()) { @@ -112,6 +137,12 @@ public class RegistriesImpl { } } } + + for (Map.Entry>, Consumer>> entry : listeners.entries()) { + if (entry.getKey().location().equals(registry.getRegistryName())) { + entry.getValue().accept(archRegistry); + } + } } } } diff --git a/gradle.properties b/gradle.properties index 1eeab1e1..db286ed3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ cf_type=beta archives_base_name=architectury archives_base_name_snapshot=architectury-snapshot -base_version=3.0 +base_version=3.1 maven_group=dev.architectury fabric_loader_version=0.12.5