mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-24 20:07:54 +01:00
Not a lut left
- Prune empty layers from the lut to avoid it just getting larger as the player explores the world
This commit is contained in:
parent
6431a84f67
commit
f3845a15fb
2 changed files with 136 additions and 0 deletions
|
@ -23,6 +23,11 @@ public final class LightLut {
|
||||||
.set(z, index + 1);
|
.set(z, index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void prune() {
|
||||||
|
// Maybe this could be done better incrementally?
|
||||||
|
indices.prune((middle) -> middle.prune(IntLayer::prune));
|
||||||
|
}
|
||||||
|
|
||||||
public void remove(long section) {
|
public void remove(long section) {
|
||||||
final var x = SectionPos.x(section);
|
final var x = SectionPos.x(section);
|
||||||
final var y = SectionPos.y(section);
|
final var y = SectionPos.y(section);
|
||||||
|
@ -49,6 +54,11 @@ public final class LightLut {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Prune<T> {
|
||||||
|
boolean prune(T t);
|
||||||
|
}
|
||||||
|
|
||||||
public static final class Layer<T> {
|
public static final class Layer<T> {
|
||||||
private boolean hasBase = false;
|
private boolean hasBase = false;
|
||||||
private int base = 0;
|
private int base = 0;
|
||||||
|
@ -135,6 +145,69 @@ public final class LightLut {
|
||||||
return (T) out;
|
return (T) out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true} if the layer is now empty.
|
||||||
|
*/
|
||||||
|
public boolean prune(Prune<T> inner) {
|
||||||
|
if (!hasBase) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prune the next layer before checking for leading/trailing zeros.
|
||||||
|
for (var i = 0; i < nextLayer.length; i++) {
|
||||||
|
var o = nextLayer[i];
|
||||||
|
if (o != null && inner.prune((T) o)) {
|
||||||
|
nextLayer[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var leadingZeros = getLeadingZeros();
|
||||||
|
|
||||||
|
if (leadingZeros == nextLayer.length) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var trailingZeros = getTrailingZeros();
|
||||||
|
|
||||||
|
if (leadingZeros == 0 && trailingZeros == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final var newIndices = new Object[nextLayer.length - leadingZeros - trailingZeros];
|
||||||
|
|
||||||
|
System.arraycopy(nextLayer, leadingZeros, newIndices, 0, newIndices.length);
|
||||||
|
nextLayer = newIndices;
|
||||||
|
base += leadingZeros;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getLeadingZeros() {
|
||||||
|
int out = 0;
|
||||||
|
|
||||||
|
for (Object index : nextLayer) {
|
||||||
|
if (index == null) {
|
||||||
|
out++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getTrailingZeros() {
|
||||||
|
int out = 0;
|
||||||
|
|
||||||
|
for (int i = nextLayer.length - 1; i >= 0; i--) {
|
||||||
|
if (nextLayer[i] == null) {
|
||||||
|
out++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
private void resize(int length) {
|
private void resize(int length) {
|
||||||
final var newIndices = new Object[length];
|
final var newIndices = new Object[length];
|
||||||
System.arraycopy(nextLayer, 0, newIndices, 0, nextLayer.length);
|
System.arraycopy(nextLayer, 0, newIndices, 0, nextLayer.length);
|
||||||
|
@ -214,6 +287,61 @@ public final class LightLut {
|
||||||
indices[offset] = index;
|
indices[offset] = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true} if the layer is now empty.
|
||||||
|
*/
|
||||||
|
public boolean prune() {
|
||||||
|
if (!hasBase) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var leadingZeros = getLeadingZeros();
|
||||||
|
|
||||||
|
if (leadingZeros == indices.length) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var trailingZeros = getTrailingZeros();
|
||||||
|
|
||||||
|
if (leadingZeros == 0 && trailingZeros == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final var newIndices = new int[indices.length - leadingZeros - trailingZeros];
|
||||||
|
|
||||||
|
System.arraycopy(indices, leadingZeros, newIndices, 0, newIndices.length);
|
||||||
|
indices = newIndices;
|
||||||
|
base += leadingZeros;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getTrailingZeros() {
|
||||||
|
int out = 0;
|
||||||
|
|
||||||
|
for (int i = indices.length - 1; i >= 0; i--) {
|
||||||
|
if (indices[i] == 0) {
|
||||||
|
out++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getLeadingZeros() {
|
||||||
|
int out = 0;
|
||||||
|
|
||||||
|
for (int index : indices) {
|
||||||
|
if (index == 0) {
|
||||||
|
out++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
public void clear(int i) {
|
public void clear(int i) {
|
||||||
if (!hasBase) {
|
if (!hasBase) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -171,6 +171,8 @@ public class LightStorage implements Effect {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean anyRemoved = false;
|
||||||
|
|
||||||
var entries = section2ArenaIndex.long2IntEntrySet();
|
var entries = section2ArenaIndex.long2IntEntrySet();
|
||||||
var it = entries.iterator();
|
var it = entries.iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
|
@ -181,8 +183,14 @@ public class LightStorage implements Effect {
|
||||||
arena.free(entry.getIntValue());
|
arena.free(entry.getIntValue());
|
||||||
endTrackingSection(section);
|
endTrackingSection(section);
|
||||||
it.remove();
|
it.remove();
|
||||||
|
anyRemoved = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (anyRemoved) {
|
||||||
|
lut.prune();
|
||||||
|
needsLutRebuild = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void beginTrackingSection(long section, int index) {
|
private void beginTrackingSection(long section, int index) {
|
||||||
|
|
Loading…
Reference in a new issue