Restructure Packages (read commit description)

There are now three root packages
- Engine: Generator & JSON Scaffolding
- Core: Managers, Commands, NMS
- Util: Random utility packages
This commit is contained in:
Daniel Mills
2021-07-16 01:46:22 -04:00
parent eef548f6a1
commit c984eb9b8c
423 changed files with 1001 additions and 1977 deletions

View File

@@ -0,0 +1,166 @@
/*
* 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.engine.hunk.Hunk;
import org.bukkit.block.TileState;
import org.bukkit.block.data.BlockData;
public interface ParallaxAccess {
default BlockData getBlock(int x, int y, int z) {
return getBlocksR(x >> 4, z >> 4).get(x & 15, y, z & 15);
}
default void setBlock(int x, int y, int z, BlockData d) {
getBlocksRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
}
default TileData<? extends TileState> getTile(int x, int y, int z) {
return getTilesR(x >> 4, z >> 4).get(x & 15, y, z & 15);
}
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);
}
default String getObject(int x, int y, int z) {
return getObjectsR(x >> 4, z >> 4).get(x & 15, y, z & 15);
}
default void setObject(int x, int y, int z, String d) {
getObjectsRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
}
default String getEntity(int x, int y, int z) {
return getEntitiesR(x >> 4, z >> 4).get(x & 15, y, z & 15);
}
default void setEntity(int x, int y, int z, String d) {
getEntitiesRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
}
default Boolean isUpdate(int x, int y, int z) {
return getUpdatesR(x >> 4, z >> 4).get(x & 15, y, z & 15);
}
default void updateBlock(int x, int y, int z) {
setUpdate(x, y, z, true);
}
default void setUpdate(int x, int y, int z, boolean d) {
getUpdatesRW(x >> 4, z >> 4).set(x & 15, y, z & 15, d);
}
default boolean isParallaxGenerated(int x, int z) {
return getMetaR(x, z).isParallaxGenerated();
}
default boolean isChunkGenerated(int x, int z) {
return getMetaR(x, z).isGenerated();
}
default boolean isFeatureGenerated(int x, int z) {
return getMetaR(x, z).isFeatureGenerated();
}
default void setParallaxGenerated(int x, int z) {
setParallaxGenerated(x, z, true);
}
default void setChunkGenerated(int x, int z) {
setChunkGenerated(x, z, true);
}
default void setFeatureGenerated(int x, int z) {
setFeatureGenerated(x, z, true);
}
default void setParallaxGenerated(int x, int z, boolean v) {
getMetaRW(x, z).setParallaxGenerated(v);
}
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);
}
}
default void setChunkGenerated(int x, int z, boolean v) {
getMetaRW(x, z).setGenerated(v);
}
default void setFeatureGenerated(int x, int z, boolean v) {
getMetaRW(x, z).setFeatureGenerated(v);
}
Hunk<TileData<? extends TileState>> getTilesR(int x, int z);
Hunk<TileData<? extends TileState>> getTilesRW(int x, int z);
Hunk<BlockData> getBlocksR(int x, int z);
Hunk<BlockData> getBlocksRW(int x, int z);
Hunk<String> getObjectsR(int x, int z);
Hunk<String> getObjectsRW(int x, int z);
Hunk<String> getEntitiesRW(int x, int z);
Hunk<String> getEntitiesR(int x, int z);
Hunk<Boolean> getUpdatesR(int x, int z);
Hunk<Boolean> getUpdatesRW(int x, int z);
ParallaxChunkMeta getMetaR(int x, int z);
ParallaxChunkMeta getMetaRW(int x, int z);
void cleanup(long regionIdle, long chunkIdle);
void cleanup();
void saveAll();
void saveAllNOW();
int getRegionCount();
int getChunkCount();
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

@@ -0,0 +1,64 @@
/*
* 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.IrisFeaturePositional;
import com.volmit.iris.engine.hunk.io.HunkIOAdapter;
import com.volmit.iris.engine.hunk.io.PaletteHunkIOAdapter;
import com.volmit.iris.util.CompoundTag;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Function;
@AllArgsConstructor
@Data
public class ParallaxChunkMeta {
public static final Function<CompoundTag, HunkIOAdapter<ParallaxChunkMeta>> adapter = (c) -> new PaletteHunkIOAdapter<>() {
@Override
public void write(ParallaxChunkMeta parallaxChunkMeta, DataOutputStream dos) throws IOException {
dos.writeUTF(new Gson().toJson(parallaxChunkMeta));
}
@Override
public ParallaxChunkMeta read(DataInputStream din) throws IOException {
return new Gson().fromJson(din.readUTF(), ParallaxChunkMeta.class);
}
};
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 CopyOnWriteArrayList<IrisFeaturePositional> features;
public ParallaxChunkMeta() {
this(false, false, false, false, false, false, -1, -1, 0, new CopyOnWriteArrayList<>());
}
}

View File

@@ -0,0 +1,209 @@
/*
* 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.engine.object.tile.TileData;
import com.volmit.iris.engine.hunk.Hunk;
import com.volmit.iris.engine.hunk.io.HunkIOAdapter;
import com.volmit.iris.engine.hunk.io.HunkRegion;
import com.volmit.iris.engine.hunk.io.HunkRegionSlice;
import com.volmit.iris.engine.parallel.GridLock;
import com.volmit.iris.util.ByteArrayTag;
import com.volmit.iris.util.CompoundTag;
import com.volmit.iris.util.M;
import com.volmit.iris.util.Tag;
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;
public ParallaxRegion(int height, File folder, int x, int z, CompoundTag compound) {
super(folder, x, z, compound);
this.height = height;
setupSlices();
lock = new GridLock(32, 32);
}
public ParallaxRegion(int height, File folder, int x, int z) {
super(folder, x, z);
this.height = height;
setupSlices();
lock = 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.newArrayHunk(32, 1, 32), (ByteArrayTag) t);
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
}
}
if (meta == null) {
meta = Hunk.newArrayHunk(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();
}
}
}
public synchronized void save() throws IOException {
blockSlice.save();
objectSlice.save();
entitySlice.save();
tileSlice.save();
updateSlice.save();
saveMetaHunk();
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

@@ -0,0 +1,244 @@
/*
* 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.engine.hunk.Hunk;
import com.volmit.iris.util.J;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.KMap;
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 int height;
public ParallaxWorld(int height, File folder) {
this.height = height;
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();
}
}
public boolean isLoaded(int x, int z) {
return loadedRegions.containsKey(key(x, z));
}
public void save(int x, int z) {
if (isLoaded(x, z)) {
save(getR(x, z));
}
}
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();
}
}
return v;
}
public ParallaxRegion load(int x, int z) {
if (isLoaded(x, z)) {
return loadedRegions.get(key(x, z));
}
ParallaxRegion v = new ParallaxRegion(height, folder, x, z);
loadedRegions.put(key(x, z), v);
return v;
}
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;
}
public ParallaxRegion getRW(int x, int z) {
save.addIfMissing(key(x, z));
return getR(x, z);
}
private long key(int x, int z) {
return (((long) x) << 32) | (((long) z) & 0xffffffffL);
}
@Override
public Hunk<BlockData> getBlocksR(int x, int z) {
return getR(x >> 5, z >> 5).getBlockSlice().getR(x & 31, z & 31);
}
@Override
public Hunk<BlockData> getBlocksRW(int x, int z) {
return getRW(x >> 5, z >> 5).getBlockSlice().getRW(x & 31, z & 31);
}
@Override
public Hunk<TileData<? extends TileState>> getTilesR(int x, int z) {
return getR(x >> 5, z >> 5).getTileSlice().getR(x & 31, z & 31);
}
@Override
public Hunk<TileData<? extends TileState>> getTilesRW(int x, int z) {
return getRW(x >> 5, z >> 5).getTileSlice().getRW(x & 31, z & 31);
}
@Override
public Hunk<String> getObjectsR(int x, int z) {
return getR(x >> 5, z >> 5).getObjectSlice().getR(x & 31, z & 31);
}
@Override
public Hunk<String> getObjectsRW(int x, int z) {
return getRW(x >> 5, z >> 5).getObjectSlice().getRW(x & 31, z & 31);
}
@Override
public Hunk<String> getEntitiesRW(int x, int z) {
return getRW(x >> 5, z >> 5).getEntitySlice().getRW(x & 31, z & 31);
}
@Override
public Hunk<String> getEntitiesR(int x, int z) {
return getRW(x >> 5, z >> 5).getEntitySlice().getR(x & 31, z & 31);
}
@Override
public Hunk<Boolean> getUpdatesR(int x, int z) {
return getR(x >> 5, z >> 5).getUpdateSlice().getR(x & 31, z & 31);
}
@Override
public Hunk<Boolean> getUpdatesRW(int x, int z) {
return getRW(x >> 5, z >> 5).getUpdateSlice().getRW(x & 31, z & 31);
}
@Override
public ParallaxChunkMeta getMetaR(int x, int z) {
return getR(x >> 5, z >> 5).getMetaR(x & 31, z & 31);
}
@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 void cleanup(long r, long c) {
J.a(() -> {
try {
int rr = 0;
int cc = 0;
for (ParallaxRegion i : loadedRegions.v()) {
if (i.hasBeenIdleLongerThan(r)) {
rr++;
unload(i.getX(), i.getZ());
} else {
cc += i.cleanup(c);
}
}
} catch (Throwable e) {Iris.reportError(e);
e.printStackTrace();
}
});
}
@Override
public void saveAll() {
J.a(this::saveAllNOW);
}
@Override
public void saveAllNOW() {
for (ParallaxRegion i : loadedRegions.v()) {
if (save.contains(key(i.getX(), i.getZ()))) {
save(i.getX(), i.getZ());
}
}
}
}