Files
go-game/res.go

213 lines
4.0 KiB
Go

package goga
import (
"errors"
"io/ioutil"
"path/filepath"
"strings"
)
// A generic resource.
// Must be cast to appropriate type.
// The name is the file name and must be unique.
type Res struct {
name string
path string
ext string
}
// Returns the file name of actual resource.
func (r *Res) GetName() string {
return r.name
}
// Returns the file path (as passed in) of actual resource.
func (r *Res) GetPath() string {
return r.path
}
// Returns the file extension of actual resource.
func (r *Res) GetExt() string {
return r.ext
}
// Resource loader interface.
// The loader accepts files by file extension.
// and loads them if accepted.
type ResLoader interface {
Load(string) (*Res, error)
Ext() string
}
var (
resloader []ResLoader
resources []*Res
)
// Adds a loader.
// If a loader with the same file extension exists already, false will be returned.
func AddLoader(loader ResLoader) bool {
ext := strings.ToLower(loader.Ext())
for _, l := range resloader {
if strings.ToLower(l.Ext()) == ext {
return false
}
}
resloader = append(resloader, loader)
return true
}
// Removes a loader.
// Returns false if loader could not be found.
func RemoveLoader(loader ResLoader) bool {
for i, l := range resloader {
if l == loader {
resloader = append(resloader[:i], resloader[i+1:]...)
return true
}
}
return false
}
// Removes a loader by file extension.
// Returns false if loader could not be found.
func RemoveLoaderByExt(ext string) bool {
ext = strings.ToLower(ext)
for i, l := range resloader {
if strings.ToLower(l.Ext()) == ext {
resloader = append(resloader[:i], resloader[i+1:]...)
return true
}
}
return false
}
// Removes all loaders.
func RemoveAllLoaders() {
resloader = make([]ResLoader, 0)
}
// Returns a loader by file extension.
// If not found, nil will be returned.
func GetLoaderByExt(ext string) ResLoader {
ext = strings.ToLower(ext)
for _, l := range resloader {
if strings.ToLower(l.Ext()) == ext {
return l
}
}
return nil
}
// Loads a resource by file path.
// If no loader is present for given file, an error will be returned.
// If the loader fails to load the resource, an error will be returned.
func LoadRes(path string) (*Res, error) {
ext := filepath.Ext(path)
loader := GetLoaderByExt(ext)
if loader == nil {
return nil, errors.New("No loader available for file extension " + ext)
}
res, err := loader.Load(path)
if err != nil {
return nil, err
}
for _, r := range resources {
if r.name == res.name {
return nil, errors.New("Resource with file name " + res.name + " exists already")
}
}
resources = append(resources, res)
return res, nil
}
// Loads all files from given folder path.
// If a loader is missing or fails to load the resource, an error will be returned.
// All resources will be kept until an error occures.
func LoadResFromFolder(path string) error {
dir, err := ioutil.ReadDir(path)
if err != nil {
return err
}
for _, file := range dir {
if file.IsDir() {
continue
}
if _, err := LoadRes(filepath.Join(path, file.Name())); err != nil {
return err
}
}
return nil
}
// Returns a resource by name or nil, if not found.
func GetResByName(name string) *Res {
for _, r := range resources {
if r.name == name {
return r
}
}
return nil
}
// Returns a resource by path or nil, if not found.
func GetResByPath(path string) *Res {
for _, r := range resources {
if r.path == path {
return r
}
}
return nil
}
// Removes a resource by name.
// Returns false if resource could not be found.
func RemoveResByName(name string) bool {
for i, r := range resources {
if r.name == name {
resources = append(resources[:i], resources[i+1:]...)
return true
}
}
return false
}
// Removes a resource by path.
// Returns false if resource could not be found.
func RemoveResByPath(path string) bool {
for i, r := range resources {
if r.path == path {
resources = append(resources[:i], resources[i+1:]...)
return true
}
}
return false
}
// Removes all resources.
func RemoveAllRes() {
resources = make([]*Res, 0)
}