2025-11-24 22:52:51 +03:00

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;
}
}
}