place/storage/storage.go

117 lines
2.3 KiB
Go
Raw Normal View History

2024-06-12 18:44:12 +00:00
package storage
import (
2024-06-13 11:25:18 +00:00
"bytes"
2024-06-12 18:44:12 +00:00
"errors"
"fmt"
"image"
"image/color"
"image/draw"
"log"
"os"
2024-06-13 11:25:18 +00:00
"time"
2024-06-12 18:44:12 +00:00
)
2024-06-13 11:25:18 +00:00
var tiles [][]tile
2024-06-12 18:44:12 +00:00
type WrongSizeError struct {
ExpectedSize int
ActualSize image.Point
X int
Y int
}
func (err *WrongSizeError) Error() string {
return fmt.Sprintf("expected %dx%d tile, got %dx%d (coords: %d-%d)", err.ExpectedSize, err.ExpectedSize, err.ActualSize.X, err.ActualSize.Y, err.X, err.Y)
}
func Load(path string, canvasSize int, tileSize int) {
if err := os.Chdir(path); err != nil {
panic(err)
}
2024-06-13 11:25:18 +00:00
tiles = make([][]tile, canvasSize)
2024-06-12 18:44:12 +00:00
for i := range tiles {
2024-06-13 11:25:18 +00:00
tiles[i] = make([]tile, canvasSize)
2024-06-12 18:44:12 +00:00
}
for y := range tiles {
for x := range tiles[y] {
2024-06-13 11:25:18 +00:00
tiles[y][x].image = image.NewRGBA(image.Rect(0, 0, tileSize, tileSize))
2024-06-12 18:44:12 +00:00
filename := fmt.Sprintf("%d-%d.png", x, y)
file, err := os.Open(filename)
if err != nil {
2024-06-13 11:25:18 +00:00
tiles[y][x].fill()
if err = tiles[y][x].save(filename); err != nil {
2024-06-12 18:44:12 +00:00
panic(err)
}
log.Printf("Created tile (%d-%d)\n", x, y)
} else {
img, _, err := image.Decode(file)
if err != nil {
panic(err)
}
2024-06-13 11:25:18 +00:00
draw.Draw(tiles[y][x].image, img.Bounds(), img, img.Bounds().Min, draw.Src)
2024-06-12 18:44:12 +00:00
}
defer file.Close()
2024-06-13 11:25:18 +00:00
if tiles[y][x].image.Bounds().Size().X != tileSize && tiles[y][x].image.Bounds().Size().Y != tileSize {
panic(WrongSizeError{ExpectedSize: tileSize, ActualSize: tiles[y][x].image.Bounds().Size(), X: x, Y: y})
2024-06-12 18:44:12 +00:00
}
2024-06-13 11:25:18 +00:00
tiles[y][x].dirty = false
2024-06-12 18:44:12 +00:00
}
}
}
func Save() {
for y := range tiles {
for x := range tiles[y] {
2024-06-13 11:25:18 +00:00
if tiles[y][x].dirty {
2024-06-12 18:44:12 +00:00
filename := fmt.Sprintf("%d-%d.png", x, y)
2024-06-13 11:25:18 +00:00
if err := tiles[y][x].save(filename); err != nil {
2024-06-12 18:44:12 +00:00
panic(err)
}
}
}
}
}
2024-06-13 11:25:18 +00:00
func StartSaves(saveFrequency int) {
go func() {
for range time.Tick(time.Second * time.Duration(saveFrequency)) {
Save()
}
}()
}
func GetTile(x int, y int) (*bytes.Buffer, error) {
2024-06-12 18:44:12 +00:00
if x >= len(tiles) || y >= len(tiles) {
return nil, errors.New("tile coordinates out of range")
}
2024-06-13 11:25:18 +00:00
return tiles[y][x].toBytesPNG()
2024-06-12 18:44:12 +00:00
}
2024-06-13 11:25:18 +00:00
func SetPixel(x int, y int, c color.Color) error {
size := tiles[0][0].size()
var tx int = x / size.X
var ty int = y / size.Y
x = x % size.X
y = y % size.Y
if ty >= len(tiles) || tx >= len(tiles[ty]) {
return errors.New("coordinates out of range")
2024-06-12 18:44:12 +00:00
}
2024-06-13 11:25:18 +00:00
tiles[ty][tx].image.Set(x, y, c)
tiles[ty][tx].dirty = true
2024-06-12 18:44:12 +00:00
return nil
}