BlockStateModelDispatcher.java

net.minecraft.client.renderer.block.dispatch.BlockStateModelDispatcher

信息

  • 全限定名:net.minecraft.client.renderer.block.dispatch.BlockStateModelDispatcher
  • 类型:public record
  • 包:net.minecraft.client.renderer.block.dispatch
  • 源码路径:src/main/java/net/minecraft/client/renderer/block/dispatch/BlockStateModelDispatcher.java
  • 起始行号:L28
  • 职责:

    TODO

字段/常量

  • LOGGER

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

      TODO

  • CODEC

    • 类型: Codec<BlockStateModelDispatcher>
    • 修饰符: public static final
    • 源码定位: L32
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.renderer.block.dispatch.BlockStateModelDispatcher.MultiPartDefinition

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

      TODO

  • net.minecraft.client.renderer.block.dispatch.BlockStateModelDispatcher.SimpleModelSelectors

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

      TODO

构造器

方法

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

public Map<BlockState,BlockStateModel.UnbakedRoot> instantiate(StateDefinition<Block,BlockState> stateDefinition, Supplier<String> source) @ L45

  • 方法名:instantiate
  • 源码定位:L45
  • 返回类型:Map<BlockState,BlockStateModel.UnbakedRoot>
  • 修饰符:public

参数:

  • stateDefinition: StateDefinition<Block,BlockState>
  • source: Supplier

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public record BlockStateModelDispatcher(
    Optional<BlockStateModelDispatcher.SimpleModelSelectors> simpleModels, Optional<BlockStateModelDispatcher.MultiPartDefinition> multiPart
) {
    private static final Logger LOGGER = LogUtils.getLogger();
    public static final Codec<BlockStateModelDispatcher> CODEC = RecordCodecBuilder.<BlockStateModelDispatcher>create(
            i -> i.group(
                    BlockStateModelDispatcher.SimpleModelSelectors.CODEC.optionalFieldOf("variants").forGetter(BlockStateModelDispatcher::simpleModels),
                    BlockStateModelDispatcher.MultiPartDefinition.CODEC.optionalFieldOf("multipart").forGetter(BlockStateModelDispatcher::multiPart)
                )
                .apply(i, BlockStateModelDispatcher::new)
        )
        .validate(
            o -> o.simpleModels().isEmpty() && o.multiPart().isEmpty()
                ? DataResult.error(() -> "Neither 'variants' nor 'multipart' found")
                : DataResult.success(o)
        );
 
    public Map<BlockState, BlockStateModel.UnbakedRoot> instantiate(StateDefinition<Block, BlockState> stateDefinition, Supplier<String> source) {
        Map<BlockState, BlockStateModel.UnbakedRoot> matchedStates = new IdentityHashMap<>();
        this.simpleModels.ifPresent(s -> s.instantiate(stateDefinition, source, (state, model) -> {
            BlockStateModel.UnbakedRoot previousValue = matchedStates.put(state, model);
            if (previousValue != null) {
                throw new IllegalArgumentException("Overlapping definition on state: " + state);
            }
        }));
        this.multiPart.ifPresent(m -> {
            List<BlockState> possibleStates = stateDefinition.getPossibleStates();
            BlockStateModel.UnbakedRoot model = m.instantiate(stateDefinition);
 
            for (BlockState state : possibleStates) {
                matchedStates.putIfAbsent(state, model);
            }
        });
        return matchedStates;
    }
 
    @OnlyIn(Dist.CLIENT)
    public record MultiPartDefinition(List<Selector> selectors) {
        public static final Codec<BlockStateModelDispatcher.MultiPartDefinition> CODEC = ExtraCodecs.nonEmptyList(Selector.CODEC.listOf())
            .xmap(BlockStateModelDispatcher.MultiPartDefinition::new, BlockStateModelDispatcher.MultiPartDefinition::selectors);
 
        public MultiPartModel.Unbaked instantiate(StateDefinition<Block, BlockState> stateDefinition) {
            Builder<MultiPartModel.Selector<BlockStateModel.Unbaked>> instantiatedSelectors = ImmutableList.builderWithExpectedSize(this.selectors.size());
 
            for (Selector selector : this.selectors) {
                instantiatedSelectors.add(new MultiPartModel.Selector<>(selector.instantiate(stateDefinition), selector.variant()));
            }
 
            return new MultiPartModel.Unbaked(instantiatedSelectors.build());
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    public record SimpleModelSelectors(Map<String, BlockStateModel.Unbaked> models) {
        public static final Codec<BlockStateModelDispatcher.SimpleModelSelectors> CODEC = ExtraCodecs.nonEmptyMap(
                Codec.unboundedMap(Codec.STRING, BlockStateModel.Unbaked.CODEC)
            )
            .xmap(BlockStateModelDispatcher.SimpleModelSelectors::new, BlockStateModelDispatcher.SimpleModelSelectors::models);
 
        public void instantiate(
            StateDefinition<Block, BlockState> stateDefinition, Supplier<String> source, BiConsumer<BlockState, BlockStateModel.UnbakedRoot> output
        ) {
            this.models
                .forEach(
                    (selectorString, model) -> {
                        try {
                            Predicate<StateHolder<Block, BlockState>> selector = VariantSelector.predicate(stateDefinition, selectorString);
                            BlockStateModel.UnbakedRoot wrapper = model.asRoot();
 
                            for (BlockState state : stateDefinition.getPossibleStates()) {
                                if (selector.test(state)) {
                                    output.accept(state, wrapper);
                                }
                            }
                        } catch (Exception var9) {
                            BlockStateModelDispatcher.LOGGER
                                .warn("Exception loading blockstate definition: '{}' for variant: '{}': {}", source.get(), selectorString, var9.getMessage());
                        }
                    }
                );
        }
    }
}

引用的其他类

  • BlockStateModel

    • 引用位置: 返回值
  • VariantSelector

    • 引用位置: 方法调用
    • 关联成员: VariantSelector.predicate()
  • MultiPartModel

    • 引用位置: 方法调用/构造调用
    • 关联成员: MultiPartModel.Unbaked(), Unbaked()
  • ExtraCodecs

    • 引用位置: 方法调用
    • 关联成员: ExtraCodecs.nonEmptyList(), ExtraCodecs.nonEmptyMap()
  • Block

    • 引用位置: 参数
  • BlockState

    • 引用位置: 参数/返回值
  • StateDefinition

    • 引用位置: 参数