Drop parallax core

This commit is contained in:
Daniel Mills 2021-08-09 09:43:30 -04:00
parent 6569038777
commit de51d4860e
4 changed files with 0 additions and 795 deletions

View File

@ -1,202 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.parallax;
import com.volmit.iris.engine.object.tile.TileData;
import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.hunk.Hunk;
import org.bukkit.block.TileState;
import org.bukkit.block.data.BlockData;
public interface ParallaxAccess {
@BlockCoordinates
default BlockData getBlock(int x, int y, int z) {
return getBlocksR(x >> 4, z >> 4).get(x & 15, y, z & 15);
}
@BlockCoordinates
default void setBlock(int x, int y, int z, BlockData d) {
getBlocksRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
}
@BlockCoordinates
default TileData<? extends TileState> getTile(int x, int y, int z) {
return getTilesR(x >> 4, z >> 4).get(x & 15, y, z & 15);
}
@BlockCoordinates
default void setTile(int x, int y, int z, TileData<? extends TileState> d) {
getTilesRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
}
@BlockCoordinates
default String getObject(int x, int y, int z) {
return getObjectsR(x >> 4, z >> 4).get(x & 15, y, z & 15);
}
@BlockCoordinates
default void setObject(int x, int y, int z, String d) {
getObjectsRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
}
@BlockCoordinates
default String getEntity(int x, int y, int z) {
return getEntitiesR(x >> 4, z >> 4).get(x & 15, y, z & 15);
}
@BlockCoordinates
default void setEntity(int x, int y, int z, String d) {
getEntitiesRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
}
@BlockCoordinates
default Boolean isUpdate(int x, int y, int z) {
return getUpdatesR(x >> 4, z >> 4).get(x & 15, y, z & 15);
}
@BlockCoordinates
default void updateBlock(int x, int y, int z) {
setUpdate(x, y, z, true);
}
@BlockCoordinates
default void setUpdate(int x, int y, int z, boolean d) {
getUpdatesRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
}
@ChunkCoordinates
default boolean isParallaxGenerated(int x, int z) {
return getMetaR(x, z).isParallaxGenerated();
}
@ChunkCoordinates
default boolean isChunkGenerated(int x, int z) {
return getMetaR(x, z).isGenerated();
}
@ChunkCoordinates
default boolean isFeatureGenerated(int x, int z) {
return getMetaR(x, z).isFeatureGenerated();
}
@ChunkCoordinates
default void setParallaxGenerated(int x, int z) {
setParallaxGenerated(x, z, true);
}
@ChunkCoordinates
default void setChunkGenerated(int x, int z) {
setChunkGenerated(x, z, true);
}
@ChunkCoordinates
default void setFeatureGenerated(int x, int z) {
setFeatureGenerated(x, z, true);
}
@ChunkCoordinates
default void setParallaxGenerated(int x, int z, boolean v) {
getMetaRW(x, z).setParallaxGenerated(v);
}
@ChunkCoordinates
default void maxMin(int x, int z, int value) {
ParallaxChunkMeta meat = getMetaRW(x, z);
if (value > meat.getMaxObject()) {
meat.setMaxObject(value);
}
if (meat.getMinObject() <= -1) {
meat.setMinObject(value);
}
if (value < meat.getMinObject()) {
meat.setMinObject(value);
}
}
@ChunkCoordinates
default void setChunkGenerated(int x, int z, boolean v) {
getMetaRW(x, z).setGenerated(v);
}
@ChunkCoordinates
default void setFeatureGenerated(int x, int z, boolean v) {
getMetaRW(x, z).setFeatureGenerated(v);
}
@ChunkCoordinates
Hunk<TileData<? extends TileState>> getTilesR(int x, int z);
@ChunkCoordinates
Hunk<TileData<? extends TileState>> getTilesRW(int x, int z);
@ChunkCoordinates
Hunk<BlockData> getBlocksR(int x, int z);
@ChunkCoordinates
Hunk<BlockData> getBlocksRW(int x, int z);
@ChunkCoordinates
Hunk<String> getObjectsR(int x, int z);
@ChunkCoordinates
Hunk<String> getObjectsRW(int x, int z);
@ChunkCoordinates
Hunk<String> getEntitiesRW(int x, int z);
@ChunkCoordinates
Hunk<String> getEntitiesR(int x, int z);
@ChunkCoordinates
Hunk<Boolean> getUpdatesR(int x, int z);
@ChunkCoordinates
Hunk<Boolean> getUpdatesRW(int x, int z);
@ChunkCoordinates
ParallaxChunkMeta getMetaR(int x, int z);
@ChunkCoordinates
ParallaxChunkMeta getMetaRW(int x, int z);
void cleanup(long regionIdle, long chunkIdle);
void cleanup();
void saveAll();
void saveAllNOW();
int getRegionCount();
int getChunkCount();
@ChunkCoordinates
default void delete(int x, int z) {
getUpdatesRW(x, z).empty(false);
getBlocksRW(x, z).empty(null);
getTilesRW(x, z).empty(null);
getEntitiesRW(x, z).empty(null);
getObjectsRW(x, z).empty(null);
}
}

