package hunternif.mc.atlas.core;
import hunternif.mc.atlas.AntiqueAtlasMod;
import hunternif.mc.atlas.util.Log;
import hunternif.mc.atlas.util.Rect;
import hunternif.mc.atlas.util.ShortVec2;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/** All tiles seen in dimension. Thread-safe (probably) */
public class DimensionData implements ITileStorage {
private final AtlasData parent;
private final int dimension;
private int browsingX, browsingY;
private double browsingZoom = 0.5;
/** a map of chunks the player has seen. This map is thread-safe.
* CAREFUL! Don't modify chunk coordinates that are already put in the map! */
private final Map<ShortVec2, Tile> tiles = new ConcurrentHashMap<>(2, 0.75f, 2);
/** Maps threads to the temporary key for thread-safe access to the tile map. */
private final Map<Thread, ShortVec2> thread2KeyMap = new ConcurrentHashMap<>(2, 0.75f, 2);
/** Limits of explored area, in chunks. */
private final Rect scope = new Rect();
public DimensionData(AtlasData parent, int dimension) {
this.parent = parent;
this.dimension = dimension;
}
public Map<ShortVec2, Tile> getSeenChunks() {
return tiles;
}
/** Set world coordinates that are in the center of the GUI. */
public void setBrowsingPosition(int x, int y, double zoom) {
this.browsingX = x;
this.browsingY = y;
this.browsingZoom = zoom;
if (browsingZoom <= 0) {
Log.warn("Setting map zoom to invalid value of %f", zoom);
browsingZoom = AntiqueAtlasMod.settings.minScale;
}
parent.markDirty();
}
public int getBrowsingX() {
return browsingX;
}
public int getBrowsingY() {
return browsingY;
}
public double getBrowsingZoom() {
return browsingZoom;
}
/** Temporary key for thread-safe access to the tile map. */
private ShortVec2 getKey() {
return thread2KeyMap.computeIfAbsent(Thread.currentThread(), k -> new ShortVec2(0, 0));
}
@Override
public void setTile(int x, int y, Tile tile) {
tiles.put(new ShortVec2(x, y), tile);
scope.extendTo(x, y);
parent.markDirty();
}
@Override
public Tile removeTile(int x, int y) {
Tile oldTile = tiles.remove(getKey().set(x, y));
if (oldTile != null) parent.markDirty();
return oldTile;
}
@Override
public Tile getTile(int x, int y) {
return tiles.get(getKey().set(x, y));
}
@Override
public boolean hasTileAt(int x, int y) {
return tiles.containsKey(getKey().set(x, y));
}
@Override
public Rect getScope() {
return scope;
}
}