source: nrEngine/include/ResourceLoader.h @ 1

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