feat: Finished testing Unity files and got retrieval working
This commit is contained in:
parent
5c4ee2bc2e
commit
e0f1cd2436
@ -3,6 +3,7 @@ package storage
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.nicholasnovak.io/nnovak/spatial-db/world"
|
"git.nicholasnovak.io/nnovak/spatial-db/world"
|
||||||
@ -16,7 +17,12 @@ type UnityFile struct {
|
|||||||
fd *os.File
|
fd *os.File
|
||||||
fileSize int
|
fileSize int
|
||||||
// metadata maps the position of a chunk to its start index within the file
|
// metadata maps the position of a chunk to its start index within the file
|
||||||
metadata map[world.ChunkPos]int
|
metadata map[world.ChunkPos]fileMetadata
|
||||||
|
}
|
||||||
|
|
||||||
|
type fileMetadata struct {
|
||||||
|
startOffset int
|
||||||
|
fileSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateUnityFile(fileName string) (UnityFile, error) {
|
func CreateUnityFile(fileName string) (UnityFile, error) {
|
||||||
@ -28,7 +34,7 @@ func CreateUnityFile(fileName string) (UnityFile, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u.fd = f
|
u.fd = f
|
||||||
u.metadata = make(map[world.ChunkPos]int)
|
u.metadata = make(map[world.ChunkPos]fileMetadata)
|
||||||
|
|
||||||
return u, nil
|
return u, nil
|
||||||
}
|
}
|
||||||
@ -55,7 +61,10 @@ func (u *UnityFile) WriteChunk(data world.ChunkData) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update the metadata with the new file
|
// Update the metadata with the new file
|
||||||
u.metadata[data.Pos] = u.fileSize
|
u.metadata[data.Pos] = fileMetadata{
|
||||||
|
startOffset: u.fileSize,
|
||||||
|
fileSize: encodedSize,
|
||||||
|
}
|
||||||
u.fileSize += encodedSize
|
u.fileSize += encodedSize
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -88,6 +97,17 @@ func (u *UnityFile) ReadMetadataFile(fileName string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u UnityFile) ReadChunk() world.ChunkData {
|
func (u UnityFile) ReadChunk(pos world.ChunkPos) (world.ChunkData, error) {
|
||||||
return world.ChunkData{}
|
m := u.metadata[pos]
|
||||||
|
|
||||||
|
u.fd.Seek(0, m.startOffset)
|
||||||
|
|
||||||
|
fileReader := io.LimitReader(u.fd, int64(m.fileSize))
|
||||||
|
|
||||||
|
var data world.ChunkData
|
||||||
|
if err := json.NewDecoder(fileReader).Decode(&data); err != nil {
|
||||||
|
return world.ChunkData{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,10 @@ package storage
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"git.nicholasnovak.io/nnovak/spatial-db/world"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCreateUnityFile(t *testing.T) {
|
func TestCreateUnityFile(t *testing.T) {
|
||||||
@ -28,3 +31,91 @@ func TestCreateUnityFile(t *testing.T) {
|
|||||||
t.Fatalf("Got an error saving the empty metadata: %v", err)
|
t.Fatalf("Got an error saving the empty metadata: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWriteSingleFile(t *testing.T) {
|
||||||
|
tempDir, err := os.MkdirTemp("", "unity")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error creating temporary directory: %v", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tempDir)
|
||||||
|
|
||||||
|
u, err := CreateUnityFile(path.Join(tempDir, "test-unity"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error creating unity file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write a single file
|
||||||
|
var data world.ChunkData
|
||||||
|
data.Sections[0].BlockStates[0] = 2
|
||||||
|
|
||||||
|
if err := u.WriteChunk(data); err != nil {
|
||||||
|
t.Fatalf("Error writing chunk: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the chunk back
|
||||||
|
readChunk, err := u.ReadChunk(data.Pos)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error reading chunk: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare the chunks directly
|
||||||
|
if !reflect.DeepEqual(data, readChunk) {
|
||||||
|
t.Fatalf("Chunks differed, sent %v, received %v", data, readChunk)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteMultipleFiles(t *testing.T) {
|
||||||
|
tempDir, err := os.MkdirTemp("", "unity")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error creating temporary directory: %v", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tempDir)
|
||||||
|
|
||||||
|
u, err := CreateUnityFile(path.Join(tempDir, "test-unity"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error creating unity file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
chunk1 world.ChunkData
|
||||||
|
chunk2 world.ChunkData
|
||||||
|
chunk3 world.ChunkData
|
||||||
|
)
|
||||||
|
chunk1.Pos = world.ChunkPos{
|
||||||
|
X: 0,
|
||||||
|
Z: 0,
|
||||||
|
}
|
||||||
|
chunk1.Sections[0].BlockStates[0] = 2
|
||||||
|
chunk2.Sections[0].BlockStates[0] = 3
|
||||||
|
chunk2.Pos = world.ChunkPos{
|
||||||
|
X: 1,
|
||||||
|
Z: 0,
|
||||||
|
}
|
||||||
|
chunk3.Sections[0].BlockStates[0] = 4
|
||||||
|
chunk3.Pos = world.ChunkPos{
|
||||||
|
X: 2,
|
||||||
|
Z: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
chunks := []world.ChunkData{chunk1, chunk2, chunk3}
|
||||||
|
|
||||||
|
// Write all chunks
|
||||||
|
for _, data := range chunks {
|
||||||
|
if err := u.WriteChunk(data); err != nil {
|
||||||
|
t.Fatalf("Error writing chunk: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the chunks back
|
||||||
|
for _, data := range chunks {
|
||||||
|
readChunk, err := u.ReadChunk(data.Pos)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error reading chunk: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare the chunks directly
|
||||||
|
if !reflect.DeepEqual(data, readChunk) {
|
||||||
|
t.Fatalf("Chunks differed, sent %v, received %v", data, readChunk)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,6 +3,8 @@ package world
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BlockPos struct {
|
type BlockPos struct {
|
||||||
@ -36,7 +38,25 @@ type ChunkPos struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cp ChunkPos) MarshalText() ([]byte, error) {
|
func (cp ChunkPos) MarshalText() ([]byte, error) {
|
||||||
return []byte(fmt.Sprintf("%d %d", cp.Z, cp.Z)), nil
|
return []byte(fmt.Sprintf("%d %d", cp.X, cp.Z)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cp *ChunkPos) UnmarshalText(text []byte) error {
|
||||||
|
words := strings.Split(string(text), " ")
|
||||||
|
x, err := strconv.Atoi(words[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
z, err := strconv.Atoi(words[1])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cp.X = x
|
||||||
|
cp.Z = z
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp ChunkPos) ToFileName() string {
|
func (cp ChunkPos) ToFileName() string {
|
||||||
|
Loading…
Reference in New Issue
Block a user