source: trunk/src/nrEngine/ResourceManager.cpp @ 61

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