source: nrEngine/src/ResourceManager.cpp @ 25

Revision 25, 28.7 KB checked in by art, 12 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::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                SharedPtr<IResource> res (creator->create(name, group, resourceType, params));
274                if (res.get() == 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                SharedPtr<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", res->getResName().c_str(), res->getResHandle());
351                        Result ret = res->unloadResThroughLoader();
352                unlockPure(res);
353
354                return ret;
355        }
356
357        //----------------------------------------------------------------------------------
358        Result ResourceManager::unload(IResourcePtr& res){
359
360                if (res.isNull()){
361                        return RES_NOT_FOUND;
362                }
363
364                lockPure(res);
365                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload resource %s",
366                                res.getBase()->getResName().c_str(), res.getBase()->getResHandle());
367                        Result ret = res.getBase()->unloadResThroughLoader();
368                unlockPure(res);
369
370                return ret;
371        }
372
373        //----------------------------------------------------------------------------------
374        Result ResourceManager::unload(ResourceHandle& handle){
375
376                ResourcePtr<IResource> res = getByHandle(handle);
377
378                if (res.isNull()){
379                        return RES_NOT_FOUND;
380                }
381
382                lockPure(res);
383                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload resource %s",
384                                res->getResName().c_str(), res->getResHandle());
385                        Result ret = res->unloadResThroughLoader();
386                unlockPure(res);
387
388                return ret;
389        }
390
391        //----------------------------------------------------------------------------------
392        Result ResourceManager::reload(const ::std::string& name){
393
394                ResourcePtr<IResource> res = getByName(name);
395
396                if (res.isNull()){
397                        return RES_NOT_FOUND;
398                }
399
400                lockPure(res);
401                        NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceManager: Reload resource %s",
402                                res->getResName().c_str(), res->getResHandle());
403                        Result ret = res->reloadResThroughLoader();
404                unlockPure(res);
405
406                return ret;
407        }
408
409        //----------------------------------------------------------------------------------
410        Result ResourceManager::reload(ResourceHandle& handle){
411
412                ResourcePtr<IResource> res = getByHandle(handle);
413
414                if (res.isNull()){
415                        return RES_NOT_FOUND;
416                }
417
418                lockPure(res);
419                        NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceManager: Reload resource %s",
420                                res->getResName().c_str(), res->getResHandle());
421                        Result ret = res->reloadResThroughLoader();
422                unlockPure(res);
423
424                return ret;
425        }
426
427        //----------------------------------------------------------------------------------
428        Result ResourceManager::reload(IResourcePtr& res){
429
430                if (res.isNull()){
431                        return RES_NOT_FOUND;
432                }
433
434                lockPure(res);
435                        NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceManager: Reload resource %s",
436                                res.getBase()->getResName().c_str(), res.getBase()->getResHandle());
437                        Result ret = res.getBase()->reloadResThroughLoader();
438                unlockPure(res);
439
440                return ret;
441        }
442
443        //----------------------------------------------------------------------------------
444/*      Result ResourceManager::removeImpl(IResourcePtr& resPtr){
445
446                NR_ASSERT(!resPtr.isNull() && "Given pointer shouldn't be zero");
447
448                // we need to lock the resource, because we need the real resource object not empty
449                lockPure(resPtr);
450
451                        ResourcePtr<IResource> ptr = resPtr;
452                        ResourceHandle hdl = ptr->getResHandle();
453                        ::std::string name = ptr->getResName();
454                        ::std::string grp = ptr->getResGroup();
455
456                        if (hdl == 0){
457                                NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not remove resource %s because it is not in the database", name.c_str());
458                                return RES_NOT_FOUND;
459                        }
460
461                        // first unload it
462                        unload(resPtr);
463
464                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %s (%s)", name.c_str(), grp.c_str());
465
466                        // remove the handle from the group list
467                        if (grp.length() > 0){
468                                res_grp_map::iterator jt = mResourceGroup.find(grp);
469                                if (jt != mResourceGroup.end()){
470                                        jt->second.remove(hdl);
471
472                                        // check whenever group contains nomore elements, and delete it
473                                        if (jt->second.size() == 0){
474                                                mResourceGroup.erase(grp);
475                                                NR_Log(Log::LOG_ENGINE, "ResourceManager: %s's group \"%s\" does not contain elements, so remove it", name.c_str(), grp.c_str());
476                                        }
477                                }else{
478                                        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());
479                                }
480                        }
481
482                // unlock it back
483                unlockPure(resPtr);
484
485                // clear the database
486                mResourceName.erase(name);
487                mResource.erase(hdl);
488
489                return OK;
490        }
491*/
492        //----------------------------------------------------------------------------------
493        Result ResourceManager::remove(const ::std::string& name){
494
495                // check whenever such a resource exists
496                IResourcePtr ptr = getByName(name);
497
498                if (ptr.isNull()){
499                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %s not found", name.c_str());
500                        return RES_NOT_FOUND;
501                }
502
503                lockPure(ptr);
504                        Result ret = ptr.getBase()->removeResThroughLoader();
505                unlockPure(ptr);
506
507                return ret;
508        }
509
510        //----------------------------------------------------------------------------------
511        Result ResourceManager::remove(ResourceHandle& handle){
512
513                // check whenever such a resource exists
514                IResourcePtr ptr = getByHandle(handle);
515
516                if (ptr.isNull()){
517                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %d not found", handle);
518                        return RES_NOT_FOUND;
519                }
520
521                lockPure(ptr);
522                        Result ret = ptr.getBase()->removeResThroughLoader();
523                unlockPure(ptr);
524
525                return ret;
526        }
527
528        //----------------------------------------------------------------------------------
529        Result ResourceManager::remove(IResourcePtr& ptr){
530
531                // check whenever such a resource exists
532                if (!ptr.isNull()){
533                        lockPure(ptr);
534                                Result ret = ptr.getBase()->removeResThroughLoader();
535                        unlockPure(ptr);
536
537                        return ret;
538                }
539                return OK;
540        }
541
542        //----------------------------------------------------------------------------------
543        SharedPtr<ResourceHolder>* ResourceManager::getHolderByName(const ::std::string& name)
544        {
545                // find the handle
546                res_str_map::iterator it = mResourceName.find(name);
547                if (it == mResourceName.end()){
548                        return NULL;
549                }
550
551                // get through the handle the holder
552                res_hdl_map::iterator jt = mResource.find(it->second);
553                NR_ASSERT(jt != mResource.end() && "Fatal Error in the Database !!!");
554                return &(jt->second);
555        }
556
557        //----------------------------------------------------------------------------------
558        SharedPtr<ResourceHolder>* ResourceManager::getHolderByHandle(const ResourceHandle& handle)
559        {
560                // find through the handle
561                res_hdl_map::iterator it = mResource.find(handle);
562                if (it == mResource.end()){
563                        return NULL;
564                }
565                return &(it->second);
566        }
567
568        //----------------------------------------------------------------------------------
569        IResourcePtr ResourceManager::getByName(const ::std::string& name){
570                SharedPtr<ResourceHolder>* holder = getHolderByName(name);
571                if (holder == NULL){
572                        return IResourcePtr();
573                }
574
575                return IResourcePtr(*holder);
576        }
577
578        //----------------------------------------------------------------------------------
579        IResourcePtr ResourceManager::getByHandle(const ResourceHandle& handle){
580                SharedPtr<ResourceHolder>* holder = getHolderByHandle(handle);
581                if (holder == NULL){
582                        return IResourcePtr();
583                }
584                return IResourcePtr(*holder);
585        }
586
587        //----------------------------------------------------------------------------------
588/*      Result ResourceManager::add(IResource* res, const std::string& name, const std::string& group)
589        {
590
591                // check for bad parameters
592                if (res == NULL) return OK;
593                if (name.length() == 0) return BAD_PARAMETERS;
594                if (res->mResLoader == NULL) return RES_LOADER_NOT_EXISTS;
595
596                // check whenever such resource already exists
597                if (!getByName(name).isNull()){
598                        NR_Log(Log::LOG_ENGINE, "ResourceManager: WARNING: Add resource %s but it already exists", name.c_str());
599                        return OK;
600                }
601
602                ResourceHandle handle = mLastHandle++;
603                NR_Log(Log::LOG_ENGINE, "ResourceManager: Add resource %s id=%d to the database from outside", name.c_str(), handle);
604
605                // check now if a empty resource of that type already exists and load it if not
606                SharedPtr<IResource> empty;
607                checkEmptyResource(res->getResType(), empty, res->mResLoader);
608
609                // create a holder for that resource
610                SharedPtr<ResourceHolder> holder(new ResourceHolder());
611                holder->resetRes(res);
612                holder->setEmptyResource(empty);
613
614                // store the resource in database
615                mResourceGroup[group].push_back(handle);
616                mResource[handle] = holder;
617                mResourceName[name] = handle;
618
619                res->mResGroup = group;
620                res->mResName = name;
621                res->mResHandle = handle;
622                res->mParentManager = this;
623
624                // check for memory usage
625                mMemUsage += holder->getResource()->getResDataSize();
626                Result ret = checkMemoryUsage();
627
628                if (ret != OK){
629                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Could not rearrange memory");
630                        return ret;
631                }
632
633                // return a pointer to that resource
634                return OK;
635        }
636*/
637       
638        //----------------------------------------------------------------------------------
639        Result ResourceManager::lockPure(const ::std::string& name){
640
641                // get appropriate pointer
642                IResourcePtr ptr = getByName(name);
643
644                // if it is null, so we do not have such a resource
645                if (ptr.isNull()) return RES_NOT_FOUND;
646
647                return ptr.lockPure();
648        }
649
650        //----------------------------------------------------------------------------------
651        Result ResourceManager::lockPure(ResourceHandle& handle){
652
653                // get appropriate pointer
654                IResourcePtr ptr = getByHandle(handle);
655
656                // if it is null, so we do not have such a resource
657                if (ptr.isNull()) return RES_NOT_FOUND;
658
659                return ptr.lockPure();
660
661        }
662
663        //----------------------------------------------------------------------------------
664        Result ResourceManager::lockPure(IResourcePtr& res){
665
666                // lock through the pointer
667                return res.lockPure();
668
669        }
670
671        //----------------------------------------------------------------------------------
672        Result ResourceManager::unlockPure(const ::std::string& name){
673
674                // get appropriate holder
675                SharedPtr<ResourceHolder>* holder = getHolderByName(name);
676
677                if (holder != NULL){
678                        // lock the resource through the holder
679                        (*holder)->unlockPure();
680                }else{
681                        return RES_NOT_FOUND;
682                }
683
684                return OK;
685
686        }
687
688        //----------------------------------------------------------------------------------
689        Result ResourceManager::unlockPure(ResourceHandle& handle){
690
691                // get appropriate holder
692                SharedPtr<ResourceHolder>* holder = getHolderByHandle(handle);
693
694                if (holder != NULL){
695                        // lock the resource through the holder
696                        (*holder)->unlockPure();
697                }else{
698                        return RES_NOT_FOUND;
699                }
700
701                return OK;
702
703        }
704
705        //----------------------------------------------------------------------------------
706        Result ResourceManager::unlockPure(IResourcePtr& res){
707
708                // if pointer does not pointing anywhere
709                if (res.isNull()){
710                        return RES_ERROR;
711                }
712
713                // lock through the holder
714                res.getResourceHolder()->unlockPure();
715
716                return OK;
717        }
718
719        //----------------------------------------------------------------------------------
720        Result ResourceManager::unloadGroup(const ::std::string& group){
721
722                // check whenever such a group exists
723                res_grp_map::const_iterator it = mResourceGroup.find(group);
724                if (it == mResourceGroup.end()){
725                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not unload group \"%s\" because not found in database", group.c_str());
726                        return RES_GROUP_NOT_FOUND;
727                }
728
729                NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload the group \"%s\"", group.c_str());
730
731                // scan through all elements
732                ::std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
733                for (; jt != mResourceGroup[group].end(); jt++){
734                        Result ret = unload(*jt);
735                        if (ret != OK) return ret;
736                }
737
738                // OK
739                return OK;
740        }
741
742        //----------------------------------------------------------------------------------
743        Result ResourceManager::reloadGroup(const ::std::string& group){
744
745                // check whenever such a group exists
746                res_grp_map::const_iterator it = mResourceGroup.find(group);
747                if (it == mResourceGroup.end()){
748                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not reload group \"%s\" because not found in database", group.c_str());
749                        return RES_GROUP_NOT_FOUND;
750                }
751
752                NR_Log(Log::LOG_ENGINE, "ResourceManager: Reload the group \"%s\"", group.c_str());
753
754                // scan through all elements
755                ::std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
756                for (; jt != mResourceGroup[group].end(); jt++){
757                        Result ret = reload(*jt);
758                        if (ret != OK) return ret;
759                }
760
761                // OK
762                return OK;
763
764        }
765
766        //----------------------------------------------------------------------------------
767        Result ResourceManager::removeGroup(const ::std::string& group){
768
769                // check whenever such a group exists
770                res_grp_map::const_iterator it = mResourceGroup.find(group);
771                if (it == mResourceGroup.end()){
772                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not remove group \"%s\" because not found in database", group.c_str());
773                        return RES_GROUP_NOT_FOUND;
774                }
775
776                NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove all elements from the group \"%s\"", group.c_str());
777
778                // scan through all elements
779                ::std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
780                for (; jt != mResourceGroup[group].end(); jt++){
781                        Result ret = remove(*jt);
782                        if (ret != OK) return ret;
783                }
784
785                // remove the group
786                mResourceGroup.erase(group);
787
788                // OK
789                return OK;
790
791        }
792
793        //----------------------------------------------------------------------------------
794        const std::list<ResourceHandle>& ResourceManager::getGroupHandles(const std::string& name)
795        {
796                // check if such a group exists
797                res_grp_map::const_iterator it = mResourceGroup.find(name);
798               
799                // return the empty list
800                if (it == mResourceGroup.end())
801                        return mEmptyResourceGroupHandleList;
802                       
803                // return the group to this name
804                return it->second;
805        }
806       
807        //----------------------------------------------------------------------------------
808        SharedPtr<IResource> ResourceManager::getEmpty(const std::string& type)
809        {
810                res_empty_map::iterator it = mEmptyResource.find(type);
811                if (it == mEmptyResource.end())
812                {
813                        return SharedPtr<IResource>();
814                }
815
816                return it->second;
817        }
818               
819        //----------------------------------------------------------------------------------
820        void ResourceManager::setEmpty(const std::string& type, SharedPtr<IResource> empty)
821        {
822                // check if empty is valid
823                if (empty == NULL) return;
824               
825                // setup some default data on it
826                mEmptyResource[type] = empty;
827        }
828
829        //----------------------------------------------------------------------------------
830        bool ResourceManager::isResourceRegistered(const std::string& name)
831        {
832                IResourcePtr res = getByName(name);
833                return res.isNull() == false;
834        }
835
836        //----------------------------------------------------------------------------------
837        void ResourceManager::notifyLoaded(IResource* res)
838        {
839                if (res == NULL) return;
840
841                // check if such a resource is already in the database
842                if (isResourceRegistered(res->getResName())) return;
843
844                // get some data from the resource
845                const std::string& group = res->getResGroup();
846                const std::string& name = res->getResName();
847                const ResourceHandle& handle = res->getResHandle();
848                const std::string& type = res->getResType();
849                 
850                // get according empty resource object and give exception if no such exists
851                IResource* empty = getEmpty(type).get();
852                if (empty == NULL){
853                        char msg[128];
854                        sprintf(msg, "There was no empty resource created for the type %s", type.c_str());
855                        NR_EXCEPT(RES_NO_EMPTY_RES_FOUND, std::string(msg), "ResourceManager::notifyLoaded()");
856                }
857               
858                // get name of the resource and create a holder for this
859                SharedPtr<ResourceHolder> holder(new ResourceHolder(res, empty));
860
861                // store the resource in database
862                mResourceGroup[group].push_back(handle);
863                mResource[handle] = holder;
864                mResourceName[name] = handle;
865
866                //printf("LOADED: %s\n", holder->getResource()->getResName().c_str());         
867        }
868
869        //----------------------------------------------------------------------------------
870        void ResourceManager::notifyCreated(IResource* res)
871        {
872                notifyLoaded(res);
873        }
874
875        //----------------------------------------------------------------------------------
876        void ResourceManager::notifyUnloaded(IResource*)
877        {
878
879        }
880
881        //----------------------------------------------------------------------------------
882        void ResourceManager::notifyRemove(IResource* res)
883        {
884                if (res == NULL) return;
885
886                // check if such a resource is already in the database
887                if (!isResourceRegistered(res->getResName())) return;
888
889                // get some data from the resource
890                const std::string& group = res->getResGroup();
891                const std::string& name = res->getResName();
892                const ResourceHandle& handle = res->getResHandle();
893
894                NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %s (%s)", name.c_str(), group.c_str());
895
896                if (handle == 0){
897                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not remove resource %s because it is not in the database", name.c_str());
898                        return;
899                }
900
901                // remove the handle from the group list
902                if (group.length() > 0){
903                        res_grp_map::iterator jt = mResourceGroup.find(group);
904                        if (jt != mResourceGroup.end()){
905                                jt->second.remove(handle);
906
907                                // check whenever group contains no more elements, and delete it
908                                if (jt->second.size() == 0){
909                                        mResourceGroup.erase(group);
910                                        NR_Log(Log::LOG_ENGINE, "ResourceManager: %s's group \"%s\" does not contain elements, so remove it", name.c_str(), group.c_str());
911                                }
912                        }else{
913                                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());
914                        }
915                }
916                // get the according holder and remove the resource there
917                SharedPtr<ResourceHolder>& holder = *getHolderByName(name);
918                if (holder == NULL){
919                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceManager: Could not find resource holder for %s", name.c_str());
920                        return;
921                }
922                holder->resetRes(NULL);
923
924                // clear the database
925                mResourceName.erase(name);
926                mResource.erase(handle);
927        }
928       
929};
930
Note: See TracBrowser for help on using the repository browser.