diff --git a/res.go b/res.go new file mode 100644 index 0000000..e79059e --- /dev/null +++ b/res.go @@ -0,0 +1,212 @@ +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) +}