mirror of
https://github.com/PaperMC/Paper.git
synced 2025-08-01 12:42:05 -07:00
Co-authored-by: Bjarne Koll <git@lynxplay.dev> Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com> Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Co-authored-by: Noah van der Aa <ndvdaa@gmail.com> Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
169 lines
8.1 KiB
Diff
169 lines
8.1 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
|
Date: Mon, 6 Apr 2020 17:53:29 -0700
|
|
Subject: [PATCH] Optimize GoalSelector Goal.Flag Set operations
|
|
|
|
Optimise the stream.anyMatch statement to move to a bitset
|
|
where we can replace the call with a single bitwise operation.
|
|
|
|
diff --git a/net/minecraft/world/entity/ai/goal/Goal.java b/net/minecraft/world/entity/ai/goal/Goal.java
|
|
index a66c86066ca2eda10f0ef62e5197a765a994f250..f54bbe2e65b18f214266769c7a64144baafa9a58 100644
|
|
--- a/net/minecraft/world/entity/ai/goal/Goal.java
|
|
+++ b/net/minecraft/world/entity/ai/goal/Goal.java
|
|
@@ -7,7 +7,15 @@ import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.level.Level;
|
|
|
|
public abstract class Goal {
|
|
- private final EnumSet<Goal.Flag> flags = EnumSet.noneOf(Goal.Flag.class);
|
|
+ private final ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<net.minecraft.world.entity.ai.goal.Goal.Flag> goalTypes = new ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from GoalSelector
|
|
+
|
|
+ // Paper start - remove streams from GoalSelector; make sure types are not empty
|
|
+ protected Goal() {
|
|
+ if (this.goalTypes.size() == 0) {
|
|
+ this.goalTypes.addUnchecked(Flag.UNKNOWN_BEHAVIOR);
|
|
+ }
|
|
+ }
|
|
+ // Paper end - remove streams from GoalSelector
|
|
|
|
public abstract boolean canUse();
|
|
|
|
@@ -33,8 +41,13 @@ public abstract class Goal {
|
|
}
|
|
|
|
public void setFlags(EnumSet<Goal.Flag> flagSet) {
|
|
- this.flags.clear();
|
|
- this.flags.addAll(flagSet);
|
|
+ // Paper start - remove streams from GoalSelector
|
|
+ this.goalTypes.clear();
|
|
+ this.goalTypes.addAllUnchecked(flagSet);
|
|
+ if (this.goalTypes.size() == 0) {
|
|
+ this.goalTypes.addUnchecked(Flag.UNKNOWN_BEHAVIOR);
|
|
+ }
|
|
+ // Paper end - remove streams from GoalSelector
|
|
}
|
|
|
|
@Override
|
|
@@ -42,18 +55,20 @@ public abstract class Goal {
|
|
return this.getClass().getSimpleName();
|
|
}
|
|
|
|
- public EnumSet<Goal.Flag> getFlags() {
|
|
- return this.flags;
|
|
+ // Paper start - remove streams from GoalSelector
|
|
+ public ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<Goal.Flag> getFlags() {
|
|
+ return this.goalTypes;
|
|
+ // Paper end - remove streams from GoalSelector
|
|
}
|
|
|
|
|
|
// Paper start - Mob Goal API
|
|
public boolean hasFlag(final Goal.Flag flag) {
|
|
- return this.flags.contains(flag);
|
|
+ return this.goalTypes.hasElement(flag);
|
|
}
|
|
|
|
public void addFlag(final Goal.Flag flag) {
|
|
- this.flags.add(flag);
|
|
+ this.goalTypes.addUnchecked(flag);
|
|
}
|
|
// Paper end - Mob Goal API
|
|
|
|
diff --git a/net/minecraft/world/entity/ai/goal/GoalSelector.java b/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
|
index 674966c580220a4e0c83a628c763aaea8bfd0b1c..859b859d29b637200cf7c9a0bd52d9f712413e3d 100644
|
|
--- a/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
|
+++ b/net/minecraft/world/entity/ai/goal/GoalSelector.java
|
|
@@ -23,7 +23,8 @@ public class GoalSelector {
|
|
};
|
|
private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap<>(Goal.Flag.class);
|
|
private final Set<WrappedGoal> availableGoals = new ObjectLinkedOpenHashSet<>();
|
|
- private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.class);
|
|
+ private static final Goal.Flag[] GOAL_FLAG_VALUES = Goal.Flag.values(); // Paper - remove streams from GoalSelector
|
|
+ private final ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<net.minecraft.world.entity.ai.goal.Goal.Flag> goalTypes = new ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from GoalSelector
|
|
private int curRate; // Paper - EAR 2
|
|
|
|
public void addGoal(int priority, Goal goal) {
|
|
@@ -60,18 +61,18 @@ public class GoalSelector {
|
|
this.availableGoals.removeIf(wrappedGoal1 -> wrappedGoal1.getGoal() == goal);
|
|
}
|
|
|
|
- private static boolean goalContainsAnyFlags(WrappedGoal goal, EnumSet<Goal.Flag> flag) {
|
|
- for (Goal.Flag flag1 : goal.getFlags()) {
|
|
- if (flag.contains(flag1)) {
|
|
- return true;
|
|
- }
|
|
- }
|
|
-
|
|
- return false;
|
|
+ // Paper start - Perf: optimize goal types
|
|
+ private static boolean goalContainsAnyFlags(WrappedGoal goal, ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<Goal.Flag> flags) {
|
|
+ return goal.getFlags().hasCommonElements(flags);
|
|
}
|
|
|
|
private static boolean goalCanBeReplacedForAllFlags(WrappedGoal goal, Map<Goal.Flag, WrappedGoal> flag) {
|
|
- for (Goal.Flag flag1 : goal.getFlags()) {
|
|
+ long flagIterator = goal.getFlags().getBackingSet();
|
|
+ int wrappedGoalSize = goal.getFlags().size();
|
|
+ for (int i = 0; i < wrappedGoalSize; ++i) {
|
|
+ final Goal.Flag flag1 = GOAL_FLAG_VALUES[Long.numberOfTrailingZeros(flagIterator)];
|
|
+ flagIterator ^= ca.spottedleaf.concurrentutil.util.IntegerUtil.getTrailingBit(flagIterator);
|
|
+ // Paper end - Perf: optimize goal types
|
|
if (!flag.getOrDefault(flag1, NO_GOAL).canBeReplacedBy(goal)) {
|
|
return false;
|
|
}
|
|
@@ -85,7 +86,7 @@ public class GoalSelector {
|
|
profilerFiller.push("goalCleanup");
|
|
|
|
for (WrappedGoal wrappedGoal : this.availableGoals) {
|
|
- if (wrappedGoal.isRunning() && (goalContainsAnyFlags(wrappedGoal, this.disabledFlags) || !wrappedGoal.canContinueToUse())) {
|
|
+ if (wrappedGoal.isRunning() && (goalContainsAnyFlags(wrappedGoal, this.goalTypes) || !wrappedGoal.canContinueToUse())) { // Paper - Perf: optimize goal types by removing streams
|
|
wrappedGoal.stop();
|
|
}
|
|
}
|
|
@@ -95,11 +96,14 @@ public class GoalSelector {
|
|
profilerFiller.push("goalUpdate");
|
|
|
|
for (WrappedGoal wrappedGoalx : this.availableGoals) {
|
|
- if (!wrappedGoalx.isRunning()
|
|
- && !goalContainsAnyFlags(wrappedGoalx, this.disabledFlags)
|
|
- && goalCanBeReplacedForAllFlags(wrappedGoalx, this.lockedFlags)
|
|
- && wrappedGoalx.canUse()) {
|
|
- for (Goal.Flag flag : wrappedGoalx.getFlags()) {
|
|
+ // Paper start
|
|
+ if (!wrappedGoalx.isRunning() && !goalContainsAnyFlags(wrappedGoalx, this.goalTypes) && goalCanBeReplacedForAllFlags(wrappedGoalx, this.lockedFlags) && wrappedGoalx.canUse()) {
|
|
+ long flagIterator = wrappedGoalx.getFlags().getBackingSet();
|
|
+ int wrappedGoalSize = wrappedGoalx.getFlags().size();
|
|
+ for (int i = 0; i < wrappedGoalSize; ++i) {
|
|
+ final Goal.Flag flag = GOAL_FLAG_VALUES[Long.numberOfTrailingZeros(flagIterator)];
|
|
+ flagIterator ^= ca.spottedleaf.concurrentutil.util.IntegerUtil.getTrailingBit(flagIterator);
|
|
+ // Paper end
|
|
WrappedGoal wrappedGoal1 = this.lockedFlags.getOrDefault(flag, NO_GOAL);
|
|
wrappedGoal1.stop();
|
|
this.lockedFlags.put(flag, wrappedGoalx);
|
|
@@ -131,11 +135,11 @@ public class GoalSelector {
|
|
}
|
|
|
|
public void disableControlFlag(Goal.Flag flag) {
|
|
- this.disabledFlags.add(flag);
|
|
+ this.goalTypes.addUnchecked(flag); // Paper - remove streams from GoalSelector
|
|
}
|
|
|
|
public void enableControlFlag(Goal.Flag flag) {
|
|
- this.disabledFlags.remove(flag);
|
|
+ this.goalTypes.removeUnchecked(flag); // Paper - remove streams from GoalSelector
|
|
}
|
|
|
|
public void setControlFlag(Goal.Flag flag, boolean enabled) {
|
|
diff --git a/net/minecraft/world/entity/ai/goal/WrappedGoal.java b/net/minecraft/world/entity/ai/goal/WrappedGoal.java
|
|
index 4bdbd323b642ed3422948fe24780be8b503602dc..2c2ab6a1df9d3d23773e44ce4041cc1c21b55163 100644
|
|
--- a/net/minecraft/world/entity/ai/goal/WrappedGoal.java
|
|
+++ b/net/minecraft/world/entity/ai/goal/WrappedGoal.java
|
|
@@ -69,7 +69,7 @@ public class WrappedGoal extends Goal {
|
|
}
|
|
|
|
@Override
|
|
- public EnumSet<Goal.Flag> getFlags() {
|
|
+ public ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<Goal.Flag> getFlags() { // Paper - remove streams from GoalSelector
|
|
return this.goal.getFlags();
|
|
}
|
|
|