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

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