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

170 lines
6.9 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* it.unimi.dsi.fastutil.longs.Long2ByteMap
* it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap
* it.unimi.dsi.fastutil.longs.LongArrayList
* it.unimi.dsi.fastutil.longs.LongList
*/
package net.minecraft.world.level.lighting;
import it.unimi.dsi.fastutil.longs.Long2ByteMap;
import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongArrayList;
import it.unimi.dsi.fastutil.longs.LongList;
import java.util.function.LongPredicate;
import net.minecraft.util.Mth;
import net.minecraft.world.level.lighting.LeveledPriorityQueue;
public abstract class DynamicGraphMinFixedPoint {
public static final long SOURCE = Long.MAX_VALUE;
private static final int NO_COMPUTED_LEVEL = 255;
protected final int levelCount;
private final LeveledPriorityQueue priorityQueue;
private final Long2ByteMap computedLevels;
private volatile boolean hasWork;
protected DynamicGraphMinFixedPoint(int levelCount, int minQueueSize, final int minMapSize) {
if (levelCount >= 254) {
throw new IllegalArgumentException("Level count must be < 254.");
}
this.levelCount = levelCount;
this.priorityQueue = new LeveledPriorityQueue(levelCount, minQueueSize);
this.computedLevels = new Long2ByteOpenHashMap(minMapSize, 0.5f){
protected void rehash(int newN) {
if (newN > minMapSize) {
super.rehash(newN);
}
}
};
this.computedLevels.defaultReturnValue((byte)-1);
}
protected void removeFromQueue(long node) {
int computedLevel = this.computedLevels.remove(node) & 0xFF;
if (computedLevel == 255) {
return;
}
int level = this.getLevel(node);
int priority = this.calculatePriority(level, computedLevel);
this.priorityQueue.dequeue(node, priority, this.levelCount);
this.hasWork = !this.priorityQueue.isEmpty();
}
public void removeIf(LongPredicate pred) {
LongArrayList nodesToRemove = new LongArrayList();
this.computedLevels.keySet().forEach(arg_0 -> DynamicGraphMinFixedPoint.lambda$removeIf$0(pred, (LongList)nodesToRemove, arg_0));
nodesToRemove.forEach(this::removeFromQueue);
}
private int calculatePriority(int level, int computedLevel) {
return Math.min(Math.min(level, computedLevel), this.levelCount - 1);
}
protected void checkNode(long node) {
this.checkEdge(node, node, this.levelCount - 1, false);
}
protected void checkEdge(long from, long to, int newLevelFrom, boolean onlyDecreased) {
this.checkEdge(from, to, newLevelFrom, this.getLevel(to), this.computedLevels.get(to) & 0xFF, onlyDecreased);
this.hasWork = !this.priorityQueue.isEmpty();
}
private void checkEdge(long from, long to, int newLevelFrom, int levelTo, int oldComputedLevel, boolean onlyDecreased) {
boolean wasConsistent;
if (this.isSource(to)) {
return;
}
newLevelFrom = Mth.clamp(newLevelFrom, 0, this.levelCount - 1);
levelTo = Mth.clamp(levelTo, 0, this.levelCount - 1);
boolean bl = wasConsistent = oldComputedLevel == 255;
if (wasConsistent) {
oldComputedLevel = levelTo;
}
int newComputedLevel = onlyDecreased ? Math.min(oldComputedLevel, newLevelFrom) : Mth.clamp(this.getComputedLevel(to, from, newLevelFrom), 0, this.levelCount - 1);
int oldPriority = this.calculatePriority(levelTo, oldComputedLevel);
if (levelTo != newComputedLevel) {
int newPriority = this.calculatePriority(levelTo, newComputedLevel);
if (oldPriority != newPriority && !wasConsistent) {
this.priorityQueue.dequeue(to, oldPriority, newPriority);
}
this.priorityQueue.enqueue(to, newPriority);
this.computedLevels.put(to, (byte)newComputedLevel);
} else if (!wasConsistent) {
this.priorityQueue.dequeue(to, oldPriority, this.levelCount);
this.computedLevels.remove(to);
}
}
protected final void checkNeighbor(long from, long to, int level, boolean onlyDecreased) {
int storedOldComputedLevel = this.computedLevels.get(to) & 0xFF;
int levelFrom = Mth.clamp(this.computeLevelFromNeighbor(from, to, level), 0, this.levelCount - 1);
if (onlyDecreased) {
this.checkEdge(from, to, levelFrom, this.getLevel(to), storedOldComputedLevel, onlyDecreased);
} else {
boolean wasConsistent = storedOldComputedLevel == 255;
int oldComputedLevel = wasConsistent ? Mth.clamp(this.getLevel(to), 0, this.levelCount - 1) : storedOldComputedLevel;
if (levelFrom == oldComputedLevel) {
this.checkEdge(from, to, this.levelCount - 1, wasConsistent ? oldComputedLevel : this.getLevel(to), storedOldComputedLevel, onlyDecreased);
}
}
}
protected final boolean hasWork() {
return this.hasWork;
}
protected final int runUpdates(int count) {
if (this.priorityQueue.isEmpty()) {
return count;
}
while (!this.priorityQueue.isEmpty() && count > 0) {
--count;
long node = this.priorityQueue.removeFirstLong();
int level = Mth.clamp(this.getLevel(node), 0, this.levelCount - 1);
int computedLevel = this.computedLevels.remove(node) & 0xFF;
if (computedLevel < level) {
this.setLevel(node, computedLevel);
this.checkNeighborsAfterUpdate(node, computedLevel, true);
continue;
}
if (computedLevel <= level) continue;
this.setLevel(node, this.levelCount - 1);
if (computedLevel != this.levelCount - 1) {
this.priorityQueue.enqueue(node, this.calculatePriority(this.levelCount - 1, computedLevel));
this.computedLevels.put(node, (byte)computedLevel);
}
this.checkNeighborsAfterUpdate(node, level, false);
}
this.hasWork = !this.priorityQueue.isEmpty();
return count;
}
public int getQueueSize() {
return this.computedLevels.size();
}
protected boolean isSource(long node) {
return node == Long.MAX_VALUE;
}
protected abstract int getComputedLevel(long var1, long var3, int var5);
protected abstract void checkNeighborsAfterUpdate(long var1, int var3, boolean var4);
protected abstract int getLevel(long var1);
protected abstract void setLevel(long var1, int var3);
protected abstract int computeLevelFromNeighbor(long var1, long var3, int var5);
private static /* synthetic */ void lambda$removeIf$0(LongPredicate pred, LongList nodesToRemove, long node) {
if (pred.test(node)) {
nodesToRemove.add(node);
}
}
}