View File

@ -1,100 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.parallax;
import com.google.gson.Gson;
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
import com.volmit.iris.util.hunk.io.HunkIOAdapter;
import com.volmit.iris.util.hunk.io.PaletteHunkIOAdapter;
import com.volmit.iris.util.oldnbt.CompoundTag;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Function;
@AllArgsConstructor
@Data
public class ParallaxChunkMeta {
private static final Gson gson = new Gson();
public static final Function<CompoundTag, HunkIOAdapter<ParallaxChunkMeta>> adapter = (c) -> new PaletteHunkIOAdapter<>() {
@Override
public void write(ParallaxChunkMeta parallaxChunkMeta, DataOutputStream dos) throws IOException {
dos.writeBoolean(parallaxChunkMeta.updates);
dos.writeBoolean(parallaxChunkMeta.generated);
dos.writeBoolean(parallaxChunkMeta.tilesGenerated);
dos.writeBoolean(parallaxChunkMeta.parallaxGenerated);
dos.writeBoolean(parallaxChunkMeta.featureGenerated);
dos.writeBoolean(parallaxChunkMeta.objects);
dos.writeInt(parallaxChunkMeta.maxObject);
dos.writeInt(parallaxChunkMeta.minObject);
dos.writeInt(parallaxChunkMeta.count);
dos.writeInt(parallaxChunkMeta.features.size());
for (IrisFeaturePositional i : parallaxChunkMeta.features) {
dos.writeUTF(gson.toJson(i));
}
}
@Override
public ParallaxChunkMeta read(DataInputStream din) throws IOException {
ParallaxChunkMeta pcm = new ParallaxChunkMeta();
pcm.setUpdates(din.readBoolean());
pcm.setGenerated(din.readBoolean());
pcm.setTilesGenerated(din.readBoolean());
pcm.setParallaxGenerated(din.readBoolean());
pcm.setFeatureGenerated(din.readBoolean());
pcm.setObjects(din.readBoolean());
pcm.setMaxObject(din.readInt());
pcm.setMinObject(din.readInt());
pcm.setCount(din.readInt());
pcm.setFeatures(newSet());
int c = din.readInt();
for (int i = 0; i < c; i++) {
pcm.getFeatures().add(gson.fromJson(din.readUTF(), IrisFeaturePositional.class));
}
return pcm;
}
};
private boolean updates;
private boolean generated;
private boolean tilesGenerated;
private boolean parallaxGenerated;
private boolean featureGenerated;
private boolean objects;
private int maxObject = -1;
private int minObject = -1;
private int count;
private Set<IrisFeaturePositional> features;
private static Set<IrisFeaturePositional> newSet() {
return new CopyOnWriteArraySet<>();
}
public ParallaxChunkMeta() {
this(false, false, false, false, false, false, -1, -1, 0, newSet());
}
}

View File

