Files
questshock/modding/hacked/ss1/content/bitmap/PaletteCache.go
T

68 lines
1.8 KiB
Go

package bitmap
import (
"github.com/inkyblackness/hacked/ss1/resource"
"github.com/inkyblackness/hacked/ss1/serial"
)
// PaletteCache retrieves palettes from a localizer and keeps them decoded until they are invalidated.
type PaletteCache struct {
localizer resource.Localizer
defaultPalette Palette
palettes map[resource.Key]Palette
}
// NewPaletteCache returns a new instance.
func NewPaletteCache(localizer resource.Localizer) *PaletteCache {
cache := &PaletteCache{
localizer: localizer,
palettes: make(map[resource.Key]Palette),
}
for i := 0; i < len(cache.defaultPalette); i++ {
col := &cache.defaultPalette[i]
col.Red = uint8(i)
col.Green = uint8(i)
col.Blue = uint8(i)
}
return cache
}
// InvalidateResources lets the cache remove any palettes from resources that are specified in the given slice.
func (cache *PaletteCache) InvalidateResources(ids []resource.ID) {
for _, id := range ids {
for key := range cache.palettes {
if key.ID == id {
delete(cache.palettes, key)
}
}
}
}
// Palette tries to look up given palette.
func (cache *PaletteCache) Palette(key resource.Key) (pal Palette, err error) {
pal, existing := cache.palettes[key]
if existing {
return pal, nil
}
selector := cache.localizer.LocalizedResources(key.Lang)
view, err := selector.Select(key.ID)
if err != nil {
return cache.defaultPalette, err
}
if (view.ContentType() != resource.Palette) || (view.BlockCount() != 1) {
return cache.defaultPalette, resource.ErrWrongType(key, resource.Palette)
}
reader, err := view.Block(0)
if err != nil {
return cache.defaultPalette, err
}
decoder := serial.NewDecoder(reader)
decoder.Code(&pal)
if decoder.FirstError() != nil {
return cache.defaultPalette, decoder.FirstError()
}
cache.palettes[key] = pal
return pal, nil
}