ResourceManager.cpp

00001 /***************************************************************************
00002  *                                                                         *
00003  *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
00004  *       mailto: <tevs@mpi-sb.mpg.de>                                      *
00005  *                                                                         *
00006  *   This program is free software; you can redistribute it and/or modify  *
00007  *   it under the terms of the GNU General Public License as published by  *
00008  *   the Free Software Foundation; either version 2 of the License, or     *
00009  *   (at your option) any later version.                                   *
00010  *                                                                         *
00011  ***************************************************************************/
00012 
00013 //----------------------------------------------------------------------------------
00014 // Includes
00015 //----------------------------------------------------------------------------------
00016 #include "ResourceManager.h"
00017 #include "Log.h"
00018 #include "Exception.h"
00019 #include "Engine.h"
00020 
00021 namespace nrEngine{
00022 
00023         //----------------------------------------------------------------------------------
00024         ScriptFunctionDec(scriptLoadResource, ResourceManager)
00025         {
00026                 // check parameter count
00027                 if (args.size() < 3){
00028                         return ScriptResult(std::string("Not valid parameter count! Parameters (name,group,filename [,type])"));
00029                 }
00030 
00031                 std::string type;
00032                 if (args.size() == 5 ) type = args[4];
00033 
00034                 // load a resource with the given name in a group from a file
00035                 if (Engine::sResourceManager()->loadResource(args[1], args[2], args[3], type).isNull())
00036                 {
00037                         char msg[128];
00038                         sprintf(msg, "There was an error by loading a resource %s from %s", args[1].c_str(), args[3].c_str());
00039                         return ScriptResult(std::string(msg));
00040                 }
00041 
00042                 return ScriptResult();
00043         }
00044 
00045         //----------------------------------------------------------------------------------
00046         ScriptFunctionDec(scriptUnloadResource, ResourceManager)
00047         {
00048                 // check parameter count
00049                 if (args.size() < 1){
00050                         return ScriptResult(std::string("Not valid parameter count! You should specify (name)"));
00051                 }
00052 
00053                 // unload resource and check for return code
00054                 if (Engine::sResourceManager()->unload(args[1]) != OK)
00055                 {
00056                         char msg[128];
00057                         sprintf(msg, "Could not unload %s", args[1].c_str());
00058                         return ScriptResult(std::string(msg));
00059                 }
00060 
00061                 return ScriptResult();
00062         }
00063 
00064         //----------------------------------------------------------------------------------
00065         ResourceManager::ResourceManager(){
00066                 mLastHandle = 1;
00067 
00068                 // register functions by scripting engine
00069                 Engine::sScriptEngine()->add("loadResource", scriptLoadResource);
00070                 Engine::sScriptEngine()->add("unloadResource", scriptUnloadResource);
00071 
00072         }
00073 
00074 
00075         //----------------------------------------------------------------------------------
00076         ResourceManager::~ResourceManager(){
00077 
00078                 // remove registered functions
00079                 Engine::sScriptEngine()->del("loadResource");
00080                 Engine::sScriptEngine()->del("unloadResource");
00081 
00082                 // unload all resources
00083                 removeAllRes();
00084 
00085                 // remove all loaders
00086                 removeAllLoaders();
00087 
00088         }
00089 
00090         //----------------------------------------------------------------------------------
00091         void ResourceManager::removeAllRes()
00092         {
00093 
00094                 // iterate through each resource and remove it
00095                 /*res_hdl_map::const_iterator it;
00096 
00097                 for (it = mResource.begin(); it != mResource.end(); it++){
00098                         ResourceHandle hdl = it->first;
00099                         remove(hdl);
00100                 }
00101                 mResource.clear();
00102                 */
00103 
00104                 // iterate through each empty resource and remove it
00105                 res_empty_map::iterator jt;
00106 
00107                 for (jt = mEmptyResource.begin(); jt != mEmptyResource.end(); jt++){
00108                         SharedPtr<IResource>& res = jt->second;
00109 
00110                         NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceManager: Remove empty resource of type %s", res->getResourceType().c_str());
00111                         res.reset();
00112                         mEmptyResource.erase(jt);
00113                 }
00114                 mEmptyResource.clear();
00115 
00116         }
00117 
00118         //----------------------------------------------------------------------------------
00119         void ResourceManager::removeAllLoaders(){
00120 
00121                 // iterate through all loaders
00122                 loader_map::const_iterator it;
00123 
00124                 for (it = mLoader.begin(); it != mLoader.end(); it++){
00125                         removeLoader(it->first);
00126                 }
00127 
00128         }
00129 
00130         //----------------------------------------------------------------------------------
00131         /*Result ResourceManager::setMemoryBudget(size_t bytes){
00132                 mMemBudget = bytes;
00133                 return checkMemoryUsage();
00134         }
00135 
00136 
00137         //----------------------------------------------------------------------------------
00138         size_t ResourceManager::getMemoryBudget() const{
00139                 return mMemBudget;
00140         }
00141 
00142         //----------------------------------------------------------------------------------
00143         size_t ResourceManager::getMemoryUsage() const{
00144                 return mMemUsage;
00145         }*/
00146 
00147         //----------------------------------------------------------------------------------
00148         Result ResourceManager::registerLoader(const std::string& name, ResourceLoader loader){
00149 
00150                 // check whenver such a loader already exists
00151                 if (mLoader.find(name) != mLoader.end()){
00152                         NR_Log(Log::LOG_ENGINE, "ResourceManager: %s loader already registered", name.c_str());
00153                         return RES_LOADER_ALREADY_EXISTS;
00154                 }
00155 
00156                 // check for bad parameters
00157                 if (loader == NULL || name.length() == 0){
00158                         return BAD_PARAMETERS;
00159                 }
00160 
00161                 NR_Log(Log::LOG_ENGINE, "ResourceManager: Register new resource loader %s", name.c_str());
00162 
00163                 // register the loader
00164                 mLoader[name] = loader;
00165 
00166                 // Give some log information about supported filetypes and resource types
00167                 try{
00168                         std::vector< std::string>::const_iterator it;
00169                         std::string strTemp;
00170 
00171                         const std::vector< std::string>&        fileTypes = loader->getSupportedFileTypes();
00172                         for (it = fileTypes.begin(); it != fileTypes.end(); it++){
00173                                 strTemp += (*it) + " ";
00174                         }
00175                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Found loader \"%s\" for file types %s", name.c_str(), strTemp.c_str());
00176                         strTemp = "";
00177 
00178                         const std::vector< std::string>&        resTypes = loader->getSupportedResourceTypes();
00179                         for (it = resTypes.begin(); it != resTypes.end(); it++){
00180                                 strTemp += (*it) + " ";
00181                         }
00182                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Found loader \"%s\" for resource types %s", name.c_str(), strTemp.c_str());
00183                 }catch(...){
00184                         return BAD_PARAMETERS;
00185                 }
00186 
00187                 return OK;
00188         }
00189 
00190         //----------------------------------------------------------------------------------
00191         Result ResourceManager::removeLoader(const std::string& name){
00192 
00193                 // get id of the loader
00194                 loader_map::iterator jt = mLoader.find(name);
00195                 if (jt == mLoader.end()){
00196                         return RES_LOADER_NOT_REGISTERED;
00197                 }
00198 
00199                 NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove loader %s", name.c_str());
00200 
00201                 mLoader.erase(name);
00202 
00203                 return OK;
00204         }
00205 
00206         //----------------------------------------------------------------------------------
00207         ResourceLoader ResourceManager::getLoaderByFile(const std::string& fileType){
00208 
00209                 if (fileType.length() == 0) return ResourceLoader();
00210 
00211                 // scan through all loaders and ask them if they do support this kind of file type
00212                 loader_map::const_iterator it;
00213 
00214                 for (it = mLoader.begin(); it != mLoader.end(); it++){
00215                         if (it->second->supportFileType(fileType)){
00216                                 return it->second;
00217                         }
00218                 }
00219 
00220                 // Give some log information
00221                 NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceManager: There is no loader for *.%s files", fileType.c_str());
00222 
00223                 return ResourceLoader();
00224         }
00225 
00226         //----------------------------------------------------------------------------------
00227         ResourceLoader ResourceManager::getLoader(const std::string& name){
00228 
00229                 loader_map::iterator it = mLoader.find(name);
00230 
00231                 if (it == mLoader.end()){
00232                         return ResourceLoader();
00233                 }
00234 
00235                 return mLoader[name];
00236         }
00237 
00238         //----------------------------------------------------------------------------------
00239         ResourceLoader ResourceManager::getLoaderByResource(const std::string& resType){
00240 
00241                 // scan through all loaders and ask them if they do support this kind of file type
00242                 loader_map::const_iterator it;
00243 
00244                 for (it = mLoader.begin(); it != mLoader.end(); it++){
00245                         if (it->second->supportResourceType(resType)){
00246                                 return it->second;
00247                         }
00248                 }
00249 
00250                 return ResourceLoader();
00251 
00252         }
00253 
00254         //----------------------------------------------------------------------------------
00255         IResourcePtr ResourceManager::createResource (const std::string& name, const std::string& group, const std::string& resourceType, PropertyList* params)
00256         {
00257                 // check if such a resource already exists
00258                 IResourcePtr pRes = getByName(name);
00259                 if (!pRes.isNull()){
00260                         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());
00261                         return pRes;
00262                 }
00263 
00264                 // Get appropriate loader/creator
00265                 ResourceLoader creator = getLoaderByResource(resourceType);
00266                 if (creator == NULL){
00267                         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());
00268                         return IResourcePtr();
00269                 }
00270 
00271                 // now call the loader to create a resource
00272                 SharedPtr<IResource> res (creator->create(name, group, resourceType, params));
00273                 if (res.get() == NULL)
00274                 {
00275                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not create a resource %s of %s type", name.c_str(), resourceType.c_str());
00276                         return IResourcePtr();
00277                 }
00278 
00279                 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());
00280 
00281                 // get the holder for this resource, it must be there
00282                 SharedPtr<ResourceHolder>& holder = *getHolderByName(name);
00283                 NR_ASSERT(holder != NULL && "Holder must be valid here!");
00284 
00285                 return IResourcePtr(holder);
00286         }
00287 
00288 
00289         //----------------------------------------------------------------------------------
00290         IResourcePtr ResourceManager::loadResource(
00291                         const std::string& name,const std::string& group,const std::string& fileName,
00292                         const std::string& resourceType,PropertyList* params,ResourceLoader loader)
00293         {
00294 
00295                 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());
00296 
00297                 // check for right parameters
00298                 if (name.length() == 0 || fileName.length() == 0)
00299                         return IResourcePtr();
00300 
00301                 // check whenever such a resource already exists
00302                 IResourcePtr pRes = getByName(name);
00303                 if (!pRes.isNull()){
00304                         NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceManager: Resource %s already loaded. Do nothing.", name.c_str());
00305                         return pRes;
00306                 }
00307 
00308                 // detect the file type by reading out it's last characters
00309                 std::string type;
00310                 for (int32 i = fileName.length()-1; i >= 0; i--){
00311                         if (fileName[i] == '.'){
00312                                 break;
00313                         }
00314                         type = fileName[i] + type;
00315                 }
00316                 bool isManualSpecified = (loader != NULL);
00317 
00318                 // if the loader is manually specified, so do nothing
00319                 if (!isManualSpecified)
00320                 {
00321                         loader = getLoaderByResource(resourceType);
00322                         if (loader == NULL) loader = getLoaderByFile(type);
00323 
00324                         if (loader == NULL){
00325                                 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());
00326                                 return IResourcePtr();
00327                         }
00328                 }
00329 
00330                 // now call the loader to create a resource
00331                 // loader will notify the manager, manager will add it into database
00332                 SharedPtr<IResource> res = loader->load(name, group, fileName, resourceType, params);
00333                 if (res == NULL) return IResourcePtr();
00334 
00335                 // get the holder for this resource, it must be there
00336                 SharedPtr<ResourceHolder>& holder = *getHolderByName(name);
00337                 NR_ASSERT(holder.get() != NULL && "Holder must be valid here!");
00338 
00339                 return IResourcePtr(holder);
00340         }
00341 
00342         //----------------------------------------------------------------------------------
00343         Result ResourceManager::unload(const std::string& name){
00344 
00345                 ResourcePtr<IResource> res = getByName(name);
00346 
00347                 if (res.isNull()){
00348                         return RES_NOT_FOUND;
00349                 }
00350 
00351                 lockResource(res);
00352                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload resource %s", res->getResourceName().c_str(), res->getResourceHandle());
00353                         Result ret = res->unload();
00354                 unlockResource(res);
00355 
00356                 return ret;
00357         }
00358 
00359         //----------------------------------------------------------------------------------
00360         Result ResourceManager::unload(IResourcePtr& res){
00361 
00362                 if (res.isNull()){
00363                         return RES_NOT_FOUND;
00364                 }
00365 
00366                 lockResource(res);
00367                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload resource %s",
00368                                 res.getBase()->getResourceName().c_str(), res.getBase()->getResourceHandle());
00369                         Result ret = res.getBase()->unload();
00370                 unlockResource(res);
00371 
00372                 return ret;
00373         }
00374 
00375         //----------------------------------------------------------------------------------
00376         Result ResourceManager::unload(ResourceHandle& handle){
00377 
00378                 ResourcePtr<IResource> res = getByHandle(handle);
00379 
00380                 if (res.isNull()){
00381                         return RES_NOT_FOUND;
00382                 }
00383 
00384                 lockResource(res);
00385                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload resource %s",
00386                                 res->getResourceName().c_str(), res->getResourceHandle());
00387                         Result ret = res->unload();
00388                 unlockResource(res);
00389 
00390                 return ret;
00391         }
00392 
00393         //----------------------------------------------------------------------------------
00394         Result ResourceManager::reload(const std::string& name){
00395 
00396                 ResourcePtr<IResource> res = getByName(name);
00397 
00398                 if (res.isNull()){
00399                         return RES_NOT_FOUND;
00400                 }
00401 
00402                 lockResource(res);
00403                         NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceManager: Reload resource %s",
00404                                 res->getResourceName().c_str(), res->getResourceHandle());
00405                         Result ret = res->reload();
00406                 unlockResource(res);
00407 
00408                 return ret;
00409         }
00410 
00411         //----------------------------------------------------------------------------------
00412         Result ResourceManager::reload(ResourceHandle& handle){
00413 
00414                 ResourcePtr<IResource> res = getByHandle(handle);
00415 
00416                 if (res.isNull()){
00417                         return RES_NOT_FOUND;
00418                 }
00419 
00420                 lockResource(res);
00421                         NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceManager: Reload resource %s",
00422                                 res->getResourceName().c_str(), res->getResourceHandle());
00423                         Result ret = res->reload();
00424                 unlockResource(res);
00425 
00426                 return ret;
00427         }
00428 
00429         //----------------------------------------------------------------------------------
00430         Result ResourceManager::reload(IResourcePtr& res){
00431 
00432                 if (res.isNull()){
00433                         return RES_NOT_FOUND;
00434                 }
00435 
00436                 lockResource(res);
00437                         NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceManager: Reload resource %s",
00438                                 res.getBase()->getResourceName().c_str(), res.getBase()->getResourceHandle());
00439                         Result ret = res.getBase()->reload();
00440                 unlockResource(res);
00441 
00442                 return ret;
00443         }
00444 
00445         //----------------------------------------------------------------------------------
00446 /*      Result ResourceManager::removeImpl(IResourcePtr& resPtr){
00447 
00448                 NR_ASSERT(!resPtr.isNull() && "Given pointer shouldn't be zero");
00449 
00450                 // we need to lock the resource, because we need the real resource object not empty
00451                 lockResource(resPtr);
00452 
00453                         ResourcePtr<IResource> ptr = resPtr;
00454                         ResourceHandle hdl = ptr->getResourceHandle();
00455                         std::string name = ptr->getResourceName();
00456                         std::string grp = ptr->getResourceGroup();
00457 
00458                         if (hdl == 0){
00459                                 NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not remove resource %s because it is not in the database", name.c_str());
00460                                 return RES_NOT_FOUND;
00461                         }
00462 
00463                         // first unload it
00464                         unload(resPtr);
00465 
00466                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %s (%s)", name.c_str(), grp.c_str());
00467 
00468                         // remove the handle from the group list
00469                         if (grp.length() > 0){
00470                                 res_grp_map::iterator jt = mResourceGroup.find(grp);
00471                                 if (jt != mResourceGroup.end()){
00472                                         jt->second.remove(hdl);
00473 
00474                                         // check whenever group contains nomore elements, and delete it
00475                                         if (jt->second.size() == 0){
00476                                                 mResourceGroup.erase(grp);
00477                                                 NR_Log(Log::LOG_ENGINE, "ResourceManager: %s's group \"%s\" does not contain elements, so remove it", name.c_str(), grp.c_str());
00478                                         }
00479                                 }else{
00480                                         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());
00481                                 }
00482                         }
00483 
00484                 // unlock it back
00485                 unlockResource(resPtr);
00486 
00487                 // clear the database
00488                 mResourceName.erase(name);
00489                 mResource.erase(hdl);
00490 
00491                 return OK;
00492         }
00493 */
00494         //----------------------------------------------------------------------------------
00495         Result ResourceManager::remove(const std::string& name){
00496 
00497                 // check whenever such a resource exists
00498                 IResourcePtr ptr = getByName(name);
00499 
00500                 if (ptr.isNull()){
00501                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %s not found", name.c_str());
00502                         return RES_NOT_FOUND;
00503                 }
00504 
00505                 lockResource(ptr);
00506                         Result ret = ptr.getBase()->remove();
00507                 unlockResource(ptr);
00508 
00509                 return ret;
00510         }
00511 
00512         //----------------------------------------------------------------------------------
00513         Result ResourceManager::remove(ResourceHandle& handle){
00514 
00515                 // check whenever such a resource exists
00516                 IResourcePtr ptr = getByHandle(handle);
00517 
00518                 if (ptr.isNull()){
00519                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %d not found", handle);
00520                         return RES_NOT_FOUND;
00521                 }
00522 
00523                 lockResource(ptr);
00524                         Result ret = ptr.getBase()->remove();
00525                 unlockResource(ptr);
00526 
00527                 return ret;
00528         }
00529 
00530         //----------------------------------------------------------------------------------
00531         Result ResourceManager::remove(IResourcePtr& ptr){
00532 
00533                 // check whenever such a resource exists
00534                 if (!ptr.isNull()){
00535                         lockResource(ptr);
00536                                 Result ret = ptr.getBase()->remove();
00537                         unlockResource(ptr);
00538 
00539                         return ret;
00540                 }
00541                 return OK;
00542         }
00543 
00544         //----------------------------------------------------------------------------------
00545         SharedPtr<ResourceHolder>* ResourceManager::getHolderByName(const std::string& name)
00546         {
00547                 // find the handle
00548                 res_str_map::iterator it = mResourceName.find(name);
00549                 if (it == mResourceName.end()){
00550                         return NULL;
00551                 }
00552 
00553                 // get through the handle the holder
00554                 res_hdl_map::iterator jt = mResource.find(it->second);
00555                 NR_ASSERT(jt != mResource.end() && "Fatal Error in the Database !!!");
00556                 return &(jt->second);
00557         }
00558 
00559         //----------------------------------------------------------------------------------
00560         SharedPtr<ResourceHolder>* ResourceManager::getHolderByHandle(const ResourceHandle& handle)
00561         {
00562                 // find through the handle
00563                 res_hdl_map::iterator it = mResource.find(handle);
00564                 if (it == mResource.end())
00565                 {
00566                         return NULL;
00567                 }
00568                 return &(it->second);
00569         }
00570 
00571         //----------------------------------------------------------------------------------
00572         IResourcePtr ResourceManager::getByName(const std::string& name){
00573                 SharedPtr<ResourceHolder>* holder = getHolderByName(name);
00574                 if (holder == NULL){
00575                         return IResourcePtr();
00576                 }
00577 
00578                 return IResourcePtr(*holder);
00579         }
00580 
00581         //----------------------------------------------------------------------------------
00582         IResourcePtr ResourceManager::getByHandle(const ResourceHandle& handle){
00583                 SharedPtr<ResourceHolder>* holder = getHolderByHandle(handle);
00584                 if (holder == NULL){
00585                         return IResourcePtr();
00586                 }
00587                 return IResourcePtr(*holder);
00588         }
00589 
00590         //----------------------------------------------------------------------------------
00591 /*      Result ResourceManager::add(IResource* res, const std::string& name, const std::string& group)
00592         {
00593 
00594                 // check for bad parameters
00595                 if (res == NULL) return OK;
00596                 if (name.length() == 0) return BAD_PARAMETERS;
00597                 if (res->mResLoader == NULL) return RES_LOADER_NOT_EXISTS;
00598 
00599                 // check whenever such resource already exists
00600                 if (!getByName(name).isNull()){
00601                         NR_Log(Log::LOG_ENGINE, "ResourceManager: WARNING: Add resource %s but it already exists", name.c_str());
00602                         return OK;
00603                 }
00604 
00605                 ResourceHandle handle = mLastHandle++;
00606                 NR_Log(Log::LOG_ENGINE, "ResourceManager: Add resource %s id=%d to the database from outside", name.c_str(), handle);
00607 
00608                 // check now if a empty resource of that type already exists and load it if not
00609                 SharedPtr<IResource> empty;
00610                 checkEmptyResource(res->getResourceType(), empty, res->mResLoader);
00611 
00612                 // create a holder for that resource
00613                 SharedPtr<ResourceHolder> holder(new ResourceHolder());
00614                 holder->resetRes(res);
00615                 holder->setEmptyResource(empty);
00616 
00617                 // store the resource in database
00618                 mResourceGroup[group].push_back(handle);
00619                 mResource[handle] = holder;
00620                 mResourceName[name] = handle;
00621 
00622                 res->mResGroup = group;
00623                 res->mResName = name;
00624                 res->mResHandle = handle;
00625                 res->mParentManager = this;
00626 
00627                 // check for memory usage
00628                 mMemUsage += holder->getResource()->getResDataSize();
00629                 Result ret = checkMemoryUsage();
00630 
00631                 if (ret != OK){
00632                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Could not rearrange memory");
00633                         return ret;
00634                 }
00635 
00636                 // return a pointer to that resource
00637                 return OK;
00638         }
00639 */
00640 
00641         //----------------------------------------------------------------------------------
00642         Result ResourceManager::lockResource(const std::string& name){
00643 
00644                 // get appropriate pointer
00645                 IResourcePtr ptr = getByName(name);
00646 
00647                 // if it is null, so we do not have such a resource
00648                 if (ptr.isNull()) return RES_NOT_FOUND;
00649 
00650                 return ptr.lockResource();
00651         }
00652 
00653         //----------------------------------------------------------------------------------
00654         Result ResourceManager::lockResource(ResourceHandle& handle){
00655 
00656                 // get appropriate pointer
00657                 IResourcePtr ptr = getByHandle(handle);
00658 
00659                 // if it is null, so we do not have such a resource
00660                 if (ptr.isNull()) return RES_NOT_FOUND;
00661 
00662                 return ptr.lockResource();
00663 
00664         }
00665 
00666         //----------------------------------------------------------------------------------
00667         Result ResourceManager::lockResource(IResourcePtr& res){
00668 
00669                 // lock through the pointer
00670                 return res.lockResource();
00671 
00672         }
00673 
00674         //----------------------------------------------------------------------------------
00675         Result ResourceManager::unlockResource(const std::string& name){
00676 
00677                 // get appropriate holder
00678                 SharedPtr<ResourceHolder>* holder = getHolderByName(name);
00679 
00680                 if (holder != NULL){
00681                         // lock the resource through the holder
00682                         (*holder)->unlockResource();
00683                 }else{
00684                         return RES_NOT_FOUND;
00685                 }
00686 
00687                 return OK;
00688 
00689         }
00690 
00691         //----------------------------------------------------------------------------------
00692         Result ResourceManager::unlockResource(ResourceHandle& handle){
00693 
00694                 // get appropriate holder
00695                 SharedPtr<ResourceHolder>* holder = getHolderByHandle(handle);
00696 
00697                 if (holder != NULL){
00698                         // lock the resource through the holder
00699                         (*holder)->unlockResource();
00700                 }else{
00701                         return RES_NOT_FOUND;
00702                 }
00703 
00704                 return OK;
00705 
00706         }
00707 
00708         //----------------------------------------------------------------------------------
00709         Result ResourceManager::unlockResource(IResourcePtr& res){
00710 
00711                 // if pointer does not pointing anywhere
00712                 if (res.isNull()){
00713                         return RES_ERROR;
00714                 }
00715 
00716                 // lock through the holder
00717                 res.getResourceHolder()->unlockResource();
00718 
00719                 return OK;
00720         }
00721 
00722         //----------------------------------------------------------------------------------
00723         Result ResourceManager::unloadGroup(const std::string& group){
00724 
00725                 // check whenever such a group exists
00726                 ResourceGroupMap::const_iterator it = mResourceGroup.find(group);
00727                 if (it == mResourceGroup.end()){
00728                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not unload group \"%s\" because not found in database", group.c_str());
00729                         return RES_GROUP_NOT_FOUND;
00730                 }
00731 
00732                 NR_Log(Log::LOG_ENGINE, "ResourceManager: Unload the group \"%s\"", group.c_str());
00733 
00734                 // scan through all elements
00735                 std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
00736                 for (; jt != mResourceGroup[group].end(); jt++){
00737                         Result ret = unload(*jt);
00738                         if (ret != OK) return ret;
00739                 }
00740 
00741                 // OK
00742                 return OK;
00743         }
00744 
00745         //----------------------------------------------------------------------------------
00746         Result ResourceManager::reloadGroup(const std::string& group){
00747 
00748                 // check whenever such a group exists
00749                 ResourceGroupMap::const_iterator it = mResourceGroup.find(group);
00750                 if (it == mResourceGroup.end()){
00751                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not reload group \"%s\" because not found in database", group.c_str());
00752                         return RES_GROUP_NOT_FOUND;
00753                 }
00754 
00755                 NR_Log(Log::LOG_ENGINE, "ResourceManager: Reload the group \"%s\"", group.c_str());
00756 
00757                 // scan through all elements
00758                 std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
00759                 for (; jt != mResourceGroup[group].end(); jt++){
00760                         Result ret = reload(*jt);
00761                         if (ret != OK) return ret;
00762                 }
00763 
00764                 // OK
00765                 return OK;
00766 
00767         }
00768 
00769         //----------------------------------------------------------------------------------
00770         Result ResourceManager::removeGroup(const std::string& group){
00771 
00772                 // check whenever such a group exists
00773                 ResourceGroupMap::const_iterator it = mResourceGroup.find(group);
00774                 if (it == mResourceGroup.end()){
00775                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not remove group \"%s\" because not found in database", group.c_str());
00776                         return RES_GROUP_NOT_FOUND;
00777                 }
00778 
00779                 NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove all elements from the group \"%s\"", group.c_str());
00780 
00781                 // scan through all elements
00782                 std::list<ResourceHandle>::iterator jt = mResourceGroup[group].begin();
00783                 for (; jt != mResourceGroup[group].end(); jt++){
00784                         Result ret = remove(*jt);
00785                         if (ret != OK) return ret;
00786                 }
00787 
00788                 // remove the group
00789                 mResourceGroup.erase(group);
00790 
00791                 // OK
00792                 return OK;
00793 
00794         }
00795 
00796         //----------------------------------------------------------------------------------
00797         const std::list<ResourceHandle>& ResourceManager::getGroupHandles(const std::string& name)
00798         {
00799                 // check if such a group exists
00800                 ResourceGroupMap::const_iterator it = mResourceGroup.find(name);
00801 
00802                 // return the empty list
00803                 if (it == mResourceGroup.end())
00804                         return mEmptyResourceGroupHandleList;
00805 
00806                 // return the group to this name
00807                 return it->second;
00808         }
00809 
00810         //----------------------------------------------------------------------------------
00811         SharedPtr<IResource> ResourceManager::getEmpty(const std::string& type)
00812         {
00813                 res_empty_map::iterator it = mEmptyResource.find(type);
00814                 if (it == mEmptyResource.end())
00815                 {
00816                         return SharedPtr<IResource>();
00817                 }
00818 
00819                 return it->second;
00820         }
00821 
00822         //----------------------------------------------------------------------------------
00823         void ResourceManager::setEmpty(const std::string& type, SharedPtr<IResource> empty)
00824         {
00825                 // check if empty is valid
00826                 if (empty == NULL) return;
00827 
00828                 // setup some default data on it
00829                 mEmptyResource[type] = empty;
00830         }
00831 
00832         //----------------------------------------------------------------------------------
00833         bool ResourceManager::isResourceRegistered(const std::string& name)
00834         {
00835                 IResourcePtr res = getByName(name);
00836                 return res.isNull() == false;
00837         }
00838 
00839         //----------------------------------------------------------------------------------
00840         void ResourceManager::notifyLoaded(IResource* res)
00841         {
00842                 if (res == NULL) return;
00843 
00844                 // check if such a resource is already in the database
00845                 if (isResourceRegistered(res->getResourceName())) return;
00846 
00847                 // get some data from the resource
00848                 const std::string& group = res->getResourceGroup();
00849                 const std::string& name = res->getResourceName();
00850                 const ResourceHandle& handle = res->getResourceHandle();
00851                 const std::string& type = res->getResourceType();
00852 
00853                 // get according empty resource object and give exception if no such exists
00854                 IResource* empty = getEmpty(type).get();
00855                 if (empty == NULL)
00856                 {
00857                         char msg[128];
00858                         sprintf(msg, "There was no empty resource created for the type %s", type.c_str());
00859                         NR_EXCEPT(RES_NO_EMPTY_RES_FOUND, std::string(msg), "ResourceManager::notifyLoaded()");
00860                 }
00861 
00862                 // get name of the resource and create a holder for this
00863                 SharedPtr<ResourceHolder> holder(new ResourceHolder(res, empty));
00864 
00865                 // store the resource in database
00866                 mResourceGroup[group].push_back(handle);
00867                 mResource[handle] = holder;
00868                 mResourceName[name] = handle;
00869 
00870                 //printf("LOADED: %s\n", holder->getResource()->getResourceName().c_str());
00871         }
00872 
00873         //----------------------------------------------------------------------------------
00874         void ResourceManager::notifyCreated(IResource* res)
00875         {
00876                 notifyLoaded(res);
00877         }
00878 
00879         //----------------------------------------------------------------------------------
00880         void ResourceManager::notifyUnloaded(IResource*)
00881         {
00882 
00883         }
00884 
00885         //----------------------------------------------------------------------------------
00886         void ResourceManager::notifyRemove(IResource* res)
00887         {
00888                 if (res == NULL) return;
00889 
00890                 // check if such a resource is already in the database
00891                 if (!isResourceRegistered(res->getResourceName())) return;
00892 
00893                 // get some data from the resource
00894                 const std::string& group = res->getResourceGroup();
00895                 const std::string& name = res->getResourceName();
00896                 const ResourceHandle& handle = res->getResourceHandle();
00897 
00898                 NR_Log(Log::LOG_ENGINE, "ResourceManager: Remove resource %s (%s)", name.c_str(), group.c_str());
00899 
00900                 if (handle == 0){
00901                         NR_Log(Log::LOG_ENGINE, "ResourceManager: Can not remove resource %s because it is not in the database", name.c_str());
00902                         return;
00903                 }
00904 
00905                 // remove the handle from the group list
00906                 if (group.length() > 0){
00907                         ResourceGroupMap::iterator jt = mResourceGroup.find(group);
00908                         if (jt != mResourceGroup.end()){
00909                                 jt->second.remove(handle);
00910 
00911                                 // check whenever group contains no more elements, and delete it
00912                                 if (jt->second.size() == 0){
00913                                         mResourceGroup.erase(group);
00914                                         NR_Log(Log::LOG_ENGINE, "ResourceManager: %s's group \"%s\" does not contain elements, so remove it", name.c_str(), group.c_str());
00915                                 }
00916                         }else{
00917                                 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());
00918                         }
00919                 }
00920                 // get the according holder and remove the resource there
00921                 SharedPtr<ResourceHolder>& holder = *getHolderByName(name);
00922                 if (holder == NULL){
00923                         NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceManager: Could not find resource holder for %s", name.c_str());
00924                         return;
00925                 }
00926                 holder->resetResource(NULL);
00927 
00928                 // clear the database
00929                 mResourceName.erase(name);
00930                 mResource.erase(handle);
00931         }
00932 
00933 };
00934 

Generated on Wed Sep 12 23:19:42 2007 for nrEngine by  doxygen 1.5.1