source: nrEngine/src/ResourceLoader.cpp @ 27

Revision 27, 12.2 KB checked in by art, 12 years ago (diff)

nrScript: using of subscripts is now possible

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//----------------------------------------------------------------------------------
15// Includes
16//----------------------------------------------------------------------------------
17#include "ResourceLoader.h"
18#include "Log.h"
19#include "Exception.h"
20#include "Engine.h"
21#include "ResourceManager.h"
22
23namespace nrEngine{
24
25        //----------------------------------------------------------------------------------
26        IResourceLoader::IResourceLoader(const std::string& name) : mName(name)
27        {
28
29        }
30
31        //----------------------------------------------------------------------------------
32        IResourceLoader::~IResourceLoader()
33        {
34                // copy the list in another list, so we can iterate and remove them
35                std::vector<SharedPtr<IResource> > lst;
36                for (ResourceList::iterator it = mHandledResources.begin(); it != mHandledResources.end(); it ++)
37                        lst.push_back(*it);
38
39                // now go through the vector and remove elements
40                for (uint32 i=0; i < lst.size(); i++)
41                        remove(lst[i]);
42        }
43
44        //----------------------------------------------------------------------------------
45        SharedPtr<IResource> IResourceLoader::load(const std::string& name, const std::string& group, const std::string& fileName, const std::string& resourceType, PropertyList* param)
46        {
47                // check if a such resource already registered by the manager
48                if (Engine::sResourceManager()->isResourceRegistered(name))
49                {
50                        NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceLoader: You are trying to load resource %s which is already loaded.", name.c_str());
51                        return SharedPtr<IResource>();
52                }
53
54                bool typeFound = false;
55                std::string type;
56
57                // we search for the type if no type is specified
58                if (resourceType.length() == 0){
59                        NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceLoader \"%s\" try to find according resource type by filename \"%s\"", mName.c_str(), fileName.c_str(), fileName.c_str());
60
61                        // detect the file type by reading out it's last characters
62                        for (int32 i = fileName.length()-1; i >= 0 && !typeFound; i--){
63                                if ((char)fileName[i] == '.'){
64                                        typeFound = true;
65                                }
66                                if (!typeFound) type = (char)fileName[i] + type;
67                        }
68                        if (!typeFound) type = "";
69
70                        // check whenever the given file name is supported by the resource
71                        if (typeFound && !supportFileType(type))
72                        {
73                                NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceLoader \"%s\" can not load file of type \".%s\", because the type is not supported", mName.c_str(), type.c_str());
74                                return SharedPtr<IResource>();
75                        }
76
77                        // if no type was specified so give up
78                        if (!typeFound){
79                                NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceLoader %s neither resource type nor valid file ending was found, give up!", mName.c_str());
80                                return SharedPtr<IResource>();
81                        }
82                }
83
84                // ok the name is supported, so now create a instance
85                SharedPtr<IResource> res;
86                if (resourceType.length() == 0){
87                        res = create(mapFileTypeToResourceType(type), param);
88                }else{
89                        res = create(resourceType, param);
90                }
91                if (res.get() == NULL) return res;
92
93                // setup some data on resource
94                res->mResFileName = fileName;
95                res->mResName = name;
96                res->mResGroup = group;
97
98                // now call the implemented loading function
99                if (loadResourceImpl(res.get(), fileName, param) != OK)
100                {
101                        NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceLoader %s can not load resource from file %s", mName.c_str(), fileName.c_str());
102                        remove(res);
103                        return SharedPtr<IResource>();
104                }
105                res->mResIsLoaded = true;
106
107                // now notify the resource manager, that a new resource was loaded
108                Engine::sResourceManager()->notifyLoaded(res.get());
109
110                return res;
111        }
112
113        //----------------------------------------------------------------------------------
114        SharedPtr<IResource> IResourceLoader::create(const std::string& resourceType, PropertyList* params)
115        {
116                NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceLoader: Create resource of type %s", resourceType.c_str());
117
118                // first check if this type of resource is supported
119                if (!supportResourceType(resourceType))
120                {
121                        NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceLoader %s does not support resources of type %s", mName.c_str(), resourceType.c_str());
122                        return SharedPtr<IResource>();
123                }
124
125                // now call the implemented function to create the resource
126                SharedPtr<IResource> res (createResourceImpl(resourceType, params), IResource::_deleter());
127
128                // check if the result is valid, then add it into our database
129                if (res.get() == NULL) return SharedPtr<IResource>();
130
131                // now check if we have to create an empty resource for this type
132                SharedPtr<IResource> empty = Engine::sResourceManager()->getEmpty(resourceType);
133
134                // if not created before, so create it and register by the manager
135                if (empty == NULL)
136                {
137                        empty.reset( createEmptyResource(resourceType), IResource::_deleter() );
138                        empty->mResGroup = "_Empty_Resource_Group_";
139                        empty->mResName = "_Empty_" + resourceType;
140                        empty->mResHandle = Engine::sResourceManager()->getNewHandle();
141                        empty->mResIsEmpty = true;
142                        empty->mResLoader = getSharedPtrFromThis();
143                        empty->setResourceType(resourceType);
144                }
145
146                // set the resource in the manager
147                Engine::sResourceManager()->setEmpty(resourceType, empty);
148
149                // setup default resource data
150                res->setResourceType(resourceType);
151                res->mResHandle = Engine::sResourceManager()->getNewHandle();
152                res->mResIsEmpty = false;
153                res->mResLoader = getSharedPtrFromThis();
154
155                // now set this resource in the list of handled resource objects
156                mHandledResources.push_back(res);
157
158                // ok now return the instance
159                return res;
160        }
161
162        //----------------------------------------------------------------------------------
163        SharedPtr<IResource> IResourceLoader::create(const std::string& name, const std::string& group, const std::string& resourceType, PropertyList* params)
164        {
165                // first check if this type of resource is supported
166                if (!supportResourceType(resourceType))
167                {
168                        NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceLoader %s does not support resources of type %s", mName.c_str(), resourceType.c_str());
169                        return SharedPtr<IResource>();
170                }
171
172                // now check if such a resource is already in the database
173                IResourcePtr res = Engine::sResourceManager()->getByName(name);
174                if (!res.isNull()){
175                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "You are trying to create a resource %s of type %s which is already in the database", name.c_str(), resourceType.c_str());
176                        return SharedPtr<IResource>();
177                }
178
179                // ok now create the resource
180                SharedPtr<IResource> r = create(resourceType, params);
181                if (r.get() == NULL) return SharedPtr<IResource>();
182
183                // setup values
184                r->mResName = name;
185                r->mResGroup = group;
186
187                // now let manager know about the new resource
188                Engine::sResourceManager()->notifyCreated(r.get());
189
190                return r;
191        }
192
193        //----------------------------------------------------------------------------------
194        Result IResourceLoader::unload(SharedPtr<IResource> resource)
195        {
196                // empty resource could not be unloaded
197                if (resource.get() == NULL) return OK;
198
199                // call the implementation of the unloader
200                if (resource->mResIsLoaded){
201
202                        Result ret = unloadResourceImpl(resource.get());
203                        if (ret != OK) return ret;
204
205                        // now mark the resource that it has been unloaded
206                        resource->mResIsLoaded = false;
207
208                        // notify the resource manager about unloading the resource
209                        Engine::sResourceManager()->notifyUnloaded(resource.get());
210                }
211
212                return OK;
213        }
214
215        //----------------------------------------------------------------------------------
216        Result IResourceLoader::reload(SharedPtr<IResource> resource)
217        {
218                // check if we are the handler for this resource
219                if (std::find(mHandledResources.begin(), mHandledResources.end(), resource) == mHandledResources.end()){
220                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceLoader: You are trying to reload resource %s not handled by this loader %s", resource->getResName().c_str(), mName.c_str());
221                        return OK;
222                }
223
224                // unload the resource
225                unload(resource);
226
227                // call the implementation of the unloader
228                if (resource->mResIsLoaded == false)
229                {
230
231                        Result ret = reloadResourceImpl(resource.get());
232                        if (ret != OK) return ret;
233
234                        // now mark the resource that it has been unloaded
235                        resource->mResIsLoaded = true;
236
237                        // notify the resource manager about unloading the resource
238                        Engine::sResourceManager()->notifyLoaded(resource.get());
239                }
240
241                return OK;
242        }
243
244        //----------------------------------------------------------------------------------
245        Result IResourceLoader::remove(SharedPtr<IResource> resource)
246        {
247                // remove only valid resources
248                if (resource.get() == NULL) return OK;
249
250                // emove only handled resources
251                if (std::find(mHandledResources.begin(), mHandledResources.end(), resource) == mHandledResources.end())
252                {
253                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceLoader: You are trying to remove resource %s not handled by this loader %s!", resource->getResName().c_str(), mName.c_str());
254                        return OK;
255                }
256
257                // unload
258                unload(resource);
259
260                // notify to remove the resource
261                notifyRemoveResource(resource);
262
263                // reset the resource, so it gets deleted, if it is not referenced elsewhere
264                resource.reset();
265
266                return OK;
267        }
268
269        //----------------------------------------------------------------------------------
270        void IResourceLoader::notifyRemoveResource(SharedPtr<IResource> res)
271        {
272                ResourceList::iterator resit = std::find(mHandledResources.begin(), mHandledResources.end(), res);
273
274                // check if such resource is loaded
275                if (resit != mHandledResources.end() ){
276
277                        // ok remove the resource from the handled resources
278                        mHandledResources.erase(resit);
279
280                        // notify the manager about removing the resource
281                        Engine::sResourceManager()->notifyRemove(res.get());
282                }
283        }
284
285        //----------------------------------------------------------------------------------
286        void IResourceLoader::notifyUnloadResource(SharedPtr<IResource> res)
287        {
288                if (res == NULL) return;
289                if (std::find(mHandledResources.begin(), mHandledResources.end(), res) != mHandledResources.end() && res->mResIsLoaded){
290                        Engine::sResourceManager()->notifyUnloaded(res.get());
291                }
292        }
293
294        //----------------------------------------------------------------------------------
295        Result IResourceLoader::unloadResourceImpl(IResource* res)
296        {
297                if (res == NULL) return OK;
298                if (res->mResIsLoaded) return res->unloadRes();
299                return OK;
300        }
301
302        //----------------------------------------------------------------------------------
303        Result IResourceLoader::reloadResourceImpl(IResource* res)
304        {
305                if (res == NULL) return OK;
306                /*Result ret = loadResourceImpl(res, res->getResFileName(), NULL);
307                if (ret != OK){
308                        NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceLoader %s can not load resource from file %s", mName.c_str(), res->getResFileName().c_str());
309                        return ret;
310                }*/
311                if (res->mResIsLoaded == false) res->reloadRes();
312                //res->mResIsLoaded = true;
313
314                // now notify the resource manager, that a new resource was loaded
315                //Engine::sResourceManager()->notifyLoaded(res);
316
317                return OK;
318        }
319
320        //----------------------------------------------------------------------------------
321        bool IResourceLoader::supportResourceType(const std::string& resourceType) const {
322                std::vector<std::string>::const_iterator it;
323                for (it = mSupportedResourceTypes.begin(); it != mSupportedResourceTypes.end(); it++){
324                        if ((*it) == resourceType) return true;
325                }
326                return false;
327        }
328
329        //----------------------------------------------------------------------------------
330        bool IResourceLoader::supportFileType(const std::string& fileType) const {
331                std::vector<std::string>::const_iterator it;
332                for (it = mSupportedFileTypes.begin(); it != mSupportedFileTypes.end(); it++){
333                        if ((*it) == fileType) {
334                                return true;
335                        }
336                }
337                return false;
338        }
339
340};
341
Note: See TracBrowser for help on using the repository browser.