mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-25 09:59:15 +00:00
fix async-target-finding
This commit is contained in:
@@ -13,19 +13,19 @@ import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
public class AsyncGoalExecutor {
|
||||
|
||||
public 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 wake;
|
||||
protected final SpscIntQueue submit;
|
||||
private final AsyncGoalThread thread;
|
||||
private final ServerLevel world;
|
||||
private boolean dirty = false;
|
||||
private long tickCount = 0L;
|
||||
private long midTickCount = 0L;
|
||||
|
||||
public AsyncGoalExecutor(AsyncGoalThread thread, ServerLevel world) {
|
||||
this.world = world;
|
||||
this.queue = new SpscIntQueue(AsyncTargetFinding.queueSize);
|
||||
this.wake = new SpscIntQueue(AsyncTargetFinding.queueSize);
|
||||
this.submit = new SpscIntQueue(AsyncTargetFinding.queueSize);
|
||||
this.thread = thread;
|
||||
}
|
||||
|
||||
@@ -34,24 +34,33 @@ public class AsyncGoalExecutor {
|
||||
if (entity == null || entity.isRemoved() || !(entity instanceof Mob mob)) {
|
||||
return false;
|
||||
}
|
||||
mob.goalSelector.wake();
|
||||
mob.targetSelector.wake();
|
||||
mob.goalSelector.ctx.wake();
|
||||
mob.targetSelector.ctx.wake();
|
||||
return true;
|
||||
}
|
||||
|
||||
public final void submit(int entityId) {
|
||||
dirty = true;
|
||||
if (!this.queue.send(entityId)) {
|
||||
unpark();
|
||||
do {
|
||||
if (!this.submit.send(entityId)) {
|
||||
while (poll(entityId)) {
|
||||
wake(entityId);
|
||||
} while (poll(entityId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void unpark() {
|
||||
if (dirty) LockSupport.unpark(thread);
|
||||
dirty = false;
|
||||
public final void tick() {
|
||||
while (true) {
|
||||
OptionalInt result = this.submit.recv();
|
||||
if (result.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
int id = result.getAsInt();
|
||||
if (poll(id) && !this.queue.send(id)) {
|
||||
do {
|
||||
wake(id);
|
||||
} while (poll(id));
|
||||
}
|
||||
}
|
||||
LockSupport.unpark(thread);
|
||||
}
|
||||
|
||||
public final void midTick() {
|
||||
@@ -61,26 +70,51 @@ public class AsyncGoalExecutor {
|
||||
break;
|
||||
}
|
||||
int id = result.getAsInt();
|
||||
if (poll(id)) {
|
||||
submit(id);
|
||||
if (poll(id) && !this.queue.send(id)) {
|
||||
do {
|
||||
wake(id);
|
||||
} while (poll(id));
|
||||
}
|
||||
}
|
||||
if ((tickCount % AsyncTargetFinding.threshold) == 0L) {
|
||||
unpark();
|
||||
if (AsyncTargetFinding.threshold <= 0L || (midTickCount % AsyncTargetFinding.threshold) == 0L) {
|
||||
boolean submitted = false;
|
||||
while (true) {
|
||||
OptionalInt result = this.submit.recv();
|
||||
if (result.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
submitted = true;
|
||||
int id = result.getAsInt();
|
||||
if (poll(id) && !this.queue.send(id)) {
|
||||
do {
|
||||
wake(id);
|
||||
} while (poll(id));
|
||||
}
|
||||
}
|
||||
if (submitted) {
|
||||
LockSupport.unpark(thread);
|
||||
}
|
||||
}
|
||||
tickCount += 1;
|
||||
|
||||
midTickCount += 1;
|
||||
}
|
||||
|
||||
private boolean poll(int id) {
|
||||
Entity entity = this.world.getEntities().get(id);
|
||||
if (entity == null || !entity.isAlive() || !(entity instanceof Mob mob)) {
|
||||
if (entity == null || entity.isRemoved() || !(entity instanceof Mob mob)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mob.tickingTarget = true;
|
||||
boolean a = mob.targetSelector.poll();
|
||||
mob.tickingTarget = false;
|
||||
boolean b = mob.goalSelector.poll();
|
||||
return a || b;
|
||||
try {
|
||||
mob.tickingTarget = true;
|
||||
boolean a = mob.targetSelector.poll();
|
||||
mob.tickingTarget = false;
|
||||
boolean b = mob.goalSelector.poll();
|
||||
return a || b;
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Exception while polling", e);
|
||||
// retry
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.dreeam.leaf.async.ai;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface VWaker {
|
||||
@Nullable Object wake();
|
||||
}
|
||||
@@ -5,14 +5,26 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class Waker {
|
||||
|
||||
@Nullable
|
||||
public volatile Runnable wake = null;
|
||||
public volatile VWaker wake = null;
|
||||
@Nullable
|
||||
public volatile Object result = null;
|
||||
public volatile boolean state = true;
|
||||
public boolean state = true;
|
||||
|
||||
public final @Nullable Object result() {
|
||||
Object result = this.result;
|
||||
this.result = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
final void wake() {
|
||||
final var wake = this.wake;
|
||||
if (wake != null) {
|
||||
try {
|
||||
this.result = wake.wake();
|
||||
} catch (Exception e) {
|
||||
AsyncGoalExecutor.LOGGER.error("Exception while wake", e);
|
||||
}
|
||||
this.wake = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@ public class AsyncTargetFinding extends ConfigModules {
|
||||
asyncTargetFindingInitialized = true;
|
||||
|
||||
enabled = config.getBoolean(getBasePath() + ".enabled", enabled);
|
||||
// TODO
|
||||
enabled = false;
|
||||
alertOther = config.getBoolean(getBasePath() + ".async-alert-other", true);
|
||||
searchBlock = config.getBoolean(getBasePath() + ".async-search-block", true);
|
||||
searchEntity = config.getBoolean(getBasePath() + ".async-search-entity", true);
|
||||
@@ -45,7 +43,7 @@ public class AsyncTargetFinding extends ConfigModules {
|
||||
if (queueSize <= 0) {
|
||||
queueSize = 4096;
|
||||
}
|
||||
if (threshold <= 0L) {
|
||||
if (threshold == 0L) {
|
||||
threshold = 10L;
|
||||
}
|
||||
if (!enabled) {
|
||||
|
||||
Reference in New Issue
Block a user