Added RegisterClientReloadListenersEvent which lets you register reload listeners with appropriate timing.

Added new entity rendering events.
- EntityRenderersEvent.RegisterLayerDefinitions: Used to register layer definitions for entity models.
- EntityRenderersEvent.RegisterRenderers: Used to register entity renderers.
- EntityRenderersEvent.AddLayers: Called during resource reload after all renderers have been constructed and it's safe to add layers.
Removed RenderingRegistry, which is now not necessary.
Removed a few unused things.
Fixes #7920
This commit is contained in:
gigaherz committed 2021-07-25 12:06:36 +02:00
1 parent eeec737188
commit 6ddf56ef15
13 files changed
+405 -153

No files matched your search

@@ -20,8 +20,12 @@
package net.minecraftforge.client;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.client.model.geom.builders.LayerDefinition;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.level.block.state.BlockState;
import com.mojang.blaze3d.platform.Window;
@@ -112,11 +116,13 @@ import java.io.File;
import java.lang.reflect.Field;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Stream;
import static net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType.BOSSINFO;
@@ -840,4 +846,17 @@ public class ForgeHooksClient
ForgeTextureMetadata metadata = ForgeTextureMetadata.forResource(resource);
return metadata.getLoader() == null ? null : metadata.getLoader().load(textureAtlas, resourceManager, textureInfo, resource, atlasWidth, atlasHeight, spriteX, spriteY, mipmapLevel, image);
}
private static final Map<ModelLayerLocation, Supplier<LayerDefinition>> layerDefinitions = new HashMap<>();
public static void registerLayerDefinition(ModelLayerLocation layerLocation, Supplier<LayerDefinition> supplier)
{
layerDefinitions.put(layerLocation, supplier);
}
public static void loadLayerDefinitions(ImmutableMap.Builder<ModelLayerLocation, LayerDefinition> builder) {
layerDefinitions.forEach((k, v) -> builder.put(k, v.get()));
}
}
@@ -0,0 +1,132 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.event;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.EntityModel;
import net.minecraft.client.model.geom.EntityModelSet;
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.client.model.geom.builders.LayerDefinition;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.EntityRenderers;
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.IModBusEvent;
import javax.annotation.Nullable;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
public class EntityRenderersEvent extends Event implements IModBusEvent
{
public static class RegisterLayerDefinitions extends EntityRenderersEvent
{
/**
* Registers a layer definition supplier with the given {@link ModelLayerLocation}.
* These will be inserted into the main layer definition map for entity model layers at the appropriate time.
*
* @param layerLocation The model layer location, which should be used in conjunction with {@link EntityRendererProvider.Context#bakeLayer(ModelLayerLocation)}
* @param supplier A supplier to create a {@link LayerDefinition}, generally a static method reference in the entity model class
*/
public void registerLayerDefinition(ModelLayerLocation layerLocation, Supplier<LayerDefinition> supplier)
{
ForgeHooksClient.registerLayerDefinition(layerLocation, supplier);
}
}
/**
* Provides a safe place to register entity renderers and layer renderers.
*/
public static class RegisterRenderers extends EntityRenderersEvent
{
/**
* Registers an entity renderer.
*
* @param entityType The EntityType to register a renderer for
* @param entityRendererProvider The renderer provider, can be a lambda like MyRenderer::new
*/
public <T extends Entity> void registerEntityRenderer(EntityType<? extends T> entityType, EntityRendererProvider<T> entityRendererProvider)
{
EntityRenderers.register(entityType, entityRendererProvider);
}
}
/**
* Provides a safe place to register entity renderer layers.
*/
public static class AddLayers extends EntityRenderersEvent
{
private final Map<EntityType<?>, EntityRenderer<?>> renderers;
private final Map<String, EntityRenderer<? extends Player>> skinMap;
private final EntityModelSet entityModels = Minecraft.getInstance().getEntityModels();
public AddLayers(Map<EntityType<?>, EntityRenderer<?>> renderers, Map<String, EntityRenderer<? extends Player>> playerRenderers)
{
this.renderers = renderers;
this.skinMap = playerRenderers;
}
/**
* Returns the list of skins.
*/
public Set<String> getSkins()
{
return skinMap.keySet();
}
/**
* Returns a player skin renderer. Vanilla skins are "default" and "slim".
* @param skinName The name of the skin renderer to return
* @param <R> The type of the skin renderer, usually PlayerRenderer
* @return The skin renderer, or null if not found
*/
@Nullable
@SuppressWarnings("unchecked")
public <R extends LivingEntityRenderer<? extends Player, ? extends EntityModel<? extends Player>>> R getSkin(String skinName)
{
return (R) skinMap.get(skinName);
}
/**
* Returns an entity renderer for the given entity type.
* @param entityType The entity to return a renderer for
* @param <T> The type of entity the renderer is for
* @param <R> The renderer type
* @return The renderer
*/
@Nullable
@SuppressWarnings("unchecked")
public <T extends LivingEntity, R extends LivingEntityRenderer<T, ? extends EntityModel<T>>> R getRenderer(EntityType<? extends T> entityType) {
return (R) renderers.get(entityType);
}
public EntityModelSet getEntityModels()
{
return entityModels;
}
}
}
@@ -17,13 +17,24 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fmlclient.registry;
package net.minecraftforge.client.event;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.world.entity.Entity;
import net.minecraft.server.packs.resources.PreparableReloadListener;
import net.minecraft.server.packs.resources.ReloadableResourceManager;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.IModBusEvent;
public interface IRenderFactory<T extends Entity>
public class RegisterClientReloadListenersEvent extends Event implements IModBusEvent
{
EntityRenderer<? super T> createRenderFor(EntityRenderDispatcher manager);
private final ReloadableResourceManager resourceManager;
public RegisterClientReloadListenersEvent(ReloadableResourceManager resourceManager)
{
this.resourceManager = resourceManager;
}
public void registerReloadListener(PreparableReloadListener reloadListener)
{
resourceManager.registerReloadListener(reloadListener);
}
}
@@ -39,7 +39,6 @@ import net.minecraft.server.packs.repository.Pack;
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.world.level.DataPackConfig;
import net.minecraftforge.fml.*;
import net.minecraftforge.fmlclient.registry.RenderingRegistry;
import net.minecraftforge.fmllegacy.BrandingControl;
import net.minecraftforge.fmllegacy.CrashReportExtender;
import net.minecraftforge.fmllegacy.LogicalSidedProvider;
@@ -137,15 +136,6 @@ public class ClientModLoader
createRunnableWithCatch(() -> ModLoader.get().loadMods(syncExecutor, parallelExecutor, new SpacedRunnable(earlyLoaderGUI::renderTick))).run();
}
private static void postSidedRunnable() {
LOGGER.debug(LOADING, "Running post client event work");
RenderingRegistry.loadEntityRenderers();
}
private static void preSidedRunnable() {
LOGGER.debug(LOADING, "Running pre client event work");
}
private static void finishModLoading(ModWorkManager.DrivenExecutor syncExecutor, Executor parallelExecutor)
{
createRunnableWithCatch(() -> ModLoader.get().finishMods(syncExecutor, parallelExecutor, new SpacedRunnable(earlyLoaderGUI::renderTick))).run();
@@ -1,120 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2021.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fmlclient.registry;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import com.google.common.collect.ImmutableMap;
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.client.model.geom.builders.LayerDefinition;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.EntityRenderers;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
public class RenderingRegistry
{
private static final RenderingRegistry INSTANCE = new RenderingRegistry();
private final Map<EntityType<? extends Entity>, EntityRendererProvider<? extends Entity>> entityRenderers = new ConcurrentHashMap<>();
private final Map<ModelLayerLocation, Supplier<LayerDefinition>> layerDefinitions = new ConcurrentHashMap<>();
/**
* Register an entity rendering handler. This will, after mod initialization, be inserted into the main
* render map for entities.
* Call this during {@link net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent}.
* This method is safe to call during parallel mod loading.
*/
public static <T extends Entity> void registerEntityRenderingHandler(EntityType<T> entityClass, EntityRendererProvider<? super T> renderProvider)
{
INSTANCE.entityRenderers.put(entityClass, renderProvider);
}
/**
* Registers a layer definition supplier with the given {@link ModelLayerLocation}. This will, after mod
* initialization, be inserted into the main layer definition map for entity model layers.
* <p>
* Call this during {@link net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent}.
* This method is safe to call during parallel mod loading.
* @param layerLocation The model layer location, which should be used in conjunction with {@link EntityRendererProvider.Context#bakeLayer(ModelLayerLocation)}
* @param supplier A supplier to create a {@link LayerDefinition}, generally a static method reference in the entity model class
*/
public static void registerLayerDefinition(ModelLayerLocation layerLocation, Supplier<LayerDefinition> supplier)
{
INSTANCE.layerDefinitions.put(layerLocation, supplier);
}
public static void loadEntityRenderers()
{
INSTANCE.entityRenderers.forEach(RenderingRegistry::register);
EntityRenderers.validateRegistrations();
}
public static void loadLayerDefinitions(ImmutableMap.Builder<ModelLayerLocation, LayerDefinition> builder) {
INSTANCE.layerDefinitions.forEach((k, v) -> builder.put(k, v.get()));
}
@SuppressWarnings("unchecked")
private static <T extends Entity> void register(EntityType<T> entityType, EntityRendererProvider<?> renderProvider)
{
EntityRenderers.register(entityType, ((EntityRendererProvider<T>)renderProvider));
}
private static ModelLayerLocation registerModelLayer(ResourceLocation model, String layer)
{
return new ModelLayerLocation(model, layer);
}
/**
* Registers a model layer location for the main layer definition of an entity.
*
* @param model The model {@link ResourceLocation}
* @return A main model layer location
*/
public static ModelLayerLocation registerMainModelLayer(ResourceLocation model)
{
return registerModelLayer(model, "main");
}
/**
* Registers a model layer location for the inner armor layer definition of an entity.
*
* @param model The model {@link ResourceLocation}
* @return An inner armor model layer location
*/
public static ModelLayerLocation registerInnerArmorModelLayer(ResourceLocation model)
{
return registerModelLayer(model, "inner_armor");
}
/**
* Registers a model layer location for the outer armor layer definition of an entity.
*
* @param model The model {@link ResourceLocation}
* @return An outer armor model layer location
*/
public static ModelLayerLocation registerOuterArmorModelLayer(ResourceLocation model)
{
return registerModelLayer(model, "outer_armor");
}
}