Skip to content

Commit

Permalink
Add RegionPosition class, replace all usages of ChunkPosition as a re…
Browse files Browse the repository at this point in the history
…gion with it. (#1622)

* Add RegionPosition class, replace all usages of ChunkPosition as a region with it.

* Remove methods instead of deprecating them (breaking change for 2.5)
  • Loading branch information
NotStirred authored Sep 23, 2024
1 parent 41a9797 commit 62b58b1
Show file tree
Hide file tree
Showing 19 changed files with 139 additions and 89 deletions.
7 changes: 4 additions & 3 deletions chunky/src/java/se/llbit/chunky/map/MapTile.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,15 @@ public void draw(MapBuffer buffer, WorldMapLoader mapLoader, ChunkView view,
}
}
} else {
boolean isValid = mapLoader.getWorld().currentDimension().regionExistsWithinRange(pos, view.yMin, view.yMax);
Region region = mapLoader.getWorld().currentDimension().getRegionWithinRange(pos, view.yMin, view.yMax);
RegionPosition regionPos = new RegionPosition(pos.x, pos.z); // intentionally don't convert, this position represented a region already.
boolean isValid = mapLoader.getWorld().currentDimension().regionExistsWithinRange(regionPos, view.yMin, view.yMax);
Region region = mapLoader.getWorld().currentDimension().getRegionWithinRange(regionPos, view.yMin, view.yMax);
int pixelOffset = 0;
for (int z = 0; z < 32; ++z) {
for (int x = 0; x < 32; ++x) {
Chunk chunk = region.getChunk(x, z);
//Calculate the chunk position as empty chunks are (0, 0)
ChunkPosition pos = region.getPosition().chunkPositionFromRegion(x, z);
ChunkPosition pos = region.getPosition().asChunkPosition(x, z);

pixels[pixelOffset] = chunk.biomeColor();
if (isValid && !(chunk instanceof EmptyRegionChunk) && selection.isSelected(pos)) {
Expand Down
4 changes: 2 additions & 2 deletions chunky/src/java/se/llbit/chunky/map/WorldMapLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public void addWorldLoadListener(BiConsumer<World, Boolean> callback) {
// Enqueue visible regions and chunks to be loaded.
for (int rx = rx0; rx <= rx1; ++rx) {
for (int rz = rz0; rz <= rz1; ++rz) {
regionQueue.add(new ChunkPosition(rx, rz));
regionQueue.add(new RegionPosition(rx, rz));
}
}
}
Expand All @@ -136,7 +136,7 @@ public synchronized void withWorld(Consumer<World> fun) {
}

/** Called to notify the world loader that a region was changed. */
public void regionUpdated(ChunkPosition region) {
public void regionUpdated(RegionPosition region) {
regionQueue.add(region);
}

Expand Down
4 changes: 2 additions & 2 deletions chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java
Original file line number Diff line number Diff line change
Expand Up @@ -814,12 +814,12 @@ public synchronized void loadChunks(TaskTracker taskTracker, World world, Collec
emitterGrid = new Grid(gridSize);

// Parse the regions first - force chunk lists to be populated!
Set<ChunkPosition> regions = new HashSet<>();
Set<RegionPosition> regions = new HashSet<>();
for (ChunkPosition cp : chunksToLoad) {
regions.add(cp.getRegionPosition());
}

for (ChunkPosition region : regions) {
for (RegionPosition region : regions) {
dimension.getRegion(region).parse(yMin, yMax);
}
}
Expand Down
17 changes: 6 additions & 11 deletions chunky/src/java/se/llbit/chunky/ui/ChunkMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,8 @@
import se.llbit.chunky.ui.controller.ChunkyFxController;
import se.llbit.chunky.ui.dialogs.SelectChunksInRadiusDialog;
import se.llbit.chunky.ui.elements.TextFieldLabelWrapper;
import se.llbit.chunky.world.Chunk;
import se.llbit.chunky.world.ChunkPosition;
import se.llbit.chunky.world.ChunkSelectionTracker;
import se.llbit.chunky.world.ChunkView;
import se.llbit.chunky.world.*;
import se.llbit.chunky.world.Dimension;
import se.llbit.chunky.world.Icon;
import se.llbit.chunky.world.PlayerEntityData;
import se.llbit.chunky.world.World;
import se.llbit.chunky.world.listeners.ChunkUpdateListener;
import se.llbit.chunky.world.region.MCRegion;
import se.llbit.log.Log;
Expand Down Expand Up @@ -226,7 +220,7 @@ public ChunkMap(WorldMapLoader loader, ChunkyFxController controller,
}
}

@Override public void regionChunksUpdated(ChunkPosition region) {
@Override public void regionChunksUpdated(RegionPosition region) {
if (view.chunkScale >= 16) {
int minChunkX = region.x << 5;
int minChunkZ = region.z << 5;
Expand All @@ -241,7 +235,7 @@ public ChunkMap(WorldMapLoader loader, ChunkyFxController controller,
}
}

@Override public void regionChunksUpdated(ChunkPosition region, Collection<ChunkPosition> chunks) {
@Override public void regionChunksUpdated(RegionPosition region, Collection<ChunkPosition> chunks) {
if (view.chunkScale >= 16) {
for (ChunkPosition chunk : chunks) {
mapBuffer.drawTile(mapLoader, chunk, chunkSelection);
Expand Down Expand Up @@ -403,9 +397,10 @@ public void renderView(File targetFile, ProgressTracker progress) {
}
}

@Override public void regionUpdated(ChunkPosition region) {
@Override public void regionUpdated(RegionPosition region) {
if (view.scale < 16) {
mapBuffer.drawTile(mapLoader, region, chunkSelection);
// intentionally don't convert, positions are all stored as ChunkPosition internally.
mapBuffer.drawTile(mapLoader, new ChunkPosition(region.x, region.z), chunkSelection);
mapLoader.regionUpdated(region);
repaintRatelimited();
}
Expand Down
19 changes: 5 additions & 14 deletions chunky/src/java/se/llbit/chunky/world/ChunkPosition.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,19 @@ public long getLong() {

/**
* @return The .mca name for the region with this position
*
* @deprecated Use {@link RegionPosition#getMcaName()}. Remove in 2.6
*/
@Deprecated
public String getMcaName() {
return String.format("r.%d.%d.mca", x, z);
}

/**
* @return The region position of this chunk position
*/
public ChunkPosition getRegionPosition() {
return new ChunkPosition(x >> 5, z >> 5);
}

public ChunkPosition chunkPositionFromRegion(int localX, int localZ) {
return new ChunkPosition((this.x << 5) | (localX & 0x1f), (this.z << 5) | (localZ & 0x1f));
public RegionPosition getRegionPosition() {
return new RegionPosition(x >> 5, z >> 5);
}

/**
Expand Down Expand Up @@ -99,14 +98,6 @@ public int hashCode() {
return 31 * x + z;
}

/**
* @deprecated Use {@link ChunkPosition#getRegionPosition()}. Remove in 2.6.
*/
@Deprecated
public ChunkPosition regionPosition() {
return getRegionPosition();
}

/**
* @deprecated Remove in 2.6.
*/
Expand Down
26 changes: 13 additions & 13 deletions chunky/src/java/se/llbit/chunky/world/ChunkSelectionTracker.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ private boolean setChunk(Dimension dimension, ChunkPosition pos, boolean selecte
* Minimum and maximum are both INCLUSIVE
* @return Whether the selection changed
*/
private boolean setChunksWithinRegion(Dimension dimension, ChunkPosition regionPos, int minX, int maxX, int minZ, int maxZ, boolean selected) {
private boolean setChunksWithinRegion(Dimension dimension, RegionPosition regionPos, int minX, int maxX, int minZ, int maxZ, boolean selected) {
BitSet selectedChunksForRegion = selectedChunksByRegion.computeIfAbsent(regionPos.getLong(), p -> new BitSet(MCRegion.CHUNKS_X * MCRegion.CHUNKS_Z));

Collection<ChunkPosition> changedChunks = new ArrayList<>();
Expand Down Expand Up @@ -111,7 +111,7 @@ private boolean setChunksWithinRegion(Dimension dimension, ChunkPosition regionP
/**
* @return Whether the selection changed
*/
private boolean setRegion(Dimension dimension, ChunkPosition regionPos, boolean selected) {
private boolean setRegion(Dimension dimension, RegionPosition regionPos, boolean selected) {
return setChunks(dimension, regionPos.x << 5, regionPos.z << 5, (regionPos.x << 5) + 31, (regionPos.z << 5) + 31, selected);
}

Expand Down Expand Up @@ -157,7 +157,7 @@ private void notifyChunksUpdated(Collection<ChunkPosition> chunks) {
*
* @param region the region with updated chunks
*/
private void notifyRegionChunksUpdated(ChunkPosition region) {
private void notifyRegionChunksUpdated(RegionPosition region) {
for (ChunkUpdateListener listener : chunkUpdateListeners) {
listener.regionChunksUpdated(region);
}
Expand All @@ -169,7 +169,7 @@ private void notifyRegionChunksUpdated(ChunkPosition region) {
* @param region the region with updated chunks
* @param chunks the chunks within the region that have been updated
*/
private void notifyRegionChunksUpdated(ChunkPosition region, Collection<ChunkPosition> chunks) {
private void notifyRegionChunksUpdated(RegionPosition region, Collection<ChunkPosition> chunks) {
for (ChunkUpdateListener listener : chunkUpdateListeners) {
listener.regionChunksUpdated(region, chunks);
}
Expand Down Expand Up @@ -235,7 +235,7 @@ public synchronized void selectChunk(Dimension dimension, int cx, int cz) {
*/
public synchronized void toggleRegion(Dimension dimension, int cx, int cz) {
ChunkPosition chunk = new ChunkPosition(cx, cz);
setRegion(dimension, new ChunkPosition(cx >> 5, cz >> 5), !isChunkSelected(chunk));
setRegion(dimension, chunk.getRegionPosition(), !isChunkSelected(chunk));
notifyChunkSelectionChange();
}

Expand Down Expand Up @@ -277,10 +277,10 @@ public synchronized boolean setChunks(Dimension dimension, int minChunkX, int mi
for (int regionZ = minRegionZ; regionZ < maxRegionZ + 1; regionZ++) {
if(regionX >= minInnerRegionX && regionX < maxInnerRegionX && regionZ >= minInnerRegionZ && regionZ < maxInnerRegionZ) {
// this region is an inner region, we set all chunks within it
selectionChanged |= setRegion(dimension, new ChunkPosition(regionX, regionZ), selected);
selectionChanged |= setRegion(dimension, new RegionPosition(regionX, regionZ), selected);
} else {
// this region is an outer region, we set only the chunks within the bounds of the selection area
selectionChanged |= setChunksWithinRegion(dimension, new ChunkPosition(regionX, regionZ),
selectionChanged |= setChunksWithinRegion(dimension, new RegionPosition(regionX, regionZ),
Math.max(regionX << 5, minChunkX), Math.min(((regionX + 1) << 5) - 1, maxChunkX),
Math.max(regionZ << 5, minChunkZ), Math.min(((regionZ + 1) << 5) - 1, maxChunkZ),
selected);
Expand All @@ -297,7 +297,7 @@ public synchronized boolean setChunks(Dimension dimension, int minChunkX, int mi

for (int regionX = minRegionX; regionX < maxRegionX + 1; regionX++) {
for (int regionZ = minRegionZ; regionZ < maxRegionZ + 1; regionZ++) {
selectionChanged |= setChunksWithinRegion(dimension, new ChunkPosition(regionX, regionZ),
selectionChanged |= setChunksWithinRegion(dimension, new RegionPosition(regionX, regionZ),
Math.max(regionX << 5, minChunkX), Math.min(((regionX + 1) << 5) - 1, maxChunkX),
Math.max(regionZ << 5, minChunkZ), Math.min(((regionZ + 1) << 5) - 1, maxChunkZ),
selected);
Expand Down Expand Up @@ -350,13 +350,13 @@ public synchronized void clearSelection() {
if (!selectedChunksByRegion.isEmpty()) {
//Collect all region positions currently selected (slightly weird because concurrent map)
Enumeration<Long> keys = selectedChunksByRegion.keys();
Collection<ChunkPosition> regionPositions = new ArrayList<>();
Collection<RegionPosition> regionPositions = new ArrayList<>();
while (keys.hasMoreElements()) {
regionPositions.add(new ChunkPosition(keys.nextElement()));
regionPositions.add(new RegionPosition(keys.nextElement()));
}

selectedChunksByRegion.clear();
for (ChunkPosition regionPosition : regionPositions) {
for (RegionPosition regionPosition : regionPositions) {
notifyRegionChunksUpdated(regionPosition);
}
notifyChunkSelectionChange();
Expand Down Expand Up @@ -395,13 +395,13 @@ public synchronized Collection<ChunkPosition> getSelection() {
public synchronized Map<ChunkPosition, List<ChunkPosition>> getSelectionByRegion() {
Map<ChunkPosition, List<ChunkPosition>> selectedChunksByRegionPosition = new Object2ReferenceOpenHashMap<>();
selectedChunksByRegion.forEach((regionPosition, selectedChunksBitSet) -> {
ChunkPosition regionPos = new ChunkPosition(regionPosition);
RegionPosition regionPos = new RegionPosition(regionPosition);
List<ChunkPosition> positions = new ArrayList<>();
for (int localX = 0; localX < MCRegion.CHUNKS_X; localX++) {
for (int localZ = 0; localZ < MCRegion.CHUNKS_Z; localZ++) {
int idx = localX + (localZ * MCRegion.CHUNKS_X);
if(selectedChunksBitSet.get(idx)) {
positions.add(new ChunkPosition((regionPos.x << 5) + localX, (regionPos.z << 5) + localZ));
positions.add(regionPos.asChunkPosition(localX, localZ));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion chunky/src/java/se/llbit/chunky/world/ChunkView.java
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public boolean isChunkVisible(int x, int z) {
return px0 <= x && px1 >= x && pz0 <= z && pz1 >= z;
}

public boolean isRegionVisible(ChunkPosition pos) {
public boolean isRegionVisible(RegionPosition pos) {
return isRegionVisible(pos.x, pos.z);
}

Expand Down
10 changes: 5 additions & 5 deletions chunky/src/java/se/llbit/chunky/world/CubicDimension.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ public ChunkData createChunkData(ChunkData chunkData, int chunkVersion) {
}

@Override
public Region createRegion(ChunkPosition pos) {
public Region createRegion(RegionPosition pos) {
return new ImposterCubicRegion(pos, this);
}

public synchronized Region getRegionWithinRange(ChunkPosition pos, int minY, int maxY) {
public synchronized Region getRegionWithinRange(RegionPosition pos, int minY, int maxY) {
return regionMap.computeIfAbsent(pos.getLong(), p -> {
// check if the region is present in the world directory
Region region = EmptyRegion.instance;
Expand All @@ -63,7 +63,7 @@ public synchronized Region getRegionWithinRange(ChunkPosition pos, int minY, int

/** no choice but to iterate over every file in the directory */
@Override
public boolean regionExists(ChunkPosition pos) {
public boolean regionExists(RegionPosition pos) {
File regionDirectory = getRegionDirectory();
try {
Stream<Path> list = Files.list(regionDirectory.toPath());
Expand All @@ -84,7 +84,7 @@ public boolean regionExists(ChunkPosition pos) {
}

@Override
public boolean regionExistsWithinRange(ChunkPosition pos, int minY, int maxY) {
public boolean regionExistsWithinRange(RegionPosition pos, int minY, int maxY) {
int cubicRegionX = pos.x << 1;
int cubicRegionZ = pos.z << 1;

Expand All @@ -104,7 +104,7 @@ public boolean regionExistsWithinRange(ChunkPosition pos, int minY, int maxY) {
}

/** Called when a new region has been discovered by the region parser. */
public void regionDiscovered(ChunkPosition pos) {
public void regionDiscovered(RegionPosition pos) {
synchronized (this) {
regionMap.computeIfAbsent(pos.getLong(), (p) -> createRegion(pos));
}
Expand Down
20 changes: 10 additions & 10 deletions chunky/src/java/se/llbit/chunky/world/Dimension.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public ChunkData createChunkData(@Nullable ChunkData chunkData, int chunkVersion
}
}

public Region createRegion(ChunkPosition pos) {
public Region createRegion(RegionPosition pos) {
return new MCRegion(pos, this);
}

Expand All @@ -126,7 +126,7 @@ public RegionChangeWatcher createRegionChangeWatcher(WorldMapLoader worldMapLoad
* @param pos Region position
* @return The region at the given position
*/
public synchronized Region getRegion(ChunkPosition pos) {
public synchronized Region getRegion(RegionPosition pos) {
return regionMap.computeIfAbsent(pos.getLong(), p -> {
// check if the region is present in the world directory
Region region = EmptyRegion.instance;
Expand All @@ -137,21 +137,21 @@ public synchronized Region getRegion(ChunkPosition pos) {
});
}

public Region getRegionWithinRange(ChunkPosition pos, int yMin, int yMax) {
public Region getRegionWithinRange(RegionPosition pos, int yMin, int yMax) {
return getRegion(pos);
}

/** Set the region for the given position. */
public synchronized void setRegion(ChunkPosition pos, Region region) {
public synchronized void setRegion(RegionPosition pos, Region region) {
regionMap.put(pos.getLong(), region);
}

/**
* @param pos region position
* @return {@code true} if a region file exists for the given position
*/
public boolean regionExists(ChunkPosition pos) {
File regionFile = new File(getRegionDirectory(), MCRegion.getFileName(pos));
public boolean regionExists(RegionPosition pos) {
File regionFile = new File(getRegionDirectory(), pos.getMcaName());
return regionFile.exists();
}

Expand All @@ -161,7 +161,7 @@ public boolean regionExists(ChunkPosition pos) {
* @param maxY Maximum block Y (exclusive)
* @return Whether the region exists
*/
public boolean regionExistsWithinRange(ChunkPosition pos, int minY, int maxY) {
public boolean regionExistsWithinRange(RegionPosition pos, int minY, int maxY) {
return this.regionExists(pos);
}

Expand Down Expand Up @@ -203,7 +203,7 @@ public Heightmap getHeightmap() {
}

/** Called when a new region has been discovered by the region parser. */
public void regionDiscovered(ChunkPosition pos) {
public void regionDiscovered(RegionPosition pos) {
synchronized (this) {
regionMap.computeIfAbsent(pos.getLong(), p -> createRegion(pos));
}
Expand All @@ -219,7 +219,7 @@ private void fireChunkUpdated(ChunkPosition chunk) {
}

/** Notify region update listeners. */
private void fireRegionUpdated(ChunkPosition region) {
private void fireRegionUpdated(RegionPosition region) {
synchronized (chunkUpdateListeners) {
for (ChunkUpdateListener listener : chunkUpdateListeners) {
listener.regionUpdated(region);
Expand All @@ -237,7 +237,7 @@ public void chunkUpdated(ChunkPosition chunk) {
}

/** Called when a chunk has been updated. */
public void regionUpdated(ChunkPosition region) {
public void regionUpdated(RegionPosition region) {
fireRegionUpdated(region);
}

Expand Down
Loading

0 comments on commit 62b58b1

Please sign in to comment.