139 lines
5.1 KiB
Java
139 lines
5.1 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* com.google.common.collect.HashBasedTable
|
|
* com.google.common.collect.Table
|
|
* com.google.common.primitives.UnsignedLong
|
|
* com.mojang.logging.LogUtils
|
|
* com.mojang.serialization.Dynamic
|
|
* com.mojang.serialization.DynamicOps
|
|
* org.slf4j.Logger
|
|
*/
|
|
package net.minecraft.world.level.timers;
|
|
|
|
import com.google.common.collect.HashBasedTable;
|
|
import com.google.common.collect.Table;
|
|
import com.google.common.primitives.UnsignedLong;
|
|
import com.mojang.logging.LogUtils;
|
|
import com.mojang.serialization.Dynamic;
|
|
import com.mojang.serialization.DynamicOps;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.Comparator;
|
|
import java.util.PriorityQueue;
|
|
import java.util.Queue;
|
|
import java.util.Set;
|
|
import java.util.stream.Stream;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.nbt.ListTag;
|
|
import net.minecraft.nbt.NbtOps;
|
|
import net.minecraft.nbt.Tag;
|
|
import net.minecraft.world.level.timers.TimerCallback;
|
|
import net.minecraft.world.level.timers.TimerCallbacks;
|
|
import org.slf4j.Logger;
|
|
|
|
public class TimerQueue<T> {
|
|
private static final Logger LOGGER = LogUtils.getLogger();
|
|
private static final String CALLBACK_DATA_TAG = "Callback";
|
|
private static final String TIMER_NAME_TAG = "Name";
|
|
private static final String TIMER_TRIGGER_TIME_TAG = "TriggerTime";
|
|
private final TimerCallbacks<T> callbacksRegistry;
|
|
private final Queue<Event<T>> queue = new PriorityQueue<Event<T>>(TimerQueue.createComparator());
|
|
private UnsignedLong sequentialId = UnsignedLong.ZERO;
|
|
private final Table<String, Long, Event<T>> events = HashBasedTable.create();
|
|
|
|
private static <T> Comparator<Event<T>> createComparator() {
|
|
return Comparator.comparingLong(l -> l.triggerTime).thenComparing(l -> l.sequentialId);
|
|
}
|
|
|
|
public TimerQueue(TimerCallbacks<T> callbacksRegistry, Stream<? extends Dynamic<?>> eventData) {
|
|
this(callbacksRegistry);
|
|
this.queue.clear();
|
|
this.events.clear();
|
|
this.sequentialId = UnsignedLong.ZERO;
|
|
eventData.forEach(input -> {
|
|
Tag tag = (Tag)input.convert((DynamicOps)NbtOps.INSTANCE).getValue();
|
|
if (tag instanceof CompoundTag) {
|
|
CompoundTag compoundTag = (CompoundTag)tag;
|
|
this.loadEvent(compoundTag);
|
|
} else {
|
|
LOGGER.warn("Invalid format of events: {}", (Object)tag);
|
|
}
|
|
});
|
|
}
|
|
|
|
public TimerQueue(TimerCallbacks<T> callbacksRegistry) {
|
|
this.callbacksRegistry = callbacksRegistry;
|
|
}
|
|
|
|
public void tick(T context, long currentTick) {
|
|
Event<T> event;
|
|
while ((event = this.queue.peek()) != null && event.triggerTime <= currentTick) {
|
|
this.queue.remove();
|
|
this.events.remove((Object)event.id, (Object)currentTick);
|
|
event.callback.handle(context, this, currentTick);
|
|
}
|
|
}
|
|
|
|
public void schedule(String id, long time, TimerCallback<T> callback) {
|
|
if (this.events.contains((Object)id, (Object)time)) {
|
|
return;
|
|
}
|
|
this.sequentialId = this.sequentialId.plus(UnsignedLong.ONE);
|
|
Event<T> newEvent = new Event<T>(time, this.sequentialId, id, callback);
|
|
this.events.put((Object)id, (Object)time, newEvent);
|
|
this.queue.add(newEvent);
|
|
}
|
|
|
|
public int remove(String id) {
|
|
Collection eventsToRemove = this.events.row((Object)id).values();
|
|
eventsToRemove.forEach(this.queue::remove);
|
|
int size = eventsToRemove.size();
|
|
eventsToRemove.clear();
|
|
return size;
|
|
}
|
|
|
|
public Set<String> getEventsIds() {
|
|
return Collections.unmodifiableSet(this.events.rowKeySet());
|
|
}
|
|
|
|
private void loadEvent(CompoundTag tag) {
|
|
TimerCallback callback = tag.read(CALLBACK_DATA_TAG, this.callbacksRegistry.codec()).orElse(null);
|
|
if (callback != null) {
|
|
String id = tag.getStringOr(TIMER_NAME_TAG, "");
|
|
long time = tag.getLongOr(TIMER_TRIGGER_TIME_TAG, 0L);
|
|
this.schedule(id, time, callback);
|
|
}
|
|
}
|
|
|
|
private CompoundTag storeEvent(Event<T> event) {
|
|
CompoundTag result = new CompoundTag();
|
|
result.putString(TIMER_NAME_TAG, event.id);
|
|
result.putLong(TIMER_TRIGGER_TIME_TAG, event.triggerTime);
|
|
result.store(CALLBACK_DATA_TAG, this.callbacksRegistry.codec(), event.callback);
|
|
return result;
|
|
}
|
|
|
|
public ListTag store() {
|
|
ListTag result = new ListTag();
|
|
this.queue.stream().sorted(TimerQueue.createComparator()).map(this::storeEvent).forEach(result::add);
|
|
return result;
|
|
}
|
|
|
|
public static class Event<T> {
|
|
public final long triggerTime;
|
|
public final UnsignedLong sequentialId;
|
|
public final String id;
|
|
public final TimerCallback<T> callback;
|
|
|
|
private Event(long triggerTime, UnsignedLong sequentialId, String id, TimerCallback<T> callback) {
|
|
this.triggerTime = triggerTime;
|
|
this.sequentialId = sequentialId;
|
|
this.id = id;
|
|
this.callback = callback;
|
|
}
|
|
}
|
|
}
|
|
|