ichigo/engine/imageref.go

62 lines
1.4 KiB
Go
Raw Normal View History

2021-08-26 11:33:58 +10:00
package engine
import (
"encoding/gob"
"image"
"io/fs"
"github.com/hajimehoshi/ebiten/v2"
)
var (
imageCache = make(map[assetKey]*ebiten.Image)
// Ensure types satisfy interfaces.
_ Loader = &ImageRef{}
)
func init() {
2021-09-03 09:13:12 +10:00
gob.Register(&ImageRef{})
2021-08-26 11:33:58 +10:00
}
2021-08-26 11:35:15 +10:00
// ImageRef loads images from the AssetFS into *ebiten.Image form. It is your
// responsibility to import _ "image/..." for whatever format the files are in,
// and to load it (either return it as a subcomponent from Scan so that Game
// will Load it, or call Load yourself).
2021-08-26 11:33:58 +10:00
type ImageRef struct {
Path string
image *ebiten.Image
}
2021-08-26 11:35:15 +10:00
// Image returns the image, or nil if not loaded. Multiple distinct ImageRefs
// can use the same path efficiently.
2021-08-26 11:33:58 +10:00
func (r *ImageRef) Image() *ebiten.Image {
return r.image
}
2021-08-26 11:35:15 +10:00
// Load loads the image. Load is required before Image returns. Loading the same
// path multiple times uses a cache to return the same image.
2021-08-26 11:33:58 +10:00
func (r *ImageRef) Load(assets fs.FS) error {
// Fast path load from cache
r.image = imageCache[assetKey{assets, r.Path}]
if r.image != nil {
return nil
}
// Slow path
f, err := assets.Open(r.Path)
if err != nil {
return err
}
defer f.Close()
i, _, err := image.Decode(f)
if err != nil {
return err
}
r.image = ebiten.NewImageFromImage(i)
imageCache[assetKey{assets, r.Path}] = r.image
return nil
}
2021-09-23 14:17:18 +10:00
func (r *ImageRef) String() string { return "ImageRef{" + r.Path + "}" }