Files
ordoor/internal/assetstore/object.go
Nick Thomas 5fccf97f4b Lazily load sprite image data
This cuts memory use significantly, since many sprites in an object are
never used. We can get savings over time by evicting sprites when they
go out of scope, but that's, well, out of scope.

To achieve this, I introduce an assetstore package that is in charge of
loading things from the filesystem. This also allows some lingering
case-sensitivity issues to be handled cleanly.

I'd hoped that creating fewer ebiten.Image instances would help CPU
usage, but that doesn't seem to be the case.
2020-03-19 22:24:21 +00:00

65 lines
1.1 KiB
Go

package assetstore
import (
"github.com/hajimehoshi/ebiten"
"code.ur.gs/lupine/ordoor/internal/data"
)
type Object struct {
assets *AssetStore
images []*ebiten.Image
raw *data.Object
}
func (a *AssetStore) Object(name string) (*Object, error) {
name = canonical(name)
if obj, ok := a.objs[name]; ok {
return obj, nil
}
filename, err := a.lookup(name, "obj", "Obj")
if err != nil {
return nil, err
}
raw, err := data.LoadObjectLazily(filename)
if err != nil {
return nil, err
}
obj := &Object{
assets: a,
images: make([]*ebiten.Image, int(raw.NumSprites)),
raw: raw,
}
a.objs[name] = obj
return obj, nil
}
// Filled lazily
func (o *Object) Image(idx int) (*ebiten.Image, error) {
if img := o.images[idx]; img != nil {
return img, nil
}
if o.raw.Sprites[idx] == nil {
if err := o.raw.LoadSprite(idx); err != nil {
return nil, err
}
}
stdImg := o.raw.Sprites[idx].ToImage()
img, err := ebiten.NewImageFromImage(stdImg, ebiten.FilterDefault)
if err != nil {
return nil, err
}
o.images[idx] = img
return img, nil
}