package storage import ( "bytes" "errors" "fmt" "image" "image/color" "path/filepath" "time" ) var tiles [][]tile 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) { tiles = make([][]tile, canvasSize) for i := range tiles { tiles[i] = make([]tile, canvasSize) } for y := range tiles { for x := range tiles[y] { err := tiles[y][x].load(filepath.Join(path, fmt.Sprintf("%d-%d.png", x, y)), tileSize) if err != nil { panic(err) } } } } func Save() { for y := range tiles { for x := range tiles[y] { if tiles[y][x].dirty { if err := tiles[y][x].save(); err != nil { panic(err) } } } } } 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) { if x >= len(tiles) || y >= len(tiles) { return nil, errors.New("tile coordinates out of range") } return tiles[y][x].toBytesPNG() } 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") } tiles[ty][tx].image.Set(x, y, c) tiles[ty][tx].dirty = true return nil }