/* * 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 { 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 callbacksRegistry; private final Queue> queue = new PriorityQueue>(TimerQueue.createComparator()); private UnsignedLong sequentialId = UnsignedLong.ZERO; private final Table> events = HashBasedTable.create(); private static Comparator> createComparator() { return Comparator.comparingLong(l -> l.triggerTime).thenComparing(l -> l.sequentialId); } public TimerQueue(TimerCallbacks callbacksRegistry, Stream> 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 callbacksRegistry) { this.callbacksRegistry = callbacksRegistry; } public void tick(T context, long currentTick) { Event 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 callback) { if (this.events.contains((Object)id, (Object)time)) { return; } this.sequentialId = this.sequentialId.plus(UnsignedLong.ONE); Event newEvent = new Event(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 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 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 { public final long triggerTime; public final UnsignedLong sequentialId; public final String id; public final TimerCallback callback; private Event(long triggerTime, UnsignedLong sequentialId, String id, TimerCallback callback) { this.triggerTime = triggerTime; this.sequentialId = sequentialId; this.id = id; this.callback = callback; } } }