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     void ResourceManager::cleanupCommonArchive () {
    00327       mCommonVFS.clear();
    00328       mCommonArchiveFiles.clear();
    00329     }
    00330 }
    00331
    00332
    00333

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:43 2004