From 4bdddf1051f9d037b218ac8a540bc72a187640fd Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 27 Apr 2025 20:29:21 -0400 Subject: [PATCH] Attempt to improve parity/reliability of dynamic_entity_renderers --- .../modernfix/entity/EntityRendererMap.java | 94 +++++++++++++++---- 1 file changed, 76 insertions(+), 18 deletions(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/entity/EntityRendererMap.java b/common/src/main/java/org/embeddedt/modernfix/entity/EntityRendererMap.java index f9532eaf..b2ab9510 100644 --- a/common/src/main/java/org/embeddedt/modernfix/entity/EntityRendererMap.java +++ b/common/src/main/java/org/embeddedt/modernfix/entity/EntityRendererMap.java @@ -3,6 +3,8 @@ package org.embeddedt.modernfix.entity; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; +import com.google.common.collect.Iterators; +import com.google.common.collect.Maps; import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.EntityRenderers; @@ -12,14 +14,20 @@ import org.embeddedt.modernfix.ModernFix; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.AbstractCollection; +import java.util.AbstractSet; import java.util.Collection; +import java.util.Iterator; import java.util.Map; +import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutionException; +@SuppressWarnings("OptionalAssignedToNull") public class EntityRendererMap implements Map, EntityRenderer> { private final Map, EntityRendererProvider> rendererProviders; - private final LoadingCache, EntityRenderer> rendererMap; + private final LoadingCache, Optional>> rendererMap; private final EntityRendererProvider.Context context; public EntityRendererMap(Map, EntityRendererProvider> rendererProviders, EntityRendererProvider.Context context) { @@ -28,22 +36,22 @@ public class EntityRendererMap implements Map, EntityRenderer> this.rendererMap = CacheBuilder.newBuilder().build(new RenderConstructor()); } - class RenderConstructor extends CacheLoader, EntityRenderer> { + class RenderConstructor extends CacheLoader, Optional>> { @Override - public EntityRenderer load(EntityType key) throws Exception { + public Optional> load(EntityType key) throws Exception { EntityRendererProvider provider = rendererProviders.get(key); + if(provider == null) + return Optional.empty(); synchronized(EntityRenderers.class) { EntityRenderer renderer; try { - if(provider == null) - throw new RuntimeException("Provider not registered"); renderer = provider.create(context); ModernFix.LOGGER.info("Loaded entity {}", BuiltInRegistries.ENTITY_TYPE.getKey(key)); } catch(RuntimeException e) { ModernFix.LOGGER.error("Failed to create entity model for " + BuiltInRegistries.ENTITY_TYPE.getKey(key) + ":", e); renderer = new ErroredEntityRenderer<>(context); } - return renderer; + return Optional.ofNullable(renderer); } } } @@ -71,10 +79,8 @@ public class EntityRendererMap implements Map, EntityRenderer> @Override public EntityRenderer get(Object o) { try { - EntityRenderer renderer = rendererMap.get((EntityType)o); - if(renderer == null) - throw new AssertionError("Returned entity renderer should never be null"); - return renderer; + Optional> renderer = rendererMap.get((EntityType)o); + return renderer.orElse(null); } catch (IllegalStateException e) { return null; /* emulate value not being present if recursive load occurs */ } catch (ExecutionException e) { @@ -85,21 +91,21 @@ public class EntityRendererMap implements Map, EntityRenderer> @Nullable @Override public EntityRenderer put(EntityType entityType, EntityRenderer entityRenderer) { - EntityRenderer old = rendererMap.getIfPresent(entityType); - rendererMap.put(entityType, entityRenderer); - return old; + Optional> old = rendererMap.getIfPresent(entityType); + rendererMap.put(entityType, Optional.ofNullable(entityRenderer)); + return old != null ? old.orElse(null) : null; } @Override public EntityRenderer remove(Object o) { - EntityRenderer r = rendererMap.getIfPresent(o); + Optional> old = rendererMap.getIfPresent(o); rendererMap.invalidate(o); - return r; + return old != null ? old.orElse(null) : null; } @Override public void putAll(@NotNull Map, ? extends EntityRenderer> map) { - rendererMap.putAll(map); + rendererMap.putAll(Maps.transformValues(map, Optional::ofNullable)); } @Override @@ -116,12 +122,64 @@ public class EntityRendererMap implements Map, EntityRenderer> @NotNull @Override public Collection> values() { - return rendererMap.asMap().values(); + return new AbstractCollection<>() { + @Override + public Iterator> iterator() { + return Iterators.transform(Iterators.unmodifiableIterator(rendererProviders.keySet().iterator()), EntityRendererMap.this::get); + } + + @Override + public int size() { + return rendererProviders.size(); + } + }; + } + + private class Entry implements Map.Entry, EntityRenderer> { + private final EntityType key; + + private Entry(EntityType key) { + this.key = key; + } + + @Override + public EntityType getKey() { + return key; + } + + @Override + public EntityRenderer getValue() { + return get(key); + } + + @Override + public EntityRenderer setValue(EntityRenderer value) { + return put(key, value); + } } @NotNull @Override public Set, EntityRenderer>> entrySet() { - return rendererMap.asMap().entrySet(); + return new AbstractSet<>() { + @Override + public Iterator, EntityRenderer>> iterator() { + return Iterators.transform(Iterators.unmodifiableIterator(rendererProviders.keySet().iterator()), Entry::new); + } + + @Override + public boolean contains(Object o) { + if (o instanceof Map.Entry e) { + return rendererProviders.containsKey(e.getKey()) && Objects.equals(get(e.getKey()), e.getValue()); + } else { + return false; + } + } + + @Override + public int size() { + return rendererProviders.size(); + } + }; } }