source: nrEngine/src/ResourceManager.cpp @ 27

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

nrScript: using of subscripts is now possible

Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13//----------------------------------------------------------------------------------
14// 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                        return NULL;
565                }
566                return &(it->second);
567        }
568
569        //----------------------------------------------------------------------------------
570        IResourcePtr ResourceManager::getByName(const ::std::string& name){
571                SharedPtr<ResourceHolder>* holder = getHolderByName(name);
572                if (holder == NULL){
573                        return IResourcePtr();
574                }
575
576                return IResourcePtr(*holder);
577        }
578
579        //----------------------------------------------------------------------------------
580        IResourcePtr ResourceManager::getByHandle(const ResourceHandle& handle){
581                SharedPtr<ResourceHolder>* holder = getHolderByHandle(handle);
582                if (holder == NULL){
583                        return IResourcePtr();
584                }
585                return IResourcePtr(*holder);
586        }
587
588        //----------------------------------------------------------------------------------
589/*      Result ResourceManager::add(IResource* res, const std::string& name, const std::string& group)
590        {
591
592                // check for bad parameters
593                if (res == NULL) return OK;
594                if (name.length() == 0) return BAD_PARAMETERS;
595                if (res->mResLoader == NULL) return RES_LOADER_NOT_EXISTS;
596
597                // check whenever such resource already exists
598                if (!getByName(name).isNull()){
599                        NR_Log(Log::LOG_ENGINE, "ResourceManager: WARNING: Add resource %s but it already exists", name.c_str());
600                        return OK;
601                }
602
603                ResourceHandle handle = mLastHandle++;
604                NR_Log(Log::LOG_ENGINE, "ResourceManager: Add resource %s id=%d to the database from outside", name.c_str(), handle);
605
606                // check now if a empty resource of that type already exists and load it if not
607                SharedPtr<IResource> empty;
608                checkEmptyResource(res->getResType(), empty, res->mResLoader);
609
610                // create a holder for that resource
611                SharedPtr<ResourceHolder> holder(new ResourceHolder());
612                holder->resetRes(res);
613                holder->setEmptyResource(empty);
614
615                // store the resource in database
616                mResourceGroup[group].push_back(handle);
617                mResource[handle] = holder;
618                mResourceName[name] = handle;
619
620                res->mResGroup = group;
621                res->mResName = name;
622                res->mResHandle = handle;
623                res->mParentManager = this;
624
625                // check for memory usage
626                mMemUsage += holder->getResource()->getResDataSize();
627                Result ret = checkMemoryUsage();
628
629                if (ret != OK){
630                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Could not rearrange memory");
631                        return ret;
632                }
633
634                // return a pointer to that resource
635                return OK;
636        }
637*/
638
639        //----------------------------------------------------------------------------------
640        Result ResourceManager::lockPure(const ::std::string& name){
641
642                // get appropriate pointer
643                IResourcePtr ptr = getByName(name);
644
645                // if it is null, so we do not have such a resource
646                if (ptr.isNull()) return RES_NOT_FOUND;
647
648                return ptr.lockPure();
649        }
650
651        //----------------------------------------------------------------------------------
652        Result ResourceManager::lockPure(ResourceHandle& handle){
653
654                // get appropriate pointer
655                IResourcePtr ptr = getByHandle(handle);
656
657                // if it is null, so we do not have such a resource
658                if (ptr.isNull()) return RES_NOT_FOUND;
659
660                return ptr.lockPure();
661
662        }
663
664        //----------------------------------------------------------------------------------
665        Result ResourceManager::lockPure(IResourcePtr& res){
666
667                // lock through the pointer
668                return res.lockPure();
669
670        }
671
672        //----------------------------------------------------------------------------------
673        Result ResourceManager::unlockPure(const ::std::string& name){
674
675                // get appropriate holder
676                SharedPtr<ResourceHolder>* holder = getHolderByName(name);
677
678                if (holder != NULL){
679                        // lock the resource through the holder
680                        (*holder)->unlockPure();
681                }else{
682                        return RES_NOT_FOUND;
683                }
684
685                return OK;
686
687        }
688
689        //----------------------------------------------------------------------------------
690        Result ResourceManager::unlockPure(ResourceHandle& handle){
691
692                // get appropriate holder
693                SharedPtr<ResourceHolder>* holder = getHolderByHandle(handle);
694
695                if (holder != NULL){
696                        // lock the resource through the holder
697                        (*holder)->unlockPure();
698                }else{
699                        return RES_NOT_FOUND;
700                }
701
702                return OK;
703
704        }
705
706        //----------------------------------------------------------------------------------
707        Result ResourceManager::unlockPure(IResourcePtr& res){
708
709                // if pointer does not pointing anywhere
710                if (res.isNull()){
711                        return RES_ERROR;
712                }
713
714                // lock through the holder
715                res.getResourceHolder()->unlockPure();
716
717                return OK;
718        }
719
720        //----------------------------------------------------------------------------------
721        Result ResourceManager::unloadGroup(const ::std::string& group){
722
723                // check whenever such a group exists
724                res_grp_map::const_iterator it = mResourceGroup.find(group);
725                if (it == mResourceGroup.end()){
726                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not unload group \"%s\" because not found in database", group.c_str());
727                        return RES_GROUP_NOT_FOUND;
728                }
729
730                NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload the group \"%s\"", group.c_str());
731
732                // scan through all elements
733                ::std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
734                for (; jt != mResourceGroup[group].end(); jt++){
735                        Result ret = unload(*jt);
736                        if (ret != OK) return ret;
737                }
738
739                // OK
740                return OK;
741        }
742
743        //----------------------------------------------------------------------------------
744        Result ResourceManager::reloadGroup(const ::std::string& group){
745
746                // check whenever such a group exists
747                res_grp_map::const_iterator it = mResourceGroup.find(group);
748                if (it == mResourceGroup.end()){
749                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not reload group \"%s\" because not found in database", group.c_str());
750                        return RES_GROUP_NOT_FOUND;
751                }
752
753                NR_Log(Log::LOG_ENGINE, "ResourceManager: Reload the group \"%s\"", group.c_str());
754
755                // scan through all elements
756                ::std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
757                for (; jt != mResourceGroup[group].end(); jt++){
758                        Result ret = reload(*jt);
759                        if (ret != OK) return ret;
760                }
761
762                // OK
763                return OK;
764
765        }
766
767        //----------------------------------------------------------------------------------
768        Result ResourceManager::removeGroup(const ::std::string& group){
769
770                // check whenever such a group exists
771                res_grp_map::const_iterator it = mResourceGroup.find(group);
772                if (it == mResourceGroup.end()){
773                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not remove group \"%s\" because not found in database", group.c_str());
774                        return RES_GROUP_NOT_FOUND;
775                }
776
777                NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove all elements from the group \"%s\"", group.c_str());
778
779                // scan through all elements
780                ::std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
781                for (; jt != mResourceGroup[group].end(); jt++){
782                        Result ret = remove(*jt);
783                        if (ret != OK) return ret;
784                }
785
786                // remove the group
787                mResourceGroup.erase(group);
788
789                // OK
790                return OK;
791
792        }
793
794        //----------------------------------------------------------------------------------
795        const std::list<ResourceHandle>& ResourceManager::getGroupHandles(const std::string& name)
796        {
797                // check if such a group exists
798                res_grp_map::const_iterator it = mResourceGroup.find(name);
799
800                // return the empty list
801                if (it == mResourceGroup.end())
802                        return mEmptyResourceGroupHandleList;
803
804                // return the group to this name
805                return it->second;
806        }
807
808        //----------------------------------------------------------------------------------
809        SharedPtr<IResource> ResourceManager::getEmpty(const std::string& type)
810        {
811                res_empty_map::iterator it = mEmptyResource.find(type);
812                if (it == mEmptyResource.end())
813                {
814                        return SharedPtr<IResource>();
815                }
816
817                return it->second;
818        }
819
820        //----------------------------------------------------------------------------------
821        void ResourceManager::setEmpty(const std::string& type, SharedPtr<IResource> empty)
822        {
823                // check if empty is valid
824                if (empty == NULL) return;
825
826                // setup some default data on it
827                mEmptyResource[type] = empty;
828        }
829
830        //----------------------------------------------------------------------------------
831        bool ResourceManager::isResourceRegistered(const std::string& name)
832        {
833                IResourcePtr res = getByName(name);
834                return res.isNull() == false;
835        }
836
837        //----------------------------------------------------------------------------------
838        void ResourceManager::notifyLoaded(IResource* res)
839        {
840                if (res == NULL) return;
841
842                // check if such a resource is already in the database
843                if (isResourceRegistered(res->getResName())) return;
844
845                // get some data from the resource
846                const std::string& group = res->getResGroup();
847                const std::string& name = res->getResName();
848                const ResourceHandle& handle = res->getResHandle();
849                const std::string& type = res->getResType();
850
851                // get according empty resource object and give exception if no such exists
852                IResource* empty = getEmpty(type).get();
853                if (empty == NULL)
854                {
855                        char msg[128];
856                        sprintf(msg, "There was no empty resource created for the type %s", type.c_str());
857                        NR_EXCEPT(RES_NO_EMPTY_RES_FOUND, std::string(msg), "ResourceManager::notifyLoaded()");
858                }
859
860                // get name of the resource and create a holder for this
861                SharedPtr<ResourceHolder> holder(new ResourceHolder(res, empty));
862
863                // store the resource in database
864                mResourceGroup[group].push_back(handle);
865                mResource[handle] = holder;
866                mResourceName[name] = handle;
867
868                //printf("LOADED: %s\n", holder->getResource()->getResName().c_str());
869        }
870
871        //----------------------------------------------------------------------------------
872        void ResourceManager::notifyCreated(IResource* res)
873        {
874                notifyLoaded(res);
875        }
876
877        //----------------------------------------------------------------------------------
878        void ResourceManager::notifyUnloaded(IResource*)
879        {
880
881        }
882
883        //----------------------------------------------------------------------------------
884        void ResourceManager::notifyRemove(IResource* res)
885        {
886                if (res == NULL) return;
887
888                // check if such a resource is already in the database
889                if (!isResourceRegistered(res->getResName())) return;
890
891                // get some data from the resource
892                const std::string& group = res->getResGroup();
893                const std::string& name = res->getResName();
894                const ResourceHandle& handle = res->getResHandle();
895
896                NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %s (%s)", name.c_str(), group.c_str());
897
898                if (handle == 0){
899                        NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not remove resource %s because it is not in the database", name.c_str());
900                        return;
901                }
902
903                // remove the handle from the group list
904                if (group.length() > 0){
905                        res_grp_map::iterator jt = mResourceGroup.find(group);
906                        if (jt != mResourceGroup.end()){
907                                jt->second.remove(handle);
908
909                                // check whenever group contains no more elements, and delete it
910                                if (jt->second.size() == 0){
911                                        mResourceGroup.erase(group);
912                                        NR_Log(Log::LOG_ENGINE, "ResourceManager: %s's group \"%s\" does not contain elements, so remove it", name.c_str(), group.c_str());
913                                }
914                        }else{
915                                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());
916                        }
917                }
918                // get the according holder and remove the resource there
919                SharedPtr<ResourceHolder>& holder = *getHolderByName(name);
920                if (holder == NULL){
921                        NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceManager: Could not find resource holder for %s", name.c_str());
922                        return;
923                }
924                holder->resetRes(NULL);
925
926                // clear the database
927                mResourceName.erase(name);
928                mResource.erase(handle);
929        }
930
931};
932
Note: See TracBrowser for help on using the repository browser.