#ifndef __AUTORELEASEPOOL_H__
#define __AUTORELEASEPOOL_H__
#include "CCObject.h"
#include "CCArray.h"
NS_CC_BEGIN
class CC_DLL CCAutoreleasePool : public CCObject //Object自动释放存储池
{
CCArray* m_pManagedObjectArray; // object 数组
public:
CCAutoreleasePool(void);
~CCAutoreleasePool(void);
void addObject(CCObject *pObject); //add
void CCAutoreleasePool::addObject(CCObject* pObject)
{
m_pManagedObjectArray->addObject(pObject); //内部有一次 object->retain();
CCAssert(pObject->m_uReference > 1, "reference count should be greater than 1");
++(pObject->m_uAutoReleaseCount); //同个object可以多次加入释放池
pObject->release(); // 加入自动释放池时引用次数不变
}
void removeObject(CCObject *pObject); //remove
void CCAutoreleasePool::removeObject(CCObject* pObject)
{
for (unsigned int i = 0; i < pObject->m_uAutoReleaseCount; ++i) //因为同个object可以多次加入释放池 所以要这个循环remove多次
{
m_pManagedObjectArray->removeObject(pObject, false);
}
}
void clear();
void CCAutoreleasePool::clear()
{
if(m_pManagedObjectArray->count() > 0)
{
//CCAutoreleasePool* pReleasePool;
#ifdef _DEBUG
int nIndex = m_pManagedObjectArray->count() - 1;
#endif
CCObject* pObj = NULL;
CCARRAY_FOREACH_REVERSE(m_pManagedObjectArray, pObj)
{
if(!pObj)
break;
--(pObj->m_uAutoReleaseCount);
//(*it)->release();
//delete (*it);
#ifdef _DEBUG
nIndex--;
#endif
}
m_pManagedObjectArray->removeAllObjects();
}
}
};
class CC_DLL CCPoolManager
{
CCArray* m_pReleasePoolStack; //自动释放池数组
CCAutoreleasePool* m_pCurReleasePool;//当前释放池
CCAutoreleasePool* getCurReleasePool();
public:
CCPoolManager();
~CCPoolManager();
void finalize();
void CCPoolManager::finalize()
{
if(m_pReleasePoolStack->count() > 0)
{
//CCAutoreleasePool* pReleasePool;
CCObject* pObj = NULL;
CCARRAY_FOREACH(m_pReleasePoolStack, pObj)
{
if(!pObj)
break;
CCAutoreleasePool* pPool = (CCAutoreleasePool*)pObj;
pPool->clear();
}
}
}
void push();
void CCPoolManager::push()
{
CCAutoreleasePool* pPool = new CCAutoreleasePool(); //ref = 1
m_pCurReleasePool = pPool;
m_pReleasePoolStack->addObject(pPool); //ref = 2
pPool->release(); //ref = 1
}
void pop();
void CCPoolManager::pop()
{
if (! m_pCurReleasePool)
{
return;
}
int nCount = m_pReleasePoolStack->count();
m_pCurReleasePool->clear();
if(nCount > 1)
{
m_pReleasePoolStack->removeObjectAtIndex(nCount-1);
// if(nCount > 1)
// {
// m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2);
// return;
// }
m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2);
}
/*m_pCurReleasePool = NULL;*/
}
void removeObject(CCObject* pObject);
void CCPoolManager::removeObject(CCObject* pObject)
{
CCAssert(m_pCurReleasePool, "current auto release pool should not be null");
m_pCurReleasePool->removeObject(pObject);
}
void addObject(CCObject* pObject);
void CCPoolManager::addObject(CCObject* pObject)
{
getCurReleasePool()->addObject(pObject);
}
static CCPoolManager* sharedPoolManager();
CCPoolManager* CCPoolManager::sharedPoolManager()
{
if (s_pPoolManager == NULL)
{
s_pPoolManager = new CCPoolManager();
}
return s_pPoolManager;
}
static void purgePoolManager();
void CCPoolManager::purgePoolManager()
{
CC_SAFE_DELETE(s_pPoolManager);
}
friend class CCAutoreleasePool;
};
// end of base_nodes group
/// @}
NS_CC_END
#endif //__AUTORELEASEPOOL_H__