ResourceLoader.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_RESOURCE_LOADER_H_
00015 #define _NR_RESOURCE_LOADER_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         
00028         //! Interface for loading/creating resources
00029         /**
00030         * This is an interface which has to be implemented by each resource loader.
00031         * A resource loader is an object which can load different kind of resources
00032         * from different kind of files. For example there can be a image loader
00033         * which can load PNG, DDS, TGA, .. images and this one can be used to load
00034         * texture resources. In this case you can derive resource loader classes for
00035         * different filetypes from your texture resource loader class or just use
00036         * image loading functions for different types.
00037         *
00038         * Resource loader should be registered by the resource manager. After it is
00039         * registered it will be automaticly used to load files of different types.
00040         * If there is no loader registered for that type, so file will not be loaded,
00041         * error will occurs and empty resource will be used.
00042         *
00043         * Each loader has also to support creating/loading of empty resources.
00044         * By creating of an empty resource it's holder will not hold any resource.
00045         * After you loading the resource it will be initialized with the resource data
00046         * and with the empty resource.
00047         *
00048         * Each loader has a method which says to the manager what kind of resource types
00049         * it supports. By creating of a resource, you should specify the type of to be 
00050         * created resource. Manager will look in the database, wich loader can create an instance
00051         * of such a type and will force such a loader to create an instance.
00052         *
00053         * Because only loader does know how to load/unload or create/delete resources
00054         * in/from the memory so it has the full access on the resources. If you remove
00055         * any loader, so all associated resources will be also removed from the memory.
00056         * We need this behaviour also to prevent seg faults by using loaders from plugins,
00057         * which does own own memory.
00058         * 
00059         * @note File types and resource types are case sensitive. So *.png and *.PNG are different file types.
00060         *
00061         * \ingroup resource
00062         **/
00063         class _NRExport IResourceLoader : public boost::enable_shared_from_this<IResourceLoader>{
00064                 public:
00065                         
00066                         /**
00067                          * Removing resource loader from the memory, will also remove
00068                          * all loaded objects with this loader.
00069                         **/
00070                         virtual ~IResourceLoader();
00071                                 
00072                         /**
00073                          * This method should create and load a resource from file. The resource does
00074                          * know its filename.
00075                          *
00076                          * @param name Unique name for the resource
00077                          * @param group Unique group name for this resource
00078                          * @param fileName Name of the file containing the resource
00079                          * @param resourceType Unique type name of the resource [optional]
00080                          * @param param Define load specific name value pairs. Derived classes
00081                          *                              should know how to handle them. [optional]
00082                          * 
00083                          * @return either OK or an error code
00084                         **/
00085                         SharedPtr<IResource> load(const std::string& name, const std::string& group, const std::string& fileName, const std::string& resourceType = std::string(), PropertyList* param = NULL);
00086 
00087                         /**
00088                          * Create an instance of appropriate resource object. Like <code>new ResourceType()</code>
00089                          *
00090                          * @param name Unique name of the resource
00091                          * @param group Unique group name for the resource
00092                          * @param resourceType Unique name of the resource type to be created
00093                          * @param params Default is NULL, so no parameters. Specify here pairs of string that
00094                          *                              represents the parameters for the creating functions. The derived
00095                          *                              resource loader should know how to handle with them.
00096                          * @return Instance of such a resource
00097                          *
00098                          * NOTE: If a new type of resource will be created, so also a new empty resource
00099                          * object will be created of this type. This will be automaticaly registered by the manager.
00100                          **/
00101                         SharedPtr<IResource> create(const std::string& name, const std::string& group, const std::string& resourceType, PropertyList* params = NULL);
00102 
00103                         /**
00104                         * This method should return a vector of strings containing information about
00105                         * which kind of resource instances can this loader create. Each resource has it's
00106                         * unique resource type name. So this vector contains such names.
00107                         **/
00108                         NR_FORCEINLINE const std::vector<std::string>& getSupportedResourceTypes(){return mSupportedResourceTypes;}
00109                         
00110                         /**
00111                          * This function will return a vector containing information about supported filetypes.
00112                          * It means that this loader can load each file of such a filetype.
00113                          **/
00114                         NR_FORCEINLINE const std::vector<std::string>& getSupportedFileTypes(){return mSupportedFileTypes;}
00115                         
00116                         /**
00117                         * This method will say if this loader does support creating of resource of the given
00118                         * resource type.
00119                         * 
00120                         * @param resourceType Unique name of the resource type
00121                         * @return <b>true</b> if this loader can create instances of such a type, false otherwise
00122                         **/
00123                         bool supportResourceType(const std::string& resourceType) const;
00124 
00125                         /**
00126                         * This method will say if this loader does support loading of resource of the given
00127                         * file type.
00128                         * 
00129                         * @param fileType File type name 
00130                         * @return <b>true</b> if this loader can load such files, false otherwise
00131                         **/
00132                         bool supportFileType(const std::string& fileType) const ;
00133 
00134 #if 0
00135                         /**
00136                          * Unload the given resource. Unloading of a resource does not mean that the
00137                          * resource is removed from the memory. It just release almost all used
00138                          * memory and an empty resource will be used instead. To remove it completly
00139                          * from the memory call remove() instead.
00140                          *
00141                          * This method will be called by the manager or the resource, as soon as a resource must
00142                          * be unloaded.
00143                          **/
00144                         Result unload(SharedPtr<IResource> resource);
00145 
00146                         /**
00147                          * Reload a certain resource again. A resource object has to be created before.
00148                          * If the resource object is loaded, so it will be unloaded and loaded again. Also
00149                          * the resource object will be notified about this event, so it can react on this.
00150                          * No new instancies will be created.
00151                          **/
00152                         Result reload(SharedPtr<IResource> resource);
00153 #endif
00154                         /**
00155                          * Remove the resource from the memory. This method will be called
00156                          * by the resource manager, so the loader can do the stuff needed
00157                          * to remove the resource.
00158                          **/
00159                         Result remove(SharedPtr<IResource> resource);
00160 
00161                 protected:
00162 #if 0
00163                         /**
00164                          * Unload a certain resource from the memory.
00165                          * To unload a resource the IResource::unloadRes() method will be called. Herefor
00166                          * each resource should know how to release it's data. However you can overwrite
00167                          * this method in derived classes to change this default behaviour.
00168                          * 
00169                          * @param res Pointer to the resource which should be unloaded
00170                          *
00171                          **/
00172                         virtual Result unloadResourceImpl(IResource* res);
00173 
00174                         /**
00175                          * Each derived class has to implement a bahaviour of reloading
00176                          * of a resource. This method will be called to reload a given
00177                          * resource object from the file again. All according data is already
00178                          * stored in the resource only the data from the file must be reloaded.
00179                          *
00180                          * The default behaviour of this method is to call loadImpl() again
00181                          * with the given resource object and a file name (as user parameters the
00182                          * NULL will be passed).
00183                          * @param res Resource to be reloaded
00184                          **/
00185                         virtual Result reloadResourceImpl(IResource* res);
00186 #endif                  
00187                         /**
00188                          * Derived classes must overload this function. This method
00189                          * should load a resource for a given file name
00190                          *
00191                          * @param res Resource instance created before with create()
00192                          * @param fileName Name of the file containing the resource
00193                          * @param param Specific parameters specified by the user
00194                          **/
00195                         virtual Result loadResource(IResource* res, const std::string& fileName, PropertyList* param = NULL) = 0;
00196 
00197                         /**
00198                          * Implement this function to provide functionaliy
00199                          * of creating resources of certain types. In this function you do not
00200                          * have to check whenever the given resourceType string is valid. This
00201                          * method can only be called from the base class, which does already
00202                          * have checked this.
00203                          * @param resourceType Type of the resource
00204                          * @param params Parameter list which can be passed for creating
00205                          **/
00206                         virtual IResource* createResource(const std::string& resourceType, PropertyList* params = NULL) = 0;
00207                         
00208                         /**
00209                          * Creating of an empty resource object. An empty resource object can be used in
00210                          * normal way but contains no data.
00211                          *
00212                          * @param resourceType Unique name of the resource type to be created
00213                          * @return Instance of empty resource
00214                          **/
00215                         virtual IResource* createEmptyResource(const std::string& resourceType) = 0;
00216                         
00217                         /**
00218                          * Call this function to initilize the loader. Usually initialization of the
00219                          * loader does declare supported file and resource types. So because this function
00220                          * is pure virtual it must overloaded by derived classes.
00221                          *
00222                          * This method should be called from the constructor, to declare supported types.
00223                          **/
00224                         virtual Result initializeResourceLoader() = 0;
00225                         
00226                         /**
00227                          * Create instance of the resource loader.
00228                          * @param name Unique name of the loader
00229                          **/
00230                         IResourceLoader(const std::string& name);
00231 
00232                         /**
00233                         * Map a certain file type to the resource type. Call this method if
00234                         * you want to find out resources of which types will be created
00235                         * if you use this filetype.
00236                         *
00237                         * @param fileType Type of the file (ending *.so, *.bmp, ...)
00238                         * @return resource type name which will be create for this file type. If
00239                         *                       the given file type is not supported empty string will be given back
00240                         **/
00241                         NR_FORCEINLINE std::string mapFileTypeToResourceType(const std::string& fileType)
00242                         {
00243                                 std::map<std::string, std::string>::const_iterator it = mTypeMap.find(fileType);
00244                                 if (it == mTypeMap.end()) return std::string();
00245                                 return it->second;
00246                         }
00247                                                 
00248                         /**
00249                         * Declare the mapping of file types to resource types.
00250                         * NOTE: You have to specify supported types before
00251                         **/
00252                         NR_FORCEINLINE void declareTypeMap(const std::string& fileType, const std::string& resourceType)
00253                         {
00254                                 if (supportResourceType(resourceType) && supportFileType(fileType))
00255                                         mTypeMap[fileType] = resourceType;
00256                         }
00257                         
00258                         /**
00259                         * Internal function which must be called by all derived classes to 
00260                         * setup all supported resource types.
00261                         * @param name Unique name of supported resource type
00262                         */
00263                         NR_FORCEINLINE void declareSupportedResourceType(const std::string& name){
00264                                 mSupportedResourceTypes.push_back(name);
00265                         }
00266         
00267                         /**
00268                         * Internal function which must be called by all derived classes to 
00269                         * setup all supported file types.
00270                         * @param name Unique name of file type which is supported by the derived loader
00271                         */
00272                         NR_FORCEINLINE void declareSupportedFileType(const std::string& name)
00273                         {
00274                                 mSupportedFileTypes.push_back(name);
00275                         }
00276                         
00277 #if 0
00278                         /**
00279                          * This method will return back a proper suffix according to the resource type.
00280                          * Derived classes should overwrite this method, because they know which suffix 
00281                          * are proper to use. The suffix does not contain dot. Empty suffixes are possible.
00282                          * @param resType Resource type for which one suffix is generated
00283                          **/
00284                         virtual std::string getSuffix(const std::string& resType){return std::string();}
00285 #endif
00286                         /**
00287                          * Notify the resource loader that a certain resource object
00288                          * will be now removed from the memory. The method should be called,
00289                          * by the resource manager, to notify the loader.
00290                          **/
00291                         void notifyRemoveResource(SharedPtr<IResource>);
00292 
00293 #if 0
00294                         /**
00295                         * Resource will notify the loader that it has been reloaded through
00296                         * this method. Resource loader should
00297                          **/
00298                         void notifyUnloadResource(SharedPtr<IResource>);
00299 #endif
00300 
00301                 private:
00302 
00303                         //! Resource manager can access the methods here
00304                         friend class ResourceManager;
00305                         
00306                         //! List of supported resource types
00307                         std::vector< std::string >              mSupportedResourceTypes;
00308 
00309                         //! List of supported file types
00310                         std::vector< std::string >              mSupportedFileTypes;
00311 
00312                         //! Mapping from file type to resource type
00313                         std::map<std::string, std::string> mTypeMap;
00314 
00315                         //! Unuque name of the loader
00316                         std::string mName;
00317 
00318                         typedef std::list< SharedPtr<IResource> >  ResourceList;
00319                         
00320                         //! List of resources managed by this loader
00321                         ResourceList mHandledResources;
00322 
00323                                         
00324                         /**
00325                          * Create an instance of appropriate resource object. 
00326                          **/
00327                         SharedPtr<IResource> create(const std::string& resourceType, PropertyList* params = NULL);
00328 
00329                         /**
00330                          * Get shared pointer from this class
00331                          **/    
00332                         SharedPtr<IResourceLoader> getSharedPtrFromThis()
00333                         {
00334                                 return shared_from_this();
00335                         }
00336 
00337 #if 0
00338                         /**
00339                          * Notify unload resource. The method can be called either
00340                          * from resource manager or by the resource itself
00341                          **/
00342                         void notifyUnloadResource(SharedPtr<IResource>);
00343 #endif
00344         };
00345 
00346 };
00347 
00348 #endif

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