Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreResourceManager.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright © 2000-2002 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #include "OgreStableHeaders.h"
00026 #include "OgreResourceManager.h"
00027 
00028 #include "OgreException.h"
00029 #include "OgreArchiveEx.h"
00030 #include "OgreArchiveManager.h"
00031 #include "OgreStringVector.h"
00032 #include "OgreStringConverter.h"
00033 
00034 namespace Ogre {
00035 
00036     std::vector<ArchiveEx*> ResourceManager::mCommonVFS;
00037     ResourceManager::FileMap ResourceManager::mCommonArchiveFiles;
00038 
00041     static String convertPath( const String &init)
00042     {
00043         String path = init;
00044 
00045         std::replace( path.begin(), path.end(), '\\', '/' );
00046         if( path[path.length() - 1] != '/' )
00047             path += '/';
00048 
00049         return path;
00050     }
00051 
00052     //-----------------------------------------------------------------------
00053     ResourceManager::ResourceManager()
00054     {
00055         // Init memory limit & usage
00056         mMemoryBudget = std::numeric_limits<unsigned long>::max();
00057         mMemoryUsage = 0;
00058         mNextHandle = 1;
00059     }
00060     //-----------------------------------------------------------------------
00061     ResourceManager::~ResourceManager()
00062     {
00063         this->unloadAndDestroyAll();
00064     }
00065 
00066     //-----------------------------------------------------------------------
00067     void ResourceManager::load(Resource *res, int priority)
00068     {
00069         res->load();
00070         res->touch();
00071         this->add(res);
00072     }
00073 
00074     //-----------------------------------------------------------------------
00075     void ResourceManager::add( Resource *res )
00076     {
00077         std::pair<ResourceMap::iterator, bool> result = 
00078             mResources.insert( ResourceMap::value_type( res->getName(), res ) );
00079         if (!result.second)
00080         {
00081             Except(Exception::ERR_DUPLICATE_ITEM, "Resource with the name " + res->getName() + 
00082                 " already exists.", "ResourceManager::add");
00083         }
00084         // Assign a new handle
00085         res->mHandle = getNextHandle();
00086         std::pair<ResourceHandleMap::iterator, bool> resultHandle = 
00087             mResourcesByHandle.insert( ResourceHandleMap::value_type( res->mHandle, res ) );
00088         if (!result.second)
00089         {
00090             Except(Exception::ERR_DUPLICATE_ITEM, "Resource with the handle " + 
00091                 StringConverter::toString(res->mHandle) + 
00092                 " already exists.", "ResourceManager::add");
00093         }
00094 
00095     }
00096     //-----------------------------------------------------------------------
00097     void ResourceManager::setMemoryBudget( size_t bytes)
00098     {
00099         // Update limit & check usage
00100         mMemoryBudget = bytes;
00101         checkUsage();
00102     }
00103 
00104     //-----------------------------------------------------------------------
00105     void ResourceManager::unload(Resource* res)
00106     {
00107         if (!res)
00108             return;
00109 
00110         // Unload resource
00111         res->unload();
00112 
00113         // Erase entry in map
00114         mResources.erase( res->getName() );
00115         mResourcesByHandle.erase( res->getHandle() );
00116 
00117         // Update memory usage
00118         mMemoryUsage -= res->getSize();
00119     }
00120 
00121     //-----------------------------------------------------------------------
00122     void ResourceManager::unloadAndDestroyAll()
00123     {
00124         // Unload & delete resources in turn
00125         for(
00126             ResourceMap::iterator it = mResources.begin();
00127             it != mResources.end();
00128             ++it)
00129         {
00130             it->second->unload();
00131             it->second->destroy();
00132         }
00133 
00134         // Empty the list
00135         mResources.clear();
00136         mResourcesByHandle.clear();
00137     }
00138     //-----------------------------------------------------------------------
00139     Resource* ResourceManager::getByName(const String& name)
00140     {
00141         ResourceMap::iterator it = mResources.find(name);
00142 
00143         if( it == mResources.end() )
00144             return 0;
00145         else
00146         {
00147             return it->second;
00148         }
00149     }
00150     //-----------------------------------------------------------------------
00151     Resource* ResourceManager::getByHandle(ResourceHandle handle)
00152     {
00153         ResourceHandleMap::iterator it = mResourcesByHandle.find(handle);
00154         if (it == mResourcesByHandle.end())
00155         {
00156             return NULL;
00157         }
00158         else
00159         {
00160             it->second->touch();
00161             return it->second;
00162         }
00163     }
00164     //-----------------------------------------------------------------------
00165     ResourceHandle ResourceManager::getNextHandle(void)
00166     {
00167         return mNextHandle++;
00168     }
00169     //-----------------------------------------------------------------------
00170     void ResourceManager::checkUsage(void)
00171     {
00172         // Page out here?
00173     }
00174 
00175     //-----------------------------------------------------------------------
00176     void ResourceManager::addSearchPath( const String& path)
00177     {
00178         addArchiveEx( convertPath(path), "FileSystem" );
00179     }
00180 
00181     //-----------------------------------------------------------------------
00182     void ResourceManager::addCommonSearchPath( const String& path)
00183     {
00184         addCommonArchiveEx( convertPath(path), "FileSystem" );
00185     }
00186 
00187     //-----------------------------------------------------------------------
00188     void ResourceManager::addArchiveEx( const String& strName, const String& strDriverName )
00189     {
00190         ArchiveEx* pArch = ArchiveManager::getSingleton().load( strName, strDriverName );
00191 
00192         StringVector vec = pArch->getAllNamesLike( "", "" );
00193         for( StringVector::iterator it = vec.begin(); it != vec.end(); ++it )
00194             mArchiveFiles[(*it)] = pArch;
00195 
00196         mVFS.push_back(pArch);
00197     }
00198 
00199     //-----------------------------------------------------------------------
00200     void ResourceManager::addCommonArchiveEx( const String& strName, const String& strDriverName )
00201     {
00202         ArchiveEx* pArch = ArchiveManager::getSingleton().load( strName, strDriverName );
00203 
00204         StringVector vec = pArch->getAllNamesLike( "", "" );
00205         for( StringVector::iterator it = vec.begin(); it != vec.end(); ++it )
00206             mCommonArchiveFiles[(*it)] = pArch;
00207 
00208         mCommonVFS.push_back(pArch);
00209     }
00210 
00211     //-----------------------------------------------------------------------
00212     bool ResourceManager::_findResourceData(
00213         const String& filename,
00214         DataChunk& refChunk )
00215     {
00216         DataChunk* pChunk = &refChunk;
00217         // Search file cache first
00218         // NB don't treat this as definitive, incase ArchiveEx can't list all existing files
00219         FileMap::const_iterator it;
00220         if( ( it = mArchiveFiles.find( filename ) ) != mArchiveFiles.end() )
00221             return it->second->fileRead( filename, &pChunk );
00222         if( ( it = mCommonArchiveFiles.find( filename ) ) != mCommonArchiveFiles.end() )
00223             return it->second->fileRead( filename, &pChunk );
00224 
00225         // Not found in cache
00226         // Look for it the hard way
00227         std::vector<ArchiveEx*>::iterator j; 
00228         // Search archives specific to this resource type
00229         for(j = mVFS.begin(); j != mVFS.end(); ++j )
00230         {
00231             if( *j && (*j)->fileTest(filename) )
00232             {
00233                 return (*j)->fileRead( filename, &pChunk );
00234             }
00235         }
00236         // Search common archives
00237         for(j = mCommonVFS.begin(); j != mCommonVFS.end(); ++j )                 
00238         {
00239             if( *j && (*j)->fileTest(filename) )
00240             {
00241                 return (*j)->fileRead( filename, &pChunk );
00242             }
00243         }
00244         
00245         // Not found
00246         Except(
00247             Exception::ERR_ITEM_NOT_FOUND,
00248             "Resource " + filename + " not found.",
00249             "ResourceManager::_findResourceData" );
00250 
00251         // To keep compiler happy
00252         return false;
00253     }
00254     //-----------------------------------------------------------------------
00255     std::set<String> ResourceManager::_getAllCommonNamesLike( const String& startPath, const String& extension )
00256     {
00257         std::vector<ArchiveEx*>::iterator i;
00258         StringVector vecFiles;
00259         std::set<String> retFiles;
00260 
00261         // search common archives
00262         for (i = mCommonVFS.begin(); i != mCommonVFS.end(); ++i)
00263         {
00264             vecFiles = (*i)->getAllNamesLike( startPath, extension);
00265             for (StringVector::iterator si = vecFiles.begin(); si != vecFiles.end(); ++si)
00266             {
00267                 retFiles.insert(*si);
00268             }
00269         }
00270 
00271         return retFiles;
00272     }
00273     //-----------------------------------------------------------------------
00274     std::set<String> ResourceManager::_getAllNamesLike( const String& startPath, const String& extension )
00275     {
00276         std::vector<ArchiveEx*>::iterator i;
00277         StringVector vecFiles;
00278         // Get all common files
00279         std::set<String> retFiles = ResourceManager::_getAllCommonNamesLike(startPath, extension);
00280 
00281         // Get all specific files
00282         for (i = mVFS.begin(); i != mVFS.end(); ++i)
00283         {
00284             vecFiles = (*i)->getAllNamesLike( startPath, extension);
00285             for (StringVector::iterator si = vecFiles.begin(); si != vecFiles.end(); ++si)
00286             {
00287                 retFiles.insert(*si);
00288             }
00289         }
00290 
00291         return retFiles;
00292     }
00293     //-----------------------------------------------------------------------
00294     bool ResourceManager::_findCommonResourceData( const String& filename, DataChunk& refChunk )
00295     {
00296         DataChunk* pChunk = &refChunk;
00297         // Search file cache first
00298         // NB don't treat this as definitive, incase ArchiveEx can't list all existing files
00299         FileMap::const_iterator it;
00300         if( ( it = mCommonArchiveFiles.find( filename ) ) != mCommonArchiveFiles.end() )
00301             return it->second->fileRead( filename, &pChunk );
00302 
00303         // Not found in cache
00304         // Look for it the hard way
00305         std::vector<ArchiveEx*>::iterator j; 
00306         // Search common archives
00307         for(j = mCommonVFS.begin(); j != mCommonVFS.end(); ++j )                 
00308         {
00309             if( *j && (*j)->fileTest(filename) )
00310             {
00311                 return (*j)->fileRead( filename, &pChunk );
00312             }
00313         }
00314         
00315         // Not found
00316         Except(
00317             Exception::ERR_ITEM_NOT_FOUND,
00318             "Resource " + filename + " not found.",
00319             "ResourceManager::_findCommonResourceData" );
00320 
00321         // To keep compiler happy
00322         return false;
00323     }
00324 
00325 }
00326 
00327 
00328 

Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:25 2004