mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-23 08:59:23 +00:00
Smart sorting & Remove streams & Throttle hopper (#157)
* =-= * Reuse comparator * Cleanup DAB patch
This commit is contained in:
458
patches/server/0128-Asynchronous-locator.patch
Normal file
458
patches/server/0128-Asynchronous-locator.patch
Normal file
@@ -0,0 +1,458 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com>
|
||||
Date: Wed, 23 Oct 2024 23:54:00 +0800
|
||||
Subject: [PATCH] Asynchronous locator
|
||||
|
||||
This patch was ported from project: https://github.com/thebrightspark/AsyncLocator
|
||||
|
||||
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
|
||||
index 11b7f15755dde766140c29bedca456c80d53293f..749d00449ac3f3c79bfc73a5517ea3a07675e447 100644
|
||||
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
|
||||
+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java
|
||||
@@ -80,7 +80,7 @@ public class TickThread extends Thread {
|
||||
this(run, name, ID_GENERATOR.incrementAndGet());
|
||||
}
|
||||
|
||||
- private TickThread(final Runnable run, final String name, final int id) {
|
||||
+ protected TickThread(final Runnable run, final String name, final int id) { // Leaf - private -> protected
|
||||
super(run, name);
|
||||
this.id = id;
|
||||
}
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
|
||||
index 6676be8304e9415099ed423d3315180cafebd928..30b56382e9574004e344c1c8289d7dcbb177386b 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
|
||||
@@ -48,6 +48,12 @@ class PaperEventManager {
|
||||
return;
|
||||
}
|
||||
// Leaf end - Multithreaded tracker
|
||||
+ // Leaf start - Async locator
|
||||
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) {
|
||||
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(event::callEvent);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaf end - Async locator
|
||||
throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously.");
|
||||
}
|
||||
// Leaves start - skip photographer
|
||||
diff --git a/src/main/java/net/minecraft/server/commands/LocateCommand.java b/src/main/java/net/minecraft/server/commands/LocateCommand.java
|
||||
index 39f5deea47d8f573c3cfec5df431216ee806c32c..51994f272737f8754aac41dc0c55f43f45617519 100644
|
||||
--- a/src/main/java/net/minecraft/server/commands/LocateCommand.java
|
||||
+++ b/src/main/java/net/minecraft/server/commands/LocateCommand.java
|
||||
@@ -106,6 +106,37 @@ public class LocateCommand {
|
||||
BlockPos blockPos = BlockPos.containing(source.getPosition());
|
||||
ServerLevel serverLevel = source.getLevel();
|
||||
Stopwatch stopwatch = Stopwatch.createStarted(Util.TICKER);
|
||||
+ // Leaf start - Async locator
|
||||
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) {
|
||||
+ net.minecraft.commands.CommandSource locatorSource = source.source;
|
||||
+ if (locatorSource instanceof net.minecraft.server.level.ServerPlayer ||
|
||||
+ locatorSource instanceof net.minecraft.server.MinecraftServer) {
|
||||
+ BlockPos originPos = BlockPos.containing(source.getPosition());
|
||||
+ org.dreeam.leaf.async.locate.AsyncLocator.locate(source.getLevel(), holderSet, originPos, 100, false)
|
||||
+ .thenOnServerThread(pair -> {
|
||||
+ stopwatch.stop();
|
||||
+ if (pair != null) {
|
||||
+ showLocateResult(
|
||||
+ source,
|
||||
+ predicate,
|
||||
+ originPos,
|
||||
+ pair,
|
||||
+ "commands.locate.structure.success",
|
||||
+ false,
|
||||
+ stopwatch.elapsed()
|
||||
+ );
|
||||
+ } else {
|
||||
+ source.sendFailure(
|
||||
+ Component.literal(
|
||||
+ ERROR_STRUCTURE_NOT_FOUND.create(predicate.asPrintable()).getMessage()
|
||||
+ )
|
||||
+ );
|
||||
+ }
|
||||
+ });
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaf end - Async locator
|
||||
Pair<BlockPos, Holder<Structure>> pair = serverLevel.getChunkSource()
|
||||
.getGenerator()
|
||||
.findNearestMapStructure(serverLevel, holderSet, blockPos, 100, false);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
|
||||
index ef0124ceb7cafd58c01c7f0b4b542f38a383ab88..061d020c08b722b92187ba9042ab4084ecd72b06 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Dolphin.java
|
||||
@@ -466,6 +466,8 @@ public class Dolphin extends WaterAnimal {
|
||||
|
||||
private final Dolphin dolphin;
|
||||
private boolean stuck;
|
||||
+ @Nullable
|
||||
+ private org.dreeam.leaf.async.locate.AsyncLocator.LocateTask<?> asyncLocator$locateTask;
|
||||
|
||||
DolphinSwimToTreasureGoal(Dolphin dolphin) {
|
||||
this.dolphin = dolphin;
|
||||
@@ -485,6 +487,11 @@ public class Dolphin extends WaterAnimal {
|
||||
|
||||
@Override
|
||||
public boolean canContinueToUse() {
|
||||
+ // Leaf start - Async locator
|
||||
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTask != null) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Leaf end - Async locator
|
||||
BlockPos blockposition = this.dolphin.getTreasurePos();
|
||||
|
||||
return !BlockPos.containing((double) blockposition.getX(), this.dolphin.getY(), (double) blockposition.getZ()).closerToCenterThan(this.dolphin.position(), 4.0D) && !this.stuck && this.dolphin.getAirSupply() >= 100;
|
||||
@@ -498,6 +505,21 @@ public class Dolphin extends WaterAnimal {
|
||||
this.stuck = false;
|
||||
this.dolphin.getNavigation().stop();
|
||||
BlockPos blockposition = this.dolphin.blockPosition();
|
||||
+ // Leaf start - Async locator
|
||||
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) {
|
||||
+ asyncLocator$locateTask = org.dreeam.leaf.async.locate.AsyncLocator.locate(worldserver, StructureTags.DOLPHIN_LOCATED, blockposition, 50, false)
|
||||
+ .thenOnServerThread(pos -> {
|
||||
+ asyncLocator$locateTask = null;
|
||||
+ if (pos != null) {
|
||||
+ this.dolphin.setTreasurePos(pos);
|
||||
+ worldserver.broadcastEntityEvent(this.dolphin, (byte) 38);
|
||||
+ } else {
|
||||
+ this.stuck = true;
|
||||
+ }
|
||||
+ });
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaf end - Async locator
|
||||
BlockPos blockposition1 = worldserver.findNearestMapStructure(StructureTags.DOLPHIN_LOCATED, blockposition, 50, false);
|
||||
|
||||
if (blockposition1 != null) {
|
||||
@@ -511,6 +533,12 @@ public class Dolphin extends WaterAnimal {
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
+ // Leaf start - Async locator
|
||||
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTask != null) {
|
||||
+ this.asyncLocator$locateTask.cancel();
|
||||
+ this.asyncLocator$locateTask = null;
|
||||
+ }
|
||||
+ // Leaf end - Async locator
|
||||
BlockPos blockposition = this.dolphin.getTreasurePos();
|
||||
|
||||
if (BlockPos.containing((double) blockposition.getX(), this.dolphin.getY(), (double) blockposition.getZ()).closerToCenterThan(this.dolphin.position(), 4.0D) || this.stuck) {
|
||||
@@ -521,6 +549,11 @@ public class Dolphin extends WaterAnimal {
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
+ // Leaf start - Async locator
|
||||
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTask != null) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaf end - Async locator
|
||||
Level world = this.dolphin.level();
|
||||
|
||||
if (this.dolphin.closeToNextPos() || this.dolphin.getNavigation().isDone()) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java b/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java
|
||||
index fca3786d0a3f99a3e61e7a4b2251361276eff9d7..cb4ff1e98418c651ef21f04f3c74cac7065031ae 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java
|
||||
@@ -27,6 +27,7 @@ public class EyeOfEnder extends Entity implements ItemSupplier {
|
||||
public double tz;
|
||||
public int life;
|
||||
public boolean surviveAfterDeath;
|
||||
+ public boolean asyncLocator$locateTaskOngoing = false; // Leaf - Async locator
|
||||
|
||||
public EyeOfEnder(EntityType<? extends EyeOfEnder> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -114,6 +115,11 @@ public class EyeOfEnder extends Entity implements ItemSupplier {
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
+ // Leaf start - Async locator
|
||||
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTaskOngoing) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaf end - Async locator
|
||||
Vec3 vec3d = this.getDeltaMovement();
|
||||
double d0 = this.getX() + vec3d.x;
|
||||
double d1 = this.getY() + vec3d.y;
|
||||
diff --git a/src/main/java/net/minecraft/world/item/EnderEyeItem.java b/src/main/java/net/minecraft/world/item/EnderEyeItem.java
|
||||
index d8ce44a180f848f4c9c04967470c4359af979b2f..90abb83a6baa60bbcbedc7d818c3bc9f4317f04f 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/EnderEyeItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/EnderEyeItem.java
|
||||
@@ -113,20 +113,54 @@ public class EnderEyeItem extends Item {
|
||||
user.startUsingItem(hand);
|
||||
if (world instanceof ServerLevel) {
|
||||
ServerLevel worldserver = (ServerLevel) world;
|
||||
- BlockPos blockposition = worldserver.findNearestMapStructure(StructureTags.EYE_OF_ENDER_LOCATED, user.blockPosition(), 100, false);
|
||||
+ // Leaf start - Async locator
|
||||
+ BlockPos blockposition;
|
||||
+ if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) {
|
||||
+ blockposition = BlockPos.ZERO;
|
||||
+ } else {
|
||||
+ blockposition = worldserver.findNearestMapStructure(StructureTags.EYE_OF_ENDER_LOCATED, user.blockPosition(), 100, false);
|
||||
+ }
|
||||
+ // Leaf end - Async locator
|
||||
|
||||
if (blockposition != null) {
|
||||
EyeOfEnder entityendersignal = new EyeOfEnder(world, user.getX(), user.getY(0.5D), user.getZ());
|
||||
|
||||
+ // Leaf start - Async locator
|
||||
+ final boolean isAsyncLocatorEnabled = org.dreeam.leaf.config.modules.async.AsyncLocator.enabled;
|
||||
+ if (isAsyncLocatorEnabled) {
|
||||
+ entityendersignal.asyncLocator$locateTaskOngoing = true;
|
||||
+ org.dreeam.leaf.async.locate.AsyncLocator.locate(
|
||||
+ worldserver,
|
||||
+ StructureTags.EYE_OF_ENDER_LOCATED,
|
||||
+ user.blockPosition(),
|
||||
+ 100,
|
||||
+ false
|
||||
+ ).thenOnServerThread(pos -> {
|
||||
+ entityendersignal.asyncLocator$locateTaskOngoing = false;
|
||||
+ if (pos != null) {
|
||||
+ entityendersignal.signalTo(pos);
|
||||
+ CriteriaTriggers.USED_ENDER_EYE.trigger((ServerPlayer) user, pos);
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ } else {
|
||||
+ // Set the entity's life to long enough that it dies
|
||||
+ entityendersignal.life = Integer.MAX_VALUE - 100;
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+ // Leaf end - Async locator
|
||||
entityendersignal.setItem(itemstack);
|
||||
- entityendersignal.signalTo(blockposition);
|
||||
+ // Leaf start - Async locator
|
||||
+ if (!isAsyncLocatorEnabled) {
|
||||
+ entityendersignal.signalTo(blockposition);
|
||||
+ }
|
||||
+ // Leaf end - Async locator
|
||||
world.gameEvent((Holder) GameEvent.PROJECTILE_SHOOT, entityendersignal.position(), GameEvent.Context.of((Entity) user));
|
||||
// CraftBukkit start
|
||||
if (!world.addFreshEntity(entityendersignal)) {
|
||||
return new InteractionResultHolder(InteractionResult.FAIL, itemstack);
|
||||
}
|
||||
// CraftBukkit end
|
||||
- if (user instanceof ServerPlayer) {
|
||||
+ if (!isAsyncLocatorEnabled && user instanceof ServerPlayer) { // Leaf - Async locator
|
||||
ServerPlayer entityplayer = (ServerPlayer) user;
|
||||
|
||||
CriteriaTriggers.USED_ENDER_EYE.trigger(entityplayer, blockposition);
|
||||
@@ -136,7 +170,11 @@ public class EnderEyeItem extends Item {
|
||||
|
||||
world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_EYE_LAUNCH, SoundSource.NEUTRAL, 1.0F, f);
|
||||
itemstack.consume(1, user);
|
||||
- user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ // Leaf start - Async locator
|
||||
+ if (!isAsyncLocatorEnabled) {
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ }
|
||||
+ // Leaf end - Async locator
|
||||
user.swing(hand, true);
|
||||
return InteractionResultHolder.success(itemstack);
|
||||
}
|
||||
diff --git a/src/main/java/org/dreeam/leaf/async/locate/AsyncLocator.java b/src/main/java/org/dreeam/leaf/async/locate/AsyncLocator.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0eaa9b60ac139db47a028970557c3a84166efc49
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/dreeam/leaf/async/locate/AsyncLocator.java
|
||||
@@ -0,0 +1,160 @@
|
||||
+package org.dreeam.leaf.async.locate;
|
||||
+
|
||||
+import ca.spottedleaf.moonrise.common.util.TickThread;
|
||||
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
+import com.mojang.datafixers.util.Pair;
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.core.Holder;
|
||||
+import net.minecraft.core.HolderSet;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.tags.TagKey;
|
||||
+import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
+import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
+
|
||||
+import java.util.concurrent.*;
|
||||
+import java.util.concurrent.atomic.AtomicInteger;
|
||||
+import java.util.function.Consumer;
|
||||
+
|
||||
+// Original project: https://github.com/thebrightspark/AsyncLocator
|
||||
+public class AsyncLocator {
|
||||
+ private static final ExecutorService LOCATING_EXECUTOR_SERVICE;
|
||||
+
|
||||
+ private AsyncLocator() {}
|
||||
+
|
||||
+ public static class AsyncLocatorThread extends TickThread {
|
||||
+ private static final AtomicInteger THREAD_COUNTER = new AtomicInteger(0);
|
||||
+ public AsyncLocatorThread(Runnable run, String name) {
|
||||
+ super(run, name, THREAD_COUNTER.incrementAndGet());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void run() {
|
||||
+ super.run();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ static {
|
||||
+ int threads = org.dreeam.leaf.config.modules.async.AsyncLocator.asyncLocatorThreads;
|
||||
+ LOCATING_EXECUTOR_SERVICE = Executors.newFixedThreadPool(
|
||||
+ threads,
|
||||
+ new ThreadFactoryBuilder()
|
||||
+ .setThreadFactory(
|
||||
+ r -> new AsyncLocatorThread(r, "Leaf Async Locator Thread") {
|
||||
+ @Override
|
||||
+ public void run() {
|
||||
+ r.run();
|
||||
+ }
|
||||
+ }
|
||||
+ )
|
||||
+ .setNameFormat("Leaf Async Locator Thread - %d")
|
||||
+ .setPriority(Thread.NORM_PRIORITY - 2)
|
||||
+ .build()
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ public static void shutdownExecutorService() {
|
||||
+ if (LOCATING_EXECUTOR_SERVICE != null) {
|
||||
+ LOCATING_EXECUTOR_SERVICE.shutdown();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Queues a task to locate a feature using {@link ServerLevel#findNearestMapStructure(TagKey, BlockPos, int, boolean)}
|
||||
+ * and returns a {@link LocateTask} with the futures for it.
|
||||
+ */
|
||||
+ public static LocateTask<BlockPos> locate(
|
||||
+ ServerLevel level,
|
||||
+ TagKey<Structure> structureTag,
|
||||
+ BlockPos pos,
|
||||
+ int searchRadius,
|
||||
+ boolean skipKnownStructures
|
||||
+ ) {
|
||||
+ CompletableFuture<BlockPos> completableFuture = new CompletableFuture<>();
|
||||
+ Future<?> future = LOCATING_EXECUTOR_SERVICE.submit(
|
||||
+ () -> doLocateLevel(completableFuture, level, structureTag, pos, searchRadius, skipKnownStructures)
|
||||
+ );
|
||||
+ return new LocateTask<>(level.getServer(), completableFuture, future);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Queues a task to locate a feature using
|
||||
+ * {@link ChunkGenerator#findNearestMapStructure(ServerLevel, HolderSet, BlockPos, int, boolean)} and returns a
|
||||
+ * {@link LocateTask} with the futures for it.
|
||||
+ */
|
||||
+ public static LocateTask<Pair<BlockPos, Holder<Structure>>> locate(
|
||||
+ ServerLevel level,
|
||||
+ HolderSet<Structure> structureSet,
|
||||
+ BlockPos pos,
|
||||
+ int searchRadius,
|
||||
+ boolean skipKnownStructures
|
||||
+ ) {
|
||||
+ CompletableFuture<Pair<BlockPos, Holder<Structure>>> completableFuture = new CompletableFuture<>();
|
||||
+ Future<?> future = LOCATING_EXECUTOR_SERVICE.submit(
|
||||
+ () -> doLocateChunkGenerator(completableFuture, level, structureSet, pos, searchRadius, skipKnownStructures)
|
||||
+ );
|
||||
+ return new LocateTask<>(level.getServer(), completableFuture, future);
|
||||
+ }
|
||||
+
|
||||
+ private static void doLocateLevel(
|
||||
+ CompletableFuture<BlockPos> completableFuture,
|
||||
+ ServerLevel level,
|
||||
+ TagKey<Structure> structureTag,
|
||||
+ BlockPos pos,
|
||||
+ int searchRadius,
|
||||
+ boolean skipExistingChunks
|
||||
+ ) {
|
||||
+ BlockPos foundPos = level.findNearestMapStructure(structureTag, pos, searchRadius, skipExistingChunks);
|
||||
+ completableFuture.complete(foundPos);
|
||||
+ }
|
||||
+
|
||||
+ private static void doLocateChunkGenerator(
|
||||
+ CompletableFuture<Pair<BlockPos, Holder<Structure>>> completableFuture,
|
||||
+ ServerLevel level,
|
||||
+ HolderSet<Structure> structureSet,
|
||||
+ BlockPos pos,
|
||||
+ int searchRadius,
|
||||
+ boolean skipExistingChunks
|
||||
+ ) {
|
||||
+ Pair<BlockPos, Holder<Structure>> foundPair = level.getChunkSource().getGenerator()
|
||||
+ .findNearestMapStructure(level, structureSet, pos, searchRadius, skipExistingChunks);
|
||||
+ completableFuture.complete(foundPair);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Holder of the futures for an async locate task as well as providing some helper functions.
|
||||
+ * The completableFuture will be completed once the call to
|
||||
+ * {@link ServerLevel#findNearestMapStructure(TagKey, BlockPos, int, boolean)} has completed, and will hold the
|
||||
+ * result of it.
|
||||
+ * The taskFuture is the future for the {@link Runnable} itself in the executor service.
|
||||
+ */
|
||||
+ public record LocateTask<T>(MinecraftServer server, CompletableFuture<T> completableFuture, Future<?> taskFuture) {
|
||||
+ /**
|
||||
+ * Helper function that calls {@link CompletableFuture#thenAccept(Consumer)} with the given action.
|
||||
+ * Bear in mind that the action will be executed from the task's thread. If you intend to change any game data,
|
||||
+ * it's strongly advised you use {@link #thenOnServerThread(Consumer)} instead so that it's queued and executed
|
||||
+ * on the main server thread instead.
|
||||
+ */
|
||||
+ public LocateTask<T> then(Consumer<T> action) {
|
||||
+ completableFuture.thenAccept(action);
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Helper function that calls {@link CompletableFuture#thenAccept(Consumer)} with the given action on the server
|
||||
+ * thread.
|
||||
+ */
|
||||
+ public LocateTask<T> thenOnServerThread(Consumer<T> action) {
|
||||
+ completableFuture.thenAccept(pos -> server.scheduleOnMain(() -> action.accept(pos)));
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Helper function that cancels both completableFuture and taskFuture.
|
||||
+ */
|
||||
+ public void cancel() {
|
||||
+ taskFuture.cancel(true);
|
||||
+ completableFuture.cancel(false);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/org/dreeam/leaf/config/modules/async/AsyncLocator.java b/src/main/java/org/dreeam/leaf/config/modules/async/AsyncLocator.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..33bf0155cac0776457f124f7815b7e9ecc2ef8da
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/dreeam/leaf/config/modules/async/AsyncLocator.java
|
||||
@@ -0,0 +1,35 @@
|
||||
+package org.dreeam.leaf.config.modules.async;
|
||||
+
|
||||
+import org.dreeam.leaf.config.ConfigModules;
|
||||
+import org.dreeam.leaf.config.EnumConfigCategory;
|
||||
+import org.dreeam.leaf.config.LeafConfig;
|
||||
+
|
||||
+public class AsyncLocator extends ConfigModules {
|
||||
+
|
||||
+ public String getBasePath() {
|
||||
+ return EnumConfigCategory.ASYNC.getBaseKeyName() + ".async-locator";
|
||||
+ }
|
||||
+
|
||||
+ public static boolean enabled = false;
|
||||
+ public static int asyncLocatorThreads = 0;
|
||||
+
|
||||
+ @Override
|
||||
+ public void onLoaded() {
|
||||
+ config.addComment(getBasePath(), """
|
||||
+ ***Experimental feature, report any bugs you encounter!***
|
||||
+ Whether or not asynchronous locator should be enabled.
|
||||
+ This offloads structure locating to other threads.
|
||||
+ Only for locate command, dolphin treasure finding and eye of ender currently.""");
|
||||
+ enabled = config.getBoolean(getBasePath() + ".enabled", enabled);
|
||||
+ asyncLocatorThreads = config.getInt(getBasePath() + ".threads", asyncLocatorThreads);
|
||||
+
|
||||
+ if (asyncLocatorThreads < 0)
|
||||
+ asyncLocatorThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncLocatorThreads, 1);
|
||||
+ else if (asyncLocatorThreads == 0)
|
||||
+ asyncLocatorThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1);
|
||||
+ if (!enabled)
|
||||
+ asyncLocatorThreads = 0;
|
||||
+ else
|
||||
+ LeafConfig.LOGGER.info("Using {} threads for Async Locator", asyncLocatorThreads);
|
||||
+ }
|
||||
+}
|
||||
Reference in New Issue
Block a user