source: nrEngine/src/ResourceManager.cpp @ 1

Revision 1, 28.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// Includes
15//----------------------------------------------------------------------------------
16#include "ResourceManager.h"
17#include "Log.h"
18#include "Exception.h"
19#include "Engine.h"
20
21namespace nrEngine{
22
23        //----------------------------------------------------------------------------------
24        ScriptFunctionDec(scriptLoadResource, ResourceManager)
25        {
26                // check parameter count
27                if (args.size() < 3){
28                        return ScriptResult(std::string("Not valid parameter count! Parameters (name,group,filename [,type])"));
29                }
30
31                std::string type;
32                if (args.size() == 5 ) type = args[4];
33               
34                // load a resource with the given name in a group from a file
35                if (Engine::sResourceManager()->loadResource(args[1], args[2], args[3], type).isNull())
36                {
37                        char msg[128];
38                        sprintf(msg, "There was an error by loading a resource %s from %s", args[1].c_str(), args[3].c_str());
39                        return ScriptResult(std::string(msg));
40                }
41               
42                return ScriptResult();
43        }
44
45        //----------------------------------------------------------------------------------
46        ScriptFunctionDec(scriptUnloadResource, ResourceManager)
47        {
48                // check parameter count
49                if (args.size() < 1){
50                        return ScriptResult(std::string("Not valid parameter count! You should specify (name)"));
51                }
52
53                // unload resource and check for return code
54                if (Engine::sResourceManager()->unload(args[1]) != OK)
55                {
56                        char msg[128];
57                        sprintf(msg, "Could not unload %s", args[1].c_str());
58                        return ScriptResult(std::string(msg));
59                }
60               
61                return ScriptResult();
62        }
63
64        //----------------------------------------------------------------------------------
65        ResourceManager::ResourceManager(){
66                mLastHandle = 1;
67
68                // register functions by scripting engine
69                Engine::sScriptEngine()->add("loadResource", scriptLoadResource);
70                Engine::sScriptEngine()->add("unloadResource", scriptUnloadResource);
71               
72        }
73
74
75        //----------------------------------------------------------------------------------
76        ResourceManager::~ResourceManager(){
77
78                // remove registered functions
79                Engine::sScriptEngine()->del("loadResource");
80                Engine::sScriptEngine()->del("unloadResource");
81               
82                // unload all resources
83                removeAllRes();
84
85                // remove all loaders
86                removeAllLoaders();
87
88        }
89
90        //----------------------------------------------------------------------------------
91        void ResourceManager::removeAllRes(){
92
93                // iterate through each resource and remove it
94                /*res_hdl_map::const_iterator it;
95
96                for (it = mResource.begin(); it != mResource.end(); it++){
97                        ResourceHandle hdl = it->first;
98                        remove(hdl);
99                }
100                mResource.clear();
101                */
102
103                // iterate through each empty resource and remove it
104                res_empty_map::iterator jt;
105
106                for (jt = mEmptyResource.begin(); jt != mEmptyResource.end(); jt++){
107                        SharedPtr<IResource>& res = jt->second;
108
109                        NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceManager: Remove empty resource of type %s", res->getResType().c_str());
110                        res.reset();
111                        mEmptyResource.erase(jt);
112                }
113                mEmptyResource.clear();
114
115        }
116
117        //----------------------------------------------------------------------------------
118        void ResourceManager::removeAllLoaders(){
119
120                // iterate through all loaders
121                loader_map::const_iterator it;
122
123                for (it = mLoader.begin(); it != mLoader.end(); it++){
124                        removeLoader(it->first);
125                }
126
127        }
128
129        //----------------------------------------------------------------------------------
130        /*Result ResourceManager::setMemoryBudget(size_t bytes){
131                mMemBudget = bytes;
132                return checkMemoryUsage();
133        }
134
135
136        //----------------------------------------------------------------------------------
137        size_t ResourceManager::getMemoryBudget() const{
138                return mMemBudget;
139        }
140
141        //----------------------------------------------------------------------------------
142        size_t ResourceManager::getMemoryUsage() const{
143                return mMemUsage;
144        }*/
145
146        //----------------------------------------------------------------------------------
147        Result ResourceManager::registerLoader(const ::std::string& name, ResourceLoader loader){
148
149                // check whenver such a loader already exists
150                if (mLoader.find(name) != mLoader.end()){
151                        NR_Log(Log::LOG_ENGINE, "ResourceManager: %s loader already registered", name.c_str());
152                        return RES_LOADER_ALREADY_EXISTS;
153                }
154
155                // check for bad parameters
156                if (loader == NULL || name.length() == 0){
157                        return BAD_PARAMETERS;
158                }
159
160                NR_Log(Log::LOG_ENGINE, "ResourceManager: Register new resource loader %s", name.c_str());
161
162                // register the loader
163                mLoader[name] = loader;
164
165                // Give some log information about supported filetypes and resource types
166                try{
167                        ::std::vector< ::std::string>::const_iterator it;
168                        ::std::string strTemp;
169
170                        const ::std::vector< ::std::string>&    fileTypes = loader->getSupportedFileTypes();
171                        for (it = fileTypes.begin(); it != fileTypes.end(); it++){
172                                strTemp += (*it) + " ";
173                        }
174                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Found loader \"%s\" for file types %s", name.c_str(), strTemp.c_str());
175                        strTemp = "";
176
177                        const ::std::vector< ::std::string>&    resTypes = loader->getSupportedResourceTypes();
178                        for (it = resTypes.begin(); it != resTypes.end(); it++){
179                                strTemp += (*it) + " ";
180                        }
181                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Found loader \"%s\" for resource types %s", name.c_str(), strTemp.c_str());
182                }catch(...){
183                        return BAD_PARAMETERS;
184                }
185
186                return OK;
187        }
188
189        //----------------------------------------------------------------------------------
190        Result ResourceManager::removeLoader(const ::std::string& name){
191
192                // get id of the loader
193                loader_map::const_iterator jt = mLoader.find(name);
194                if (jt == mLoader.end()){
195                        return RES_LOADER_NOT_REGISTERED;
196                }
197
198                NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove loader %s", name.c_str());
199
200                mLoader.erase(name);
201
202                return OK;
203        }
204
205        //----------------------------------------------------------------------------------
206        ResourceLoader ResourceManager::getLoaderByFile(const ::std::string& fileType){
207
208                if (fileType.length() == 0) return ResourceLoader();
209               
210                // scan through all loaders and ask them if they do support this kind of file type
211                loader_map::const_iterator it;
212
213                for (it = mLoader.begin(); it != mLoader.end(); it++){
214                        if (it->second->supportFileType(fileType)){
215                                return it->second;
216                        }
217                }
218
219                // Give some log information
220                NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceManager: There is no loader for *.%s files", fileType.c_str());
221
222                return ResourceLoader();
223        }
224
225        //----------------------------------------------------------------------------------
226        ResourceLoader ResourceManager::getLoader(const ::std::string& name){
227
228                loader_map::iterator it = mLoader.find(name);
229
230                if (it == mLoader.end()){
231                        return ResourceLoader();
232                }
233
234                return mLoader[name];
235        }
236
237        //----------------------------------------------------------------------------------
238        ResourceLoader ResourceManager::getLoaderByResource(const ::std::string& resType){
239
240                // scan through all loaders and ask them if they do support this kind of file type
241                loader_map::const_iterator it;
242
243                for (it = mLoader.begin(); it != mLoader.end(); it++){
244                        if (it->second->supportResourceType(resType)){
245                                return it->second;
246                        }
247                }
248
249                return ResourceLoader();
250
251        }
252
253        //----------------------------------------------------------------------------------
254        IResourcePtr ResourceManager::createResource (const std::string& name, const std::string& group, const std::string& resourceType, PropertyList* params)
255        {
256                NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceManager: Create resource %s of type %s in group %s", name.c_str(), resourceType.c_str(), group.c_str());
257               
258                // check if such a resource already exists
259                IResourcePtr pRes = getByName(name);
260                if (!pRes.isNull()){
261                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceManager: Can not create new resource %s of type %s because such already exists", name.c_str(), resourceType.c_str());
262                        return pRes;
263                }
264               
265                // Get appropriate loader/creator
266                ResourceLoader creator = getLoaderByResource(resourceType);
267                if (creator == NULL){
268                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not create a resource %s because there is no loader for %s resource type", name.c_str(), resourceType.c_str());
269                        return IResourcePtr();
270                }
271
272                // now call the loader to create a resource
273                IResource* res (creator->create(name, group, resourceType, params));
274                if (res == NULL){
275                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not create a resource %s of %s type", name.c_str(), resourceType.c_str());
276                        return IResourcePtr();
277                }
278
279                // get the holder for this resource, it must be there
280                SharedPtr<ResourceHolder>& holder = *getHolderByName(name);
281                NR_ASSERT(holder != NULL && "Holder must be valid here!");
282               
283                return IResourcePtr(holder);
284        }
285       
286
287        //----------------------------------------------------------------------------------
288        IResourcePtr ResourceManager::loadResource(
289                        const std::string& name,const std::string& group,const std::string& fileName,
290                        const std::string& resourceType,PropertyList* params,ResourceLoader loader)
291        {
292
293                NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceManager: Load resource %s of type %s from file %s", name.c_str(), resourceType.c_str(), fileName.c_str());
294
295                // check for right parameters
296                if (name.length() == 0 || fileName.length() == 0)
297                        return IResourcePtr();
298
299                // check whenever such a resource already exists
300                IResourcePtr pRes = getByName(name);
301                if (!pRes.isNull()){
302                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceManager: Resource %s already loaded. Do nothing.", name.c_str());
303                        return pRes;
304                }
305
306                // detect the file type by reading out it's last characters
307                std::string type;
308                for (int32 i = fileName.length()-1; i >= 0; i--){
309                        if (fileName[i] == '.'){
310                                break;
311                        }
312                        type = fileName[i] + type;
313                }
314                bool isManualSpecified = (loader != NULL);
315
316                // if the loader is manually specified, so do nothing
317                if (!isManualSpecified)
318                {
319                        loader = getLoaderByResource(resourceType);
320                        if (loader == NULL) loader = getLoaderByFile(type);
321
322                        if (loader == NULL){
323                                NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceManager: valid loader for resource %s was not found or no manual loader was specified, give up!", name.c_str());
324                                return IResourcePtr();
325                        }
326                }
327
328                // now call the loader to create a resource
329                // loader will notify the manager, manager will add it into database
330                IResource* res = loader->load(name, group, fileName, resourceType, params);
331                if (res == NULL) return IResourcePtr();
332               
333                // get the holder for this resource, it must be there
334                SharedPtr<ResourceHolder>& holder = *getHolderByName(name);
335                NR_ASSERT(holder.get() != NULL && "Holder must be valid here!");
336               
337                return IResourcePtr(holder);   
338        }
339       
340        //----------------------------------------------------------------------------------
341        Result ResourceManager::unload(const ::std::string& name){
342
343                ResourcePtr<IResource> res = getByName(name);
344
345                if (res.isNull()){
346                        return RES_NOT_FOUND;
347                }
348
349                lockPure(res);
350                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload resource %s",
351                                res->getResName().c_str(), res->getResHandle());
352                        Result ret = res->unloadResThroughLoader();
353                unlockPure(res);
354
355                return ret;
356        }
357
358        //----------------------------------------------------------------------------------
359        Result ResourceManager::unload(IResourcePtr& res){
360
361                if (res.isNull()){
362                        return RES_NOT_FOUND;
363                }
364
365                lockPure(res);
366                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload resource %s",
367                                res.getBase()->getResName().c_str(), res.getBase()->getResHandle());
368                        Result ret = res.getBase()->unloadResThroughLoader();
369                unlockPure(res);
370
371                return ret;
372        }
373
374        //----------------------------------------------------------------------------------
375        Result ResourceManager::unload(ResourceHandle& handle){
376
377                ResourcePtr<IResource> res = getByHandle(handle);
378
379                if (res.isNull()){
380                        return RES_NOT_FOUND;
381                }
382
383                lockPure(res);
384                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload resource %s",
385                                res->getResName().c_str(), res->getResHandle());
386                        Result ret = res->unloadResThroughLoader();
387                unlockPure(res);
388
389                return ret;
390        }
391
392        //----------------------------------------------------------------------------------
393        Result ResourceManager::reload(const ::std::string& name){
394
395                ResourcePtr<IResource> res = getByName(name);
396
397                if (res.isNull()){
398                        return RES_NOT_FOUND;
399                }
400
401                lockPure(res);
402                        NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceManager: Reload resource %s",
403                                res->getResName().c_str(), res->getResHandle());
404                        Result ret = res->reloadResThroughLoader();
405                unlockPure(res);
406
407                return ret;
408        }
409
410        //----------------------------------------------------------------------------------
411        Result ResourceManager::reload(ResourceHandle& handle){
412
413                ResourcePtr<IResource> res = getByHandle(handle);
414
415                if (res.isNull()){
416                        return RES_NOT_FOUND;
417                }
418
419                lockPure(res);
420                        NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceManager: Reload resource %s",
421                                res->getResName().c_str(), res->getResHandle());
422                        Result ret = res->reloadResThroughLoader();
423                unlockPure(res);
424
425                return ret;
426        }
427
428        //----------------------------------------------------------------------------------
429        Result ResourceManager::reload(IResourcePtr& res){
430
431                if (res.isNull()){
432                        return RES_NOT_FOUND;
433                }
434
435                lockPure(res);
436                        NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceManager: Reload resource %s",
437                                res.getBase()->getResName().c_str(), res.getBase()->getResHandle());
438                        Result ret = res.getBase()->reloadResThroughLoader();
439                unlockPure(res);
440
441                return ret;
442        }
443
444        //----------------------------------------------------------------------------------
445/*      Result ResourceManager::removeImpl(IResourcePtr& resPtr){
446
447                NR_ASSERT(!resPtr.isNull() && "Given pointer shouldn't be zero");
448
449                // we need to lock the resource, because we need the real resource object not empty
450                lockPure(resPtr);
451
452                        ResourcePtr<IResource> ptr = resPtr;
453                        ResourceHandle hdl = ptr->getResHandle();
454                        ::std::string name = ptr->getResName();
455                        ::std::string grp = ptr->getResGroup();
456
457                        if (hdl == 0){
458                                NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not remove resource %s because it is not in the database", name.c_str());
459                                return RES_NOT_FOUND;
460                        }
461
462                        // first unload it
463                        unload(resPtr);
464
465                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %s (%s)", name.c_str(), grp.c_str());
466
467                        // remove the handle from the group list
468                        if (grp.length() > 0){
469                                res_grp_map::iterator jt = mResourceGroup.find(grp);
470                                if (jt != mResourceGroup.end()){
471                                        jt->second.remove(hdl);
472
473                                        // check whenever group contains nomore elements, and delete it
474                                        if (jt->second.size() == 0){
475                                                mResourceGroup.erase(grp);
476                                                NR_Log(Log::LOG_ENGINE, "ResourceManager: %s's group \"%s\" does not contain elements, so remove it", name.c_str(), grp.c_str());
477                                        }
478                                }else{
479                                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceManager: There is no group in the database according to resource's group name \"%s\"", grp.c_str());
480                                }
481                        }
482
483                // unlock it back
484                unlockPure(resPtr);
485
486                // clear the database
487                mResourceName.erase(name);
488                mResource.erase(hdl);
489
490                return OK;
491        }
492*/
493        //----------------------------------------------------------------------------------
494        Result ResourceManager::remove(const ::std::string& name){
495
496                // check whenever such a resource exists
497                IResourcePtr ptr = getByName(name);
498
499                if (ptr.isNull()){
500                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %s not found", name.c_str());
501                        return RES_NOT_FOUND;
502                }
503
504                lockPure(ptr);
505                        Result ret = ptr.getBase()->removeResThroughLoader();
506                unlockPure(ptr);
507
508                return ret;
509        }
510
511        //----------------------------------------------------------------------------------
512        Result ResourceManager::remove(ResourceHandle& handle){
513
514                // check whenever such a resource exists
515                IResourcePtr ptr = getByHandle(handle);
516
517                if (ptr.isNull()){
518                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %d not found", handle);
519                        return RES_NOT_FOUND;
520                }
521
522                lockPure(ptr);
523                        Result ret = ptr.getBase()->removeResThroughLoader();
524                unlockPure(ptr);
525
526                return ret;
527        }
528
529        //----------------------------------------------------------------------------------
530        Result ResourceManager::remove(IResourcePtr& ptr){
531
532                // check whenever such a resource exists
533                if (!ptr.isNull()){
534                        lockPure(ptr);
535                                Result ret = ptr.getBase()->removeResThroughLoader();
536                        unlockPure(ptr);
537
538                        return ret;
539                }
540                return OK;
541        }
542
543        //----------------------------------------------------------------------------------
544        SharedPtr<ResourceHolder>* ResourceManager::getHolderByName(const ::std::string& name)
545        {
546                // find the handle
547                res_str_map::iterator it = mResourceName.find(name);
548                if (it == mResourceName.end()){
549                        return NULL;
550                }
551
552                // get through the handle the holder
553                res_hdl_map::iterator jt = mResource.find(it->second);
554                NR_ASSERT(jt != mResource.end() && "Fatal Error in the Database !!!");
555                return &(jt->second);
556        }
557
558        //----------------------------------------------------------------------------------
559        SharedPtr<ResourceHolder>* ResourceManager::getHolderByHandle(const ResourceHandle& handle)
560        {
561                // find through the handle
562                res_hdl_map::iterator it = mResource.find(handle);
563                if (it == mResource.end()){
564                        return NULL;
565                }
566                return &(it->second);
567        }
568
569        //----------------------------------------------------------------------------------
570        IResourcePtr ResourceManager::getByName(const ::std::string& name){
571                SharedPtr<ResourceHolder>* holder = getHolderByName(name);
572                if (holder == NULL){
573                        return IResourcePtr();
574                }
575
576                return IResourcePtr(*holder);
577        }
578
579        //----------------------------------------------------------------------------------
580        IResourcePtr ResourceManager::getByHandle(const ResourceHandle& handle){
581                SharedPtr<ResourceHolder>* holder = getHolderByHandle(handle);
582                if (holder == NULL){
583                        return IResourcePtr();
584                }
585                return IResourcePtr(*holder);
586        }
587
588        //----------------------------------------------------------------------------------
589/*      Result ResourceManager::add(IResource* res, const std::string& name, const std::string& group)
590        {
591
592                // check for bad parameters
593                if (res == NULL) return OK;
594                if (name.length() == 0) return BAD_PARAMETERS;
595                if (res->mResLoader == NULL) return RES_LOADER_NOT_EXISTS;
596
597                // check whenever such resource already exists
598                if (!getByName(name).isNull()){
599                        NR_Log(Log::LOG_ENGINE, "ResourceManager: WARNING: Add resource %s but it already exists", name.c_str());
600                        return OK;
601                }
602
603                ResourceHandle handle = mLastHandle++;
604                NR_Log(Log::LOG_ENGINE, "ResourceManager: Add resource %s id=%d to the database from outside", name.c_str(), handle);
605
606                // check now if a empty resource of that type already exists and load it if not
607                SharedPtr<IResource> empty;
608                checkEmptyResource(res->getResType(), empty, res->mResLoader);
609
610                // create a holder for that resource
611                SharedPtr<ResourceHolder> holder(new ResourceHolder());
612                holder->resetRes(res);
613                holder->setEmptyResource(empty);
614
615                // store the resource in database
616                mResourceGroup[group].push_back(handle);
617                mResource[handle] = holder;
618                mResourceName[name] = handle;
619
620                res->mResGroup = group;
621                res->mResName = name;
622                res->mResHandle = handle;
623                res->mParentManager = this;
624
625                // check for memory usage
626                mMemUsage += holder->getResource()->getResDataSize();
627                Result ret = checkMemoryUsage();
628
629                if (ret != OK){
630                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Could not rearrange memory");
631                        return ret;
632                }
633
634                // return a pointer to that resource
635                return OK;
636        }
637*/
638       
639        //----------------------------------------------------------------------------------
640        Result ResourceManager::lockPure(const ::std::string& name){
641
642                // get appropriate pointer
643                IResourcePtr ptr = getByName(name);
644
645                // if it is null, so we do not have such a resource
646                if (ptr.isNull()) return RES_NOT_FOUND;
647
648                return ptr.lockPure();
649        }
650
651        //----------------------------------------------------------------------------------
652        Result ResourceManager::lockPure(ResourceHandle& handle){
653
654                // get appropriate pointer
655                IResourcePtr ptr = getByHandle(handle);
656
657                // if it is null, so we do not have such a resource
658                if (ptr.isNull()) return RES_NOT_FOUND;
659
660                return ptr.lockPure();
661
662        }
663
664        //----------------------------------------------------------------------------------
665        Result ResourceManager::lockPure(IResourcePtr& res){
666
667                // lock through the pointer
668                return res.lockPure();
669
670        }
671
672        //----------------------------------------------------------------------------------
673        Result ResourceManager::unlockPure(const ::std::string& name){
674
675                // get appropriate holder
676                SharedPtr<ResourceHolder>* holder = getHolderByName(name);
677
678                if (holder != NULL){
679                        // lock the resource through the holder
680                        (*holder)->unlockPure();
681                }else{
682                        return RES_NOT_FOUND;
683                }
684
685                return OK;
686
687        }
688
689        //----------------------------------------------------------------------------------
690        Result ResourceManager::unlockPure(ResourceHandle& handle){
691
692                // get appropriate holder
693                SharedPtr<ResourceHolder>* holder = getHolderByHandle(handle);
694
695                if (holder != NULL){
696                        // lock the resource through the holder
697                        (*holder)->unlockPure();
698                }else{
699                        return RES_NOT_FOUND;
700                }
701
702                return OK;
703
704        }
705
706        //----------------------------------------------------------------------------------
707        Result ResourceManager::unlockPure(IResourcePtr& res){
708
709                // if pointer does not pointing anywhere
710                if (res.isNull()){
711                        return RES_ERROR;
712                }
713
714                // lock through the holder
715                res.getResourceHolder()->unlockPure();
716
717                return OK;
718        }
719
720        //----------------------------------------------------------------------------------
721        Result ResourceManager::unloadGroup(const ::std::string& group){
722
723                // check whenever such a group exists
724                res_grp_map::const_iterator it = mResourceGroup.find(group);
725                if (it == mResourceGroup.end()){
726                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not unload group \"%s\" because not found in database", group.c_str());
727                        return RES_GROUP_NOT_FOUND;
728                }
729
730                NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload the group \"%s\"", group.c_str());
731
732                // scan through all elements
733                ::std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
734                for (; jt != mResourceGroup[group].end(); jt++){
735                        Result ret = unload(*jt);
736                        if (ret != OK) return ret;
737                }
738
739                // OK
740                return OK;
741        }
742
743        //----------------------------------------------------------------------------------
744        Result ResourceManager::reloadGroup(const ::std::string& group){
745
746                // check whenever such a group exists
747                res_grp_map::const_iterator it = mResourceGroup.find(group);
748                if (it == mResourceGroup.end()){
749                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not reload group \"%s\" because not found in database", group.c_str());
750                        return RES_GROUP_NOT_FOUND;
751                }
752
753                NR_Log(Log::LOG_ENGINE, "ResourceManager: Reload the group \"%s\"", group.c_str());
754
755                // scan through all elements
756                ::std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
757                for (; jt != mResourceGroup[group].end(); jt++){
758                        Result ret = reload(*jt);
759                        if (ret != OK) return ret;
760                }
761
762                // OK
763                return OK;
764
765        }
766
767        //----------------------------------------------------------------------------------
768        Result ResourceManager::removeGroup(const ::std::string& group){
769
770                // check whenever such a group exists
771                res_grp_map::const_iterator it = mResourceGroup.find(group);
772                if (it == mResourceGroup.end()){
773                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not remove group \"%s\" because not found in database", group.c_str());
774                        return RES_GROUP_NOT_FOUND;
775                }
776
777                NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove all elements from the group \"%s\"", group.c_str());
778
779                // scan through all elements
780                ::std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
781                for (; jt != mResourceGroup[group].end(); jt++){
782                        Result ret = remove(*jt);
783                        if (ret != OK) return ret;
784                }
785
786                // remove the group
787                mResourceGroup.erase(group);
788
789                // OK
790                return OK;
791
792        }
793
794        //----------------------------------------------------------------------------------
795        SharedPtr<IResource> ResourceManager::getEmpty(const std::string& type)
796        {
797                res_empty_map::iterator it = mEmptyResource.find(type);
798                if (it == mEmptyResource.end())
799                {
800                        return SharedPtr<IResource>();
801                }
802
803                return it->second;
804        }
805               
806        //----------------------------------------------------------------------------------
807        void ResourceManager::setEmpty(const std::string& type, SharedPtr<IResource> empty)
808        {
809                // check if empty is valid
810                if (empty == NULL) return;
811               
812                // setup some default data on it
813                mEmptyResource[type] = empty;
814        }
815
816        //----------------------------------------------------------------------------------
817        bool ResourceManager::isResourceRegistered(const std::string& name)
818        {
819                IResourcePtr res = getByName(name);
820                return res.isNull() == false;
821        }
822
823        //----------------------------------------------------------------------------------
824        void ResourceManager::notifyLoaded(IResource* res)
825        {
826                if (res == NULL) return;
827
828                // check if such a resource is already in the database
829                if (isResourceRegistered(res->getResName())) return;
830
831                // get some data from the resource
832                const std::string& group = res->getResGroup();
833                const std::string& name = res->getResName();
834                const ResourceHandle& handle = res->getResHandle();
835                const std::string& type = res->getResType();
836                               
837                // get according empty resource object and give exception if no such exists
838                IResource* empty = getEmpty(type).get();
839                if (empty == NULL){
840                        char msg[128];
841                        sprintf(msg, "There was no empty resource created for the type %s", type.c_str());
842                        NR_EXCEPT(RES_NO_EMPTY_RES_FOUND, std::string(msg), "ResourceManager::notifyLoaded()");
843                }
844               
845                // get name of the resource and create a holder for this
846                SharedPtr<ResourceHolder> holder(new ResourceHolder(res, empty));
847
848                // store the resource in database
849                mResourceGroup[group].push_back(handle);
850                mResource[handle] = holder;
851                mResourceName[name] = handle;
852
853                //printf("LOADED: %s\n", holder->getResource()->getResName().c_str());         
854        }
855
856        //----------------------------------------------------------------------------------
857        void ResourceManager::notifyCreated(IResource* res)
858        {
859                notifyLoaded(res);
860        }
861
862        //----------------------------------------------------------------------------------
863        void ResourceManager::notifyUnloaded(IResource*)
864        {
865
866        }
867
868        //----------------------------------------------------------------------------------
869        void ResourceManager::notifyRemove(IResource* res)
870        {
871                if (res == NULL) return;
872
873                // check if such a resource is already in the database
874                if (!isResourceRegistered(res->getResName())) return;
875
876                // get some data from the resource
877                const std::string& group = res->getResGroup();
878                const std::string& name = res->getResName();
879                const ResourceHandle& handle = res->getResHandle();
880
881                NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %s (%s)", name.c_str(), group.c_str());
882
883                if (handle == 0){
884                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not remove resource %s because it is not in the database", name.c_str());
885                        return;
886                }
887
888                // remove the handle from the group list
889                if (group.length() > 0){
890                        res_grp_map::iterator jt = mResourceGroup.find(group);
891                        if (jt != mResourceGroup.end()){
892                                jt->second.remove(handle);
893
894                                // check whenever group contains no more elements, and delete it
895                                if (jt->second.size() == 0){
896                                        mResourceGroup.erase(group);
897                                        NR_Log(Log::LOG_ENGINE, "ResourceManager: %s's group \"%s\" does not contain elements, so remove it", name.c_str(), group.c_str());
898                                }
899                        }else{
900                                NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceManager: There is no group in the database with the name \"%s\" for resource %s", group.c_str(), name.c_str());
901                        }
902                }
903                // get the according holder and remove the resource there
904                SharedPtr<ResourceHolder>& holder = *getHolderByName(name);
905                if (holder == NULL){
906                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceManager: Could not find resource holder for %s", name.c_str());
907                        return;
908                }
909                holder->resetRes(NULL);
910
911                // clear the database
912                mResourceName.erase(name);
913                mResource.erase(handle);
914        }
915       
916};
917
Note: See TracBrowser for help on using the repository browser.