TreeNodePosition.java

net.minecraft.advancements.TreeNodePosition

信息

  • 全限定名:net.minecraft.advancements.TreeNodePosition
  • 类型:public class
  • 包:net.minecraft.advancements
  • 源码路径:src/main/java/net/minecraft/advancements/TreeNodePosition.java
  • 起始行号:L7
  • 职责:

    TODO

字段/常量

  • node

    • 类型: AdvancementNode
    • 修饰符: private final
    • 源码定位: L8
    • 说明:

      TODO

  • parent

    • 类型: TreeNodePosition
    • 修饰符: private final
    • 源码定位: L9
    • 说明:

      TODO

  • previousSibling

    • 类型: TreeNodePosition
    • 修饰符: private final
    • 源码定位: L10
    • 说明:

      TODO

  • childIndex

    • 类型: int
    • 修饰符: private final
    • 源码定位: L11
    • 说明:

      TODO

  • children

    • 类型: List<TreeNodePosition>
    • 修饰符: private final
    • 源码定位: L12
    • 说明:

      TODO

  • ancestor

    • 类型: TreeNodePosition
    • 修饰符: private
    • 源码定位: L13
    • 说明:

      TODO

  • thread

    • 类型: TreeNodePosition
    • 修饰符: private
    • 源码定位: L14
    • 说明:

      TODO

  • x

    • 类型: int
    • 修饰符: private
    • 源码定位: L15
    • 说明:

      TODO

  • y

    • 类型: float
    • 修饰符: private
    • 源码定位: L16
    • 说明:

      TODO

  • mod

    • 类型: float
    • 修饰符: private
    • 源码定位: L17
    • 说明:

      TODO

  • change

    • 类型: float
    • 修饰符: private
    • 源码定位: L18
    • 说明:

      TODO

  • shift

    • 类型: float
    • 修饰符: private
    • 源码定位: L19
    • 说明:

      TODO

内部类/嵌套类型

构造器

public TreeNodePosition(AdvancementNode node, TreeNodePosition parent, TreeNodePosition previousSibling, int childIndex, int depth) @ L21

  • 构造器名:TreeNodePosition
  • 源码定位:L21
  • 修饰符:public

参数:

  • node: AdvancementNode
  • parent: TreeNodePosition
  • previousSibling: TreeNodePosition
  • childIndex: int
  • depth: int

说明:

TODO

方法

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

private TreeNodePosition addChild(AdvancementNode node, TreeNodePosition previous) @ L40

  • 方法名:addChild
  • 源码定位:L40
  • 返回类型:TreeNodePosition
  • 修饰符:private

参数:

  • node: AdvancementNode
  • previous: TreeNodePosition

说明:

TODO

private void firstWalk() @ L53

  • 方法名:firstWalk
  • 源码定位:L53
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private float secondWalk(float modSum, int depth, float min) @ L79

  • 方法名:secondWalk
  • 源码定位:L79
  • 返回类型:float
  • 修饰符:private

参数:

  • modSum: float
  • depth: int
  • min: float

说明:

TODO

private void thirdWalk(float offset) @ L93

  • 方法名:thirdWalk
  • 源码定位:L93
  • 返回类型:void
  • 修饰符:private

参数:

  • offset: float

说明:

TODO

private void executeShifts() @ L101

  • 方法名:executeShifts
  • 源码定位:L101
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private TreeNodePosition previousOrThread() @ L114

  • 方法名:previousOrThread
  • 源码定位:L114
  • 返回类型:TreeNodePosition
  • 修饰符:private

参数:

说明:

TODO

private TreeNodePosition nextOrThread() @ L122

  • 方法名:nextOrThread
  • 源码定位:L122
  • 返回类型:TreeNodePosition
  • 修饰符:private

参数:

说明:

TODO

private TreeNodePosition apportion(TreeNodePosition defaultAncestor) @ L130

  • 方法名:apportion
  • 源码定位:L130
  • 返回类型:TreeNodePosition
  • 修饰符:private

参数:

  • defaultAncestor: TreeNodePosition

说明:

TODO

private void moveSubtree(TreeNodePosition right, float shift) @ L177

  • 方法名:moveSubtree
  • 源码定位:L177
  • 返回类型:void
  • 修饰符:private

参数:

  • right: TreeNodePosition
  • shift: float

说明:

TODO

private TreeNodePosition getAncestor(TreeNodePosition other, TreeNodePosition defaultAncestor) @ L189

  • 方法名:getAncestor
  • 源码定位:L189
  • 返回类型:TreeNodePosition
  • 修饰符:private

参数:

  • other: TreeNodePosition
  • defaultAncestor: TreeNodePosition

说明:

TODO

private void finalizePosition() @ L193

  • 方法名:finalizePosition
  • 源码定位:L193
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

public static void run(AdvancementNode node) @ L202

  • 方法名:run
  • 源码定位:L202
  • 返回类型:void
  • 修饰符:public static

参数:

  • node: AdvancementNode

说明:

TODO

代码

public class TreeNodePosition {
    private final AdvancementNode node;
    private final @Nullable TreeNodePosition parent;
    private final @Nullable TreeNodePosition previousSibling;
    private final int childIndex;
    private final List<TreeNodePosition> children = Lists.newArrayList();
    private TreeNodePosition ancestor;
    private @Nullable TreeNodePosition thread;
    private int x;
    private float y;
    private float mod;
    private float change;
    private float shift;
 
