source: nrEngine/src/ResourceManager.cpp @ 31

Revision 31, 28.6 KB checked in by art, 13 years ago (diff)

dynamicResourceManagment Plugin added.

TODO: change file association list of resources. This is required
by the drm plugin to be able to reload the resource as soon as one of
the associated file changes.

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                {
276                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not create a resource %s of %s type", name.c_str(), resourceType.c_str());
277                        return IResourcePtr();
278                }
279
280                // get the holder for this resource, it must be there
281                SharedPtr<ResourceHolder>& holder = *getHolderByName(name);
282                NR_ASSERT(holder != NULL && "Holder must be valid here!");
283
284                return IResourcePtr(holder);
285        }
286
287
288        //----------------------------------------------------------------------------------
289        IResourcePtr ResourceManager::loadResource(
290                        const std::string& name,const std::string& group,const std::string& fileName,
291                        const std::string& resourceType,PropertyList* params,ResourceLoader loader)
292        {
293
294                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());
295
296                // check for right parameters
297                if (name.length() == 0 || fileName.length() == 0)
298                        return IResourcePtr();
299
300                // check whenever such a resource already exists
301                IResourcePtr pRes = getByName(name);
302                if (!pRes.isNull()){
303                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceManager: Resource %s already loaded. Do nothing.", name.c_str());
304                        return pRes;
305                }
306
307                // detect the file type by reading out it's last characters
308                std::string type;
309                for (int32 i = fileName.length()-1; i >= 0; i--){
310                        if (fileName[i] == '.'){
311                                break;
312                        }
313                        type = fileName[i] + type;
314                }
315                bool isManualSpecified = (loader != NULL);
316
317                // if the loader is manually specified, so do nothing
318                if (!isManualSpecified)
319                {
320                        loader = getLoaderByResource(resourceType);
321                        if (loader == NULL) loader = getLoaderByFile(type);
322
323                        if (loader == NULL){
324                                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());
325                                return IResourcePtr();
326                        }
327                }
328
329                // now call the loader to create a resource
330                // loader will notify the manager, manager will add it into database
331                SharedPtr<IResource> res = loader->load(name, group, fileName, resourceType, params);
332                if (res == NULL) return IResourcePtr();
333
334                // get the holder for this resource, it must be there
335                SharedPtr<ResourceHolder>& holder = *getHolderByName(name);
336                NR_ASSERT(holder.get() != NULL && "Holder must be valid here!");
337
338                return IResourcePtr(holder);
339        }
340
341        //----------------------------------------------------------------------------------
342        Result ResourceManager::unload(const std::string& name){
343
344                ResourcePtr<IResource> res = getByName(name);
345
346                if (res.isNull()){
347                        return RES_NOT_FOUND;
348                }
349
350                lockPure(res);
351                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload resource %s", 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                {
565                        return NULL;
566                }
567                return &(it->second);
568        }
569
570        //----------------------------------------------------------------------------------
571        IResourcePtr ResourceManager::getByName(const std::string& name){
572                SharedPtr<ResourceHolder>* holder = getHolderByName(name);
573                if (holder == NULL){
574                        return IResourcePtr();
575                }
576
577                return IResourcePtr(*holder);
578        }
579
580        //----------------------------------------------------------------------------------
581        IResourcePtr ResourceManager::getByHandle(const ResourceHandle& handle){
582                SharedPtr<ResourceHolder>* holder = getHolderByHandle(handle);
583                if (holder == NULL){
584                        return IResourcePtr();
585                }
586                return IResourcePtr(*holder);
587        }
588
589        //----------------------------------------------------------------------------------
590/*      Result ResourceManager::add(IResource* res, const std::string& name, const std::string& group)
591        {
592
593                // check for bad parameters
594                if (res == NULL) return OK;
595                if (name.length() == 0) return BAD_PARAMETERS;
596                if (res->mResLoader == NULL) return RES_LOADER_NOT_EXISTS;
597
598                // check whenever such resource already exists
599                if (!getByName(name).isNull()){
600                        NR_Log(Log::LOG_ENGINE, "ResourceManager: WARNING: Add resource %s but it already exists", name.c_str());
601                        return OK;
602                }
603
604                ResourceHandle handle = mLastHandle++;
605                NR_Log(Log::LOG_ENGINE, "ResourceManager: Add resource %s id=%d to the database from outside", name.c_str(), handle);
606
607                // check now if a empty resource of that type already exists and load it if not
608                SharedPtr<IResource> empty;
609                checkEmptyResource(res->getResType(), empty, res->mResLoader);
610
611                // create a holder for that resource
612                SharedPtr<ResourceHolder> holder(new ResourceHolder());
613                holder->resetRes(res);
614                holder->setEmptyResource(empty);
615
616                // store the resource in database
617                mResourceGroup[group].push_back(handle);
618                mResource[handle] = holder;
619                mResourceName[name] = handle;
620
621                res->mResGroup = group;
622                res->mResName = name;
623                res->mResHandle = handle;
624                res->mParentManager = this;
625
626                // check for memory usage
627                mMemUsage += holder->getResource()->getResDataSize();
628                Result ret = checkMemoryUsage();
629
630                if (ret != OK){
631                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Could not rearrange memory");
632                        return ret;
633                }
634
635                // return a pointer to that resource
636                return OK;
637        }
638*/
639
640        //----------------------------------------------------------------------------------
641        Result ResourceManager::lockPure(const std::string& name){
642
643                // get appropriate pointer
644                IResourcePtr ptr = getByName(name);
645
646                // if it is null, so we do not have such a resource
647                if (ptr.isNull()) return RES_NOT_FOUND;
648
649                return ptr.lockPure();
650        }
651
652        //----------------------------------------------------------------------------------
653        Result ResourceManager::lockPure(ResourceHandle& handle){
654
655                // get appropriate pointer
656                IResourcePtr ptr = getByHandle(handle);
657
658                // if it is null, so we do not have such a resource
659                if (ptr.isNull()) return RES_NOT_FOUND;
660
661                return ptr.lockPure();
662
663        }
664
665        //----------------------------------------------------------------------------------
666        Result ResourceManager::lockPure(IResourcePtr& res){
667
668                // lock through the pointer
669                return res.lockPure();
670
671        }
672
673        //----------------------------------------------------------------------------------
674        Result ResourceManager::unlockPure(const std::string& name){
675
676                // get appropriate holder
677                SharedPtr<ResourceHolder>* holder = getHolderByName(name);
678
679                if (holder != NULL){
680                        // lock the resource through the holder
681                        (*holder)->unlockPure();
682                }else{
683                        return RES_NOT_FOUND;
684                }
685
686                return OK;
687
688        }
689
690        //----------------------------------------------------------------------------------
691        Result ResourceManager::unlockPure(ResourceHandle& handle){
692
693                // get appropriate holder
694                SharedPtr<ResourceHolder>* holder = getHolderByHandle(handle);
695
696                if (holder != NULL){
697                        // lock the resource through the holder
698                        (*holder)->unlockPure();
699                }else{
700                        return RES_NOT_FOUND;
701                }
702
703                return OK;
704
705        }
706
707        //----------------------------------------------------------------------------------
708        Result ResourceManager::unlockPure(IResourcePtr& res){
709
710                // if pointer does not pointing anywhere
711                if (res.isNull()){
712                        return RES_ERROR;
713                }
714
715                // lock through the holder
716                res.getResourceHolder()->unlockPure();
717
718                return OK;
719        }
720
721        //----------------------------------------------------------------------------------
722        Result ResourceManager::unloadGroup(const std::string& group){
723
724                // check whenever such a group exists
725                ResourceGroupMap::const_iterator it = mResourceGroup.find(group);
726                if (it == mResourceGroup.end()){
727                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not unload group \"%s\" because not found in database", group.c_str());
728                        return RES_GROUP_NOT_FOUND;
729                }
730
731                NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload the group \"%s\"", group.c_str());
732
733                // scan through all elements
734                std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
735                for (; jt != mResourceGroup[group].end(); jt++){
736                        Result ret = unload(*jt);
737                        if (ret != OK) return ret;
738                }
739
740                // OK
741                return OK;
742        }
743
744        //----------------------------------------------------------------------------------
745        Result ResourceManager::reloadGroup(const std::string& group){
746
747                // check whenever such a group exists
748                ResourceGroupMap::const_iterator it = mResourceGroup.find(group);
749                if (it == mResourceGroup.end()){
750                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not reload group \"%s\" because not found in database", group.c_str());
751                        return RES_GROUP_NOT_FOUND;
752                }
753
754                NR_Log(Log::LOG_ENGINE, "ResourceManager: Reload the group \"%s\"", group.c_str());
755
756                // scan through all elements
757                std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
758                for (; jt != mResourceGroup[group].end(); jt++){
759                        Result ret = reload(*jt);
760                        if (ret != OK) return ret;
761                }
762
763                // OK
764                return OK;
765
766        }
767
768        //----------------------------------------------------------------------------------
769        Result ResourceManager::removeGroup(const std::string& group){
770
771                // check whenever such a group exists
772                ResourceGroupMap::const_iterator it = mResourceGroup.find(group);
773                if (it == mResourceGroup.end()){
774                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not remove group \"%s\" because not found in database", group.c_str());
775                        return RES_GROUP_NOT_FOUND;
776                }
777
778                NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove all elements from the group \"%s\"", group.c_str());
779
780                // scan through all elements
781                std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
782                for (; jt != mResourceGroup[group].end(); jt++){
783                        Result ret = remove(*jt);
784                        if (ret != OK) return ret;
785                }
786
787                // remove the group
788                mResourceGroup.erase(group);
789
790                // OK
791                return OK;
792
793        }
794
795        //----------------------------------------------------------------------------------
796        const std::list<ResourceHandle>& ResourceManager::getGroupHandles(const std::string& name)
797        {
798                // check if such a group exists
799                ResourceGroupMap::const_iterator it = mResourceGroup.find(name);
800
801                // return the empty list
802                if (it == mResourceGroup.end())
803                        return mEmptyResourceGroupHandleList;
804
805                // return the group to this name
806                return it->second;
807        }
808
809        //----------------------------------------------------------------------------------
810        SharedPtr<IResource> ResourceManager::getEmpty(const std::string& type)
811        {
812                res_empty_map::iterator it = mEmptyResource.find(type);
813                if (it == mEmptyResource.end())
814                {
815                        return SharedPtr<IResource>();
816                }
817
818                return it->second;
819        }
820
821        //----------------------------------------------------------------------------------
822        void ResourceManager::setEmpty(const std::string& type, SharedPtr<IResource> empty)
823        {
824                // check if empty is valid
825                if (empty == NULL) return;
826
827                // setup some default data on it
828                mEmptyResource[type] = empty;
829        }
830
831        //----------------------------------------------------------------------------------
832        bool ResourceManager::isResourceRegistered(const std::string& name)
833        {
834                IResourcePtr res = getByName(name);
835                return res.isNull() == false;
836        }
837
838        //----------------------------------------------------------------------------------
839        void ResourceManager::notifyLoaded(IResource* res)
840        {
841                if (res == NULL) return;
842
843                // check if such a resource is already in the database
844                if (isResourceRegistered(res->getResName())) return;
845
846                // get some data from the resource
847                const std::string& group = res->getResGroup();
848                const std::string& name = res->getResName();
849                const ResourceHandle& handle = res->getResHandle();
850                const std::string& type = res->getResType();
851
852                // get according empty resource object and give exception if no such exists
853                IResource* empty = getEmpty(type).get();
854                if (empty == NULL)
855                {
856                        char msg[128];
857                        sprintf(msg, "There was no empty resource created for the type %s", type.c_str());
858                        NR_EXCEPT(RES_NO_EMPTY_RES_FOUND, std::string(msg), "ResourceManager::notifyLoaded()");
859                }
860
861                // get name of the resource and create a holder for this
862                SharedPtr<ResourceHolder> holder(new ResourceHolder(res, empty));
863
864                // store the resource in database
865                mResourceGroup[group].push_back(handle);
866                mResource[handle] = holder;
867                mResourceName[name] = handle;
868
869                //printf("LOADED: %s\n", holder->getResource()->getResName().c_str());
870        }
871
872        //----------------------------------------------------------------------------------
873        void ResourceManager::notifyCreated(IResource* res)
874        {
875                notifyLoaded(res);
876        }
877
878        //----------------------------------------------------------------------------------
879        void ResourceManager::notifyUnloaded(IResource*)
880        {
881
882        }
883
884        //----------------------------------------------------------------------------------
885        void ResourceManager::notifyRemove(IResource* res)
886        {
887                if (res == NULL) return;
888
889                // check if such a resource is already in the database
890                if (!isResourceRegistered(res->getResName())) return;
891
892                // get some data from the resource
893                const std::string& group = res->getResGroup();
894                const std::string& name = res->getResName();
895                const ResourceHandle& handle = res->getResHandle();
896
897                NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %s (%s)", name.c_str(), group.c_str());
898
899                if (handle == 0){
900                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not remove resource %s because it is not in the database", name.c_str());
901                        return;
902                }
903
904                // remove the handle from the group list
905                if (group.length() > 0){
906                        ResourceGroupMap::iterator jt = mResourceGroup.find(group);
907                        if (jt != mResourceGroup.end()){
908                                jt->second.remove(handle);
909
910                                // check whenever group contains no more elements, and delete it
911                                if (jt->second.size() == 0){
912                                        mResourceGroup.erase(group);
913                                        NR_Log(Log::LOG_ENGINE, "ResourceManager: %s's group \"%s\" does not contain elements, so remove it", name.c_str(), group.c_str());
914                                }
915                        }else{
916                                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());
917                        }
918                }
919                // get the according holder and remove the resource there
920                SharedPtr<ResourceHolder>& holder = *getHolderByName(name);
921                if (holder == NULL){
922                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceManager: Could not find resource holder for %s", name.c_str());
923                        return;
924                }
925                holder->resetRes(NULL);
926
927                // clear the database
928                mResourceName.erase(name);
929                mResource.erase(handle);
930        }
931
932};
933
Note: See TracBrowser for help on using the repository browser.