feat: Added in-memory server to the testing suite
This commit is contained in:
parent
89a6ddc9af
commit
8ae838cc2f
104
storage/inmemory_server.go
Normal file
104
storage/inmemory_server.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.nicholasnovak.io/nnovak/spatial-db/world"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InMemoryServer struct {
|
||||||
|
StorageDir string
|
||||||
|
Chunks map[world.ChunkPos]world.ChunkData
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *InMemoryServer) SetStorageRoot(path string) {
|
||||||
|
s.StorageDir = path
|
||||||
|
|
||||||
|
chunkFiles, err := os.ReadDir(s.StorageDir)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Chunks = make(map[world.ChunkPos]world.ChunkData)
|
||||||
|
|
||||||
|
for _, chunkFile := range chunkFiles {
|
||||||
|
if chunkFile.IsDir() || !strings.HasSuffix(chunkFile.Name(), ".chunk") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
file, err := os.Open(filepath.Join(s.StorageDir, chunkFile.Name()))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
chunkData, err := ReadChunkFromFile(file)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
file.Close()
|
||||||
|
|
||||||
|
s.Chunks[chunkData.Pos] = chunkData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *InMemoryServer) FetchOrCreateChunk(pos world.ChunkPos) (world.ChunkData, error) {
|
||||||
|
return s.Chunks[pos], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *InMemoryServer) FetchChunk(pos world.ChunkPos) (world.ChunkData, error) {
|
||||||
|
chunkFileName := filepath.Join(s.StorageDir, pos.ToFileName())
|
||||||
|
|
||||||
|
var chunkData world.ChunkData
|
||||||
|
|
||||||
|
chunkFile, err := os.Open(chunkFileName)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
|
return chunkData, ChunkNotFoundError
|
||||||
|
} else {
|
||||||
|
return chunkData, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defer chunkFile.Close()
|
||||||
|
|
||||||
|
return ReadChunkFromFile(chunkFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Voxel server implementation
|
||||||
|
|
||||||
|
func (s *InMemoryServer) ChangeBlock(
|
||||||
|
worldPosition world.BlockPos,
|
||||||
|
targetState world.BlockID,
|
||||||
|
) error {
|
||||||
|
chunk, err := s.FetchOrCreateChunk(worldPosition.ToChunkPos())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk.SectionFor(worldPosition).UpdateBlock(worldPosition, targetState)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *InMemoryServer) ChangeBlockRange(
|
||||||
|
targetState world.BlockID,
|
||||||
|
start, end world.BlockPos,
|
||||||
|
) error {
|
||||||
|
panic("ChangeBlockRange is unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *InMemoryServer) ReadBlockAt(pos world.BlockPos) (world.BlockID, error) {
|
||||||
|
chunk, err := s.FetchOrCreateChunk(pos.ToChunkPos())
|
||||||
|
if err != nil {
|
||||||
|
return world.Empty, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunk.SectionFor(pos).FetchBlock(pos), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *InMemoryServer) ReadChunkAt(pos world.ChunkPos) (world.ChunkData, error) {
|
||||||
|
return s.FetchOrCreateChunk(pos)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user