HolderSetCodec.java

net.minecraft.resources.HolderSetCodec

信息

  • 全限定名:net.minecraft.resources.HolderSetCodec
  • 类型:public class
  • 包:net.minecraft.resources
  • 源码路径:src/main/java/net/minecraft/resources/HolderSetCodec.java
  • 起始行号:L19
  • 实现:Codec<HolderSet>
  • 职责:

    TODO

字段/常量

  • registryKey

    • 类型: ResourceKey<?extends Registry<E>>
    • 修饰符: private final
    • 源码定位: L20
    • 说明:

      TODO

  • elementCodec

    • 类型: Codec<Holder<E>>
    • 修饰符: private final
    • 源码定位: L21
    • 说明:

      TODO

  • homogenousListCodec

    • 类型: Codec<List<Holder<E>>>
    • 修饰符: private final
    • 源码定位: L22
    • 说明:

      TODO

  • registryAwareCodec

    • 类型: Codec<Either<TagKey<E>,List<Holder<E>>>>
    • 修饰符: private final
    • 源码定位: L23
    • 说明:

      TODO

内部类/嵌套类型

构造器

private HolderSetCodec(ResourceKey<?extends Registry<E>> registryKey, Codec<Holder<E>> elementCodec, boolean alwaysUseList) @ L34

  • 构造器名:HolderSetCodec
  • 源码定位:L34
  • 修饰符:private

参数:

  • registryKey: ResourceKey<?extends Registry>
  • elementCodec: Codec<Holder>
  • alwaysUseList: boolean

说明:

TODO

方法

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

private static <E> Codec<List<Holder<E>>> homogenousList(Codec<Holder<E>> elementCodec, boolean alwaysUseList) @ L25

  • 方法名:homogenousList
  • 源码定位:L25
  • 返回类型: Codec<List<Holder>>
  • 修饰符:private static

参数:

  • elementCodec: Codec<Holder>
  • alwaysUseList: boolean

说明:

TODO

public static <E> Codec<HolderSet<E>> create(ResourceKey<?extends Registry<E>> registryKey, Codec<Holder<E>> elementCodec, boolean alwaysUseList) @ L30

  • 方法名:create
  • 源码定位:L30
  • 返回类型: Codec<HolderSet>
  • 修饰符:public static

参数:

  • registryKey: ResourceKey<?extends Registry>
  • elementCodec: Codec<Holder>
  • alwaysUseList: boolean

说明:

TODO

public <T> DataResult<Pair<HolderSet<E>,T>> decode(DynamicOps<T> ops, T input) @ L41

  • 方法名:decode
  • 源码定位:L41
  • 返回类型: DataResult<Pair<HolderSet,T>>
  • 修饰符:public

参数:

  • ops: DynamicOps
  • input: T

说明:

TODO

private static <E> DataResult<HolderSet<E>> lookupTag(HolderGetter<E> registry, TagKey<E> key) @ L65

  • 方法名:lookupTag
  • 源码定位:L65
  • 返回类型: DataResult<HolderSet>
  • 修饰符:private static

参数:

  • registry: HolderGetter
  • key: TagKey

说明:

TODO

public <T> DataResult<T> encode(HolderSet<E> input, DynamicOps<T> ops, T prefix) @ L71

  • 方法名:encode
  • 源码定位:L71
  • 返回类型: DataResult
  • 修饰符:public

参数:

  • input: HolderSet
  • ops: DynamicOps
  • prefix: T

说明:

TODO

private <T> DataResult<Pair<HolderSet<E>,T>> decodeWithoutRegistry(DynamicOps<T> ops, T input) @ L86

  • 方法名:decodeWithoutRegistry
  • 源码定位:L86
  • 返回类型: DataResult<Pair<HolderSet,T>>
  • 修饰符:private

参数:

  • ops: DynamicOps
  • input: T

说明:

TODO

private <T> DataResult<T> encodeWithoutRegistry(HolderSet<E> input, DynamicOps<T> ops, T prefix) @ L102

  • 方法名:encodeWithoutRegistry
  • 源码定位:L102
  • 返回类型: DataResult
  • 修饰符:private

参数:

  • input: HolderSet
  • ops: DynamicOps
  • prefix: T

说明:

TODO

代码

public class HolderSetCodec<E> implements Codec<HolderSet<E>> {
    private final ResourceKey<? extends Registry<E>> registryKey;
    private final Codec<Holder<E>> elementCodec;
    private final Codec<List<Holder<E>>> homogenousListCodec;
    private final Codec<Either<TagKey<E>, List<Holder<E>>>> registryAwareCodec;
 
