cocos2d-x多线程加载pvr

//

//  ThreadLoadPVR.h

//  sgcard

//

//  Created by Apple on 13-9-24.

//

//

 

#ifndef __sgcard__MgrLoadPVR__

#define __sgcard__MgrLoadPVR__

 

#include "Uncopyable.h"

#include "cocos2d.h"

 

#include <pthread.h>

#include <queue>

#include <map>

 

namespace sgcard

{

    class CMgrLoadPVR : public CUncopyable

    {

    public:

        static CMgrLoadPVR * getMgr();

        static void * loadFile( void * arg );

        

    public:

        CMgrLoadPVR();

        ~CMgrLoadPVR();

        bool init();

        bool empty();

        bool update();

        void addFileForLoad( const char * file );

        

    public:

        cocos2d::CCTexture2D * getGameTexture2DByName( const char * file );

        void delGameTexture2DByName( const char * file );

        void clearGameTexture2D();

        

    private:

        bool m_bInit;

        std::map< const char *, cocos2d::CCTexture2D * > m_mapGameTexture;

    };

}

 

#endif /* defined(__sgcard__MgrLoadPVR__) */

//

//  ThreadLoadPVR.cpp

//  sgcard

//

//  Created by Apple on 13-9-24.

//

//

 

#include "MgrLoadPVR.h"

#include "GameTexture.h"

 

usingnamespacesgcard;

usingnamespacecocos2d;

 

struct PVR_DATA

{

    int len;

    unsigned char * data;

    const char * name;

};

 

staticbool s_bRun = true;

static bool s_bEmpty = true;

static pthread_t s_tThreadLoad;

static pthread_cond_t s_condSleep;

static pthread_mutex_t s_mutexSleep;

static pthread_mutex_t s_mutexFileName;

static pthread_mutex_t s_mutexPVRData;

static std::queue< const char * > s_queueFileName;

static std::queue< PVR_DATA > s_queuePVRData;

 

CMgrLoadPVR * CMgrLoadPVR::getMgr()

{

    staticCMgrLoadPVR mgr;

    return & mgr;

}

 

void * CMgrLoadPVR::loadFile( void * arg )

{

    while( true )

    {

        const char * pFileName = NULL;

        pthread_mutex_lock( & s_mutexFileName );

        if( s_queueFileName.empty() )

        {

            s_bEmpty = true;

            pthread_mutex_unlock( & s_mutexFileName );

            if( s_bRun )

            {

            pthread_cond_wait( & s_condSleep, & s_mutexSleep );

                continue;

            }

            break;

        }

        else

        {

            pFileName = s_queueFileName.front();

            s_queueFileName.pop();

            pthread_mutex_unlock( & s_mutexFileName );

        }

        

        if( NULL != pFileName )

        {

            unsigned char * pvrdata = NULL;

            int len = loadPVRFile( & pvrdata, pFileName );

            if( 0 < len )

            {

                PVR_DATA pvr = { len, pvrdata, pFileName };

                pthread_mutex_lock( & s_mutexPVRData );

                s_queuePVRData.push( pvr );

                pthread_mutex_unlock( & s_mutexPVRData );

            }

        }

    }

    

    pthread_cond_destroy( & s_condSleep );

    pthread_mutex_destroy( & s_mutexSleep );

    pthread_mutex_destroy( & s_mutexFileName );

    pthread_mutex_destroy( & s_mutexPVRData );

    

    returnNULL;

}

 

CMgrLoadPVR::CMgrLoadPVR()

: m_bInit( false )

{

}

 

CMgrLoadPVR::~CMgrLoadPVR()

{

    pthread_mutex_lock( & s_mutexFileName );

    while( ! s_queueFileName.empty() )

    {

        s_queueFileName.pop();

    }

    pthread_mutex_unlock( & s_mutexFileName );

    s_bRun = false;

    pthread_cond_signal( & s_condSleep );

}

 

boolCMgrLoadPVR::init()

{

    m_bInit = true;

    s_bRun = true;

    pthread_cond_init( & s_condSleep, NULL );

    pthread_mutex_init( & s_mutexSleep, NULL );

    pthread_mutex_init( & s_mutexFileName, NULL );

    pthread_mutex_init( & s_mutexPVRData, NULL );

    pthread_create( & s_tThreadLoad, NULL, CMgrLoadPVR::loadFile, NULL );

    returntrue;

}

 

boolCMgrLoadPVR::empty()

{

    bool empty = s_bEmpty;

    if( empty )

    {

        pthread_mutex_lock( & s_mutexPVRData );

        empty = s_queuePVRData.empty();

        pthread_mutex_unlock( & s_mutexPVRData );

    }

    return empty;

}

 

bool CMgrLoadPVR::update()

{

    PVR_DATA pvr = {0};

    pthread_mutex_lock( & s_mutexPVRData );

    if( ! s_queuePVRData.empty() )

    {

        pvr = s_queuePVRData.front();

        s_queuePVRData.pop();

    }

    pthread_mutex_unlock( & s_mutexPVRData );

    if( 0 < pvr.len )

    {

        CGLTexture * pTexture = new CGLTexture();

        pTexture->initWithPVRv2Data( pvr.data, pvr.len );

        

        CGameTexture * pGameTexture = new CGameTexture();

        pGameTexture->initWithGLTexture( pTexture );

        

        m_mapGameTexture[ pvr.name ] = pGameTexture;

        

        delete pTexture;

        delete[] pvr.data;

    }

    return empty();

}

 

void CMgrLoadPVR::addFileForLoad( const char * file )

{

    if( ! m_bInit )

    {

        return;

    }

    

    pthread_mutex_lock( & s_mutexFileName );

    s_queueFileName.push( file );

    s_bEmpty = false;

    pthread_mutex_unlock( & s_mutexFileName );

    pthread_cond_signal( & s_condSleep );

}

 

cocos2d::CCTexture2D * CMgrLoadPVR::getGameTexture2DByName( const char * file )

{

    std::map< const char *, cocos2d::CCTexture2D * >::iterator it = m_mapGameTexture.find( file );

    if( m_mapGameTexture.end() != it )

    {

        return it->second;

    }

    returnNULL;

}

 

void CMgrLoadPVR::delGameTexture2DByName( const char * file )

{

    std::map< const char *, cocos2d::CCTexture2D * >::iterator it = m_mapGameTexture.find( file );

    if( m_mapGameTexture.end() != it )

    {

        it->second->release();

        m_mapGameTexture.erase( it );

    }

}

 

void CMgrLoadPVR::clearGameTexture2D()

{

    std::map< constchar *, cocos2d::CCTexture2D * >::iterator it = m_mapGameTexture.begin();

    while( m_mapGameTexture.end() != it )

    {

        it->second->release();

        ++it;

    }

    m_mapGameTexture.clear();

}

 

posted on 2014-06-05 23:30  the seal  阅读(297)  评论(0编辑  收藏  举报