@ -1,223 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.parallax;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.engine.object.tile.TileData;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.hunk.io.HunkIOAdapter;
import com.volmit.iris.util.hunk.io.HunkRegion;
import com.volmit.iris.util.hunk.io.HunkRegionSlice;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.oldnbt.ByteArrayTag;
import com.volmit.iris.util.oldnbt.CompoundTag;
import com.volmit.iris.util.oldnbt.Tag;
import com.volmit.iris.util.parallel.GridLock;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.parallel.NOOPGridLock;
import org.bukkit.block.TileState;
import org.bukkit.block.data.BlockData;
import java.io.File;
import java.io.IOException;
public class ParallaxRegion extends HunkRegion {
private boolean dirtyMeta;
private Hunk<ParallaxChunkMeta> meta;
private HunkIOAdapter<ParallaxChunkMeta> metaAdapter;
private HunkRegionSlice<BlockData> blockSlice;
private HunkRegionSlice<TileData<? extends TileState>> tileSlice;
private HunkRegionSlice<String> objectSlice;
private HunkRegionSlice<String> entitySlice;
private HunkRegionSlice<Boolean> updateSlice;
private final GridLock lock;
private long lastUse;
private final int height;
private final MultiBurst burst;
public ParallaxRegion(MultiBurst burst, int height, File folder, int x, int z, CompoundTag compound) {
super(folder, x, z, compound);
this.burst = burst;
this.height = height;
setupSlices();
lock = newGridLock();
}
public ParallaxRegion(MultiBurst burst, int height, File folder, int x, int z) {
super(folder, x, z);
this.burst = burst;
this.height = height;
setupSlices();
lock = newGridLock();
}
private GridLock newGridLock() {
return IrisSettings.get().getConcurrency().isUnstableLockingHeuristics() ? new NOOPGridLock(1, 1) : new GridLock(32, 32);
}
private void setupSlices() {
blockSlice = HunkRegionSlice.BLOCKDATA.apply(height, getCompound());
tileSlice = HunkRegionSlice.TILE.apply(height, getCompound());
objectSlice = HunkRegionSlice.STRING.apply(height, getCompound(), "objects");
entitySlice = HunkRegionSlice.STRING.apply(height, getCompound(), "entities");
updateSlice = HunkRegionSlice.BOOLEAN.apply(height, getCompound(), "updates");
metaAdapter = ParallaxChunkMeta.adapter.apply(getCompound());
dirtyMeta = false;
meta = null;
lastUse = M.ms();
}
public boolean hasBeenIdleLongerThan(long time) {
return M.ms() - lastUse > time;
}
public ParallaxChunkMeta getMetaR(int x, int z) {
return lock.withResult(x, z, () -> getMetaHunkR().getOr(x, 0, z, new ParallaxChunkMeta()));
}
public ParallaxChunkMeta getMetaRW(int x, int z) {
return lock.withResult(x, z, () -> {
lastUse = M.ms();
dirtyMeta = true;
ParallaxChunkMeta p = getMetaHunkRW().get(x, 0, z);
if (p == null) {
p = new ParallaxChunkMeta();
getMetaHunkRW().set(x, 0, z, p);
}
return p;
});
}
private Hunk<ParallaxChunkMeta> getMetaHunkR() {
if (meta == null) {
meta = loadMetaHunk();
}
return meta;
}
private Hunk<ParallaxChunkMeta> getMetaHunkRW() {
dirtyMeta = true;
return getMetaHunkR();
}
private Hunk<ParallaxChunkMeta> loadMetaHunk() {
lastUse = M.ms();
if (meta == null) {
Tag t = getCompound().getValue().get("meta");
if ((t instanceof ByteArrayTag)) {
try {
meta = metaAdapter.read((x, y, z) -> Hunk.newAtomicHunk(32, 1, 32), (ByteArrayTag) t);
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
}
}
if (meta == null) {
meta = Hunk.newAtomicHunk(32, 1, 32);
}
}
return meta;
}
public void unloadMetaHunk() {
if (dirtyMeta) {
saveMetaHunk();
dirtyMeta = false;
}
meta = null;
}
public void saveMetaHunk() {
if (meta != null && dirtyMeta) {
try {
getCompound().getValue().put("meta", meta.writeByteArrayTag(metaAdapter, "meta"));
dirtyMeta = false;
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
}
}
}
@Override
public synchronized void save() throws IOException {
blockSlice.save(burst);
objectSlice.save(burst);
entitySlice.save(burst);
tileSlice.save(burst);
updateSlice.save(burst);
saveMetaHunk();
Iris.debug("Saved Parallax Region " + C.GOLD + getX() + " " + getZ());
super.save();
}
public int unload() {
unloadMetaHunk();
return blockSlice.unloadAll() +
objectSlice.unloadAll() +
entitySlice.unloadAll() +
tileSlice.unloadAll() +
updateSlice.unloadAll();
}
public HunkRegionSlice<BlockData> getBlockSlice() {
lastUse = M.ms();
return blockSlice;
}
public HunkRegionSlice<String> getEntitySlice() {
lastUse = M.ms();
return entitySlice;
}
public HunkRegionSlice<TileData<? extends TileState>> getTileSlice() {
lastUse = M.ms();
return tileSlice;
}
public HunkRegionSlice<String> getObjectSlice() {
lastUse = M.ms();
return objectSlice;
}
public HunkRegionSlice<Boolean> getUpdateSlice() {
lastUse = M.ms();
return updateSlice;
}
public synchronized int cleanup(long c) {
return blockSlice.cleanup(c) +
objectSlice.cleanup(c) +
entitySlice.cleanup(c) +
tileSlice.cleanup(c) +
updateSlice.cleanup(c);
}
public int getChunkCount() {
return blockSlice.getLoadCount() + objectSlice.getLoadCount() + entitySlice.getLoadCount() + tileSlice.getLoadCount() + updateSlice.getLoadCount();
}
}

