Remove streams from Mob AI System
The streams hurt performance and allocate tons of garbage, so replace them with the standard iterator. Also optimise the stream.anyMatch statement to move to a bitset where we can replace the call with a single bitwise operation.
This commit is contained in:
parent
bb5c294ecf
commit
09a942155f
2 changed files with 495 additions and 5 deletions
|
@ -1,4 +1,4 @@
|
||||||
From c9458dab207ad176a4dc2eb7ca23055d54c0b22c Mon Sep 17 00:00:00 2001
|
From 75ae35c120230e8fbc4a20f7472276d0f398e21a Mon Sep 17 00:00:00 2001
|
||||||
From: Aikar <aikar@aikar.co>
|
From: Aikar <aikar@aikar.co>
|
||||||
Date: Mon, 28 Mar 2016 20:55:47 -0400
|
Date: Mon, 28 Mar 2016 20:55:47 -0400
|
||||||
Subject: [PATCH] MC Utils
|
Subject: [PATCH] MC Utils
|
||||||
|
@ -815,6 +815,242 @@ index 0000000000..c2f7e4ca0f
|
||||||
+ return this.map.values().iterator();
|
+ return this.map.values().iterator();
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
|
diff --git a/src/main/java/com/destroystokyo/paper/util/math/IntegerUtil.java b/src/main/java/com/destroystokyo/paper/util/math/IntegerUtil.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..c3b936f54b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/com/destroystokyo/paper/util/math/IntegerUtil.java
|
||||||
|
@@ -0,0 +1,230 @@
|
||||||
|
+package com.destroystokyo.paper.util.math;
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * @author Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||||
|
+ */
|
||||||
|
+public final class IntegerUtil {
|
||||||
|
+
|
||||||
|
+ public static final int HIGH_BIT_U32 = Integer.MIN_VALUE;
|
||||||
|
+ public static final long HIGH_BIT_U64 = Long.MIN_VALUE;
|
||||||
|
+
|
||||||
|
+ public static int ceilLog2(final int value) {
|
||||||
|
+ return Integer.SIZE - Integer.numberOfLeadingZeros(value - 1); // see doc of numberOfLeadingZeros
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static long ceilLog2(final long value) {
|
||||||
|
+ return Long.SIZE - Long.numberOfLeadingZeros(value - 1); // see doc of numberOfLeadingZeros
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static int floorLog2(final int value) {
|
||||||
|
+ // xor is optimized subtract for 2^n -1
|
||||||
|
+ // note that (2^n -1) - k = (2^n -1) ^ k for k <= (2^n - 1)
|
||||||
|
+ return (Integer.SIZE - 1) ^ Integer.numberOfLeadingZeros(value); // see doc of numberOfLeadingZeros
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static int floorLog2(final long value) {
|
||||||
|
+ // xor is optimized subtract for 2^n -1
|
||||||
|
+ // note that (2^n -1) - k = (2^n -1) ^ k for k <= (2^n - 1)
|
||||||
|
+ return (Long.SIZE - 1) ^ Long.numberOfLeadingZeros(value); // see doc of numberOfLeadingZeros
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static int roundCeilLog2(final int value) {
|
||||||
|
+ // optimized variant of 1 << (32 - leading(val - 1))
|
||||||
|
+ // given
|
||||||
|
+ // 1 << n = HIGH_BIT_32 >>> (31 - n) for n [0, 32)
|
||||||
|
+ // 1 << (32 - leading(val - 1)) = HIGH_BIT_32 >>> (31 - (32 - leading(val - 1)))
|
||||||
|
+ // HIGH_BIT_32 >>> (31 - (32 - leading(val - 1)))
|
||||||
|
+ // HIGH_BIT_32 >>> (31 - 32 + leading(val - 1))
|
||||||
|
+ // HIGH_BIT_32 >>> (-1 + leading(val - 1))
|
||||||
|
+ return HIGH_BIT_U32 >>> (Integer.numberOfLeadingZeros(value - 1) - 1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static long roundCeilLog2(final long value) {
|
||||||
|
+ // see logic documented above
|
||||||
|
+ return HIGH_BIT_U64 >>> (Long.numberOfLeadingZeros(value - 1) - 1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static int roundFloorLog2(final int value) {
|
||||||
|
+ // optimized variant of 1 << (31 - leading(val))
|
||||||
|
+ // given
|
||||||
|
+ // 1 << n = HIGH_BIT_32 >>> (31 - n) for n [0, 32)
|
||||||
|
+ // 1 << (31 - leading(val)) = HIGH_BIT_32 >> (31 - (31 - leading(val)))
|
||||||
|
+ // HIGH_BIT_32 >> (31 - (31 - leading(val)))
|
||||||
|
+ // HIGH_BIT_32 >> (31 - 31 + leading(val))
|
||||||
|
+ return HIGH_BIT_U32 >>> Integer.numberOfLeadingZeros(value);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static long roundFloorLog2(final long value) {
|
||||||
|
+ // see logic documented above
|
||||||
|
+ return HIGH_BIT_U64 >>> Long.numberOfLeadingZeros(value);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static boolean isPowerOfTwo(final int n) {
|
||||||
|
+ // 2^n has one bit
|
||||||
|
+ // note: this rets true for 0 still
|
||||||
|
+ return IntegerUtil.getTrailingBit(n) == n;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static boolean isPowerOfTwo(final long n) {
|
||||||
|
+ // 2^n has one bit
|
||||||
|
+ // note: this rets true for 0 still
|
||||||
|
+ return IntegerUtil.getTrailingBit(n) == n;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ public static int getTrailingBit(final int n) {
|
||||||
|
+ return -n & n;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static long getTrailingBit(final long n) {
|
||||||
|
+ return -n & n;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static int trailingZeros(final int n) {
|
||||||
|
+ return Integer.numberOfTrailingZeros(n);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static long trailingZeros(final long n) {
|
||||||
|
+ return Long.numberOfTrailingZeros(n);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // from hacker's delight (signed division magic value)
|
||||||
|
+ public static int getDivisorMultiple(final long numbers) {
|
||||||
|
+ return (int)(numbers >>> 32);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // from hacker's delight (signed division magic value)
|
||||||
|
+ public static int getDivisorShift(final long numbers) {
|
||||||
|
+ return (int)numbers;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // copied from hacker's delight (signed division magic value)
|
||||||
|
+ // http://www.hackersdelight.org/hdcodetxt/magic.c.txt
|
||||||
|
+ public static long getDivisorNumbers(final int d) {
|
||||||
|
+ final int ad = IntegerUtil.branchlessAbs(d);
|
||||||
|
+
|
||||||
|
+ if (ad < 2) {
|
||||||
|
+ throw new IllegalArgumentException("|number| must be in [2, 2^31 -1], not: " + d);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ final int two31 = 0x80000000;
|
||||||
|
+ final long mask = 0xFFFFFFFFL; // mask for enforcing unsigned behaviour
|
||||||
|
+
|
||||||
|
+ int p = 31;
|
||||||
|
+
|
||||||
|
+ // all these variables are UNSIGNED!
|
||||||
|
+ int t = two31 + (d >>> 31);
|
||||||
|
+ int anc = t - 1 - t%ad;
|
||||||
|
+ int q1 = (int)((two31 & mask)/(anc & mask));
|
||||||
|
+ int r1 = two31 - q1*anc;
|
||||||
|
+ int q2 = (int)((two31 & mask)/(ad & mask));
|
||||||
|
+ int r2 = two31 - q2*ad;
|
||||||
|
+ int delta;
|
||||||
|
+
|
||||||
|
+ do {
|
||||||
|
+ p = p + 1;
|
||||||
|
+ q1 = 2*q1; // Update q1 = 2**p/|nc|.
|
||||||
|
+ r1 = 2*r1; // Update r1 = rem(2**p, |nc|).
|
||||||
|
+ if ((r1 & mask) >= (anc & mask)) {// (Must be an unsigned comparison here)
|
||||||
|
+ q1 = q1 + 1;
|
||||||
|
+ r1 = r1 - anc;
|
||||||
|
+ }
|
||||||
|
+ q2 = 2*q2; // Update q2 = 2**p/|d|.
|
||||||
|
+ r2 = 2*r2; // Update r2 = rem(2**p, |d|).
|
||||||
|
+ if ((r2 & mask) >= (ad & mask)) {// (Must be an unsigned comparison here)
|
||||||
|
+ q2 = q2 + 1;
|
||||||
|
+ r2 = r2 - ad;
|
||||||
|
+ }
|
||||||
|
+ delta = ad - r2;
|
||||||
|
+ } while ((q1 & mask) < (delta & mask) || (q1 == delta && r1 == 0));
|
||||||
|
+
|
||||||
|
+ int magicNum = q2 + 1;
|
||||||
|
+ if (d < 0) {
|
||||||
|
+ magicNum = -magicNum;
|
||||||
|
+ }
|
||||||
|
+ int shift = p - 32;
|
||||||
|
+ return ((long)magicNum << 32) | shift;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static int branchlessAbs(final int val) {
|
||||||
|
+ // -n = -1 ^ n + 1
|
||||||
|
+ final int mask = val >> (Integer.SIZE - 1); // -1 if < 0, 0 if >= 0
|
||||||
|
+ return (mask ^ val) - mask; // if val < 0, then (0 ^ val) - 0 else (-1 ^ val) + 1
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static long branchlessAbs(final long val) {
|
||||||
|
+ // -n = -1 ^ n + 1
|
||||||
|
+ final long mask = val >> (Long.SIZE - 1); // -1 if < 0, 0 if >= 0
|
||||||
|
+ return (mask ^ val) - mask; // if val < 0, then (0 ^ val) - 0 else (-1 ^ val) + 1
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ //https://github.com/skeeto/hash-prospector for hash functions
|
||||||
|
+
|
||||||
|
+ //score = ~590.47984224483832
|
||||||
|
+ public static int hash0(int x) {
|
||||||
|
+ x *= 0x36935555;
|
||||||
|
+ x ^= x >>> 16;
|
||||||
|
+ return x;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ //score = ~310.01596637036749
|
||||||
|
+ public static int hash1(int x) {
|
||||||
|
+ x ^= x >>> 15;
|
||||||
|
+ x *= 0x356aaaad;
|
||||||
|
+ x ^= x >>> 17;
|
||||||
|
+ return x;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static int hash2(int x) {
|
||||||
|
+ x ^= x >>> 16;
|
||||||
|
+ x *= 0x7feb352d;
|
||||||
|
+ x ^= x >>> 15;
|
||||||
|
+ x *= 0x846ca68b;
|
||||||
|
+ x ^= x >>> 16;
|
||||||
|
+ return x;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static int hash3(int x) {
|
||||||
|
+ x ^= x >>> 17;
|
||||||
|
+ x *= 0xed5ad4bb;
|
||||||
|
+ x ^= x >>> 11;
|
||||||
|
+ x *= 0xac4c1b51;
|
||||||
|
+ x ^= x >>> 15;
|
||||||
|
+ x *= 0x31848bab;
|
||||||
|
+ x ^= x >>> 14;
|
||||||
|
+ return x;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ //score = ~365.79959673201887
|
||||||
|
+ public static long hash1(long x) {
|
||||||
|
+ x ^= x >>> 27;
|
||||||
|
+ x *= 0xb24924b71d2d354bL;
|
||||||
|
+ x ^= x >>> 28;
|
||||||
|
+ return x;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ //h2 hash
|
||||||
|
+ public static long hash2(long x) {
|
||||||
|
+ x ^= x >>> 32;
|
||||||
|
+ x *= 0xd6e8feb86659fd93L;
|
||||||
|
+ x ^= x >>> 32;
|
||||||
|
+ x *= 0xd6e8feb86659fd93L;
|
||||||
|
+ x ^= x >>> 32;
|
||||||
|
+ return x;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static long hash3(long x) {
|
||||||
|
+ x ^= x >>> 45;
|
||||||
|
+ x *= 0xc161abe5704b6c79L;
|
||||||
|
+ x ^= x >>> 41;
|
||||||
|
+ x *= 0xe3e5389aedbc90f7L;
|
||||||
|
+ x ^= x >>> 56;
|
||||||
|
+ x *= 0x1f9aba75a52db073L;
|
||||||
|
+ x ^= x >>> 53;
|
||||||
|
+ return x;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private IntegerUtil() {
|
||||||
|
+ throw new RuntimeException();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
diff --git a/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
|
diff --git a/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java b/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000..5a44bc644b
|
index 0000000000..5a44bc644b
|
||||||
|
@ -1540,15 +1776,17 @@ index 0000000000..5f2d88797d
|
||||||
+}
|
+}
|
||||||
diff --git a/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java
|
diff --git a/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000..4d74a7a908
|
index 0000000000..9df0006c1a
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java
|
+++ b/src/main/java/com/destroystokyo/paper/util/set/OptimizedSmallEnumSet.java
|
||||||
@@ -0,0 +1,65 @@
|
@@ -0,0 +1,67 @@
|
||||||
+package com.destroystokyo.paper.util.set;
|
+package com.destroystokyo.paper.util.set;
|
||||||
+
|
+
|
||||||
+import java.util.Collection;
|
+import java.util.Collection;
|
||||||
+
|
+
|
||||||
+// containing utils to work on small numbers of enums
|
+/**
|
||||||
|
+ * @author Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||||
|
+ */
|
||||||
+public final class OptimizedSmallEnumSet<E extends Enum<E>> {
|
+public final class OptimizedSmallEnumSet<E extends Enum<E>> {
|
||||||
+
|
+
|
||||||
+ private final Class<E> enumClass;
|
+ private final Class<E> enumClass;
|
||||||
|
@ -2145,7 +2383,7 @@ index ce48210922..57ce9bde64 100644
|
||||||
this.displayName = this.getName();
|
this.displayName = this.getName();
|
||||||
this.canPickUpLoot = true;
|
this.canPickUpLoot = true;
|
||||||
diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java
|
diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java
|
||||||
index f937b72945..cbf0c2f25d 100644
|
index 29e776ca19..4328273b1f 100644
|
||||||
--- a/src/main/java/net/minecraft/server/EntityTypes.java
|
--- a/src/main/java/net/minecraft/server/EntityTypes.java
|
||||||
+++ b/src/main/java/net/minecraft/server/EntityTypes.java
|
+++ b/src/main/java/net/minecraft/server/EntityTypes.java
|
||||||
@@ -4,6 +4,7 @@ import com.mojang.datafixers.DataFixUtils;
|
@@ -4,6 +4,7 @@ import com.mojang.datafixers.DataFixUtils;
|
||||||
|
|
|
@ -0,0 +1,252 @@
|
||||||
|
From 31cd409fd68946bc43008a237ff6627c905d6633 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Spottedleaf <spottedleaf@spottedleaf.dev>
|
||||||
|
Date: Mon, 6 Apr 2020 17:53:29 -0700
|
||||||
|
Subject: [PATCH] Remove streams from Mob AI System
|
||||||
|
|
||||||
|
The streams hurt performance and allocate tons of garbage, so
|
||||||
|
replace them with the standard iterator.
|
||||||
|
|
||||||
|
Also optimise the stream.anyMatch statement to move to a bitset
|
||||||
|
where we can replace the call with a single bitwise operation.
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoal.java b/src/main/java/net/minecraft/server/PathfinderGoal.java
|
||||||
|
index bdb90a3466..134f7d0013 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/PathfinderGoal.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoal.java
|
||||||
|
@@ -1,10 +1,11 @@
|
||||||
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
+import com.destroystokyo.paper.util.set.OptimizedSmallEnumSet; // Paper - remove streams from pathfindergoalselector
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
public abstract class PathfinderGoal {
|
||||||
|
|
||||||
|
- private final EnumSet<PathfinderGoal.Type> a = EnumSet.noneOf(PathfinderGoal.Type.class);
|
||||||
|
+ private final OptimizedSmallEnumSet<Type> goalTypes = new OptimizedSmallEnumSet<>(PathfinderGoal.Type.class); // Paper - remove streams from pathfindergoalselector
|
||||||
|
|
||||||
|
public PathfinderGoal() {}
|
||||||
|
|
||||||
|
@@ -28,16 +29,20 @@ public abstract class PathfinderGoal {
|
||||||
|
public void e() {}
|
||||||
|
|
||||||
|
public void a(EnumSet<PathfinderGoal.Type> enumset) {
|
||||||
|
- this.a.clear();
|
||||||
|
- this.a.addAll(enumset);
|
||||||
|
+ // Paper start - remove streams from pathfindergoalselector
|
||||||
|
+ this.goalTypes.clear();
|
||||||
|
+ this.goalTypes.addAllUnchecked(enumset);
|
||||||
|
+ // Paper end - remove streams from pathfindergoalselector
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return this.getClass().getSimpleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
- public EnumSet<PathfinderGoal.Type> i() {
|
||||||
|
- return this.a;
|
||||||
|
+ // Paper start - remove streams from pathfindergoalselector
|
||||||
|
+ public com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<PathfinderGoal.Type> getGoalTypes() {
|
||||||
|
+ return this.goalTypes;
|
||||||
|
+ // Paper end - remove streams from pathfindergoalselector
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum Type {
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
|
||||||
|
index 935136771e..90319909e5 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java
|
||||||
|
@@ -1,8 +1,10 @@
|
||||||
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
+import com.destroystokyo.paper.util.set.OptimizedSmallEnumSet; // Paper - remove streams from pathfindergoalselector
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
+import java.util.Iterator; // Paper - remove streams from pathfindergoalselector
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
@@ -26,7 +28,7 @@ public class PathfinderGoalSelector {
|
||||||
|
private final Map<PathfinderGoal.Type, PathfinderGoalWrapped> c = new EnumMap(PathfinderGoal.Type.class);
|
||||||
|
private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet();private Set<PathfinderGoalWrapped> getTasks() { return d; }// Paper - OBFHELPER
|
||||||
|
private final GameProfilerFiller e;
|
||||||
|
- private final EnumSet<PathfinderGoal.Type> f = EnumSet.noneOf(PathfinderGoal.Type.class);
|
||||||
|
+ private final OptimizedSmallEnumSet<PathfinderGoal.Type> goalTypes = new OptimizedSmallEnumSet<>(PathfinderGoal.Type.class); // Paper - remove streams from pathfindergoalselector
|
||||||
|
private int g = 3;private int getTickRate() { return g; } // Paper - OBFHELPER
|
||||||
|
private int curRate;private int getCurRate() { return curRate; } private void incRate() { this.curRate++; } // Paper TODO
|
||||||
|
|
||||||
|
@@ -58,33 +60,36 @@ public class PathfinderGoalSelector {
|
||||||
|
// Paper end
|
||||||
|
|
||||||
|
public void a(PathfinderGoal pathfindergoal) {
|
||||||
|
- this.d.stream().filter((pathfindergoalwrapped) -> {
|
||||||
|
- return pathfindergoalwrapped.j() == pathfindergoal;
|
||||||
|
- }).filter(PathfinderGoalWrapped::g).forEach(PathfinderGoalWrapped::d);
|
||||||
|
- this.d.removeIf((pathfindergoalwrapped) -> {
|
||||||
|
- return pathfindergoalwrapped.j() == pathfindergoal;
|
||||||
|
- });
|
||||||
|
+ // Paper start - remove streams from pathfindergoalselector
|
||||||
|
+ for (Iterator<PathfinderGoalWrapped> iterator = this.d.iterator(); iterator.hasNext();) {
|
||||||
|
+ PathfinderGoalWrapped goalWrapped = iterator.next();
|
||||||
|
+ if (goalWrapped.j() != pathfindergoal) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ if (goalWrapped.g()) {
|
||||||
|
+ goalWrapped.d();
|
||||||
|
+ }
|
||||||
|
+ iterator.remove();
|
||||||
|
+ }
|
||||||
|
+ // Paper end - remove streams from pathfindergoalselector
|
||||||
|
}
|
||||||
|
|
||||||
|
+ private static final PathfinderGoal.Type[] PATHFINDER_GOAL_TYPES = PathfinderGoal.Type.values(); // Paper - remove streams from pathfindergoalselector
|
||||||
|
+
|
||||||
|
public void doTick() {
|
||||||
|
this.e.enter("goalCleanup");
|
||||||
|
- this.c().filter((pathfindergoalwrapped) -> {
|
||||||
|
- boolean flag;
|
||||||
|
-
|
||||||
|
- if (pathfindergoalwrapped.g()) {
|
||||||
|
- Stream stream = pathfindergoalwrapped.i().stream();
|
||||||
|
- EnumSet enumset = this.f;
|
||||||
|
-
|
||||||
|
- this.f.getClass();
|
||||||
|
- if (!stream.anyMatch(enumset::contains) && pathfindergoalwrapped.b()) {
|
||||||
|
- flag = false;
|
||||||
|
- return flag;
|
||||||
|
- }
|
||||||
|
+ // Paper start - remove streams from pathfindergoalselector
|
||||||
|
+ for (Iterator<PathfinderGoalWrapped> iterator = this.d.iterator(); iterator.hasNext();) {
|
||||||
|
+ PathfinderGoalWrapped wrappedGoal = iterator.next();
|
||||||
|
+ if (!wrappedGoal.g()) {
|
||||||
|
+ continue;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- flag = true;
|
||||||
|
- return flag;
|
||||||
|
- }).forEach(PathfinderGoal::d);
|
||||||
|
+ if (!this.goalTypes.hasCommonElements(wrappedGoal.getGoalTypes()) && wrappedGoal.b()) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ wrappedGoal.d();
|
||||||
|
+ }
|
||||||
|
+ // Paper end - remove streams from pathfindergoalselector
|
||||||
|
this.c.forEach((pathfindergoal_type, pathfindergoalwrapped) -> {
|
||||||
|
if (!pathfindergoalwrapped.g()) {
|
||||||
|
this.c.remove(pathfindergoal_type);
|
||||||
|
@@ -93,30 +98,58 @@ public class PathfinderGoalSelector {
|
||||||
|
});
|
||||||
|
this.e.exit();
|
||||||
|
this.e.enter("goalUpdate");
|
||||||
|
- this.d.stream().filter((pathfindergoalwrapped) -> {
|
||||||
|
- return !pathfindergoalwrapped.g();
|
||||||
|
- }).filter((pathfindergoalwrapped) -> {
|
||||||
|
- Stream stream = pathfindergoalwrapped.i().stream();
|
||||||
|
- EnumSet enumset = this.f;
|
||||||
|
-
|
||||||
|
- this.f.getClass();
|
||||||
|
- return stream.noneMatch(enumset::contains);
|
||||||
|
- }).filter((pathfindergoalwrapped) -> {
|
||||||
|
- return pathfindergoalwrapped.i().stream().allMatch((pathfindergoal_type) -> {
|
||||||
|
- return ((PathfinderGoalWrapped) this.c.getOrDefault(pathfindergoal_type, PathfinderGoalSelector.b)).a(pathfindergoalwrapped);
|
||||||
|
- });
|
||||||
|
- }).filter(PathfinderGoalWrapped::a).forEach((pathfindergoalwrapped) -> {
|
||||||
|
- pathfindergoalwrapped.i().forEach((pathfindergoal_type) -> {
|
||||||
|
- PathfinderGoalWrapped pathfindergoalwrapped1 = (PathfinderGoalWrapped) this.c.getOrDefault(pathfindergoal_type, PathfinderGoalSelector.b);
|
||||||
|
-
|
||||||
|
- pathfindergoalwrapped1.d();
|
||||||
|
- this.c.put(pathfindergoal_type, pathfindergoalwrapped);
|
||||||
|
- });
|
||||||
|
- pathfindergoalwrapped.c();
|
||||||
|
- });
|
||||||
|
+ // Paper start - remove streams from pathfindergoalselector
|
||||||
|
+ goal_update_loop: for (Iterator<PathfinderGoalWrapped> iterator = this.d.iterator(); iterator.hasNext();) {
|
||||||
|
+ PathfinderGoalWrapped wrappedGoal = iterator.next();
|
||||||
|
+ if (wrappedGoal.g()) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ OptimizedSmallEnumSet<PathfinderGoal.Type> wrappedGoalSet = wrappedGoal.getGoalTypes();
|
||||||
|
+
|
||||||
|
+ if (this.goalTypes.hasCommonElements(wrappedGoalSet)) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ long iterator1 = wrappedGoalSet.getBackingSet();
|
||||||
|
+ int wrappedGoalSize = wrappedGoalSet.size();
|
||||||
|
+ for (int i = 0; i < wrappedGoalSize; ++i) {
|
||||||
|
+ PathfinderGoal.Type type = PATHFINDER_GOAL_TYPES[Long.numberOfTrailingZeros(iterator1)];
|
||||||
|
+ iterator1 ^= com.destroystokyo.paper.util.math.IntegerUtil.getTrailingBit(iterator1);
|
||||||
|
+ PathfinderGoalWrapped wrapped = this.c.getOrDefault(type, PathfinderGoalSelector.b);
|
||||||
|
+ if (!wrapped.a(wrappedGoal)) {
|
||||||
|
+ continue goal_update_loop;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!wrappedGoal.a()) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ iterator1 = wrappedGoalSet.getBackingSet();
|
||||||
|
+ wrappedGoalSize = wrappedGoalSet.size();
|
||||||
|
+ for (int i = 0; i < wrappedGoalSize; ++i) {
|
||||||
|
+ PathfinderGoal.Type type = PATHFINDER_GOAL_TYPES[Long.numberOfTrailingZeros(iterator1)];
|
||||||
|
+ iterator1 ^= com.destroystokyo.paper.util.math.IntegerUtil.getTrailingBit(iterator1);
|
||||||
|
+ PathfinderGoalWrapped wrapped = this.c.getOrDefault(type, PathfinderGoalSelector.b);
|
||||||
|
+
|
||||||
|
+ wrapped.d();
|
||||||
|
+ this.c.put(type, wrappedGoal);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ wrappedGoal.c();
|
||||||
|
+ }
|
||||||
|
+ // Paper end - remove streams from pathfindergoalselector
|
||||||
|
this.e.exit();
|
||||||
|
this.e.enter("goalTick");
|
||||||
|
- this.c().forEach(PathfinderGoalWrapped::e);
|
||||||
|
+ // Paper start - remove streams from pathfindergoalselector
|
||||||
|
+ for (Iterator<PathfinderGoalWrapped> iterator = this.d.iterator(); iterator.hasNext();) {
|
||||||
|
+ PathfinderGoalWrapped wrappedGoal = iterator.next();
|
||||||
|
+ if (wrappedGoal.g()) {
|
||||||
|
+ wrappedGoal.e();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Paper end - remove streams from pathfindergoalselector
|
||||||
|
this.e.exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -125,11 +158,11 @@ public class PathfinderGoalSelector {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PathfinderGoal.Type pathfindergoal_type) {
|
||||||
|
- this.f.add(pathfindergoal_type);
|
||||||
|
+ this.goalTypes.addUnchecked(pathfindergoal_type); // Paper - remove streams from pathfindergoalselector
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(PathfinderGoal.Type pathfindergoal_type) {
|
||||||
|
- this.f.remove(pathfindergoal_type);
|
||||||
|
+ this.goalTypes.removeUnchecked(pathfindergoal_type); // Paper - remove streams from pathfindergoalselector
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(PathfinderGoal.Type pathfindergoal_type, boolean flag) {
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java b/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java
|
||||||
|
index 29657fed75..1b800c558f 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java
|
||||||
|
@@ -59,9 +59,10 @@ public class PathfinderGoalWrapped extends PathfinderGoal {
|
||||||
|
this.a.a(enumset);
|
||||||
|
}
|
||||||
|
|
||||||
|
- @Override
|
||||||
|
- public EnumSet<PathfinderGoal.Type> i() {
|
||||||
|
- return this.a.i();
|
||||||
|
+ // Paper start - remove streams from pathfindergoalselector
|
||||||
|
+ public com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<PathfinderGoal.Type> getGoalTypes() {
|
||||||
|
+ return this.a.getGoalTypes();
|
||||||
|
+ // Paper end - remove streams from pathfindergoalselector
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRunning() { return this.g(); } // Paper - OBFHELPER
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
Loading…
Reference in a new issue