00001 /* 00002 * Copyright (C) 2003-2009 Olivier Boudeville 00003 * 00004 * This file is part of the Ceylan library. 00005 * 00006 * The Ceylan library is free software: you can redistribute it and/or modify 00007 * it under the terms of either the GNU Lesser General Public License or 00008 * the GNU General Public License, as they are published by the Free Software 00009 * Foundation, either version 3 of these Licenses, or (at your option) 00010 * any later version. 00011 * 00012 * The Ceylan library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License and the GNU General Public License 00016 * for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License and the GNU General Public License along with the Ceylan library. 00020 * If not, see <http://www.gnu.org/licenses/>. 00021 * 00022 * Author: Olivier Boudeville (olivier.boudeville@esperide.com) 00023 * 00024 */ 00025 00026 00027 #ifndef CEYLAN_BASIC_RESOURCE_MANAGER_H_ 00028 #define CEYLAN_BASIC_RESOURCE_MANAGER_H_ 00029 00030 00031 #include "CeylanResourceManager.h" // for inheritance 00032 00033 #include "CeylanResource.h" // for Ceylan::Resource 00034 00035 #include "CeylanStringUtils.h" // for Ceylan::formatStringList 00036 #include "CeylanSystem.h" // for Ceylan::System::Size 00037 #include "CeylanOperators.h" // for string operations 00038 00039 00040 #include <map> 00041 #include <list> 00042 #include <string> 00043 #include <iostream> // for ostringstream 00044 00045 00046 00047 namespace Ceylan 00048 { 00049 00050 00051 00107 template <typename Key> 00108 class BasicResourceManager : public Ceylan::ResourceManager<Key> 00109 { 00110 00111 00112 public: 00113 00114 00126 explicit BasicResourceManager() ; 00127 00128 00129 00131 virtual ~BasicResourceManager() throw() ; 00132 00133 00134 00158 virtual void takeOwnershipOf( const Key & key, 00159 const Resource & resource ) ; 00160 00161 00162 00171 virtual bool isKeyAlreadyAssociated( const Key & key ) const ; 00172 00173 00174 00193 virtual const Resource * get( const Key & key ) ; 00194 00195 00196 00203 virtual void flush() ; 00204 00205 00206 00217 virtual const std::string toString( 00218 Ceylan::VerbosityLevels level = Ceylan::high ) const ; 00219 00220 00221 00222 00223 protected: 00224 00225 00226 /* 00227 * Takes care of the awful issue of Windows DLL with templates. 00228 * 00229 * @see Ceylan's developer guide and README-build-for-windows.txt 00230 * to understand it, and to be aware of the associated risks. 00231 * 00232 */ 00233 #pragma warning( push ) 00234 #pragma warning( disable : 4251 ) 00235 00237 std::map<Key, const Resource *> _entries ; 00238 00239 #pragma warning( pop ) 00240 00241 00242 private: 00243 00244 00245 00253 BasicResourceManager( const BasicResourceManager & source ) ; 00254 00255 00264 BasicResourceManager & operator = ( 00265 const BasicResourceManager & source ) ; 00266 00267 00268 } ; 00269 00270 00271 00272 00273 // Public section: implementation. 00274 00275 00276 template <typename Key> 00277 BasicResourceManager<Key>::BasicResourceManager() : 00278 ResourceManager<Key>(), 00279 _entries() 00280 { 00281 00282 } 00283 00284 00285 00286 template <typename Key> 00287 BasicResourceManager<Key>::~BasicResourceManager() throw() 00288 { 00289 00295 flush() ; 00296 00297 } 00298 00299 00300 00301 template <typename Key> 00302 void BasicResourceManager<Key>::takeOwnershipOf( const Key & key, 00303 const Resource & resource ) 00304 { 00305 00306 // Look-up any previous entry: 00307 typename std::map<Key, const Resource *>::const_iterator it = 00308 _entries.find( key ) ; 00309 00310 if ( it != _entries.end() ) 00311 { 00312 /* 00313 * Key type not known, using streams to get as much information as 00314 * possible: 00315 * 00316 */ 00317 std::ostringstream os ; 00318 os << key ; 00319 throw ResourceManagerException( 00320 "BasicResourceManager<Key>::takeOwnershipOf: key '" 00321 + os.str() + "' already associated with ressource '" 00322 + resource.toString() + "'." ) ; 00323 } 00324 00325 _entries[ key ] = & resource ; 00326 00327 } 00328 00329 00330 00331 template <typename Key> 00332 bool BasicResourceManager<Key>::isKeyAlreadyAssociated( const Key & key ) 00333 const 00334 { 00335 00336 // Look-up any previous entry: 00337 return ( _entries.find( key ) != _entries.end() ) ; 00338 00339 } 00340 00341 00342 00343 template <typename Key> 00344 const Resource * BasicResourceManager<Key>::get( const Key & key ) 00345 { 00346 00347 typename std::map<Key, const Resource *>::const_iterator it = 00348 _entries.find( key ) ; 00349 00350 if ( it != _entries.end() ) 00351 { 00352 this->_cacheHits++ ; 00353 return (*it).second ; 00354 } 00355 else 00356 { 00357 this->_cacheMisses++ ; 00358 return 0 ; 00359 } 00360 00361 } 00362 00363 00364 00365 template <typename Key> 00366 void BasicResourceManager<Key>::flush() 00367 { 00368 00369 for ( typename std::map<Key, const Resource *>::const_iterator it = 00370 _entries.begin() ; it != _entries.end(); it++ ) 00371 { 00372 delete (*it).second ; 00373 } 00374 00375 _entries.clear() ; 00376 00377 } 00378 00379 00380 00381 template <typename Key> 00382 const std::string BasicResourceManager<Key>::toString( 00383 VerbosityLevels level ) const 00384 { 00385 00386 std::string res = "Basic Resource manager currently managing " ; 00387 00388 System::Size resourceCount = _entries.size() ; 00389 00390 if ( resourceCount == 0 ) 00391 res += "no resource" ; 00392 else 00393 res += Ceylan::toString( 00394 static_cast<Ceylan::Uint32>( resourceCount ) ) 00395 + " resource(s)" ; 00396 00397 if ( level == Ceylan::low ) 00398 return res ; 00399 00400 00401 Ceylan::Uint32 total = this->_cacheHits + this->_cacheMisses ; 00402 00403 if ( total == 0 ) 00404 res += ". No resource request processed for the moment" ; 00405 else 00406 res += ". The average cache success is " 00407 + Ceylan::toNumericalString( static_cast<Ceylan::Uint8>( 00408 ( 100.0f * this->_cacheHits ) / total ) ) 00409 + "% (" + Ceylan::toString( this->_cacheHits ) 00410 + " cache hit(s) for " 00411 + Ceylan::toString( this->_cacheMisses ) + " cache miss(es))" ; 00412 00413 00414 if ( level == Ceylan::medium ) 00415 return res ; 00416 00417 if ( resourceCount == 0 ) 00418 return res ; 00419 00420 res += ". Displaying current cached entrie(s): " ; 00421 00422 Ceylan::Uint32 count = 0 ; 00423 std::list<std::string> entries ; 00424 00425 for ( typename std::map<Key, const Resource *>::const_iterator it = 00426 _entries.begin() ; it != _entries.end(); it++ ) 00427 { 00428 count++ ; 00429 entries.push_back( "[Entry #" + Ceylan::toString( count ) 00430 + "] resource description = '" 00431 + (*it).second->toString( Ceylan::low ) + "'" ) ; 00432 } 00433 00434 return res + Ceylan::formatStringList( entries ) ; 00435 00436 } 00437 00438 00439 } 00440 00441 00442 #endif // CEYLAN_BASIC_RESOURCE_MANAGER_H_ 00443