    public TreeNodePosition(AdvancementNode node, @Nullable TreeNodePosition parent, @Nullable TreeNodePosition previousSibling, int childIndex, int depth) {
        if (node.advancement().display().isEmpty()) {
            throw new IllegalArgumentException("Can't position an invisible advancement!");
        } else {
            this.node = node;
            this.parent = parent;
            this.previousSibling = previousSibling;
            this.childIndex = childIndex;
            this.ancestor = this;
            this.x = depth;
            this.y = -1.0F;
            TreeNodePosition previous = null;
 
            for (AdvancementNode child : node.children()) {
                previous = this.addChild(child, previous);
            }
        }
    }
 
    private @Nullable TreeNodePosition addChild(AdvancementNode node, @Nullable TreeNodePosition previous) {
        if (node.advancement().display().isPresent()) {
            previous = new TreeNodePosition(node, this, previous, this.children.size() + 1, this.x + 1);
            this.children.add(previous);
        } else {
            for (AdvancementNode grandchild : node.children()) {
                previous = this.addChild(grandchild, previous);
            }
        }
 
        return previous;
    }
 
    private void firstWalk() {
        if (this.children.isEmpty()) {
            if (this.previousSibling != null) {
                this.y = this.previousSibling.y + 1.0F;
            } else {
                this.y = 0.0F;
            }
        } else {
            TreeNodePosition defaultAncestor = null;
 
            for (TreeNodePosition child : this.children) {
                child.firstWalk();
                defaultAncestor = child.apportion(defaultAncestor == null ? child : defaultAncestor);
            }
 
            this.executeShifts();
            float midpoint = (this.children.get(0).y + this.children.get(this.children.size() - 1).y) / 2.0F;
            if (this.previousSibling != null) {
                this.y = this.previousSibling.y + 1.0F;
                this.mod = this.y - midpoint;
            } else {
                this.y = midpoint;
            }
        }
    }
 
    private float secondWalk(float modSum, int depth, float min) {
        this.y += modSum;
        this.x = depth;
        if (this.y < min) {
            min = this.y;
        }
 
        for (TreeNodePosition child : this.children) {
            min = child.secondWalk(modSum + this.mod, depth + 1, min);
        }
 
        return min;
    }
 
    private void thirdWalk(float offset) {
        this.y += offset;
 
        for (TreeNodePosition child : this.children) {
            child.thirdWalk(offset);
        }
    }
 
    private void executeShifts() {
        float shift = 0.0F;
        float change = 0.0F;
 
        for (int i = this.children.size() - 1; i >= 0; i--) {
            TreeNodePosition child = this.children.get(i);
            child.y += shift;
            child.mod += shift;
            change += child.change;
            shift += child.shift + change;
        }
    }
 
    private @Nullable TreeNodePosition previousOrThread() {
        if (this.thread != null) {
            return this.thread;
        } else {
            return !this.children.isEmpty() ? this.children.get(0) : null;
        }
    }
 
    private @Nullable TreeNodePosition nextOrThread() {
        if (this.thread != null) {
            return this.thread;
        } else {
            return !this.children.isEmpty() ? this.children.get(this.children.size() - 1) : null;
        }
    }
 
    private TreeNodePosition apportion(TreeNodePosition defaultAncestor) {
        if (this.previousSibling == null) {
            return defaultAncestor;
        } else {
            TreeNodePosition vir = this;
            TreeNodePosition vor = this;
            TreeNodePosition vil = this.previousSibling;
            TreeNodePosition vol = this.parent.children.get(0);
            float sir = this.mod;
            float sor = this.mod;
            float sil = vil.mod;
 
            float sol;
            for (sol = vol.mod; vil.nextOrThread() != null && vir.previousOrThread() != null; sor += vor.mod) {
                vil = vil.nextOrThread();
                vir = vir.previousOrThread();
                vol = vol.previousOrThread();
                vor = vor.nextOrThread();
                vor.ancestor = this;
                float shift = vil.y + sil - (vir.y + sir) + 1.0F;
                if (shift > 0.0F) {
                    vil.getAncestor(this, defaultAncestor).moveSubtree(this, shift);
                    sir += shift;
                    sor += shift;
                }
 
                sil += vil.mod;
                sir += vir.mod;
                sol += vol.mod;
            }
 
            if (vil.nextOrThread() != null && vor.nextOrThread() == null) {
                vor.thread = vil.nextOrThread();
                vor.mod += sil - sor;
            } else {
                if (vir.previousOrThread() != null && vol.previousOrThread() == null) {
                    vol.thread = vir.previousOrThread();
                    vol.mod += sir - sol;
                }
 
                defaultAncestor = this;
            }
 
            return defaultAncestor;
        }
    }
 
    private void moveSubtree(TreeNodePosition right, float shift) {
        float subtrees = right.childIndex - this.childIndex;
        if (subtrees != 0.0F) {
            right.change -= shift / subtrees;
            this.change += shift / subtrees;
        }
 
        right.shift += shift;
        right.y += shift;
        right.mod += shift;
    }
 
    private TreeNodePosition getAncestor(TreeNodePosition other, TreeNodePosition defaultAncestor) {
        return this.ancestor != null && other.parent.children.contains(this.ancestor) ? this.ancestor : defaultAncestor;
    }
 
    private void finalizePosition() {
        this.node.advancement().display().ifPresent(display -> display.setLocation(this.x, this.y));
        if (!this.children.isEmpty()) {
            for (TreeNodePosition child : this.children) {
                child.finalizePosition();
            }
        }
    }
 
    public static void run(AdvancementNode node) {
        if (node.advancement().display().isEmpty()) {
            throw new IllegalArgumentException("Can't position children of an invisible root!");
        } else {
            TreeNodePosition root = new TreeNodePosition(node, null, null, 1, 0);
            root.firstWalk();
            float min = root.secondWalk(0.0F, 0, root.y);
            if (min < 0.0F) {
                root.thirdWalk(-min);
            }
 
            root.finalizePosition();
        }
    }
}

引用的其他类