00001 /*************************************************************************** 00002 * * 00003 * (c) Art Tevs, MPI Informatik Saarbruecken * 00004 * mailto: <tevs@mpi-sb.mpg.de> * 00005 * * 00006 * This program is free software; you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation; either version 2 of the License, or * 00009 * (at your option) any later version. * 00010 * * 00011 ***************************************************************************/ 00012 00013 00014 #ifndef _NR_I_RESOURCE__H_ 00015 #define _NR_I_RESOURCE__H_ 00016 00017 00018 //---------------------------------------------------------------------------------- 00019 // Includes 00020 //---------------------------------------------------------------------------------- 00021 #include "Prerequisities.h" 00022 #include "ResourceSystem.h" 00023 #include <boost/enable_shared_from_this.hpp> 00024 00025 namespace nrEngine{ 00026 00027 //! General interface to hold any kind of resources 00028 /** 00029 * This is an interface which is describing how resource classes should looks like. 00030 * Derive your own classes to get resource management system working. Each 00031 * resource containing only once in the memory if it has the same name. So all 00032 * names of resources should be unique. Resource is not directly stored by the 00033 * manager but by the ResourceHolder. This holder just stores the resource 00034 * and is unique for each resource. Manager just manages such holders and 00035 * gives the resource pointers access to it. 00036 * 00037 * All derived classes must implement the behavior of resource objects correctly. 00038 * Correct behavior of resource objects is done if resources do nothing what can 00039 * change the empty resource behavior if they are empty. For example if you use texture 00040 * and user is setting some values to it and it is at the moment unloaded, so the method 00041 * will be called by the empty texture object. Empty texture object should stay empty and 00042 * therefor there should not be any changes. So texture object has to check whenever it is 00043 * an empty resource and should not do anything. 00044 * 00045 * The empty flag should be set by the loader, because only the loader does know 00046 * if and when a resource can be defined as empty. For example you have to load the empty 00047 * resource texture before you declare this resource as empty. 00048 * 00049 * \ingroup resource 00050 **/ 00051 class _NRExport IResource : public boost::enable_shared_from_this<IResource>{ 00052 public: 00053 00054 /** 00055 * Here the class should return count of bytes reserved 00056 * by the resource. The size must not contain the size of the class itself. 00057 * For example: 32Bit Texture of 16x16 Pixel has the size: 16*16*4 = 1024 Bytes + 00058 * some more bytes which does class need to store himself in the memory. 00059 **/ 00060 NR_FORCEINLINE std::size_t getResourceDataSize(){return mResDataSize;} 00061 00062 00063 /** 00064 * Return here the name of the resource type. This name will be used 00065 * to assign right empty resources to the resource pointer/holder objects. 00066 * E.g: "Texture", "Sound", ... 00067 **/ 00068 NR_FORCEINLINE const std::string& getResourceType() const { return mResType; } 00069 00070 00071 /** 00072 * Return true if the resource is marked as loaded. If any resource is loaded 00073 * so it contains in the memory and has it's full data there. 00074 **/ 00075 NR_FORCEINLINE bool isResourceLoaded() const {return mResIsLoaded;} 00076 00077 /** 00078 * Return handle of this resource 00079 **/ 00080 NR_FORCEINLINE ResourceHandle getResourceHandle() const {return mResHandle;} 00081 00082 /** 00083 * Return group name to which one this resource belongs 00084 **/ 00085 NR_FORCEINLINE const std::string& getResourceGroup() const {return mResGroup;} 00086 00087 /** 00088 * Get the name of the resource 00089 **/ 00090 NR_FORCEINLINE const std::string& getResourceName() const {return mResName;} 00091 00092 /** 00093 * Get the file name from which one this resource can be restored or loaded 00094 **/ 00095 NR_FORCEINLINE const std::list<std::string>& getResourceFilenameList() const {return mResFileNames;} 00096 00097 /** 00098 * Returns true if this resource is a empty resource. Empty resources are used 00099 * to replace normal resources if they are unloaded. 00100 **/ 00101 NR_FORCEINLINE bool isResourceEmpty() {return mResIsEmpty;} 00102 00103 /** 00104 * Unload resource. The resource should overwrite the IResource::unloadResource() method 00105 * which will be called. The resource should know how to unload itself. 00106 * The resource owner (in this case loader) will be notified about unloading on success. 00107 **/ 00108 Result unload(); 00109 00110 /** 00111 * Reload resource if this was previously unloaded. Each resource should overwrite 00112 * IResource::reloadResource() method. Resource should know how to reload 00113 * itself if it was previously unloaded. Resource owner (in this case loader) will be notified 00114 * on success. 00115 * @note If resource was not unloaded before, so the IResource::unload() method 00116 * will be called before reloading. 00117 **/ 00118 Result reload(PropertyList* params = NULL); 00119 00120 /** 00121 * Remove resource. Removing resource through this method, meanse to 00122 * remove the resource from the loader and from the manager. After this method call 00123 * all resource pointers associated within this resource will point to the empty 00124 * resource. All shared instaces would also be removed. 00125 * 00126 * If you call this method through resource pointer, then nothing bad happens. If 00127 * you call it directly (i.e. YourResource* res; res->remove()), hten you are 00128 * responsible for deleting the pointer by yourself 00129 **/ 00130 Result remove(); 00131 00132 /** 00133 * Add resource file name. The filename is used to associated the resource with. 00134 * If a resource is build upon of a multiple files, then all the files should 00135 * be added through this method. 00136 * @param filename Filename of a file associated with the resource 00137 **/ 00138 void addResourceFilename(const std::string& filename); 00139 00140 /** 00141 * @see addResourceFilename(const std::string& filename) 00142 * @param flist List of filenames to add 00143 **/ 00144 void addResourceFilename(const std::list<std::string>& flist); 00145 00146 /** 00147 * Set resource file name list. This method will replace the current 00148 * filename list with the given one. 00149 * @param flist List of filenames 00150 **/ 00151 void setResourceFilename(const std::list<std::string>& flist); 00152 00153 /** 00154 * Set the resource as dirty. If resource is marked as dirty, then it 00155 * will be reloaded on next access. 00156 * @param dirty True to mark resource as dirty otherwise false. 00157 * @note After the resource is reloaded it will be unmarked 00158 **/ 00159 NR_FORCEINLINE void setResourceDirty(bool dirty) { mResIsDirty = dirty; } 00160 00161 /** 00162 * Check whenever a resource is dirty. Dirty resources require 00163 * reloading as soon as possible (i.e. on next access) 00164 **/ 00165 NR_FORCEINLINE bool isResourceDirty() { return mResIsDirty; } 00166 00167 protected: 00168 00169 /** 00170 * Create resource instance. 00171 **/ 00172 IResource(const std::string& resourceType); 00173 00174 /** 00175 * As soon as this destructor is called, the resource manager will be notified. 00176 * 00177 * You have to call the unloadResource() method if you have some specific unloading 00178 * routines for your resource object. We can not call this from here, because 00179 * calling of virtual functions from constructor/destructor cause in 00180 * undefined behaviour. 00181 **/ 00182 virtual ~IResource(); 00183 00184 /** 00185 * Unload the resource. Each resource should know how to unload it from 00186 * the memory. Unloading does not remove the resource it just unload used 00187 * data from memory. To remove the resource from memory you have either 00188 * to use ResourceManager or the ResourceLoader. 00189 * 00190 **/ 00191 virtual Result unloadResource() = 0; 00192 00193 /** 00194 * Reload resource. Each resource object should be able to reload itself 00195 * from the disk or other media. It can use the assigned loader to load files 00196 * or to make it by itself. At the end the resource should be marked as loaded. 00197 * 00198 **/ 00199 virtual Result reloadResource(PropertyList* params = NULL) = 0; 00200 00201 00202 /** 00203 * Mark a resource as loaded. This method will not call the reloadResource() 00204 * method. Instead it will just mark this resource as it were loaded, 00205 * so you get access to real resource object through the pointers instead 00206 * of emtpy resource. Call this method if you create a resource by your 00207 * own without loading by loader. 00208 **/ 00209 NR_FORCEINLINE void markResourceLoaded() { mResIsLoaded = true; mResIsDirty = false; } 00210 00211 /** 00212 * Mark the resource as unloaded. When you mark it, then empty resource 00213 * will be used instead. 00214 **/ 00215 NR_FORCEINLINE void markResourceUnloaded() { mResIsLoaded = false; } 00216 00217 //! Get resource loader assigned with the resource 00218 NR_FORCEINLINE SharedPtr<IResourceLoader> getResourceLoader() { return mResLoader; } 00219 00220 private: 00221 00222 //! Only loader can change resource data 00223 friend class IResourceLoader; 00224 00225 //! Also resource manager is a friend 00226 friend class ResourceManager; 00227 00228 //! Shows whenever resource is loaded (is in the memory) 00229 bool mResIsLoaded; 00230 00231 //! If true so this is a empty resource 00232 bool mResIsEmpty; 00233 00234 //! Resource's loader with which one it was created 00235 SharedPtr<IResourceLoader> mResLoader; 00236 00237 //! Handle of the resource given from manager 00238 ResourceHandle mResHandle; 00239 00240 //! File associated with the resource 00241 std::list<std::string> mResFileNames; 00242 00243 //! Count of bytes that this resource is occupies in the memory 00244 std::size_t mResDataSize; 00245 00246 //! Name of the resource type 00247 std::string mResType; 00248 00249 //! Group name to which one this resource own 00250 std::string mResGroup; 00251 00252 //! Name of the resource 00253 std::string mResName; 00254 00255 //! Set this variable to reload the resource on next access 00256 bool mResIsDirty; 00257 00258 /** 00259 * Set the resource type for this resource. 00260 * Method is declared as protected, so only engine can do this. 00261 * 00262 * @param type Name of the resource type 00263 **/ 00264 NR_FORCEINLINE void setResourceType(const std::string& type) { mResType = type; } 00265 00266 /** 00267 * Get shared pointer from this class 00268 **/ 00269 SharedPtr<IResource> getSharedPtrFromThis() 00270 { 00271 return shared_from_this(); 00272 } 00273 00274 class _deleter{ 00275 public: 00276 void operator()(IResource* p) { delete p; } 00277 }; 00278 }; 00279 00280 }; 00281 00282 #endif