TextureSlots.java

net.minecraft.client.resources.model.sprite.TextureSlots

信息

  • 全限定名:net.minecraft.client.resources.model.sprite.TextureSlots
  • 类型:public class
  • 包:net.minecraft.client.resources.model.sprite
  • 源码路径:src/main/java/net/minecraft/client/resources/model/sprite/TextureSlots.java
  • 起始行号:L27
  • 职责:

    TODO

字段/常量

  • EMPTY

    • 类型: TextureSlots
    • 修饰符: public static final
    • 源码定位: L28
    • 说明:

      TODO

  • REFERENCE_CHAR

    • 类型: char
    • 修饰符: private static final
    • 源码定位: L29
    • 说明:

      TODO

  • resolvedValues

    • 类型: Map<String,Material>
    • 修饰符: private final
    • 源码定位: L30
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.resources.model.sprite.TextureSlots.Data

    • 类型: record
    • 修饰符: public
    • 源码定位: L67
    • 说明:

      TODO

  • net.minecraft.client.resources.model.sprite.TextureSlots.Data.Builder

    • 类型: class
    • 修饰符: public static
    • 源码定位: L71
    • 说明:

      TODO

  • net.minecraft.client.resources.model.sprite.TextureSlots.Reference

    • 类型: record
    • 修饰符: private
    • 源码定位: L91
    • 说明:

      TODO

  • net.minecraft.client.resources.model.sprite.TextureSlots.Resolver

    • 类型: class
    • 修饰符: public static
    • 源码定位: L95
    • 说明:

      TODO

  • net.minecraft.client.resources.model.sprite.TextureSlots.SlotContents

    • 类型: interface
    • 修饰符: public sealed
    • 源码定位: L170
    • 说明:

      TODO

  • net.minecraft.client.resources.model.sprite.TextureSlots.Value

    • 类型: record
    • 修饰符: private
    • 源码定位: L174
    • 说明:

      TODO

构造器

private TextureSlots(Map<String,Material> resolvedValues) @ L32

  • 构造器名:TextureSlots
  • 源码定位:L32
  • 修饰符:private

参数:

  • resolvedValues: Map<String,Material>

说明:

TODO

方法

下面的方法块按源码顺序生成。

public Material getMaterial(String reference) @ L36

  • 方法名:getMaterial
  • 源码定位:L36
  • 返回类型:Material
  • 修饰符:public

参数:

  • reference: String

说明:

TODO

private static boolean isTextureReference(String texture) @ L44

  • 方法名:isTextureReference
  • 源码定位:L44
  • 返回类型:boolean
  • 修饰符:private static

参数:

  • texture: String

说明:

TODO

public static TextureSlots.Data parseTextureMap(JsonObject texturesObject) @ L48

  • 方法名:parseTextureMap
  • 源码定位:L48
  • 返回类型:TextureSlots.Data
  • 修饰符:public static

参数:

  • texturesObject: JsonObject

说明:

TODO

private static void parseEntry(String slot, JsonElement value, TextureSlots.Data.Builder output) @ L58

  • 方法名:parseEntry
  • 源码定位:L58
  • 返回类型:void
  • 修饰符:private static

