package net.minecraft.world.ticks; import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.PriorityQueue; import java.util.Queue; import java.util.Set; import java.util.function.BiConsumer; import java.util.function.Predicate; import java.util.stream.Stream; import net.minecraft.core.BlockPos; import org.jetbrains.annotations.Nullable; public class LevelChunkTicks implements SerializableTickContainer, TickContainerAccess { private final Queue> tickQueue = new PriorityQueue(ScheduledTick.DRAIN_ORDER); @Nullable private List> pendingTicks; private final Set> ticksPerPosition = new ObjectOpenCustomHashSet<>(ScheduledTick.UNIQUE_TICK_HASH); @Nullable private BiConsumer, ScheduledTick> onTickAdded; public LevelChunkTicks() { } public LevelChunkTicks(List> pendingTicks) { this.pendingTicks = pendingTicks; for (SavedTick savedTick : pendingTicks) { this.ticksPerPosition.add(ScheduledTick.probe(savedTick.type(), savedTick.pos())); } } public void setOnTickAdded(@Nullable BiConsumer, ScheduledTick> onTickAdded) { this.onTickAdded = onTickAdded; } @Nullable public ScheduledTick peek() { return (ScheduledTick)this.tickQueue.peek(); } @Nullable public ScheduledTick poll() { ScheduledTick scheduledTick = (ScheduledTick)this.tickQueue.poll(); if (scheduledTick != null) { this.ticksPerPosition.remove(scheduledTick); } return scheduledTick; } @Override public void schedule(ScheduledTick tick) { if (this.ticksPerPosition.add(tick)) { this.scheduleUnchecked(tick); } } private void scheduleUnchecked(ScheduledTick tick) { this.tickQueue.add(tick); if (this.onTickAdded != null) { this.onTickAdded.accept(this, tick); } } @Override public boolean hasScheduledTick(BlockPos pos, T type) { return this.ticksPerPosition.contains(ScheduledTick.probe(type, pos)); } public void removeIf(Predicate> predicate) { Iterator> iterator = this.tickQueue.iterator(); while (iterator.hasNext()) { ScheduledTick scheduledTick = (ScheduledTick)iterator.next(); if (predicate.test(scheduledTick)) { iterator.remove(); this.ticksPerPosition.remove(scheduledTick); } } } public Stream> getAll() { return this.tickQueue.stream(); } @Override public int count() { return this.tickQueue.size() + (this.pendingTicks != null ? this.pendingTicks.size() : 0); } @Override public List> pack(long gametime) { List> list = new ArrayList(this.tickQueue.size()); if (this.pendingTicks != null) { list.addAll(this.pendingTicks); } for (ScheduledTick scheduledTick : this.tickQueue) { list.add(scheduledTick.toSavedTick(gametime)); } return list; } public void unpack(long gameTime) { if (this.pendingTicks != null) { int i = -this.pendingTicks.size(); for (SavedTick savedTick : this.pendingTicks) { this.scheduleUnchecked(savedTick.unpack(gameTime, i++)); } } this.pendingTicks = null; } }