Skip to content

Commit

Permalink
Begin testing different block region storage methods (#22, #37, #38)
Browse files Browse the repository at this point in the history
  • Loading branch information
avaerian committed Jun 12, 2024
1 parent a61edc1 commit fdf520e
Show file tree
Hide file tree
Showing 7 changed files with 607 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.minerift.ether.schematic.data;

import org.jetbrains.annotations.NotNull;
import org.minerift.ether.math.Array3DIterator;
import org.minerift.ether.util.Array3DAccessor;

import java.util.Iterator;

public class Array3DCubicRegion implements CubicRegion<String> {

private final int width, height, length;
private final String[][][] data;
private final Array3DAccessor<String> arrayAccessor;

public Array3DCubicRegion(int width, int height, int length) {
this(width, height, length, Array3DAccessor.xyz());
}

public Array3DCubicRegion(int width, int height, int length, Array3DAccessor<String> arrayAccessor) {
this.width = width;
this.height = height;
this.length = length;
this.data = new String[width][height][length];
this.arrayAccessor = arrayAccessor;
}

@Override
public int getWidth() {
return width;
}

@Override
public int getHeight() {
return height;
}

@Override
public int getLength() {
return length;
}

@Override
public void setBlockAt(String str, int x, int y, int z) {
arrayAccessor.set(data, str, x, y, z);
}

@Override
public String getBlockAt(int x, int y, int z) {
return arrayAccessor.get(data, x, y, z);
}

@NotNull
@Override
public Iterator<String> iterator() {
return new Array3DIterator<>(data, arrayAccessor);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.minerift.ether.schematic.data;

import com.google.common.base.Preconditions;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ArrayListCubicRegion<T> implements CubicRegion<T> {

private final List<T> blocks;
private final int width, height, length;

public ArrayListCubicRegion(int width, int height, int length) {
this.width = width;
this.height = height;
this.length = length;
this.blocks = new ArrayList<>(width * height * length);
}

@Override
public int getWidth() {
return width;
}

@Override
public int getHeight() {
return height;
}

@Override
public int getLength() {
return length;
}

@Override
public void setBlockAt(T block, int x, int y, int z) {
blocks.set(getIndexAt(x, y, z), block);
}

public static void main(String[] args) {
int width = 3;
int height = 4;
int length = 5;
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
for(int z = 0; z < length; z++) {
int idx = ((x * (width+1)) + y) * (height+1) + z;
System.out.printf("%d (%d, %d, %d)\n", idx, x, y, z);
}
}
}
}

private int getIndexAt(int x, int y, int z) {
int idx = ((x * (width+1)) + y) * (height+1) + z;
Preconditions.checkElementIndex(idx, blocks.size());
return idx;
}

@Override
public T getBlockAt(int x, int y, int z) {
return blocks.get(getIndexAt(x, y, z));
}

@NotNull
@Override
public Iterator<T> iterator() {
return blocks.iterator();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.minerift.ether.schematic.data;

import org.minerift.ether.math.Vec3i;

public interface CubicRegion<BlockData> extends Iterable<BlockData> {

int getWidth();
int getHeight();
int getLength();
default Vec3i getDimensions() {
return new Vec3i(getWidth(), getHeight(), getLength());
}

void setBlockAt(BlockData data, int x, int y, int z);
default void setBlockAt(BlockData data, Vec3i pos) {
setBlockAt(data, pos.getX(), pos.getY(), pos.getZ());
}

BlockData getBlockAt(int x, int y, int z);

}
111 changes: 111 additions & 0 deletions main/src/main/java/org/minerift/ether/util/io/BinaryFormat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package org.minerift.ether.util.io;

import it.unimi.dsi.fastutil.bytes.Byte2ObjectMap;
import it.unimi.dsi.fastutil.bytes.Byte2ObjectOpenHashMap;
import org.minerift.ether.util.pair.Pair;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BinaryFormat {

public static class Section {
private String name;
private ByteBuffer data;

public Section(String name, ByteBuffer data) {
this.name = name;
this.data = data;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public ByteBuffer getData() {
return data;
}
}

// Section: 4 parts (short textLength, char array (str of textLength), int bytedatalength, byte array of bytedatalength)

public static Section readSection(ByteBuffer buffer) {
short nameBytes = buffer.getShort();
byte[] nameBuf = new byte[nameBytes];
buffer.get(nameBuf);
String name = new String(nameBuf, StandardCharsets.UTF_8);
int dataBytes = buffer.getInt();
ByteBuffer data = buffer.slice(buffer.position(), dataBytes);

return new Section(name, data);
}

public static Section[] readSections(ByteBuffer buffer) {
buffer.rewind();
List<Section> sections = new ArrayList<>();
while(buffer.hasRemaining()) {
sections.add(readSection(buffer));
}
return sections.toArray(Section[]::new);
}

public static Map<String, Section> partitionSections(ByteBuffer buffer) {
buffer.rewind();
Map<String, Section> sections = new HashMap<>();
while(buffer.hasRemaining()) {
Section section = readSection(buffer);
sections.put(section.getName(), section);
}
return sections;
}

// parts: (int mapSize) (byte id, int strByteLen, byte array of string)
public static ByteBuffer dumpMap(Byte2ObjectMap<String> map) {
int entryCount = map.size();
int strSumByteSize = map.values().stream().mapToInt((str) -> str.getBytes().length).sum();
int byteSize = Integer.BYTES + (entryCount * (Byte.BYTES + Integer.BYTES)) + strSumByteSize;

ByteBuffer buffer = ByteBuffer.allocate(byteSize);
buffer.putInt(entryCount); // int mapSize
for(var entry : map.byte2ObjectEntrySet()) {
buffer.put(entry.getByteKey()); // byte id
byte[] strBytes = entry.getValue().getBytes(StandardCharsets.UTF_8);
buffer.putInt(strBytes.length); // strByteLen
buffer.put(strBytes); // byte array of string
}

return buffer;
}

public static Byte2ObjectMap<String> readMap(ByteBuffer buffer) {
Pair<Byte, String>[] entries = readMapEntries(buffer);
Byte2ObjectMap<String> map = new Byte2ObjectOpenHashMap<>(entries.length);
for(Pair<Byte, String> entry : entries) {
map.put(entry.getFirst().byteValue(), entry.getSecond());
}
return map;
}

public static Pair<Byte, String>[] readMapEntries(ByteBuffer buffer) {
int entryCount = buffer.getInt();
Pair<Byte, String>[] entries = new Pair[entryCount];
for(int i = 0; i < entryCount; i++) {
byte id = buffer.get(); // read id
byte[] strBytes = new byte[buffer.getInt()]; // read str byte len
buffer.get(strBytes); // read str bytes
String str = new String(strBytes, StandardCharsets.UTF_8);

entries[i] = new Pair<>(id, str);
}
return entries;
}

}
Loading

0 comments on commit fdf520e

Please sign in to comment.