Rewrote the villager texture cache. It won't attempt to verify textures every time one is retrieved now. That should improve performance.

This commit is contained in:
Sollace 2019-02-05 10:48:27 +02:00
parent 0ac62558f4
commit 8afe1ab07c
5 changed files with 129 additions and 46 deletions

View file

@ -2,7 +2,9 @@ package com.minelittlepony.render.ponies;
import com.minelittlepony.model.PMAPI;
import com.minelittlepony.render.RenderPonyMob;
import com.minelittlepony.util.render.FormattedTextureSupplier;
import com.minelittlepony.util.render.ITextureSupplier;
import com.minelittlepony.util.render.IntStringMapper;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderManager;
@ -11,17 +13,18 @@ import net.minecraft.util.ResourceLocation;
public class RenderPonyVillager extends RenderPonyMob<EntityVillager> {
private static final ITextureSupplier<Integer> PROFESSIONS = new VillagerProfessionTextureCache(
"textures/entity/villager/%d_pony.png",
new ResourceLocation("minelittlepony", "textures/entity/villager/farmer_pony.png"),
new ResourceLocation("minelittlepony", "textures/entity/villager/librarian_pony.png"),
new ResourceLocation("minelittlepony", "textures/entity/villager/priest_pony.png"),
new ResourceLocation("minelittlepony", "textures/entity/villager/smith_pony.png"),
new ResourceLocation("minelittlepony", "textures/entity/villager/butcher_pony.png"),
new ResourceLocation("minelittlepony", "textures/entity/villager/villager_pony.png")
);
private static final ResourceLocation EGG = new ResourceLocation("minelittlepony", "textures/entity/villager/silly_pony.png");
private static final ResourceLocation EGG_2 = new ResourceLocation("minelittlepony", "textures/entity/villager/tiny_silly_pony.png");
/**
* Key mapping from a villager profession id to a human readable name
*/
public static final IntStringMapper MAPPER = new IntStringMapper("farmer", "librarian", "priest", "smith", "butcher", "villager");
private static final ITextureSupplier<String> FORMATTER = new FormattedTextureSupplier("minelittlepony", "textures/entity/villager/%s_pony.png");
private static final ResourceLocation DEFAULT = FORMATTER.supplyTexture("villager");
private static final ResourceLocation EGG = FORMATTER.supplyTexture("silly");
private static final ResourceLocation EGG_2 = FORMATTER.supplyTexture("tiny_silly");
private static final ITextureSupplier<Integer> PROFESSIONS = new VillagerProfessionTextureCache(FORMATTER, MAPPER, DEFAULT);
public RenderPonyVillager(RenderManager manager) {
super(manager, PMAPI.villager);
@ -30,7 +33,7 @@ public class RenderPonyVillager extends RenderPonyMob<EntityVillager> {
@Override
public void preRenderCallback(EntityVillager villager, float ticks) {
super.preRenderCallback(villager, ticks);
GlStateManager.scale(0.9375F, 0.9375F, 0.9375F);
GlStateManager.scale(BASE_MODEL_SCALE, BASE_MODEL_SCALE, BASE_MODEL_SCALE);
}
@Override

View file

@ -2,7 +2,9 @@ package com.minelittlepony.render.ponies;
import com.minelittlepony.model.PMAPI;
import com.minelittlepony.render.RenderPonyMob;
import com.minelittlepony.util.render.FormattedTextureSupplier;
import com.minelittlepony.util.render.ITextureSupplier;
import com.minelittlepony.util.render.IntStringMapper;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.monster.EntityZombieVillager;
@ -10,17 +12,19 @@ import net.minecraft.util.ResourceLocation;
public class RenderPonyZombieVillager extends RenderPonyMob<EntityZombieVillager> {
private static final ITextureSupplier<Integer> PROFESSIONS = new VillagerProfessionTextureCache(
"textures/entity/zombie_villager/zombie_%d_pony.png",
new ResourceLocation("minelittlepony", "textures/entity/zombie_villager/zombie_farmer_pony.png"),
new ResourceLocation("minelittlepony", "textures/entity/zombie_villager/zombie_librarian_pony.png"),
new ResourceLocation("minelittlepony", "textures/entity/zombie_villager/zombie_priest_pony.png"),
new ResourceLocation("minelittlepony", "textures/entity/zombie_villager/zombie_smith_pony.png"),
new ResourceLocation("minelittlepony", "textures/entity/zombie_villager/zombie_butcher_pony.png"),
new ResourceLocation("minelittlepony", "textures/entity/zombie_villager/zombie_villager_pony.png")
);
private static final ResourceLocation EGG = new ResourceLocation("minelittlepony", "textures/entity/zombie_villager/zombie_silly_pony.png");
private static final ResourceLocation EGG_2 = new ResourceLocation("minelittlepony", "textures/entity/zombie_villager/zombie_tiny_silly_pony.png");
/**
* Ditto.
* @see RenderPonyVillager.MAPPER
*/
public static final IntStringMapper MAPPER = new IntStringMapper("farmer", "librarian", "priest", "smith", "butcher", "villager");
private static final ITextureSupplier<String> FORMATTER = new FormattedTextureSupplier("minelittlepony", "textures/entity/zombie_villager/zombie_%s_pony.png");
private static final ResourceLocation DEFAULT = FORMATTER.supplyTexture("villager");
private static final ResourceLocation EGG = FORMATTER.supplyTexture("silly");
private static final ResourceLocation EGG_2 = FORMATTER.supplyTexture("tiny_silly");
private static final ITextureSupplier<Integer> PROFESSIONS = new VillagerProfessionTextureCache(FORMATTER, MAPPER, DEFAULT);
public RenderPonyZombieVillager(RenderManager manager) {
super(manager, PMAPI.zombieVillager);

View file

@ -3,46 +3,57 @@ package com.minelittlepony.render.ponies;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ResourceLocation;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.util.render.ITextureSupplier;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
/**
* Cached pool of villager textures.
*/
class VillagerProfessionTextureCache implements ITextureSupplier<Integer> {
private final ResourceLocation[] pool;
private final String path;
private final ITextureSupplier<String> formatter;
private final Function<Integer, String> keyMapper;
private final ResourceLocation fallback;
private final Map<Integer, ResourceLocation> cache = new HashMap<>();
public VillagerProfessionTextureCache(String path, ResourceLocation... pool) {
this.path = path;
this.pool = pool;
/**
* Creates a new profession cache
*
* @param formatter Formatter used when creating new textures
* @param keyMapper Mapper to convert integer ids into a string value for format insertion
* @param fallback The default if any generated textures fail to load. This is stored in place of failing textures.
*/
public VillagerProfessionTextureCache(ITextureSupplier<String> formatter, Function<Integer, String> keyMapper, ResourceLocation fallback) {
this.formatter = formatter;
this.fallback = fallback;
this.keyMapper = keyMapper;
}
@Override
public ResourceLocation supplyTexture(Integer profession) {
ResourceLocation texture = getVillagerTexture(profession);
try {
Minecraft.getMinecraft().getResourceManager().getResource(texture);
} catch (IOException e) {
return pool[pool.length - 1];
}
return texture;
}
private ResourceLocation getVillagerTexture(int profession) {
if (profession >= pool.length) {
return cache.computeIfAbsent(profession, this::getModProfessionResource);
}
return pool[profession];
return cache.computeIfAbsent(profession, this::getModProfessionResource);
}
private ResourceLocation getModProfessionResource(int professionId) {
return new ResourceLocation("minelittlepony", String.format(path, professionId));
ResourceLocation generated = formatter.supplyTexture(keyMapper.apply(professionId));
try {
Minecraft.getMinecraft().getResourceManager().getResource(generated);
} catch (IOException e) {
MineLittlePony.logger.error("Error loading villager texture `" + generated + "`.", e);
// if texture loading fails, use the fallback.
return fallback;
}
return generated;
}
}

View file

@ -0,0 +1,23 @@
package com.minelittlepony.util.render;
import net.minecraft.util.ResourceLocation;
/**
* Supplies new resource locations based on a pre-defined domain and formatted path.
*/
public class FormattedTextureSupplier implements ITextureSupplier<String> {
private final String domain;
private final String path;
public FormattedTextureSupplier(String domain, String path) {
this.domain = domain;
this.path = path;
}
@Override
public ResourceLocation supplyTexture(String key) {
return new ResourceLocation(domain, String.format(path, key));
}
}

View file

@ -0,0 +1,42 @@
package com.minelittlepony.util.render;
import com.google.common.collect.Maps;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
/**
* Simple mapping from an integer index to a pre-defined set of strings.
* Returns the string representation of the index if no value was found.
*/
public class IntStringMapper implements Function<Integer, String> {
private final HashMap<Integer, String> values = Maps.newHashMap();
/**
* Creates a new string mapper pre-populated with the provided values by index.
*/
public IntStringMapper(String...values) {
for (int i = 0; i < values.length; i++) {
this.values.put(i, Objects.requireNonNull(values[i]));
}
}
/**
* Return the values. So you can actually modify it.
* I mean, if you want to @modders...
*/
public Map<Integer, String> getValues() {
return values;
}
@Override
public String apply(Integer t) {
if (values.containsKey(t)) {
return values.get(t);
}
return String.valueOf(t);
}
}