📄 oasispool.cpp
字号:
/******************************************************************************
* This source file is part of Bad Camel Gaming
* Copyright (C) 2003 Zephie Greyvenstein
* See Readme.html for acknowledgements
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*****************************************************************************/
/******************************************************************************
* FILENAME : oasisPool.cpp
* DESCRIPTION : Pooling object
* AUTHOR : Zephie Greyvenstein
*****************************************************************************/
#include "oasisPool.h"
#include "oasisConfiguration.h"
#include "oasisPoolable.h"
#include "oasisException.h"
#include "OgreLogManager.h"
#include "OgreStringConverter.h"
namespace Oasis {
pool::pool( const string &name ) {
// Set name
poolName = name;
// Clear lists
freePool.clear( );
usedPool.clear( );
allPool.clear( );
/// Clear naming counter
resetUniqueNames( );
}
pool::~pool( ) {
_destroyAll( );
}
void pool::clearPool( void ) {
_destroyAll( );
setPoolSize( POOL_DEFAULT_SIZE );
resetUniqueNames( );
}
bool pool::setPoolSize( uint16 newSize ) {
if ( newSize > POOL_MAX_SIZE ) {
return false;
}
uint16 currentPoolSize = ( uint16 )allPool.size( );
if ( newSize > currentPoolSize ) {
uint16 oldSize = ( uint16 )allPool.size( );
// Increase the pool
allPool.reserve( newSize );
allPool.resize( newSize );
// Fill in the objects
for( uint16 size = oldSize; size < newSize; ++size ) {
poolable *newPoolable = _createPoolable( );
allPool[ size ] = newPoolable;
newPoolable->clear( );
}
// Add new objects to free array
for ( uint16 pos = currentPoolSize; pos < newSize; ++pos ) {
freePool.push_back( allPool[ pos ] );
}
return true;
}
return false;
}
const string &pool::getPoolName( void ) const {
return poolName;
}
const uint16 pool::getPoolSize( void ) const {
return ( uint16 )allPool.size( );
}
const string &pool::getNextUniqueName( void ) {
// This is probably not the best way to do this and is being looked into
// Perhaps a more global naming system can be used too
static string uname;
uname = poolName +
Ogre::StringConverter::toString( ++namingCounter );
return uname;
}
void pool::resetUniqueNames( void ) {
namingCounter = 0;
}
poolable *pool::_getFreePoolable( const string &poolableName ) {
poolable *test = _getUsedPoolable( poolableName );
if ( test ) {
oasisError( exception::ET_DUPLICATE_ITEM,
"Poolable " + poolableName + " exists in the pool",
"pool::_getFreePoolable" );
}
if ( freePool.empty( ) ) {
// Try an increase
if ( !( setPoolSize( getPoolSize( ) + POOL_INCREASE_AMOUNT ) ) ) {
// Try one more
if ( !( setPoolSize( getPoolSize( ) + 1 ) ) ) {
oasisError( exception::ET_INTERNAL_ERROR,
poolName + " pool could not be extended any further",
"pool::_getFreePoolable" );
}
// Issue warning
Ogre::LogManager::getSingleton( ).logMessage( Ogre::LML_NORMAL, "%s pool approaching object limit ( current : %d/%d )", poolName.c_str( ), getPoolSize( ), POOL_MAX_SIZE );
}
}
poolable *free = freePool.front( );
freePool.pop_front( );
usedPool[ poolableName ] = free;
return free;
}
poolable *pool::_getUsedPoolable( const string &poolableName ) {
poolableMap::iterator it = usedPool.find( poolableName );
if ( it == usedPool.end( ) ) {
return NULL;
} else {
return it->second;
}
}
void pool::_consumePoolable( poolable *oldPoolable ) {
for ( poolableMap::iterator it = usedPool.begin( );
it != usedPool.end( ); ++it ) {
if ( it->second == oldPoolable ) {
// Clear this poolable
it->second->clear( );
freePool.push_back( oldPoolable );
usedPool.erase( it );
return;
}
}
oasisError( exception::ET_ITEM_NOT_FOUND,
"Poolable object was not found in this pool",
"pool::_consumePoolable" );
}
void pool::_consumePoolable( const string &poolableName ) {
poolable *oldPoolable = _getUsedPoolable( poolableName );
if ( !oldPoolable ) {
oasisError( exception::ET_ITEM_NOT_FOUND,
"Poolable " + poolableName + " was not found in this pool",
"pool::_consumePoolable" );
}
oldPoolable->clear( );
freePool.push_back( oldPoolable );
usedPool.erase( poolableName );
}
void pool::_destroyAll( void ) {
if ( allPool.empty( ) ) {
return;
}
Ogre::LogManager::getSingleton( ).logMessage( Ogre::LML_NORMAL, "Destroying %d objects from %s pool", allPool.size( ), poolName.c_str( ) );
// We clear all the used objects
for( poolableMap::iterator it = usedPool.begin( );
it != usedPool.end( ); ++it ) {
it->second->clear( );
}
for( poolableVector::iterator it = allPool.begin( );
it != allPool.end( ); ++it ) {
delete ( *it );
}
freePool.clear( );
usedPool.clear( );
allPool.clear( );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -