2020-04-15 19:06:45 +02:00
|
|
|
package com.minelittlepony.unicopia;
|
2020-04-15 12:37:14 +02:00
|
|
|
|
2020-05-29 20:20:50 +02:00
|
|
|
import java.lang.ref.WeakReference;
|
|
|
|
import java.util.ArrayDeque;
|
|
|
|
import java.util.ArrayList;
|
2020-04-15 12:37:14 +02:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.Queue;
|
|
|
|
import java.util.function.Consumer;
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
2020-09-22 15:11:20 +02:00
|
|
|
import net.minecraft.server.world.ServerWorld;
|
2020-04-15 12:37:14 +02:00
|
|
|
import net.minecraft.world.World;
|
|
|
|
|
|
|
|
public class AwaitTickQueue {
|
2020-04-24 15:23:36 +02:00
|
|
|
private static final Object LOCKER = new Object();
|
2020-05-29 20:20:50 +02:00
|
|
|
private static List<Entry> PENDING_TASKS = new ArrayList<>();
|
2020-04-15 12:37:14 +02:00
|
|
|
|
2020-05-29 20:20:50 +02:00
|
|
|
public static void scheduleTask(World reference, Consumer<World> task, int ticksLater) {
|
|
|
|
if (!reference.isClient) {
|
|
|
|
synchronized (LOCKER) {
|
|
|
|
PENDING_TASKS.add(new Entry(reference, task, ticksLater));
|
|
|
|
}
|
2020-04-15 12:37:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-22 15:11:20 +02:00
|
|
|
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));
|
2020-04-15 12:37:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-29 20:20:50 +02:00
|
|
|
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;
|
2020-05-29 18:11:18 +02:00
|
|
|
}
|
|
|
|
|
2020-05-29 20:20:50 +02:00
|
|
|
boolean tick(World world, Queue<Entry> tasks) {
|
|
|
|
World w = this.world.get();
|
|
|
|
return w != null && (w != world || ticks-- > 0 || !tasks.add(this));
|
|
|
|
}
|
2020-04-15 12:37:14 +02:00
|
|
|
|
2020-05-29 20:20:50 +02:00
|
|
|
void run(World world) {
|
|
|
|
if (this.world.get() == world) {
|
2020-04-15 12:37:14 +02:00
|
|
|
try {
|
|
|
|
task.accept(world);
|
|
|
|
} catch (Exception e) {
|
2020-04-16 00:44:58 +02:00
|
|
|
Unicopia.LOGGER.error(e);
|
2020-04-15 12:37:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|