9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-19 15:09:25 +00:00

cleanup & remove threshold in async target finding

This commit is contained in:
hayanesuru
2025-06-16 20:28:09 +09:00
parent 510ddf3bbc
commit 04543a97f3
5 changed files with 189 additions and 327 deletions

View File

@@ -117,10 +117,10 @@ index c1efd558cfbfd2200295ef5755aa496e95deb7d7..15bbd1f7f2a90b4b5427026d622764bb
this.tickChunks(l, list); // Gale - Purpur - remove vanilla profiler this.tickChunks(l, list); // Gale - Purpur - remove vanilla profiler
} finally { } finally {
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 7955a8fa9c4de139b24c9d53018b055ff4008e02..eb849c57992658005e0f514c6f7923f8ca43bebf 100644 index 53ea97c91684e9a0a3ed9f94ac15c242a43434ec..7cbcc2dd8533973108841d3989265a392a6f6214 100644
--- a/net/minecraft/server/level/ServerLevel.java --- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java
@@ -1521,13 +1521,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -1511,13 +1511,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
// Paper end - log detailed entity tick information // Paper end - log detailed entity tick information
public void tickNonPassenger(Entity entity) { public void tickNonPassenger(Entity entity) {
@@ -134,7 +134,7 @@ index 7955a8fa9c4de139b24c9d53018b055ff4008e02..eb849c57992658005e0f514c6f7923f8
entity.setOldPosAndRot(); entity.setOldPosAndRot();
entity.tickCount++; entity.tickCount++;
entity.totalEntityAge++; // Paper - age-like counter for all entities entity.totalEntityAge++; // Paper - age-like counter for all entities
@@ -1540,13 +1534,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -1530,13 +1524,6 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
for (Entity entity1 : entity.getPassengers()) { for (Entity entity1 : entity.getPassengers()) {
this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2 this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2
} }

View File

@@ -1,6 +1,5 @@
package org.dreeam.leaf.async.ai; package org.dreeam.leaf.async.ai;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.Mob;
@@ -10,85 +9,54 @@ import org.dreeam.leaf.config.modules.async.AsyncTargetFinding;
import org.dreeam.leaf.util.queue.SpscIntQueue; import org.dreeam.leaf.util.queue.SpscIntQueue;
import java.util.OptionalInt; import java.util.OptionalInt;
import java.util.concurrent.locks.LockSupport;
public class AsyncGoalExecutor { public class AsyncGoalExecutor {
protected static final Logger LOGGER = LogManager.getLogger("Leaf Async Goal"); protected static final Logger LOGGER = LogManager.getLogger("Leaf Async Goal");
protected final SpscIntQueue queue; protected final SpscIntQueue queue;
protected final SpscIntQueue wake;
protected final IntArrayList submit;
private final ServerLevel world; private final ServerLevel world;
private long midTickCount = 0L;
public AsyncGoalExecutor(AsyncGoalThread thread, ServerLevel world) { public AsyncGoalExecutor(ServerLevel world) {
this.world = world; this.world = world;
this.queue = new SpscIntQueue(AsyncTargetFinding.queueSize); this.queue = new SpscIntQueue(AsyncTargetFinding.queueSize);
this.wake = new SpscIntQueue(AsyncTargetFinding.queueSize);
this.submit = new IntArrayList();
} }
boolean wake(int id) { boolean wakeAll() {
Entity entity = this.world.getEntities().get(id); boolean success = false;
if (entity == null || entity.isRemoved() || !(entity instanceof Mob mob)) {
return false;
}
mob.goalSelector.ctx.wake();
mob.targetSelector.ctx.wake();
return true;
}
public final void submit(int entityId) {
this.submit.add(entityId);
}
public final void tick() {
batchSubmit();
while (true) { while (true) {
OptionalInt result = this.wake.recv(); OptionalInt result = queue.recv();
if (result.isEmpty()) { if (result.isEmpty()) {
break; break;
} }
int id = result.getAsInt(); int id = result.getAsInt();
if (poll(id) && !this.queue.send(id)) { success = true;
do {
wake(id); wake(id);
} while (poll(id));
}
} }
return success;
} }
private void batchSubmit() { public void tickMob(Mob mob) {
if (submit.isEmpty()) { if (!poll(mob)) {
return; return;
} }
int[] raw = submit.elements(); int entityId = mob.getId();
int size = submit.size(); if (!this.queue.send(entityId)) {
for (int i = 0; i < size; i++) {
int id = raw[i];
if (poll(id) && !this.queue.send(id)) {
do { do {
wake(id); wake(entityId);
} while (poll(id)); } while (poll(mob));
} }
} }
this.submit.clear();
}
public final void midTick() { private void wake(int id) {
if (AsyncTargetFinding.threshold <= 0L || (midTickCount % AsyncTargetFinding.threshold) == 0L) {
batchSubmit();
}
midTickCount += 1;
}
private boolean poll(int id) {
Entity entity = this.world.getEntities().get(id); Entity entity = this.world.getEntities().get(id);
if (entity == null || entity.isRemoved() || !(entity instanceof Mob mob)) { if (entity == null || entity.isRemoved() || !(entity instanceof Mob mob)) {
return false; return;
}
mob.goalSelector.ctx.wake();
mob.targetSelector.ctx.wake();
} }
private boolean poll(Mob mob) {
try { try {
mob.tickingTarget = true; mob.tickingTarget = true;
boolean a = mob.targetSelector.poll(); boolean a = mob.targetSelector.poll();
@@ -97,8 +65,7 @@ public class AsyncGoalExecutor {
return a || b; return a || b;
} catch (Exception e) { } catch (Exception e) {
LOGGER.error("Exception while polling", e); LOGGER.error("Exception while polling", e);
// retry return false;
return true;
} }
} }
} }

View File

@@ -22,26 +22,11 @@ public class AsyncGoalThread extends Thread {
while (RUNNING) { while (RUNNING) {
boolean retry = false; boolean retry = false;
for (ServerLevel level : server.getAllLevels()) { for (ServerLevel level : server.getAllLevels()) {
var exec = level.asyncGoalExecutor; retry |= level.asyncGoalExecutor.wakeAll();
while (true) {
OptionalInt result = exec.queue.recv();
if (result.isEmpty()) {
break;
}
int id = result.getAsInt();
retry = true;
if (exec.wake(id)) {
while (!exec.wake.send(id)) {
Thread.onSpinWait();
}
}
}
Thread.yield();
} }
if (!retry) { if (!retry) {
LockSupport.parkNanos(10_000L); LockSupport.parkNanos(1_000_000L);
} }
} }
} }

View File

@@ -15,7 +15,6 @@ public class AsyncTargetFinding extends ConfigModules {
public static boolean searchBlock = true; public static boolean searchBlock = true;
public static boolean searchEntity = true; public static boolean searchEntity = true;
public static int queueSize = 4096; public static int queueSize = 4096;
public static long threshold = 10L;
private static boolean asyncTargetFindingInitialized; private static boolean asyncTargetFindingInitialized;
@Override @Override
@@ -35,21 +34,17 @@ public class AsyncTargetFinding extends ConfigModules {
enabled = config.getBoolean(getBasePath() + ".enabled", enabled); enabled = config.getBoolean(getBasePath() + ".enabled", enabled);
// Disable if parallel world ticking is enabled, as they are incompatible. // Disable if parallel world ticking is enabled, as they are incompatible.
if (enabled && SparklyPaperParallelWorldTicking.enabled) { if (enabled && SparklyPaperParallelWorldTicking.enabled) {
LeafConfig.LOGGER.warn("Async Target Finding is incompatible with Parallel World Ticking. Disabling Async Target Finding automatically."); LeafConfig.LOGGER.warn("Async target finding is incompatible with Parallel World Ticking. Disabling Async target finding automatically.");
enabled = false; enabled = false;
} }
alertOther = config.getBoolean(getBasePath() + ".async-alert-other", true); alertOther = config.getBoolean(getBasePath() + ".async-alert-other", true);
searchBlock = config.getBoolean(getBasePath() + ".async-search-block", true); searchBlock = config.getBoolean(getBasePath() + ".async-search-block", true);
searchEntity = config.getBoolean(getBasePath() + ".async-search-entity", true); searchEntity = config.getBoolean(getBasePath() + ".async-search-entity", true);
queueSize = config.getInt(getBasePath() + ".queue-size", 0); queueSize = config.getInt(getBasePath() + ".queue-size", 0);
threshold = config.getLong(getBasePath() + ".threshold", 0);
if (queueSize <= 0) { if (queueSize <= 0) {
queueSize = 4096; queueSize = 4096;
} }
if (threshold == 0L) {
threshold = 10L;
}
if (!enabled) { if (!enabled) {
alertOther = false; alertOther = false;
searchEntity = false; searchEntity = false;