参数:

  • slot: String
  • value: JsonElement
  • output: TextureSlots.Data.Builder

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class TextureSlots {
    public static final TextureSlots EMPTY = new TextureSlots(Map.of());
    private static final char REFERENCE_CHAR = '#';
    private final Map<String, Material> resolvedValues;
 
    private TextureSlots(Map<String, Material> resolvedValues) {
        this.resolvedValues = resolvedValues;
    }
 
    public @Nullable Material getMaterial(String reference) {
        if (isTextureReference(reference)) {
            reference = reference.substring(1);
        }
 
        return this.resolvedValues.get(reference);
    }
 
    private static boolean isTextureReference(String texture) {
        return texture.charAt(0) == '#';
    }
 
    public static TextureSlots.Data parseTextureMap(JsonObject texturesObject) {
        TextureSlots.Data.Builder builder = new TextureSlots.Data.Builder();
 
        for (Entry<String, JsonElement> entry : texturesObject.entrySet()) {
            parseEntry(entry.getKey(), entry.getValue(), builder);
        }
 
        return builder.build();
    }
 
    private static void parseEntry(String slot, JsonElement value, TextureSlots.Data.Builder output) {
        if (GsonHelper.isStringValue(value) && isTextureReference(value.getAsString())) {
            output.addReference(slot, value.getAsString().substring(1));
        } else {
            output.addTexture(slot, Material.CODEC.parse(JsonOps.INSTANCE, value).getOrThrow(JsonParseException::new));
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    public record Data(Map<String, TextureSlots.SlotContents> values) {
        public static final TextureSlots.Data EMPTY = new TextureSlots.Data(Map.of());
 
        @OnlyIn(Dist.CLIENT)
        public static class Builder {
            private final Map<String, TextureSlots.SlotContents> textureMap = new HashMap<>();
 
            public TextureSlots.Data.Builder addReference(String slot, String reference) {
                this.textureMap.put(slot, new TextureSlots.Reference(reference));
                return this;
            }
 
            public TextureSlots.Data.Builder addTexture(String slot, Material material) {
                this.textureMap.put(slot, new TextureSlots.Value(material));
                return this;
            }
 
            public TextureSlots.Data build() {
                return this.textureMap.isEmpty() ? TextureSlots.Data.EMPTY : new TextureSlots.Data(Map.copyOf(this.textureMap));
            }
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    private record Reference(String target) implements TextureSlots.SlotContents {
    }
 
    @OnlyIn(Dist.CLIENT)
    public static class Resolver {
        private static final Logger LOGGER = LogUtils.getLogger();
        private final List<TextureSlots.Data> entries = new ArrayList<>();
 
        public TextureSlots.Resolver addLast(TextureSlots.Data data) {
            this.entries.addLast(data);
            return this;
        }
 
        public TextureSlots.Resolver addFirst(TextureSlots.Data data) {
            this.entries.addFirst(data);
            return this;
        }
 
        public TextureSlots resolve(ModelDebugName debugNameProvider) {
            if (this.entries.isEmpty()) {
                return TextureSlots.EMPTY;
            } else {
                Object2ObjectMap<String, Material> resolved = new Object2ObjectArrayMap<>();
                Object2ObjectMap<String, TextureSlots.Reference> unresolved = new Object2ObjectArrayMap<>();
 
                for (TextureSlots.Data data : Lists.reverse(this.entries)) {
                    data.values.forEach((slot, contents) -> {
                        switch (contents) {
                            case TextureSlots.Value value:
                                unresolved.remove(slot);
                                resolved.put(slot, value.material());
                                break;
                            case TextureSlots.Reference reference:
                                resolved.remove(slot);
                                unresolved.put(slot, reference);
                                break;
                            default:
                                throw new MatchException(null, null);
                        }
                    });
                }
 
                if (unresolved.isEmpty()) {
                    return new TextureSlots(resolved);
                } else {
                    boolean hasChanges = true;
 
                    while (hasChanges) {
                        hasChanges = false;
                        ObjectIterator<it.unimi.dsi.fastutil.objects.Object2ObjectMap.Entry<String, TextureSlots.Reference>> iterator = Object2ObjectMaps.fastIterator(
                            unresolved
                        );
 
                        while (iterator.hasNext()) {
                            it.unimi.dsi.fastutil.objects.Object2ObjectMap.Entry<String, TextureSlots.Reference> entry = iterator.next();
                            Material maybeResolved = resolved.get(entry.getValue().target);
                            if (maybeResolved != null) {
                                resolved.put(entry.getKey(), maybeResolved);
                                iterator.remove();
                                hasChanges = true;
                            }
                        }
                    }
 
                    if (!unresolved.isEmpty()) {
                        LOGGER.warn(
                            "Unresolved texture references in {}:\n{}",
                            debugNameProvider.debugName(),
                            unresolved.entrySet().stream().map(e -> "\t#" + e.getKey() + "-> #" + e.getValue().target + "\n").collect(Collectors.joining())
                        );
                    }
 
                    return new TextureSlots(resolved);
                }
            }
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    public sealed interface SlotContents permits TextureSlots.Value, TextureSlots.Reference {
    }
 
    @OnlyIn(Dist.CLIENT)
    private record Value(Material material) implements TextureSlots.SlotContents {
    }
}

引用的其他类

  • Material

    • 引用位置: 参数/字段/返回值
  • GsonHelper

    • 引用位置: 方法调用
    • 关联成员: GsonHelper.isStringValue()