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();
}