9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-19 15:09:25 +00:00
Files
Leaf/leaf-server/minecraft-patches/features/0273-optimize-goal-selector.patch
hayanesuru 043cb215fd Optimize canHoldAnyFluid in canMaybePassThrough (#527)
* optimize canHoldAnyFluid in canMaybePassThrough

* rebuild patches

* support reload
2025-10-12 14:26:33 -04:00

194 lines
9.4 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: hayanesuru <hayanesuru@outlook.jp>
Date: Fri, 15 Aug 2025 15:02:27 +0900
Subject: [PATCH] optimize goal selector
diff --git a/net/minecraft/world/entity/ai/goal/Goal.java b/net/minecraft/world/entity/ai/goal/Goal.java
index f54bbe2e65b18f214266769c7a64144baafa9a58..40d53e4469a71b33949ee2bd7b01783d343d4134 100644
--- a/net/minecraft/world/entity/ai/goal/Goal.java
+++ b/net/minecraft/world/entity/ai/goal/Goal.java
@@ -100,10 +100,12 @@ public abstract class Goal {
// Paper end - Mob goal api
public static enum Flag {
+ // Leaf - optimize goal selector - diff on change
UNKNOWN_BEHAVIOR, // Paper - add UNKNOWN_BEHAVIOR
MOVE,
LOOK,
JUMP,
TARGET;
+ // Leaf - optimize goal selector - diff on change
}
}
diff --git a/net/minecraft/world/entity/ai/goal/GoalSelector.java b/net/minecraft/world/entity/ai/goal/GoalSelector.java
index 653c58c7637c46c8b46a5082f671324a2221d431..15b6781d110b7dc95c6dfb576e5258e7457b5e2f 100644
--- a/net/minecraft/world/entity/ai/goal/GoalSelector.java
+++ b/net/minecraft/world/entity/ai/goal/GoalSelector.java
@@ -20,10 +20,12 @@ public class GoalSelector {
}
};
private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap<>(Goal.Flag.class);
- private final Set<WrappedGoal> availableGoals = new ObjectLinkedOpenHashSet<>();
+ private final org.dreeam.leaf.util.map.BinaryGoalSet leaf$availableGoals = new org.dreeam.leaf.util.map.BinaryGoalSet(); // Leaf - optimize goal selector
+ private final Set<WrappedGoal> availableGoals = leaf$availableGoals; // Leaf - optimize goal selector
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
+ private final int[] lockedPriorities = new int[GOAL_FLAG_VALUES.length]; // Leaf - optimize goal selector
public void addGoal(int priority, Goal goal) {
this.availableGoals.add(new WrappedGoal(priority, goal));
@@ -40,7 +42,12 @@ public class GoalSelector {
}
public boolean hasTasks() {
- for (WrappedGoal task : this.availableGoals) {
+ // Leaf start - optimize goal selector
+ org.dreeam.leaf.util.map.BinaryGoalSet availableGoals = this.leaf$availableGoals;
+ WrappedGoal[] elements = availableGoals.elements();
+ for (int i = 0, j = availableGoals.size(); i < j; i++) {
+ WrappedGoal task = elements[i];
+ // Leaf end - optimize goal selector
if (task.isRunning()) {
return true;
}
@@ -50,7 +57,12 @@ public class GoalSelector {
// Paper end - EAR 2
public void removeGoal(Goal goal) {
- for (WrappedGoal wrappedGoal : this.availableGoals) {
+ // Leaf start - optimize goal selector
+ org.dreeam.leaf.util.map.BinaryGoalSet availableGoals = this.leaf$availableGoals;
+ WrappedGoal[] elements = availableGoals.elements();
+ for (int i = 0, j = availableGoals.size(); i < j; i++) {
+ WrappedGoal wrappedGoal = elements[i];
+ // Leaf end - optimize goal selector
if (wrappedGoal.getGoal() == goal && wrappedGoal.isRunning()) {
wrappedGoal.stop();
}
@@ -80,37 +92,81 @@ public class GoalSelector {
}
public void tick() {
- for (WrappedGoal wrappedGoal : this.availableGoals) {
- if (wrappedGoal.isRunning() && (goalContainsAnyFlags(wrappedGoal, this.goalTypes) || !wrappedGoal.canContinueToUse())) { // Paper - Perf: optimize goal types by removing streams
- wrappedGoal.stop();
+ // Leaf start - optimize goal selector
+ final org.dreeam.leaf.util.map.BinaryGoalSet availableGoals = this.leaf$availableGoals;
+ final WrappedGoal[] elements = availableGoals.elements();
+ final long disabled = this.goalTypes.getBackingSet();
+ final int elemSize = availableGoals.size();
+ final Map<Goal.Flag, WrappedGoal> lockedFlags = this.lockedFlags;
+ final int[] lockedPriorities = this.lockedPriorities;
+ long mask = 0L;
+
+ for (int i = 0; i < elemSize; i++) {
+ final WrappedGoal goal = elements[i];
+ if (goal.isRunning() && ((disabled & goal.goal.getFlags().getBackingSet()) != 0 || !goal.canContinueToUse())) {
+ goal.stop();
}
}
-
- this.lockedFlags.entrySet().removeIf(entry -> !entry.getValue().isRunning());
-
- for (WrappedGoal wrappedGoalx : this.availableGoals) {
- // 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);
+ for (int i = 0; i < GOAL_FLAG_VALUES.length; i++) {
+ final Goal.Flag flag = GOAL_FLAG_VALUES[i];
+ final WrappedGoal locked = lockedFlags.get(flag);
+ if (locked == null) {
+ lockedPriorities[i] = Integer.MAX_VALUE;
+ } else if (!locked.isRunning()) {
+ lockedFlags.remove(flag);
+ lockedPriorities[i] = Integer.MAX_VALUE;
+ } else {
+ lockedPriorities[i] = locked.isInterruptable()
+ ? locked.getPriority()
+ : Integer.MIN_VALUE;
+ mask |= (1L << i);
+ }
+ }
+ for (int i = 0; i < elemSize; i++) {
+ final WrappedGoal goal = elements[i];
+ if (goal.isRunning()) {
+ continue;
+ }
+ final long f = goal.goal.getFlags().getBackingSet();
+ final int p = goal.getPriority();
+ if ((disabled & f) != 0L
+ || (f & mask) != 0L
+ && ((f & 1L) != 0L && p >= lockedPriorities[0]
+ || (f & 2L) != 0L && p >= lockedPriorities[1]
+ || (f & 4L) != 0L && p >= lockedPriorities[2]
+ || (f & 8L) != 0L && p >= lockedPriorities[3]
+ || (f & 16L) != 0L && p >= lockedPriorities[4])) {
+ continue;
+ } else if (!goal.canUse()) {
+ continue;
+ }
+ for (long iter = f; iter != 0L; iter &= iter - 1) {
+ final int j = Long.numberOfTrailingZeros(iter);
+ final Goal.Flag flag = GOAL_FLAG_VALUES[j];
+ final WrappedGoal locked = lockedFlags.get(flag);
+ if (locked != null) {
+ locked.stop();
}
-
- wrappedGoalx.start();
+ lockedFlags.put(flag, goal);
+ lockedPriorities[j] = goal.isInterruptable()
+ ? goal.getPriority()
+ : Integer.MIN_VALUE;
+ mask |= (1L << j);
}
+ goal.start();
}
+ // Leaf end - optimize goal selector
this.tickRunningGoals(true);
}
public void tickRunningGoals(boolean tickAllRunning) {
- for (WrappedGoal wrappedGoal : this.availableGoals) {
+ // Leaf start - optimize goal selector
+ org.dreeam.leaf.util.map.BinaryGoalSet availableGoals = this.leaf$availableGoals;
+ WrappedGoal[] elements = availableGoals.elements();
+ for (int i = 0, j = availableGoals.size(); i < j; i++) {
+ WrappedGoal wrappedGoal = elements[i];
+ // Leaf end - optimize goal selector
if (wrappedGoal.isRunning() && (tickAllRunning || wrappedGoal.requiresUpdateEveryTick())) {
wrappedGoal.tick();
}
diff --git a/net/minecraft/world/entity/ai/goal/WrappedGoal.java b/net/minecraft/world/entity/ai/goal/WrappedGoal.java
index 2c2ab6a1df9d3d23773e44ce4041cc1c21b55163..f5ef2e26ff4f9207fc56abe95fe68b3f166499bd 100644
--- a/net/minecraft/world/entity/ai/goal/WrappedGoal.java
+++ b/net/minecraft/world/entity/ai/goal/WrappedGoal.java
@@ -4,7 +4,7 @@ import java.util.EnumSet;
import javax.annotation.Nullable;
public class WrappedGoal extends Goal {
- private final Goal goal;
+ public final Goal goal; // Leaf - optimize goal selector - private -> public
private final int priority;
private boolean isRunning;
@@ -70,6 +70,7 @@ public class WrappedGoal extends Goal {
@Override
public ca.spottedleaf.moonrise.common.set.OptimizedSmallEnumSet<Goal.Flag> getFlags() { // Paper - remove streams from GoalSelector
+ // Leaf - optimize goal selector - diff on change
return this.goal.getFlags();
}