9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2026-01-04 15:41:40 +00:00
Files
Leaf/leaf-server/minecraft-patches/features/0152-Replace-brain-with-optimized-collection.patch
Dreeam f5b95a6716 Updated Upstream (Paper)
Upstream has released updates that appear to apply and compile correctly

Paper Changes:
PaperMC/Paper@b0da38c2 Repository details in RuntimeException for MavenLibraryResolver#addRepository (#12939)
PaperMC/Paper@1922be90 Update custom tags (#12183)
PaperMC/Paper@79cf1353 Ignore HopperInventorySearchEvent when it has no listeners (#13009)
PaperMC/Paper@ea014f7a feat: add stuckEntityPoiRetryDelay config (#12949)
PaperMC/Paper@a9e76749 Support for showNotification in PlayerRecipeDiscoverEvent (#12992)
PaperMC/Paper@5622c9dd Expose attribute sentiment (#12974)
PaperMC/Paper@42b653b1 Expose more argument types (#12665)
PaperMC/Paper@52d9a221 [ci/skip] Fix typo in Display javadoc (#13010)
PaperMC/Paper@614e9acf Improve APIs around riptide tridents (#12996)
PaperMC/Paper@51706e5a Fixed DyeItem sheep dye hunk
2025-08-25 15:52:00 -04:00

257 lines
14 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
Date: Sat, 26 Oct 2024 00:06:04 +0800
Subject: [PATCH] Replace brain with optimized collection
Co-authored-by: Taiyou06 <kaandindar21@gmail.com>
Co-authored-by: hayanesuru <hayanesuru@outlook.jp>
diff --git a/net/minecraft/world/entity/ai/Brain.java b/net/minecraft/world/entity/ai/Brain.java
index 29fdf94db0308031edfe7915fc587a2aa5a1a18a..d423f325adbdfd524d05af28f1a1097891ea1c40 100644
--- a/net/minecraft/world/entity/ai/Brain.java
+++ b/net/minecraft/world/entity/ai/Brain.java
@@ -45,14 +45,21 @@ public class Brain<E extends LivingEntity> {
static final Logger LOGGER = LogUtils.getLogger();
private final Supplier<Codec<Brain<E>>> codec;
private static final int SCHEDULE_UPDATE_DELAY = 20;
- private final Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = Maps.newHashMap();
- private final Map<SensorType<? extends Sensor<? super E>>, Sensor<? super E>> sensors = Maps.newLinkedHashMap();
- private final Map<Integer, Map<Activity, Set<BehaviorControl<? super E>>>> availableBehaviorsByPriority = Maps.newTreeMap();
+ // Leaf start - Replace brain maps with optimized collection
+ private final Map<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> memories = new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>();
+ private final Map<SensorType<? extends Sensor<? super E>>, Sensor<? super E>> sensors = new it.unimi.dsi.fastutil.objects.Reference2ReferenceArrayMap<>();
+ private final Map<Integer, Map<Activity, Set<BehaviorControl<? super E>>>> availableBehaviorsByPriority = new it.unimi.dsi.fastutil.objects.Object2ObjectRBTreeMap<>();
+ public static final Map[] EMPTY_MAP_ARRAY = {};
+ public static final Set[] EMPTY_SET_ARRAY = {};
+ public static final org.dreeam.leaf.util.map.BehaviorControlArraySet[] EMPTY_BEHAVIOR_ARRAY = {};
+ private Map<Activity, Set<BehaviorControl<? super E>>>[] availableBehaviorsByPriorityArray = EMPTY_MAP_ARRAY;
+ private org.dreeam.leaf.util.map.BehaviorControlArraySet<? super E>[] activeBehaviors = EMPTY_BEHAVIOR_ARRAY;
private Schedule schedule = Schedule.EMPTY;
- private final Map<Activity, Set<Pair<MemoryModuleType<?>, MemoryStatus>>> activityRequirements = Maps.newHashMap();
- private final Map<Activity, Set<MemoryModuleType<?>>> activityMemoriesToEraseWhenStopped = Maps.newHashMap();
- private Set<Activity> coreActivities = Sets.newHashSet();
- private final Set<Activity> activeActivities = Sets.newHashSet();
+ private final Map<Activity, Set<Pair<MemoryModuleType<?>, MemoryStatus>>> activityRequirements = new org.dreeam.leaf.util.map.ActivityArrayMap<>(EMPTY_SET_ARRAY);
+ private final Map<Activity, Set<MemoryModuleType<?>>> activityMemoriesToEraseWhenStopped = new org.dreeam.leaf.util.map.ActivityArrayMap<>(EMPTY_SET_ARRAY);
+ private Set<Activity> coreActivities = Set.of();
+ private final Set<Activity> activeActivities = new org.dreeam.leaf.util.map.ActivityBitSet();
+ // Leaf end - Replace brain maps with optimized collection
private Activity defaultActivity = Activity.IDLE;
private long lastScheduleUpdate = -9999L;
@@ -162,6 +169,8 @@ public class Brain<E extends LivingEntity> {
for (Brain.MemoryValue<?> memoryValue : memoryValues) {
memoryValue.setMemoryInternal(this);
}
+
+ ((it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>>) this.memories).trim(); // Leaf
}
public <T> DataResult<T> serializeStart(DynamicOps<T> ops) {
@@ -178,6 +187,8 @@ public class Brain<E extends LivingEntity> {
public void clearMemories() {
this.memories.keySet().forEach(memoryModuleType -> this.memories.put((MemoryModuleType<?>)memoryModuleType, Optional.empty()));
+ this.availableBehaviorsByPriorityArray = EMPTY_MAP_ARRAY; // Leaf - Replace brain maps with optimized collection
+ this.activeBehaviors = EMPTY_BEHAVIOR_ARRAY; // Leaf - Replace brain maps with optimized collection
}
public <U> void eraseMemory(MemoryModuleType<U> type) {
@@ -362,7 +373,7 @@ public class Brain<E extends LivingEntity> {
}
public void addActivity(Activity activity, ImmutableList<? extends Pair<Integer, ? extends BehaviorControl<? super E>>> tasks) {
- this.addActivityAndRemoveMemoriesWhenStopped(activity, tasks, ImmutableSet.of(), Sets.newHashSet());
+ this.addActivityAndRemoveMemoriesWhenStopped(activity, tasks, ImmutableSet.of(), new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>());
}
public void addActivityWithConditions(
@@ -395,15 +406,18 @@ public class Brain<E extends LivingEntity> {
for (Pair<Integer, ? extends BehaviorControl<? super E>> pair : tasks) {
this.availableBehaviorsByPriority
- .computeIfAbsent(pair.getFirst(), integer -> Maps.newHashMap())
- .computeIfAbsent(activity, activity1 -> Sets.newLinkedHashSet())
+ .computeIfAbsent(pair.getFirst(), integer -> new org.dreeam.leaf.util.map.ActivityArrayMap<>((Set<BehaviorControl<? super E>>[]) EMPTY_SET_ARRAY)) // Leaf - Replace brain maps with optimized collection
+ .computeIfAbsent(activity, activity1 -> new org.dreeam.leaf.util.map.BehaviorControlArraySet<>()) // Leaf - Replace brain maps with optimized collection
.add((BehaviorControl<? super E>)pair.getSecond());
}
+ if (this.activeBehaviors != EMPTY_BEHAVIOR_ARRAY) this.activeBehaviors = EMPTY_BEHAVIOR_ARRAY; // Leaf - Replace brain maps with optimized collection
}
@VisibleForTesting
public void removeAllBehaviors() {
this.availableBehaviorsByPriority.clear();
+ this.availableBehaviorsByPriorityArray = EMPTY_MAP_ARRAY; // Leaf - Replace brain maps with optimized collection
+ this.activeBehaviors = EMPTY_BEHAVIOR_ARRAY; // Leaf - Replace brain maps with optimized collection
}
public boolean isActive(Activity activity) {
@@ -437,14 +451,28 @@ public class Brain<E extends LivingEntity> {
}
private void forgetOutdatedMemories() {
+ boolean flag = false;
+ for (var entry : this.memories.values()) {
+ if (entry.isPresent()) {
+ ExpirableValue<?> expirableValue = entry.get();
+ if (expirableValue.hasExpired()) {
+ flag = true;
+ }
+ expirableValue.tick();
+ }
+ }
+ if (flag) {
+ eraseOutdatedMemories();
+ }
+ }
+
+ private void eraseOutdatedMemories() {
for (Entry<MemoryModuleType<?>, Optional<? extends ExpirableValue<?>>> entry : this.memories.entrySet()) {
if (entry.getValue().isPresent()) {
- ExpirableValue<?> expirableValue = (ExpirableValue<?>)entry.getValue().get();
+ ExpirableValue<?> expirableValue = entry.getValue().get();
if (expirableValue.hasExpired()) {
this.eraseMemory(entry.getKey());
}
-
- expirableValue.tick();
}
}
}
@@ -452,34 +480,95 @@ public class Brain<E extends LivingEntity> {
public void stopAll(ServerLevel level, E owner) {
long gameTime = owner.level().getGameTime();
- for (BehaviorControl<? super E> behaviorControl : this.getRunningBehaviors()) {
- behaviorControl.doStop(level, owner, gameTime);
+ // Leaf start - Replace brain maps with optimized collection
+ if (this.availableBehaviorsByPriorityArray.length != this.availableBehaviorsByPriority.size()) {
+ this.availableBehaviorsByPriorityArray = this.availableBehaviorsByPriority.values().toArray(EMPTY_MAP_ARRAY);
+ }
+ for (Map<Activity, Set<BehaviorControl<? super E>>> map : availableBehaviorsByPriorityArray) {
+ var map1 = (org.dreeam.leaf.util.map.ActivityArrayMap<Set<BehaviorControl<? super E>>>) map;
+ for (int index = 0, size = map1.size(); index < size; index++) {
+ var behaviorControls = (org.dreeam.leaf.util.map.BehaviorControlArraySet<? super E>) map1.v[index];
+ var behaviorControlsRaw = behaviorControls.raw();
+ for (int i = 0, size1 = behaviorControls.size(); i < size1; i++) {
+ BehaviorControl<? super E> behaviorControl = behaviorControlsRaw[i];
+ if (behaviorControl.getStatus() == Behavior.Status.RUNNING) {
+ behaviorControl.doStop(level, owner, gameTime);
+ behaviorControls.dec();
+ }
+ }
+ }
}
+ // Leaf end - Replace brain maps with optimized collection
}
private void startEachNonRunningBehavior(ServerLevel level, E entity) {
long gameTime = level.getGameTime();
- for (Map<Activity, Set<BehaviorControl<? super E>>> map : this.availableBehaviorsByPriority.values()) {
- for (Entry<Activity, Set<BehaviorControl<? super E>>> entry : map.entrySet()) {
- Activity activity = entry.getKey();
- if (this.activeActivities.contains(activity)) {
- for (BehaviorControl<? super E> behaviorControl : entry.getValue()) {
- if (behaviorControl.getStatus() == Behavior.Status.STOPPED) {
- behaviorControl.tryStart(level, entity, gameTime);
- }
+ // Leaf start - Replace brain maps with optimized collection
+ if (this.availableBehaviorsByPriorityArray.length != this.availableBehaviorsByPriority.size()) {
+ this.availableBehaviorsByPriorityArray = this.availableBehaviorsByPriority.values().toArray(EMPTY_MAP_ARRAY);
+ }
+ var aact = (org.dreeam.leaf.util.map.ActivityBitSet) this.activeActivities;
+ if (activeBehaviors == EMPTY_BEHAVIOR_ARRAY || aact.unsetDirty()) {
+ var list = it.unimi.dsi.fastutil.objects.ReferenceArrayList.wrap(activeBehaviors);
+ list.clear();
+ int activeSet = aact.bitSet();
+ for (Map<Activity, Set<BehaviorControl<? super E>>> map : availableBehaviorsByPriorityArray) {
+ for (int index = 0; index < org.dreeam.leaf.util.RegistryTypeManager.ACTIVITY_SIZE; index++) {
+ if ((activeSet & (1 << index)) == 0) {
+ continue;
+ }
+ var ele = ((org.dreeam.leaf.util.map.ActivityArrayMap<Set<BehaviorControl<? super E>>>) map).getValue(index);
+ if (ele == null) {
+ continue;
+ }
+ list.add((org.dreeam.leaf.util.map.BehaviorControlArraySet<? super E>) ele);
+ }
+ }
+ activeBehaviors = it.unimi.dsi.fastutil.objects.ObjectArrays.setLength(list.elements(), list.size());
+ }
+ for (int index = 0, size = activeBehaviors.length; index < size; index++) {
+ var behaviorControls = activeBehaviors[index];
+ var behaviorControlsRaw = behaviorControls.raw();
+ for (int i = 0, size1 = behaviorControls.size(); i < size1; i++) {
+ BehaviorControl<? super E> behaviorControl = behaviorControlsRaw[i];
+ if (behaviorControl.getStatus() == Behavior.Status.STOPPED) {
+ if (behaviorControl.tryStart(level, entity, gameTime)) {
+ behaviorControls.inc();
}
}
}
}
+ // Leaf end - Replace brain maps with optimized collection
}
private void tickEachRunningBehavior(ServerLevel level, E entity) {
long gameTime = level.getGameTime();
- for (BehaviorControl<? super E> behaviorControl : this.getRunningBehaviors()) {
- behaviorControl.tickOrStop(level, entity, gameTime);
+ // Leaf start - Replace brain maps with optimized collection
+ if (this.availableBehaviorsByPriorityArray.length != this.availableBehaviorsByPriority.size()) {
+ this.availableBehaviorsByPriorityArray = this.availableBehaviorsByPriority.values().toArray(new Map[0]);
+ }
+ for (Map<Activity, Set<BehaviorControl<? super E>>> map : availableBehaviorsByPriorityArray) {
+ var map1 = (org.dreeam.leaf.util.map.ActivityArrayMap<Set<BehaviorControl<? super E>>>) map;
+ for (int index = 0, size = map1.size(); index < size; index++) {
+ var behaviorControls = (org.dreeam.leaf.util.map.BehaviorControlArraySet<? super E>) map1.v[index];
+ if (!behaviorControls.running()) {
+ continue;
+ }
+ BehaviorControl<? super E>[] behaviorControlsRaw = behaviorControls.raw();
+ for (int i = 0, size1 = behaviorControls.size(); i < size1; i++) {
+ BehaviorControl<? super E> behaviorControl = behaviorControlsRaw[i];
+ if (behaviorControl.getStatus() == Behavior.Status.RUNNING) {
+ behaviorControl.tickOrStop(level, entity, gameTime);
+ if (behaviorControl.getStatus() == Behavior.Status.STOPPED) {
+ behaviorControls.dec();
+ }
+ }
+ }
+ }
}
+ // Leaf end - Replace brain maps with optimized collection
}
private boolean activityRequirementsAreMet(Activity activity) {
diff --git a/net/minecraft/world/entity/schedule/Activity.java b/net/minecraft/world/entity/schedule/Activity.java
index 5a143bb6fabba3dc4e2272afb0be636d5722ea22..7753b2b2ab00c08dc15444a1caa08faac1d82f0c 100644
--- a/net/minecraft/world/entity/schedule/Activity.java
+++ b/net/minecraft/world/entity/schedule/Activity.java
@@ -32,10 +32,12 @@ public class Activity {
public static final Activity DIG = register("dig");
private final String name;
private final int hashCode;
+ public final int id; // Leaf
- private Activity(String name) {
+ private Activity(String name, int id) { // Leaf
this.name = name;
this.hashCode = name.hashCode();
+ this.id = id; // Leaf
}
public String getName() {
@@ -43,7 +45,7 @@ public class Activity {
}
private static Activity register(String key) {
- return Registry.register(BuiltInRegistries.ACTIVITY, key, new Activity(key));
+ return Registry.register(BuiltInRegistries.ACTIVITY, key, new Activity(key, BuiltInRegistries.ACTIVITY.size())); // Leaf
}
@Override