View File

@ -1,270 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.parallax;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.engine.object.tile.TileData;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.documentation.RegionCoordinates;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.parallel.MultiBurst;
import org.bukkit.block.TileState;
import org.bukkit.block.data.BlockData;
import java.io.File;
import java.io.IOException;
@SuppressWarnings("ALL")
public class ParallaxWorld implements ParallaxAccess {
private final KMap<Long, ParallaxRegion> loadedRegions;
private final KList<Long> save;
private final File folder;
private final MultiBurst burst;
private final int height;
public ParallaxWorld(MultiBurst burst, int height, File folder) {
this.height = height;
this.burst = burst;
this.folder = folder;
save = new KList<>();
loadedRegions = new KMap<>();
folder.mkdirs();
}
public int getRegionCount() {
return loadedRegions.size();
}
public int getChunkCount() {
int m = 0;
try {
for (ParallaxRegion i : loadedRegions.values()) {
m += i.getChunkCount();
}
} catch (Throwable e) {
Iris.reportError(e);
}
return m;
}
public void close() {
for (ParallaxRegion i : loadedRegions.v()) {
unload(i.getX(), i.getZ());
}
save.clear();
loadedRegions.clear();
}
public void save(ParallaxRegion region) {
try {
region.save();
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
}
}
@RegionCoordinates
public boolean isLoaded(int x, int z) {
return loadedRegions.containsKey(key(x, z));
}
@RegionCoordinates
public void save(int x, int z) {
if (isLoaded(x, z)) {
save(getR(x, z));
}
}
@RegionCoordinates
public int unload(int x, int z) {
long key = key(x, z);
int v = 0;
if (isLoaded(x, z)) {
if (save.contains(key)) {
save(x, z);
save.remove(key);
}
ParallaxRegion lr = loadedRegions.remove(key);
if (lr != null) {
v += lr.unload();
Iris.debug("Unloaded Parallax Region " + C.RED + x + " " + z);
}
}
return v;
}
@RegionCoordinates
public ParallaxRegion load(int x, int z) {
if (isLoaded(x, z)) {
return loadedRegions.get(key(x, z));
}
ParallaxRegion v = new ParallaxRegion(burst, height, folder, x, z);
loadedRegions.put(key(x, z), v);
Iris.debug("Loaded Parallax Region " + C.RED + x + " " + z);
return v;
}
@RegionCoordinates
public ParallaxRegion getR(int x, int z) {
long key = key(x, z);
ParallaxRegion region = loadedRegions.get(key);
if (region == null) {
region = load(x, z);
}
return region;
}
@RegionCoordinates
public ParallaxRegion getRW(int x, int z) {
save.addIfMissing(key(x, z));
return getR(x, z);
}
@RegionCoordinates
private long key(int x, int z) {
return (((long) x) << 32) | (((long) z) & 0xffffffffL);
}
@ChunkCoordinates
@Override
public Hunk<BlockData> getBlocksR(int x, int z) {
return getR(x >> 5, z >> 5).getBlockSlice().getR(x & 31, z & 31);
}
@ChunkCoordinates
@Override
public Hunk<BlockData> getBlocksRW(int x, int z) {
return getRW(x >> 5, z >> 5).getBlockSlice().getRW(x & 31, z & 31);
}
@ChunkCoordinates
@Override
public Hunk<TileData<? extends TileState>> getTilesR(int x, int z) {
return getR(x >> 5, z >> 5).getTileSlice().getR(x & 31, z & 31);
}
@ChunkCoordinates
@Override
public Hunk<TileData<? extends TileState>> getTilesRW(int x, int z) {
return getRW(x >> 5, z >> 5).getTileSlice().getRW(x & 31, z & 31);
}
@ChunkCoordinates
@Override
public Hunk<String> getObjectsR(int x, int z) {
return getR(x >> 5, z >> 5).getObjectSlice().getR(x & 31, z & 31);
}
@ChunkCoordinates
@Override
public Hunk<String> getObjectsRW(int x, int z) {
return getRW(x >> 5, z >> 5).getObjectSlice().getRW(x & 31, z & 31);
}
@ChunkCoordinates
@Override
public Hunk<String> getEntitiesRW(int x, int z) {
return getRW(x >> 5, z >> 5).getEntitySlice().getRW(x & 31, z & 31);
}
@ChunkCoordinates
@Override
public Hunk<String> getEntitiesR(int x, int z) {
return getRW(x >> 5, z >> 5).getEntitySlice().getR(x & 31, z & 31);
}
@ChunkCoordinates
@Override
public Hunk<Boolean> getUpdatesR(int x, int z) {
return getR(x >> 5, z >> 5).getUpdateSlice().getR(x & 31, z & 31);
}
@ChunkCoordinates
@Override
public Hunk<Boolean> getUpdatesRW(int x, int z) {
return getRW(x >> 5, z >> 5).getUpdateSlice().getRW(x & 31, z & 31);
}
@ChunkCoordinates
@Override
public ParallaxChunkMeta getMetaR(int x, int z) {
return getR(x >> 5, z >> 5).getMetaR(x & 31, z & 31);
}
@ChunkCoordinates
@Override
public ParallaxChunkMeta getMetaRW(int x, int z) {
return getRW(x >> 5, z >> 5).getMetaRW(x & 31, z & 31);
}
public void cleanup() {
cleanup(IrisSettings.get().getParallaxRegionEvictionMS(), IrisSettings.get().getParallax().getParallaxChunkEvictionMS());
}
@Override
public synchronized void cleanup(long r, long c) {
try {
int rr = 0;
for (ParallaxRegion i : loadedRegions.v()) {
burst.lazy(() -> {
if (i.hasBeenIdleLongerThan(r)) {
unload(i.getX(), i.getZ());
} else {
i.cleanup(c);
}
});
}
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
}
}
@Override
public void saveAll() {
burst.lazy(this::saveAllNOW);
}
@Override
public void saveAllNOW() {
Iris.debug("Saving " + C.GREEN + loadedRegions.size() + " Parallax Regions");
for (ParallaxRegion i : loadedRegions.v()) {
if (save.contains(key(i.getX(), i.getZ()))) {
save(i.getX(), i.getZ());
}
}
}
}