Adding modding folder with a hacked build.
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
package text
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/inkyblackness/hacked/ss1/resource"
|
||||
)
|
||||
|
||||
type keyResolver func(resource.Key) resource.Key
|
||||
type textReader func(resource.Selector, resource.Key, Codepage) (string, error)
|
||||
|
||||
// Cache retrieves texts from a localizer and keeps them decoded until they are invalidated.
|
||||
type Cache struct {
|
||||
cp Codepage
|
||||
localizer resource.Localizer
|
||||
reader textReader
|
||||
|
||||
keyResolver keyResolver
|
||||
texts map[resource.Key]string
|
||||
}
|
||||
|
||||
func newCache(cp Codepage, localizer resource.Localizer, keyResolver keyResolver, reader textReader) *Cache {
|
||||
cache := &Cache{
|
||||
cp: cp,
|
||||
localizer: localizer,
|
||||
reader: reader,
|
||||
|
||||
keyResolver: keyResolver,
|
||||
texts: make(map[resource.Key]string),
|
||||
}
|
||||
return cache
|
||||
}
|
||||
|
||||
// NewLineCache returns a cache for single-block texts.
|
||||
func NewLineCache(cp Codepage, localizer resource.Localizer) *Cache {
|
||||
return newCache(cp, localizer, func(key resource.Key) resource.Key { return key }, readLine)
|
||||
}
|
||||
|
||||
// NewPageCache returns a cache for resource-based texts.
|
||||
func NewPageCache(cp Codepage, localizer resource.Localizer) *Cache {
|
||||
return newCache(cp, localizer, func(key resource.Key) resource.Key {
|
||||
return resource.KeyOf(key.ID.Plus(key.Index), key.Lang, 0)
|
||||
}, readPage)
|
||||
}
|
||||
|
||||
func readLine(selector resource.Selector, key resource.Key, cp Codepage) (string, error) {
|
||||
view, err := selector.Select(key.ID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if view.ContentType() != resource.Text {
|
||||
return "", resource.ErrWrongType(key, resource.Text)
|
||||
}
|
||||
reader, err := view.Block(key.Index)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
raw, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return cp.Decode(raw), nil
|
||||
}
|
||||
|
||||
func readPage(selector resource.Selector, key resource.Key, cp Codepage) (string, error) {
|
||||
view, err := selector.Select(key.ID.Plus(key.Index))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if view.ContentType() != resource.Text {
|
||||
return "", resource.ErrWrongType(key, resource.Text)
|
||||
}
|
||||
blockCount := view.BlockCount()
|
||||
value := ""
|
||||
for block := 0; block < blockCount; block++ {
|
||||
reader, err := view.Block(block)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
raw, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
value += cp.Decode(raw)
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// InvalidateResources lets the cache remove any texts from resources that are specified in the given slice.
|
||||
func (cache *Cache) InvalidateResources(ids []resource.ID) {
|
||||
for _, id := range ids {
|
||||
for key := range cache.texts {
|
||||
if key.ID == id {
|
||||
delete(cache.texts, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Text retrieves and caches the text of given key.
|
||||
func (cache *Cache) Text(key resource.Key) (string, error) {
|
||||
cacheKey := cache.keyResolver(key)
|
||||
value, existing := cache.texts[cacheKey]
|
||||
if existing {
|
||||
return value, nil
|
||||
}
|
||||
selector := cache.localizer.LocalizedResources(key.Lang)
|
||||
value, err := cache.reader(selector, key, cache.cp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
cache.texts[cacheKey] = value
|
||||
return value, nil
|
||||
}
|
||||
Reference in New Issue
Block a user