Fix ParticleProviderRegistry not working properly on Forge, add Javadocs (#305)

* Fix ParticleProviderRegistry not working properly on Forge, add Javadocs

Based on https://github.com/architectury/architectury-api/pull/196#issuecomment-1200268981, supersedes #196

* Update testmod, fix bounds on deferred register

* Warn when registering particles too late on Forge
This commit is contained in:
Max
2022-07-31 18:48:38 +02:00
committed by GitHub
parent 7b4b91ea47
commit a7d31393a0
6 changed files with 37 additions and 13 deletions

View File

@@ -19,7 +19,9 @@
package dev.architectury.registry.client.particle;
import dev.architectury.event.events.client.ClientLifecycleEvent;
import dev.architectury.injectables.annotations.ExpectPlatform;
import dev.architectury.registry.registries.RegistrySupplier;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.ParticleProvider;
@@ -31,6 +33,17 @@ import net.minecraft.core.particles.ParticleType;
import java.util.List;
/**
* A utility class for registering custom {@link ParticleProvider}s for particle types.
* <p>
* This class's methods should be invoked <b>before</b> {@link ClientLifecycleEvent#CLIENT_SETUP},
* as doing so afterwards will result in the providers not being registered properly on Forge, causing crashes on startup.
* <p>
* Generally speaking, you should either listen to the registration of your particle type yourself and use either
* {@link #register(ParticleType, ParticleProvider)} or {@link #register(ParticleType, DeferredParticleProvider)} to register the provider,
* or use the helper methods {@link #register(RegistrySupplier, ParticleProvider)} and {@link #register(RegistrySupplier, DeferredParticleProvider)},
* which will automatically handle the listening for you.
*/
@Environment(EnvType.CLIENT)
public final class ParticleProviderRegistry {
public interface ExtendedSpriteSet extends SpriteSet {
@@ -39,6 +52,14 @@ public final class ParticleProviderRegistry {
List<TextureAtlasSprite> getSprites();
}
public static <T extends ParticleOptions> void register(RegistrySupplier<? extends ParticleType<T>> supplier, ParticleProvider<T> provider) {
supplier.listen(it -> register(it, provider));
}
public static <T extends ParticleOptions> void register(RegistrySupplier<? extends ParticleType<T>> supplier, DeferredParticleProvider<T> provider) {
supplier.listen(it -> register(it, provider));
}
@ExpectPlatform
public static <T extends ParticleOptions> void register(ParticleType<T> type, ParticleProvider<T> provider) {
throw new AssertionError();

View File

@@ -19,6 +19,7 @@
package dev.architectury.registry.client.particle.forge;
import com.mojang.logging.LogUtils;
import dev.architectury.forge.ArchitecturyForge;
import dev.architectury.registry.client.particle.ParticleProviderRegistry;
import net.minecraft.client.Minecraft;
@@ -33,13 +34,17 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.ParticleFactoryRegisterEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@Mod.EventBusSubscriber(modid = ArchitecturyForge.MOD_ID, value = Dist.CLIENT)
@Mod.EventBusSubscriber(modid = ArchitecturyForge.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD)
public class ParticleProviderRegistryImpl {
public static final Logger LOGGER = LogUtils.getLogger();
private static final class ExtendedSpriteSetImpl implements ParticleProviderRegistry.ExtendedSpriteSet {
private final ParticleEngine engine;
private final SpriteSet delegate;
@@ -72,28 +77,30 @@ public class ParticleProviderRegistryImpl {
private static ArrayList<Runnable> deferred = new ArrayList<>();
private static <T extends ParticleOptions> void _register(ParticleType<T> type, ParticleProvider<T> provider) {
private static <T extends ParticleOptions> void doRegister(ParticleType<T> type, ParticleProvider<T> provider) {
Minecraft.getInstance().particleEngine.register(type, provider);
}
private static <T extends ParticleOptions> void _register(ParticleType<T> type, ParticleProviderRegistry.DeferredParticleProvider<T> provider) {
private static <T extends ParticleOptions> void doRegister(ParticleType<T> type, ParticleProviderRegistry.DeferredParticleProvider<T> provider) {
Minecraft.getInstance().particleEngine.register(type, sprites ->
provider.create(new ExtendedSpriteSetImpl(Minecraft.getInstance().particleEngine, sprites)));
}
public static <T extends ParticleOptions> void register(ParticleType<T> type, ParticleProvider<T> provider) {
if (deferred == null) {
_register(type, provider);
LOGGER.warn("Something is attempting to register particle providers at a later point than intended! This might cause issues!", new Throwable());
doRegister(type, provider);
} else {
deferred.add(() -> _register(type, provider));
deferred.add(() -> doRegister(type, provider));
}
}
public static <T extends ParticleOptions> void register(ParticleType<T> type, ParticleProviderRegistry.DeferredParticleProvider<T> provider) {
if (deferred == null) {
_register(type, provider);
LOGGER.warn("Something is attempting to register particle providers at a later point than intended! This might cause issues!", new Throwable());
doRegister(type, provider);
} else {
deferred.add(() -> _register(type, provider));
deferred.add(() -> doRegister(type, provider));
}
}

View File

@@ -10,7 +10,7 @@ artifact_type=release
archives_base_name=architectury
archives_base_name_snapshot=architectury-snapshot
base_version=4.6
base_version=4.7
maven_group=dev.architectury
fabric_loader_version=0.13.3

View File

@@ -40,9 +40,7 @@ public class TestParticles {
public static void initialize() {
PARTICLE_TYPES.register();
if (Platform.getEnvironment() == Env.CLIENT) {
ClientLifecycleEvent.CLIENT_SETUP.register(instance -> {
ParticleProviderRegistry.register(TEST_PARTICLE.get(), HeartParticle.Provider::new);
});
ParticleProviderRegistry.register(TEST_PARTICLE, HeartParticle.Provider::new);
}
}
}