X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fmoof%2Fresource.hh;h=41dfd61ac11d5ab3bbd94262fcf58c543183181f;hp=5f1a71ab41e366596ef890f26806fd9f4d097173;hb=574af38ed616d1adfa5e6ce35f67cda1f707f89d;hpb=382626aad0a683ed8642a6a807eea743db45f7f8 diff --git a/src/moof/resource.hh b/src/moof/resource.hh index 5f1a71a..41dfd61 100644 --- a/src/moof/resource.hh +++ b/src/moof/resource.hh @@ -1,13 +1,11 @@ -/*] Copyright (c) 2009-2010, Charles McGarvey [************************** +/*] Copyright (c) 2009-2011, Charles McGarvey [***************************** **] All rights reserved. * -* vi:ts=4 sw=4 tw=75 -* * Distributable under the terms and conditions of the 2-clause BSD license; * see the file COPYING for a complete text of the license. * -**************************************************************************/ +*****************************************************************************/ #ifndef _MOOF_RESOURCE_HH_ #define _MOOF_RESOURCE_HH_ @@ -17,9 +15,6 @@ * Interface for textures, sounds, and other types of resources. */ -#include "config.h" - -#include #include #include #include @@ -37,7 +32,6 @@ namespace moof { class resource; typedef boost::shared_ptr resource_ptr; - /** * Generic resource class capable of containing any type of resource, * providing a type-safe interface. @@ -46,38 +40,31 @@ class resource { public: - // FIXME: this won't be necessary once the existing code is modified to - // use the resource handles - resource() {} - /** * Add a directory to search when looking for resource files. * \param paths A colon-separated list of directory paths. */ - static void add_search_paths(const std::string& paths); - + static void set_search_paths(const std::string& paths); /** - * Get the path to a resource of a given name. - * \param path The name of the resource to find. Upon successful - * return, this is changed to an absolute path to the resource. - * \return True if a path to a resource was found, false otherwise. + * Get the path to a resource of a given name. This uses the search + * path(s) and resources prefixes to locate resource files. + * \param name The name or partial path of the resource to find. + * \return The full path of the resource. */ - static bool find(const std::string& file); - static std::string find_file(const std::string& name); /** - * Get the path to a resource of a given name and open it if a resource - * was found. - * \param path The name of the resource to find. Upon successful - * return, this is changed to an absolute path to the resource. - * \param mode The open mode. - * \return The FILE* if the resource was found, 0 otherwise. + * Get the path to a resource of a given name and explicit type. This + * uses the search path(s) and resources prefixes to locate resource + * files. + * \param name The name or partial path of the resource to find. + * \param ext The extension is appended to the name if the same + * extension is not already a part of name. + * \return The full path of the resource. */ - static FILE* open_file(const std::string& path, - const std::string& mode = "rb"); - + static std::string + find_file(const std::string& name, const std::string& ext); /** * Register a type with the extension of files which this type can @@ -86,50 +73,42 @@ public: * \param extension The file extension. */ template - static void register_type(const std::string& extension) + static void register_type(const std::string& extension, + const std::string& prefix = "") { - //if (!type_lookup_) type_lookup_ = type_lookup_ptr(new type_lookup); - loader_ptr loader(new specific_loader); - //(*type_lookup_)[extension] = loader; - //type_lookup_[extension] = loader; - manage_loader(extension, loader, true); + loader_ptr loader(new specific_loader(prefix)); + call_registry(extension, loader, set); } /** * Unregister the type associated with a file extension. Resources of * this type will no longer be loadable, although resources which are * already loaded will remain loaded. - * \param extension The file extension + * \param extension The file extension. */ static void unregister_type(const std::string& extension) { - //type_lookup_.erase(extension); - //type_lookup_->erase(extension); loader_ptr loader; - manage_loader(extension, loader, true); + call_registry(extension, loader, set); } - - static resource_ptr load(const std::string& path); - - static resource_ptr reload(std::string& path); - - /** - * Construct a resource container. - * \param ptr A pointer to the underlying resource data. + * Find and load a resource by name or path. + * \param name The name or partial path of the resource. This should + * include the extension so that the correct loader can be chosen. + * \return The resource. */ - template - explicit resource(T* ptr) : - resource_(ptr), - typeinfo_(const_cast(&typeid(T))), - unloader_(new specific_unloader(ptr)) {} + static resource_ptr load(const std::string& name); /** - * Deconstruct a resource container. + * Find and load a resource by name or path. + * \param name The name or partial path of the resource. This should + * include the extension so that the correct loader can be chosen. + * \param + * \return The resource. */ - virtual ~resource(); - + static resource_ptr + load(const std::string& name, const std::string& ext); /** * Reload the resource data. This will cause the resource file to be @@ -137,6 +116,21 @@ public: */ void reload(); + /** + * Get the path of file from which this resource was loaded. + * \return The path. + */ + std::string path() const + { + return path_; + } + + /** + * Reloads some resources which have been modified on disk since they + * were loaded. Hotloading must have been enabled at compile-time. + * \return The number of resources reloaded. + */ + static int reload_as_needed(); /** * Get whether or not the type of the underlying resource data matches @@ -161,29 +155,45 @@ public: return 0; } - /** - * Reloads some resources which have been modified on disk since they - * were loaded. Hotloading must have been enabled at compile-time. - * \return The number of resources reloaded. + * Deconstruct a resource container. */ - static int reload_as_needed(); + virtual ~resource(); - static void print_types(); +private: + template + explicit resource(T* ptr) : + resource_(ptr), + typeinfo_(const_cast(&typeid(T))), + unloader_(new specific_unloader(ptr)), + wd_(-1) {} -private: + static resource_ptr + load_with_path(const std::string& path, const std::string& extension); class loader { public: + loader(const std::string& prefix) : + prefix_(prefix) {} + virtual ~loader() {} virtual resource* load(const std::string& path) { return 0; } + + const std::string& prefix() const + { + return prefix_; + } + + private: + + std::string prefix_; }; typedef boost::shared_ptr loader_ptr; @@ -193,14 +203,15 @@ private: { public: + specific_loader(const std::string& prefix) : + loader(prefix) {} + virtual resource* load(const std::string& path) { - log_info("loading resource of type ", typeid(T).name()); return new resource(new T(path)); } }; - class unloader { public: @@ -220,46 +231,29 @@ private: virtual ~specific_unloader() { - log_info("unloading resource of type ", typeid(T).name()); delete object_; } - private: T* object_; }; - - void set_loader(const std::string& path, loader_ptr loader) + enum registry_action { - path_ = path; - loader_ = loader; - } + lookup, + set + }; + static bool call_registry(const std::string& extension, + loader_ptr& loader, registry_action action); - void* resource_; + void* resource_; std::type_info* typeinfo_; unloader_ptr unloader_; - - std::string path_; - loader_ptr loader_; - - typedef std::map type_lookup; - //typedef boost::shared_ptr type_lookup_ptr; - //static type_lookup_ptr type_lookup_; - //static type_lookup type_lookup_; - - static void manage_loader(const std::string& extension, loader_ptr& loader, bool set = false); - -#ifdef USE_HOTLOADING - int wd_; - - void set_watch_descriptor(int wd) - { - wd_ = wd; - } -#endif + int wd_; + std::string path_; + std::string type_; }; @@ -285,9 +279,11 @@ public: resource_handle(resource_ptr ptr) : resource_(ptr) {} - explicit resource_handle(const std::string& path) : - resource_(resource::load(path)) {} + explicit resource_handle(const std::string& name) : + resource_(resource::load(name)) {} + resource_handle(const std::string& name, const std::string& ext) : + resource_(resource::load(name, ext)) {} /** * Get whether or not the handle is dereferenceable to the type of this @@ -302,7 +298,6 @@ public: return resource_->check(); } - /** * Get a pointer to the underlying resource. * \return The pointer, or null if this handle is not dereferenceable. @@ -324,7 +319,6 @@ public: return *(resource_->get()); } - /** * Same as get() for getting a pointer to the underlying resources. * \return The pointer, or null if this handle is not dereferenceable. @@ -344,12 +338,35 @@ public: return get_reference(); } + /** + * Unload the resource associated with this handle. + */ + void unload() + { + resource_ = resource_ptr(); + } private: resource_ptr resource_; }; +/** + * This macro easily registers types to act as resources. It should be + * used in a module file in global scope. + * \param TYPE The type (class), qualified as needed for the scope. + * \param EXT The file extension the resource uses. + * \param PREFIX The path prefix where a resource of this type could be. + */ +#define MOOF_REGISTER_RESOURCE(TYPE, EXT, PREFIX) \ +namespace { \ + struct EXT { \ + EXT() { moof::resource::register_type(#EXT, #PREFIX); } \ + ~EXT() { moof::resource::unregister_type(#EXT); } \ + }; \ + static EXT EXT; \ +} + } // namespace moof