source: nrEngine/include/ResourceLoader.h @ 15

Revision 15, 13.6 KB checked in by art, 13 years ago (diff)
Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13
14#ifndef _NR_RESOURCE_LOADER_H_
15#define _NR_RESOURCE_LOADER_H_
16
17
18//----------------------------------------------------------------------------------
19// Includes
20//----------------------------------------------------------------------------------
21#include "Prerequisities.h"
22#include "ResourceSystem.h"
23#include <boost/enable_shared_from_this.hpp>
24
25namespace nrEngine{
26
27       
28        //! Resource loader interface for loading different resources
29        /**
30        * This is an interface which has to be implemented by each resource loader.
31        * A resource loader is an object which can load different kind of resources
32        * from different kind of files. For example there can be a image loader
33        * which can load PNG, DDS, TGA, .. images and this one can be used to load
34        * texture resources. In this case you can derive resource loader classes for
35        * different filetypes from your texture resource loader class or just use
36        * image loading functions for different types.
37        *
38        * Resource loader can be registered by the resource manager. After it is
39        * registered it will be automaticly used to load files of different types.
40        * If there is no loader registered for that type, so file will not be loaded,
41        * error will occurs and empty resource will be used.
42        *
43        * Each loader has also to support creating/loading of empty resources.
44        * By creating of an empty resource it's holder will not hold any resource.
45        * After you loading the resource it will be initialized with the resource data
46        * and with the empty resource.
47        *
48        * If you have files that are also resources but are not supported by the nrEngine
49        * you can derive a loader class from this interface. Then register the object,
50        * created from this derived class, by the resource manager and this class will
51        * automaticly used for such kind of resources. This is something like a plugin
52        * system on compiling layer/level.
53        *
54        * The resource loader has also to support creating of resource instances.
55        * Because we are using only one resource manager for any
56        * kind of resources, we have somewhere to create the instance with
57        * <code>IResource* res = new Resource()</code>. We can not use templates
58        * in the resource manager, because nothing will be compiled into the finale
59        * library file. So you will not be able to use new resource types.
60        * This loader also helps us to solve this problem by creating an instance of
61        * such a resource object for our resource database.
62        *
63        * Each loader has a method which says to the manager what kind of resource types
64        * it supports. By creating of a resource, you should specify the type of to be
65        * created resource. Manager will look in the database, wich loader can create an instance
66        * of such a type and will force such a loader to create an instance.
67        *
68        * Because only loader does know how to load/unload or create/delete resources
69        * in/from the memory so it has the full access on the resources. If you remove
70        * any loader, so all associated resources will be also removed from the memory.
71        * We need this behaviour also to prevent seg faults by using loaders from plugins,
72        * which does own own memory.
73        *
74        * @note File types are case sensitive. So *.png and *.PNG are different file types.
75        *
76        * \ingroup resource
77        **/
78        class _NRExport IResourceLoader : public boost::enable_shared_from_this<IResourceLoader>{
79                public:
80                       
81                        /**
82                         * Removing resource loader from the memory, will also remove
83                         * all loaded objects with this loader.
84                        **/
85                        virtual ~IResourceLoader();
86                               
87                        /**
88                         * This method should create and load a resource from file. The resource does
89                         * know its filename.
90                         *
91                         * @param name Unique name for the resource
92                         * @param group Unique group name for this resource
93                         * @param fileName Name of the file containing the resource
94                         * @param resourceType Unique type name of the resource [optional]
95                         * @param param Define load specific name value pairs. Derived classes
96                         *                              should know how to handle them. [optional]
97                         *
98                         * @return either OK or an error code
99                        **/
100                        SharedPtr<IResource> load(const std::string& name, const std::string& group, const std::string& fileName, const std::string& resourceType = std::string(), PropertyList* param = NULL);
101                                       
102                        /**
103                         * Create an instance of appropriate resource object. Like <code>new ResourceType()</code>
104                         *
105                         * @param resourceType Unique name of the resource type to be created
106                         * @param params Default is NULL, so no parameters. Specify here pairs of string that
107                         *                              represents the parameters for the creating functions. The derived
108                         *                              resource loader should know how to handle with them.
109                         * @return Instance of such a resource
110                         *
111                         * NOTE: If a new type of resource will be created, so also a new empty resource
112                         * object will be created of this type. This will be automaticaly registered by the manager.
113                         **/
114                        SharedPtr<IResource> create(const std::string& resourceType, PropertyList* params = NULL);
115
116                        /**
117                         * Same as create() but here you can specify the name of the resource. If
118                         * the name is specified, so the resource will be automaticaly registered
119                         * by the resource manager. Also loader will check if such a resource
120                         * already exists.
121                         **/
122                        SharedPtr<IResource> create(const std::string& name, const std::string& group, const std::string& resourceType, PropertyList* params = NULL);
123
124                        /**
125                        * This method should return a vector of strings containing information about
126                        * which kind of resource instances can this loader create. Each resource has it's
127                        * unique resource type name. So this vector contains such names.
128                        **/
129                        NR_FORCEINLINE const std::vector<std::string>& getSupportedResourceTypes(){return mSupportedResourceTypes;}
130                       
131                        /**
132                         * This function will return a vector containing information about supported filetypes.
133                         * It means that this loader can load each file of such a filetype.
134                         **/
135                        NR_FORCEINLINE const std::vector<std::string>& getSupportedFileTypes(){return mSupportedFileTypes;}
136                       
137                        /**
138                        * This method will say if this loader does support creating of resource of the given
139                        * resource type.
140                        *
141                        * @param resourceType Unique name of the resource type
142                        * @return <b>true</b> if this loader can create instances of such a type, false otherwise
143                        **/
144                        bool supportResourceType(const std::string& resourceType) const;
145
146                        /**
147                        * This method will say if this loader does support loading of resource of the given
148                        * file type.
149                        *
150                        * @param fileType File type name
151                        * @return <b>true</b> if this loader can load such files, false otherwise
152                        **/
153                        bool supportFileType(const std::string& fileType) const ;
154
155                        /**
156                         * Unload the given resource. Unloading of a resource does not mean that the
157                         * resource is removed from the memory. It just release almost all used
158                         * memory and an empty resource will be used instead. To remove it completly
159                         * from the memory call remove() instead.
160                         *
161                         * This method will be called by the manager or the resource, as soon as a resource must
162                         * be unloaded.
163                         **/
164                        Result unload(SharedPtr<IResource> resource);
165
166                        /**
167                         * Remove the resource from the memory. This method will be called
168                         * by the resource manager, so the loader can do the stuff needed
169                         * to remove the resource.
170                         **/
171                        Result remove(SharedPtr<IResource> resource);
172
173                        /**
174                         * Reload a certain resource again. A resource object has to be created before.
175                         * If the resource object is loaded, so it will be unloaded and loaded again. Also
176                         * the resource object will be notified about this event, so it can react on this.
177                         * No new instancies will be created.
178                         **/
179                        Result reload(SharedPtr<IResource> resource);
180
181
182                protected:
183
184                        /**
185                         * Unload a certain resource from the memory.
186                         * To unload a resource the IResource::unloadRes() method will be called. Herefor
187                         * each resource should know how to release it's data. However you can overwrite
188                         * this method in derived classes to change this default behaviour.
189                         *
190                         * @param res Pointer to the resource which should be unloaded
191                         *
192                         **/
193                        virtual Result unloadResourceImpl(IResource*);
194
195                        /**
196                         * Each derived class has to implement a bahaviour of reloading
197                         * of a resource. This method will be called to reload a given
198                         * resource object from the file again. All according data is already
199                         * stored in the resource only the data from the file must be reloaded.
200                         *
201                         * The default behaviour of this method is to call loadImpl() again
202                         * with the given resource object and a file name (as user parameters the
203                         * NULL will be passed).
204                         **/
205                        virtual Result reloadResourceImpl(IResource*);
206                       
207                        /**
208                         * Derived classes must overload this function. This method
209                         * should load a resource for a given file name
210                         *
211                         * @param res Resource instance created before with create()
212                         * @param fileName Name of the file containing the resource
213                         * @param param Specific parameters specified by the user
214                         **/
215                        virtual Result loadResourceImpl(IResource* res, const std::string& fileName, PropertyList* param = NULL) = 0;
216
217                        /**
218                         * Implement this function to provide functionaliy
219                         * of creating resources of certain types. In this function you do not
220                         * have to check whenever the given resourceType string is valid. This
221                         * method can only be called from the base class, which does already
222                         * have checked this.
223                         *
224                         **/
225                        virtual IResource* createResourceImpl(const std::string& resourceType, PropertyList* params = NULL) = 0;
226                       
227                        /**
228                         * Creating of an empty resource object. An empty resource object can be used in
229                         * normal way but contains no data.
230                         *
231                         * @param resourceType Unique name of the resource type to be created
232                         * @return Instance of empty resource
233                         **/
234                        virtual IResource* createEmptyResource(const std::string& resourceType) = 0;
235                       
236                        /**
237                         * Call this function to initilize the loader. Usually initialization of the
238                         * loader does declare supported file and resource types. So because this function
239                         * is pure virtual it must overloaded by derived classes.
240                         *
241                         * This method should be called from the constructor, to declare supported types.
242                         **/
243                        virtual Result initializeResourceLoader() = 0;
244                       
245                        /**
246                         *
247                         **/
248                        IResourceLoader(const std::string& name);
249
250                        /**
251                        * Map a certain file type to the resource type. Call this method if
252                        * you want to find out resources of which types will be created
253                        * if you use this filetype.
254                        *
255                        * @param fileType Type of the file (ending *.so, *.bmp, ...)
256                        * @return resource type name which will be create for this file type. If
257                        *                       the given file type is not supported empty string will be given back
258                        **/
259                        NR_FORCEINLINE std::string mapFileTypeToResourceType(const std::string& fileType)
260                        {
261                                std::map<std::string, std::string>::const_iterator it = mTypeMap.find(fileType);
262                                if (it == mTypeMap.end()) return std::string();
263                                return it->second;
264                        }
265                                               
266                        /**
267                        * Declare the mapping of file types to resource types.
268                        * NOTE: You have to specify supported types before
269                        **/
270                        NR_FORCEINLINE void declareTypeMap(const std::string& fileType, const std::string& resourceType)
271                        {
272                                if (supportResourceType(resourceType) && supportFileType(fileType))
273                                        mTypeMap[fileType] = resourceType;
274                        }
275                       
276                        /**
277                        * Internal function which must be called by all derived classes to
278                        * setup all supported resource types.
279                        * @param name Unique name of supported resource type
280                        */
281                        NR_FORCEINLINE void declareSupportedResourceType(const std::string& name){
282                                mSupportedResourceTypes.push_back(name);
283                        }
284       
285                        /**
286                        * Internal function which must be called by all derived classes to
287                        * setup all supported file types.
288                        * @param name Unique name of file type which is supported by the derived loader
289                        */
290                        NR_FORCEINLINE void declareSupportedFileType(const std::string& name)
291                        {
292                                mSupportedFileTypes.push_back(name);
293                        }
294                       
295                private:
296                       
297                        //! List of supported resource types
298                        std::vector< std::string >              mSupportedResourceTypes;
299
300                        //! List of supported file types
301                        std::vector< std::string >              mSupportedFileTypes;
302
303                        //! Mapping from file type to resource type
304                        std::map<std::string, std::string> mTypeMap;
305
306                        //! Unuque name of the loader
307                        std::string mName;
308
309                        typedef std::list< SharedPtr<IResource> >  ResourceList;
310                       
311                        //! List of resources managed by this loader
312                        ResourceList mHandledResources;
313
314                        /**
315                         * Get shared pointer from this class
316                         **/   
317                        SharedPtr<IResourceLoader> getSharedPtrFromThis()
318                        {
319                                return shared_from_this();
320                        }
321
322                        /**
323                         * Notify the resource loader that a certain resource object
324                         * will be removed from the memory now.
325                         **/
326                        void notifyRemoveResource(SharedPtr<IResource>);
327
328                        /**
329                         * Notify unload resource. The method can be called either
330                         * from resource manager or by the resource itself
331                         **/
332                        void notifyUnloadResource(SharedPtr<IResource>);
333                       
334        };
335
336};
337
338#endif
Note: See TracBrowser for help on using the repository browser.