00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <spl/collection/ObjectPool.h>
00018
00019 IPoolable::~IPoolable()
00020 {
00021 }
00022
00023 ObjectPool::ObjectPool
00024 (
00025 IPoolableFactory *factory,
00026 int minInstances,
00027 int preferedPoolMaxInstances,
00028 int maxInstances
00029 )
00030 : m_factory(factory),
00031 m_minInstances(minInstances),
00032 m_preferedPoolMaxInstances(preferedPoolMaxInstances),
00033 m_maxInstances(maxInstances),
00034 m_pool(),
00035 m_poolMutex(),
00036 m_count(0)
00037 {
00038 for ( int x = 0; x < minInstances; x++ )
00039 {
00040 m_pool.Add( factory->CreateInstance() );
00041 }
00042 m_count = minInstances;
00043 }
00044
00045 ObjectPool::~ObjectPool()
00046 {
00047 while ( m_pool.Count() > 0 )
00048 {
00049 IPoolable *item = m_pool.Pop();
00050 m_factory->Destroy( item );
00051 }
00052 }
00053
00054 IPoolablePtr ObjectPool::GetObjectSmartPtr()
00055 {
00056 return IPoolablePtr(GetObject());
00057 }
00058
00059 IPoolable *ObjectPool::GetObject()
00060 {
00061 IPoolable *item;
00062 m_poolMutex.Lock();
00063 if ( m_pool.Count() == 0 )
00064 {
00065 if ( m_count >= m_maxInstances )
00066 {
00067 m_poolMutex.Unlock();
00068 return NULL;
00069 }
00070 item = m_factory->CreateInstance();
00071 ASSERT( NULL != item );
00072 m_count++;
00073 }
00074 else
00075 {
00076 item = m_pool.Pop();
00077 }
00078 m_poolMutex.Unlock();
00079 item->OnPreRemoveFromPool();
00080 return item;
00081 }
00082
00083 void ObjectPool::ReleaseObject( IPoolablePtr item )
00084 {
00085 IPoolable *ptr = item.Detach();
00086 ReleaseObject(ptr);
00087 }
00088
00089 void ObjectPool::ReleaseObject( IPoolable *item )
00090 {
00091 item->OnPreReturnToPool();
00092 m_poolMutex.Lock();
00093 if ( m_count > m_preferedPoolMaxInstances )
00094 {
00095 m_factory->Destroy( item );
00096 m_count--;
00097 }
00098 else
00099 {
00100 m_pool.Add( item );
00101 }
00102 m_poolMutex.Unlock();
00103 }
00104
00105 #if defined(DEBUG) || defined(_DEBUG)
00106 void ObjectPool::CheckMem() const
00107 {
00108 m_factory->CheckMem();
00109
00110 m_pool.CheckMem();
00111 int count = m_pool.Count();
00112 for ( int x = 0; x < count; x++ )
00113 {
00114 IPoolable *item = m_pool.ElementAt(x);
00115 DEBUG_NOTE_MEM( item );
00116 item->CheckMem();
00117 }
00118
00119 }
00120
00121 void ObjectPool::ValidateMem() const
00122 {
00123 m_factory->ValidateMem();
00124
00125 m_pool.ValidateMem();
00126 int count = m_pool.Count();
00127 for ( int x = 0; x < count; x++ )
00128 {
00129 IPoolable *item = m_pool.ElementAt(x);
00130 ASSERT_PTR( item );
00131 item->ValidateMem();
00132 }
00133
00134 }
00135 #endif
00136