9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-28 11:39:07 +00:00

Data formats Matter

This commit is contained in:
Daniel Mills
2021-08-05 01:11:48 -04:00
parent 65fdd6e25f
commit 294a5e39a6
16 changed files with 546 additions and 94 deletions

View File

@@ -18,6 +18,7 @@
package com.volmit.iris.util.hunk;
import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.function.*;
import com.volmit.iris.util.hunk.io.HunkIOAdapter;

View File

@@ -18,6 +18,7 @@
package com.volmit.iris.util.hunk.storage;
import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.function.Consumer4;
import com.volmit.iris.util.hunk.Hunk;
@@ -37,6 +38,10 @@ public class MappedHunk<T> extends StorageHunk<T> implements Hunk<T> {
data = new KMap<>();
}
public int getEntryCount() {
return data.size();
}
@Override
public void setRaw(int x, int y, int z, T t) {
if (t == null) {

View File

@@ -22,6 +22,8 @@ import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KMap;
import lombok.Getter;
import java.lang.reflect.InvocationTargetException;
public class IrisMatter implements Matter {
private static final KMap<Class<?>, MatterSlice<?>> slicers = buildSlicers();
@@ -45,6 +47,7 @@ public class IrisMatter implements Matter {
this.height = height;
this.depth = depth;
this.header = new MatterHeader();
this.sliceMap = new KMap<>();
}
@Override
@@ -55,7 +58,13 @@ public class IrisMatter implements Matter {
return null;
}
return (MatterSlice<T>) slice;
try {
return slice.getClass().getConstructor(int.class, int.class, int.class).newInstance(getWidth(), getHeight(), getDepth());
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
private static KMap<Class<?>, MatterSlice<?>> buildSlicers() {

View File

@@ -25,6 +25,8 @@ import java.io.*;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
* When Red Matter isn't enough
@@ -208,6 +210,14 @@ public interface Matter {
*/
Map<Class<?>, MatterSlice<?>> getSliceMap();
default void write(File f) throws IOException
{
FileOutputStream out = new FileOutputStream(f);
GZIPOutputStream gzo = new GZIPOutputStream(out);
write(gzo);
gzo.close();
}
/**
* Writes the data to the output stream. The data will be flushed to the provided output
* stream however the provided stream will NOT BE CLOSED, so be sure to actually close it
@@ -231,6 +241,20 @@ public interface Matter {
dos.flush();
}
static Matter read(File f) throws IOException, ClassNotFoundException
{
FileInputStream in = new FileInputStream(f);
GZIPInputStream gzi = new GZIPInputStream(in);
Matter m = read(gzi);
gzi.close();
return m;
}
static Matter read(InputStream in) throws IOException, ClassNotFoundException
{
return read(in, (b) -> new IrisMatter(b.getX(), b.getY(), b.getZ()));
}
/**
* Reads the input stream into a matter object using a matter factory.
* Does not close the input stream. Be a man, close it yourself.

View File

@@ -1,82 +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.util.matter;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.function.Consumer4;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.hunk.storage.StorageHunk;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Map;
@SuppressWarnings({"DefaultAnnotationParam", "Lombok"})
@Data
@EqualsAndHashCode(callSuper = false)
public class MatterHunk<T> extends StorageHunk<T> implements Hunk<T> {
private final Map<Integer, T> data;
public MatterHunk(int w, int h, int d) {
super(w, h, d);
data = new KMap<>();
}
public int getCount() {
return data.size();
}
@Override
public void setRaw(int x, int y, int z, T t) {
if (t == null) {
data.remove(index(x, y, z));
return;
}
data.put(index(x, y, z), t);
}
private Integer index(int x, int y, int z) {
return (z * getWidth() * getHeight()) + (y * getWidth()) + x;
}
@Override
public synchronized Hunk<T> iterateSync(Consumer4<Integer, Integer, Integer, T> c) {
int idx, z;
for (Map.Entry<Integer, T> g : data.entrySet()) {
idx = g.getKey();
z = idx / (getWidth() * getHeight());
idx -= (z * getWidth() * getHeight());
c.accept(idx % getWidth(), idx / getWidth(), z, g.getValue());
}
return this;
}
@Override
public void empty(T b) {
data.clear();
}
@Override
public T getRaw(int x, int y, int z) {
return data.get(index(x, y, z));
}
}

View File

@@ -0,0 +1,24 @@
/*
* 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.util.matter;
@FunctionalInterface
public interface MatterReader<W, T> {
T readMatter(W w, int x, int y, int z);
}

View File

@@ -18,9 +18,13 @@
package com.volmit.iris.util.matter;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.util.data.Varint;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.hunk.storage.MappedHunk;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -33,6 +37,90 @@ public interface MatterSlice<T> extends Hunk<T> {
T readNode(DataInputStream din) throws IOException;
<W> MatterWriter<W, T> writeInto(Class<W> mediumType);
<W> MatterReader<W, T> readFrom(Class<W> mediumType);
default Class<?> getClass(Object w)
{
Class<?> c = w.getClass();
if(w instanceof World)
{
c = World.class;
}else if(w instanceof BlockData)
{
c = BlockData.class;
}
return c;
}
default <W> boolean writeInto(W w, int x, int y, int z)
{
MatterWriter<W, T> injector = (MatterWriter<W, T>) writeInto(getClass(w));
if(injector == null)
{
return false;
}
for(int i = x; i < x + getWidth(); i++)
{
for(int j = y; j < y + getHeight(); j++)
{
for(int k = z; k < z + getDepth(); k++)
{
injector.writeMatter(w, get(i - x, j - y, k - z), i, j, k);
}
}
}
return true;
}
default <W> boolean readFrom(W w, int x, int y, int z)
{
MatterReader<W, T> ejector = (MatterReader<W, T>) readFrom(getClass(w));
if(ejector == null)
{
return false;
}
for(int i = x; i < x + getWidth(); i++)
{
for(int j = y; j < y + getHeight(); j++)
{
for(int k = z; k < z + getDepth(); k++)
{
set(i - x, j - y, k - z, ejector.readMatter(w, i, j, k));
}
}
}
return true;
}
// BlockMatter<T>
// RawMatter<T> ex MappedHunk<T>
// IMatterSlice<T> ex Hunk<T>
default int getCount()
{
return ((MappedHunk<?>)this).getEntryCount();
}
default boolean canWrite(Class<?> mediumType)
{
return writeInto(mediumType) != null;
}
default boolean canRead(Class<?> mediumType)
{
return readFrom(mediumType) != null;
}
default void write(DataOutputStream dos) throws IOException {
int w = getWidth();
int h = getHeight();
@@ -40,9 +128,9 @@ public interface MatterSlice<T> extends Hunk<T> {
MatterPalette<T> palette = new MatterPalette<T>(this);
iterateSync((x, y, z, b) -> palette.assign(b));
palette.writePalette(dos);
Varint.writeUnsignedVarInt(((MatterHunk<?>) this).getCount(), dos);
Varint.writeUnsignedVarInt(getCount(), dos);
iterateSyncIO((x, y, z, b) -> {
Varint.writeUnsignedVarInt((z * w * h) + (y * w) + x, dos);
Varint.writeUnsignedVarInt(Cache.to1D(x, y, z, w, h), dos);
palette.writeNode(b, dos);
});
}
@@ -51,7 +139,6 @@ public interface MatterSlice<T> extends Hunk<T> {
int w = getWidth();
int h = getHeight();
// canonical is read in parent
MatterPalette<T> palette = new MatterPalette<T>(this, din);
int nodes = Varint.readUnsignedVarInt(din);
int[] pos;

View File

@@ -0,0 +1,24 @@
/*
* 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.util.matter;
@FunctionalInterface
public interface MatterWriter<W, T> {
void writeMatter(W w, T d, int x, int y, int z);
}

View File

@@ -18,10 +18,14 @@
package com.volmit.iris.util.matter.slices;
import com.volmit.iris.engine.parallax.ParallaxAccess;
import com.volmit.iris.engine.parallax.ParallaxWorld;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.matter.Sliced;
import com.volmit.iris.util.nbt.io.NBTUtil;
import com.volmit.iris.util.nbt.mca.NBTWorld;
import com.volmit.iris.util.nbt.tag.CompoundTag;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import java.io.DataInputStream;
@@ -36,15 +40,19 @@ public class BlockMatter extends RawMatter<BlockData> {
public BlockMatter(int width, int height, int depth) {
super(width, height, depth, BlockData.class);
registerWriter(World.class, ((w, d, x, y, z) -> w.getBlockAt(x,y,z).setBlockData(d)));
registerWriter(ParallaxWorld.class, (w, d, x, y, z) -> w.setBlock(x,y,z,d));
registerReader(World.class, (w, x, y, z) -> w.getBlockAt(x,y,z).getBlockData());
registerReader(ParallaxWorld.class, ParallaxAccess::getBlock);
}
@Override
public void writeNode(BlockData b, DataOutputStream dos) throws IOException {
NBTUtil.write(NBTWorld.getCompound(b), dos, false);
dos.writeUTF(b.getAsString(true));
}
@Override
public BlockData readNode(DataInputStream din) throws IOException {
return NBTWorld.getBlockData((CompoundTag) NBTUtil.read(din, false).getTag());
return B.get(din.readUTF());
}
}

View File

@@ -18,7 +18,10 @@
package com.volmit.iris.util.matter.slices;
import com.volmit.iris.util.matter.MatterHunk;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.hunk.storage.MappedHunk;
import com.volmit.iris.util.matter.MatterReader;
import com.volmit.iris.util.matter.MatterWriter;
import com.volmit.iris.util.matter.MatterSlice;
import lombok.Getter;
@@ -26,23 +29,39 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public abstract class RawMatter<T> extends MatterHunk<T> implements MatterSlice<T> {
public abstract class RawMatter<T> extends MappedHunk<T> implements MatterSlice<T> {
@Getter
private final Class<T> type;
private final KMap<Class<?>, MatterWriter<?, T>> injectors;
private final KMap<Class<?>, MatterReader<?, T>> ejectors;
public RawMatter(int width, int height, int depth, Class<T> type) {
super(width, height, depth);
injectors = new KMap<>();
ejectors = new KMap<>();
this.type = type;
}
@Override
public void setRaw(int x, int y, int z, T t) {
protected <W> void registerWriter(Class<W> mediumType, MatterWriter<W, T> injector)
{
injectors.put(mediumType, injector);
}
protected <W> void registerReader(Class<W> mediumType, MatterReader<W, T> injector)
{
ejectors.put(mediumType, injector);
}
@Override
public T getRaw(int x, int y, int z) {
return null;
public <W> MatterWriter<W, T> writeInto(Class<W> mediumType)
{
return (MatterWriter<W, T>) injectors.get(mediumType);
}
@Override
public <W> MatterReader<W, T> readFrom(Class<W> mediumType)
{
return (MatterReader<W, T>) ejectors.get(mediumType);
}
@Override