resourceManager.cpp
Engine/source/core/resourceManager.cpp
Public Variables
Public Functions
ConsoleFunctionGroupBegin(ResourceManagerFunctions , "Resource management functions." )
ConsoleFunctionGroupEnd(ResourceManagerFunctions )
DefineEngineFunction(reloadResource , void , (const char *path) , "Force the resource at specified input path <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">reloaded\n</a>" "@param path <a href="/coding/class/classtorque_1_1path/">Path</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the resource <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">reloaded\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "reloadResource( \"art/shapes/box.dts\" );\n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@note Currently used by editors <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editors\n</a>" "@internal" )
DefineEngineFunction(resourceDump , void , () , "@brief <a href="/coding/class/classtorque_1_1list/">List</a> the currently managed <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">resources\n\n</a>" "Currently used by editors only, <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">internal\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editors\n</a>" " @internal" )
Detailed Description
Public Variables
AutoPtr< ResourceManager > smInstance
Public Functions
ConsoleFunctionGroupBegin(ResourceManagerFunctions , "Resource management functions." )
ConsoleFunctionGroupEnd(ResourceManagerFunctions )
DefineEngineFunction(reloadResource , void , (const char *path) , "Force the resource at specified input path <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">reloaded\n</a>" "@param path <a href="/coding/class/classtorque_1_1path/">Path</a> <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the resource <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> be <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">reloaded\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "reloadResource( \"art/shapes/box.dts\" );\n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@note Currently used by editors <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editors\n</a>" "@internal" )
DefineEngineFunction(resourceDump , void , () , "@brief <a href="/coding/class/classtorque_1_1list/">List</a> the currently managed <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">resources\n\n</a>" "Currently used by editors only, <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">internal\n</a>" " @ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editors\n</a>" " @internal" )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "core/resourceManager.h" 26 27#include "core/volume.h" 28#include "console/console.h" 29#include "core/util/autoPtr.h" 30 31#include "console/engineAPI.h" 32 33using namespace Torque; 34 35static AutoPtr< ResourceManager> smInstance; 36 37ResourceManager::ResourceManager() 38: mIterSigFilter( U32_MAX ) 39{ 40} 41 42ResourceManager::~ResourceManager() 43{ 44 // TODO: Dump resources that have not been released? 45} 46 47ResourceManager &ResourceManager::get() 48{ 49 if ( smInstance.isNull() ) 50 smInstance = new ResourceManager; 51 return *smInstance; 52} 53 54ResourceBase ResourceManager::load(const Torque::Path &path) 55{ 56#ifdef TORQUE_DEBUG_RES_MANAGER 57 Con::printf( "ResourceManager::load : [%s]", path.getFullPath().c_str() ); 58#endif 59 60 ResourceHeaderMap::Iterator iter = mResourceHeaderMap.findOrInsert( path.getFullPath() ); 61 62 ResourceHeaderMap::Pair &pair = *iter; 63 64 if ( pair.value == NULL ) 65 { 66 pair.value = new ResourceBase::Header; 67 68 // TODO: This can fail if the file doesn't exist 69 // at all which is possible. 70 // 71 // The problem is the templated design in ResourceManager 72 // keeps me from checking to see if the resource load failed 73 // before adding a notification. 74 // 75 // IMO the resource manager is overly templateized and 76 // we should refactor it so that its not so. 77 // 78 FS::AddChangeNotification( path, this, &ResourceManager::notifiedFileChanged ); 79 } 80 81 ResourceBase::Header *header = pair.value; 82 83 if (header->getSignature() == 0) 84 header->mPath = path; 85 86 return ResourceBase( header ); 87} 88 89ResourceBase ResourceManager::find(const Torque::Path &path) 90{ 91#ifdef TORQUE_DEBUG_RES_MANAGER 92 Con::printf( "ResourceManager::find : [%s]", path.getFullPath().c_str() ); 93#endif 94 95 ResourceHeaderMap::Iterator iter = mResourceHeaderMap.find( path.getFullPath() ); 96 97 if ( iter == mResourceHeaderMap.end() ) 98 return ResourceBase(); 99 100 ResourceHeaderMap::Pair &pair = *iter; 101 102 ResourceBase::Header *header = pair.value; 103 104 return ResourceBase(header); 105} 106 107#ifdef TORQUE_DEBUG 108void ResourceManager::dumpToConsole() 109{ 110 const U32 numResources = mResourceHeaderMap.size(); 111 112 if ( numResources == 0 ) 113 { 114 Con::printf( "ResourceManager is not managing any resources" ); 115 return; 116 } 117 118 Con::printf( "ResourceManager is managing %d resources:", numResources ); 119 Con::printf( " [ref count/signature/path]" ); 120 121 ResourceHeaderMap::Iterator iter; 122 123 for( iter = mResourceHeaderMap.begin(); iter != mResourceHeaderMap.end(); ++iter ) 124 { 125 ResourceBase::Header *header = (*iter).value; 126 127 char fourCC[ 5 ]; 128 *( ( U32* ) fourCC ) = header->getSignature(); 129 fourCC[ 4 ] = 0; 130 131 Con::printf( " %3d %s [%s] ", header->getRefCount(), fourCC, (*iter).key.c_str() ); 132 } 133} 134#endif 135 136bool ResourceManager::remove( ResourceBase::Header* header ) 137{ 138 const Path &path = header->getPath(); 139 140#ifdef TORQUE_DEBUG_RES_MANAGER 141 Con::printf( "ResourceManager::remove : [%s]", path.getFullPath().c_str() ); 142#endif 143 144 ResourceHeaderMap::Iterator iter = mResourceHeaderMap.find( path.getFullPath() ); 145 if ( iter != mResourceHeaderMap.end() && iter->value == header ) 146 { 147 AssertISV( header && (header->getRefCount() == 0), "ResourceManager error: trying to remove resource which is still in use." ); 148 mResourceHeaderMap.erase( iter ); 149 } 150 else 151 { 152 iter = mPrevResourceHeaderMap.find( path.getFullPath() ); 153 if ( iter == mPrevResourceHeaderMap.end() || iter->value != header ) 154 { 155 Con::errorf( "ResourceManager::remove : Trying to remove non-existent resource [%s]", path.getFullPath().c_str() ); 156 return false; 157 } 158 159 AssertISV( header && (header->getRefCount() == 0), "ResourceManager error: trying to remove resource which is still in use." ); 160 mPrevResourceHeaderMap.erase( iter ); 161 } 162 163 FS::RemoveChangeNotification( path, this, &ResourceManager::notifiedFileChanged ); 164 165 return true; 166} 167 168void ResourceManager::notifiedFileChanged( const Torque::Path &path ) 169{ 170 reloadResource( path, true ); 171} 172 173void ResourceManager::reloadResource( const Torque::Path &path, bool showMessage ) 174{ 175 if ( showMessage ) 176 Con::warnf( "[ResourceManager::notifiedFileChanged] : File changed [%s]", path.getFullPath().c_str() ); 177 178 ResourceHeaderMap::Iterator iter = mResourceHeaderMap.find( path.getFullPath() ); 179 if ( iter != mResourceHeaderMap.end() ) 180 { 181 ResourceBase::Header *header = (*iter).value; 182 mResourceHeaderMap.erase( iter ); 183 184 // Move the resource into the previous resource map. 185 iter = mPrevResourceHeaderMap.findOrInsert( path ); 186 iter->value = header; 187 } 188 189 // Now notify users of the resource change so they 190 // can release and reload. 191 mChangeSignal.trigger( path ); 192} 193 194ResourceBase ResourceManager::startResourceList( ResourceBase::Signature inSignature ) 195{ 196 mIter = mResourceHeaderMap.begin(); 197 198 mIterSigFilter = inSignature; 199 200 return nextResource(); 201} 202 203ResourceBase ResourceManager::nextResource() 204{ 205 ResourceBase::Header *header = NULL; 206 207 while( mIter != mResourceHeaderMap.end() ) 208 { 209 header = (*mIter).value; 210 211 ++mIter; 212 213 if ( mIterSigFilter == U32_MAX ) 214 return ResourceBase(header); 215 216 if ( header->getSignature() == mIterSigFilter ) 217 return ResourceBase(header); 218 } 219 220 return ResourceBase(); 221} 222 223ConsoleFunctionGroupBegin(ResourceManagerFunctions, "Resource management functions."); 224 225 226DefineEngineFunction(resourceDump, void, (),, 227 "@brief List the currently managed resources\n\n" 228 "Currently used by editors only, internal\n" 229 "@ingroup Editors\n" 230 "@internal") 231{ 232#ifdef TORQUE_DEBUG 233 ResourceManager::get().dumpToConsole(); 234#endif 235} 236 237DefineEngineFunction( reloadResource, void, ( const char* path ),, 238 "Force the resource at specified input path to be reloaded\n" 239 "@param path Path to the resource to be reloaded\n\n" 240 "@tsexample\n" 241 "reloadResource( \"art/shapes/box.dts\" );\n" 242 "@endtsexample\n\n" 243 "@note Currently used by editors only\n" 244 "@ingroup Editors\n" 245 "@internal") 246{ 247 ResourceManager::get().reloadResource( path ); 248} 249 250ConsoleFunctionGroupEnd( ResourceManagerFunctions ); 251