对象池简单实现

每帧都会有贴图变化,尝试使用对象池用于优化贴图的创建和删除

ObjPool.h

#ifndef _OBJPOOL_H_
#define _OBJPOOL_H_

#include <string>
#include <list>

#include <map>


typedef struct _tagSPRITE
{
    std::string name;
}iSprite;

typedef struct _tagSpriteInUse
{
    iSprite*    pSprite;
    bool        bInUse;

    _tagSpriteInUse()
    {
        pSprite = NULL;
        bInUse  = true;
    }
}SpriteInUse;


typedef std::map<std::string,std::list<SpriteInUse*> > MapSprite;



class ObjPool
{
public:
    static ObjPool* Instance();
    static void Release();

    //add obj
    iSprite* CreateObject(std::string& name);
    
    //releaseObj
    void ReleaseObj(std::string& name,iSprite* pSprite);

    //gc
    void RemoveUnusedObjects();

protected:
    ObjPool(void);
    ~ObjPool(void);

    void ReleaseAllData();


    SpriteInUse* CreateSpriteInUse(std::string& name);
private:
    MapSprite _mapSprite;
    static ObjPool* m_pObjPool;

};

#endif

ObjPool.cpp

#include "ObjPool.h"
ObjPool* ObjPool::m_pObjPool = NULL;

ObjPool::ObjPool(void)
{
    _mapSprite.clear();
}


ObjPool::~ObjPool(void)
{
    ReleaseAllData();
}

ObjPool* ObjPool::Instance()
{
    if( !m_pObjPool )
    {
        m_pObjPool = new ObjPool();
    }
    return m_pObjPool;
}

void ObjPool::Release()
{
    m_pObjPool->ReleaseAllData();
    SAFE_DELETE( m_pObjPool );
}

void ObjPool::ReleaseAllData()
{
    MapSprite::iterator it = _mapSprite.begin();
    MapSprite::iterator itEnd = _mapSprite.begin();

    for( ; it != itEnd; ++it )
    {
        std::list<SpriteInUse*>& vec = it->second;
        std::list<SpriteInUse*>::iterator iter = vec.begin();
        std::list<SpriteInUse*>::iterator iterend = vec.end();

        while(iter != iterend )
        {
            SAFE_DELETE( (*iter)->pSprite );
            iter++;
        }
    }

    _mapSprite.clear();
}

//add obj
iSprite* ObjPool::CreateObject(std::string& name)
{
    MapSprite::iterator it = _mapSprite.find(name);
    if( it != _mapSprite.end() )
    {
        //found
        std::list<SpriteInUse*>& vec = it->second;
        std::list<SpriteInUse*>::iterator iter = vec.begin();
        std::list<SpriteInUse*>::iterator iterend = vec.end();

        for ( ; iter != iterend; ++iter )
        {
            if( !(*iter)->bInUse )
            {
                (*iter)->bInUse = true;
                (*iter)->pSprite->SetEnable(iTRUE);
                return (*iter)->pSprite;
            }
        }
    }

    //not found or found but all inuse
    //create new iSprite
    SpriteInUse* pSIU = CreateSpriteInUse(name);
    if( it != _mapSprite.end() )
    {
        std::list<SpriteInUse*>& vec = it->second;
        vec.push_back(pSIU);
    }
    else
    {
        std::list<SpriteInUse*> vecSpriteInUse;
        vecSpriteInUse.push_back(pSIU);
        _mapSprite.insert(std::make_pair(name,vecSpriteInUse));
    }

    return pSIU->pSprite;
}

SpriteInUse* I2DObjPool::CreateSpriteInUse(std::string& name)
{
    iSprite* pSprite = new iSprite();
    pSprite->name = name;

    SpriteInUse* pSpriteInUse = myNew SpriteInUse();
    pSpriteInUse->pSprite = pSprite;
    pSpriteInUse->bInUse = true;

    return pSpriteInUse;
}

void ObjPool::ReleaseObj(std::string& name,iSprite* pSprite)
{
    MapSprite::iterator it = _mapSprite.find(name);
    if( it != _mapSprite.end() )
    {
        std::list<SpriteInUse*>& vec = it->second;
        std::list<SpriteInUse*>::iterator iter = vec.begin();
        std::list<SpriteInUse*>::iterator iterend = vec.end();

        for ( ; iter != iterend; ++iter )
        {
            if( (*iter)->pSprite == pSprite )
            {
                (*iter)->bInUse = false;
                pSprite->SetEnable(iFALSE);
                return;
            }
        }

    }

    int x = 0;    //something wrong
}


//gc
void ObjPool::RemoveUnusedObjects()
{
    MapSprite::iterator it = _mapSprite.begin();
    MapSprite::iterator itEnd = _mapSprite.begin();

    for( ; it != itEnd; ++it )
    {
        std::list<SpriteInUse*>& vec = it->second;
        std::list<SpriteInUse*>::iterator iter = vec.begin();
        std::list<SpriteInUse*>::iterator iterend = vec.end();

        while(iter != iterend )
        {
            if( !(*iter)->bInUse )
            {
                SAFE_DELETE( (*iter)->pSprite );
                iter = vec.erase(iter);
            }
            else
            {
                ++iter;
            }
        }
        
    }
}

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...