Resource.h

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

Generated on Wed Sep 12 23:19:42 2007 for nrEngine by  doxygen 1.5.1