Use CompletableFuture for delaying things

This commit is contained in:
Sollace 2021-12-27 13:04:35 +02:00
parent 596e01cc24
commit b7e119a57b
3 changed files with 13 additions and 51 deletions

View file

@ -1,60 +1,25 @@
package com.minelittlepony.unicopia;
import java.lang.ref.WeakReference;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.world.World;
public class AwaitTickQueue {
private static final Object LOCKER = new Object();
private static List<Entry> PENDING_TASKS = new ArrayList<>();
public static void scheduleTask(World reference, Consumer<World> task, int ticksLater) {
if (!reference.isClient) {
synchronized (LOCKER) {
PENDING_TASKS.add(new Entry(reference, task, ticksLater));
}
if (reference instanceof ServerWorld) {
CompletableFuture.runAsync(() -> {
task.accept(reference);
}, CompletableFuture.delayedExecutor(ticksLater * 100, TimeUnit.MILLISECONDS, reference.getServer()));
}
}
static void tick(ServerWorld world) {
synchronized (LOCKER) {
final Queue<Entry> tasks = new ArrayDeque<>();
PENDING_TASKS = PENDING_TASKS.stream().filter(e -> e.tick(world, tasks)).collect(Collectors.toList());
tasks.forEach(e -> e.run(world));
}
}
private static final class Entry {
private final Consumer<World> task;
private final WeakReference<World> world;
private int ticks;
Entry(World world, Consumer<World> task, int ticks) {
this.world = new WeakReference<>(world);
this.task = task;
this.ticks = ticks;
}
boolean tick(World world, Queue<Entry> tasks) {
World w = this.world.get();
return w != null && (w != world || ticks-- > 0 || !tasks.add(this));
}
void run(World world) {
if (this.world.get() == world) {
try {
task.accept(world);
} catch (Exception e) {
Unicopia.LOGGER.error(e);
}
}
public static void scheduleTask(World reference, Consumer<World> task) {
if (reference instanceof ServerWorld) {
CompletableFuture.runAsync(() -> {
task.accept(reference);
}, reference.getServer());
}
}
}

View file

@ -50,7 +50,6 @@ public class Unicopia implements ModInitializer {
Commands.bootstrap();
ServerTickEvents.END_WORLD_TICK.register(w -> {
AwaitTickQueue.tick(w);
((BlockDestructionManager.Source)w).getDestructionManager().tick();
});
ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(TreeTypeLoader.INSTANCE);

View file

@ -67,9 +67,7 @@ public class WantItTakeItGoal extends BreakHeartGoal {
ItemStack stack = ((LivingEntity)target).getEquippedStack(slot);
if (EnchantmentHelper.getLevel(UEnchantments.WANT_IT_NEED_IT, stack) > 0) {
target.equipStack(slot, ItemStack.EMPTY);
AwaitTickQueue.scheduleTask(mob.world, w -> {
mob.tryEquip(stack);
}, 0);
AwaitTickQueue.scheduleTask(mob.world, w -> mob.tryEquip(stack));
}
}
}
@ -85,7 +83,7 @@ public class WantItTakeItGoal extends BreakHeartGoal {
mob.sendPickup(item, stack.getCount());
item.remove(RemovalReason.DISCARDED);
}
}, 0);
});
}
}
}