    private static <E> Codec<List<Holder<E>>> homogenousList(Codec<Holder<E>> elementCodec, boolean alwaysUseList) {
        Codec<List<Holder<E>>> listCodec = elementCodec.listOf().validate(ExtraCodecs.ensureHomogenous(Holder::kind));
        return alwaysUseList ? listCodec : ExtraCodecs.compactListCodec(elementCodec, listCodec);
    }
 
    public static <E> Codec<HolderSet<E>> create(ResourceKey<? extends Registry<E>> registryKey, Codec<Holder<E>> elementCodec, boolean alwaysUseList) {
        return new HolderSetCodec<>(registryKey, elementCodec, alwaysUseList);
    }
 
    private HolderSetCodec(ResourceKey<? extends Registry<E>> registryKey, Codec<Holder<E>> elementCodec, boolean alwaysUseList) {
        this.registryKey = registryKey;
        this.elementCodec = elementCodec;
        this.homogenousListCodec = homogenousList(elementCodec, alwaysUseList);
        this.registryAwareCodec = Codec.either(TagKey.hashedCodec(registryKey), this.homogenousListCodec);
    }
 
    @Override
    public <T> DataResult<Pair<HolderSet<E>, T>> decode(DynamicOps<T> ops, T input) {
        if (ops instanceof RegistryOps<T> registryOps) {
            Optional<HolderGetter<E>> registryOptional = registryOps.getter(this.registryKey);
            if (registryOptional.isPresent()) {
                HolderGetter<E> registry = registryOptional.get();
                return this.registryAwareCodec
                    .decode(ops, input)
                    .flatMap(
                        p -> {
                            DataResult<HolderSet<E>> result = p.getFirst()
                                .map(
                                    tag -> lookupTag(registry, (TagKey<E>)tag),
                                    values -> DataResult.success(HolderSet.direct((List<? extends Holder<E>>)values))
                                );
                            return result.map(holders -> Pair.of((HolderSet<E>)holders, (T)p.getSecond()));
                        }
                    );
            }
        }
 
        return this.decodeWithoutRegistry(ops, input);
    }
 
    private static <E> DataResult<HolderSet<E>> lookupTag(HolderGetter<E> registry, TagKey<E> key) {
        return registry.get(key)
            .<DataResult<HolderSet<E>>>map(DataResult::success)
            .orElseGet(() -> DataResult.error(() -> "Missing tag: '" + key.location() + "' in '" + key.registry().identifier() + "'"));
    }
 
    public <T> DataResult<T> encode(HolderSet<E> input, DynamicOps<T> ops, T prefix) {
        if (ops instanceof RegistryOps<T> registryOps) {
            Optional<HolderOwner<E>> maybeOwner = registryOps.owner(this.registryKey);
            if (maybeOwner.isPresent()) {
                if (!input.canSerializeIn(maybeOwner.get())) {
                    return DataResult.error(() -> "HolderSet " + input + " is not valid in current registry set");
                }
 
                return this.registryAwareCodec.encode(input.unwrap().mapRight(List::copyOf), ops, prefix);
            }
        }
 
        return this.encodeWithoutRegistry(input, ops, prefix);
    }
 
    private <T> DataResult<Pair<HolderSet<E>, T>> decodeWithoutRegistry(DynamicOps<T> ops, T input) {
        return this.elementCodec.listOf().decode(ops, input).flatMap(p -> {
            List<Holder.Direct<E>> directHolders = new ArrayList<>();
 
            for (Holder<E> holder : p.getFirst()) {
                if (!(holder instanceof Holder.Direct<E> direct)) {
                    return DataResult.error(() -> "Can't decode element " + holder + " without registry");
                }
 
                directHolders.add(direct);
            }
 
            return DataResult.success(new Pair<>(HolderSet.direct(directHolders), p.getSecond()));
        });
    }
 
    private <T> DataResult<T> encodeWithoutRegistry(HolderSet<E> input, DynamicOps<T> ops, T prefix) {
        return this.homogenousListCodec.encode(input.stream().toList(), ops, prefix);
    }
}

引用的其他类

  • Holder

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

    • 引用位置: 参数
  • HolderSet

    • 引用位置: 参数/实现/方法调用/返回值
    • 关联成员: HolderSet.direct()
  • Registry

    • 引用位置: 参数/字段
  • ResourceKey

    • 引用位置: 参数/字段
  • TagKey

    • 引用位置: 参数/字段/方法调用
    • 关联成员: TagKey.hashedCodec()
  • ExtraCodecs

    • 引用位置: 方法调用
    • 关联成员: ExtraCodecs.compactListCodec(), ExtraCodecs.ensureHomogenous()