CCTextureCache是用来缓存和管理cctexture2d的单例工具类,提供的功能和CCSpriteFrameCache差不多,不过功能要复杂,因为提供了异步的载入图像和回调功能。
这里就简单的备注下代码框架:
typedef struct _AsyncStruct |
typedef struct _ImageInfo |
AsyncStruct *asyncStruct; |
CCImage::EImageFormat imageType; |
static pthread_t s_loadingThread; |
static pthread_mutex_t s_SleepMutex; |
static pthread_cond_t s_SleepCondition; |
static pthread_mutex_t s_asyncStructQueueMutex; |
static pthread_mutex_t s_ImageInfoMutex; |
#define pthread_cond_signal(_) |
static unsigned long s_nAsyncRefCount = 0; |
static bool need_quit = false ; |
static std::queue<AsyncStruct*>* s_pAsyncStructQueue = NULL; |
static std::queue<ImageInfo*>* s_pImageQueue = NULL; |
static CCImage::EImageFormat computeImageFormatType(string& filename) |
static void loadImageData(AsyncStruct *pAsyncStruct) |
CCImage *pImage = new CCImage(); |
if (pImage && !pImage->initWithImageFileThreadSafe(filename, imageType)) |
CCLOG( "can not load %s" , filename); |
ImageInfo *pImageInfo = new ImageInfo(); |
pImageInfo->asyncStruct = pAsyncStruct; |
pImageInfo->image = pImage; |
pImageInfo->imageType = imageType; |
pthread_mutex_lock(&s_ImageInfoMutex); |
s_pImageQueue->push(pImageInfo); |
pthread_mutex_unlock(&s_ImageInfoMutex); |
static void * loadImage( void * data) |
AsyncStruct *pAsyncStruct = NULL; |
thread .createAutoreleasePool(); |
std::queue<AsyncStruct*> *pQueue = s_pAsyncStructQueue; |
pthread_mutex_lock(&s_asyncStructQueueMutex); |
pthread_mutex_unlock(&s_asyncStructQueueMutex); |
pthread_cond_wait(&s_SleepCondition, &s_SleepMutex); |
pAsyncStruct = pQueue->front(); |
pthread_mutex_unlock(&s_asyncStructQueueMutex); |
loadImageData(pAsyncStruct); |
if ( s_pAsyncStructQueue != NULL ) |
delete s_pAsyncStructQueue; |
s_pAsyncStructQueue = NULL; |
pthread_mutex_destroy(&s_asyncStructQueueMutex); |
pthread_mutex_destroy(&s_ImageInfoMutex); |
pthread_mutex_destroy(&s_SleepMutex); |
pthread_cond_destroy(&s_SleepCondition); |
const char * CCTextureCache::description() |
CCDictionary* CCTextureCache::snapshotTextures() |
void CCTextureCache::addImageAsync( const char *path, CCObject *target, SEL_CallFuncO selector) |
(target->*selector)(texture); |
if (s_pAsyncStructQueue == NULL) |
s_pAsyncStructQueue = new queue<AsyncStruct*>(); |
s_pImageQueue = new queue<ImageInfo*>(); |
pthread_mutex_init(&s_asyncStructQueueMutex, NULL); |
pthread_mutex_init(&s_ImageInfoMutex, NULL); |
pthread_mutex_init(&s_SleepMutex, NULL); |
pthread_cond_init(&s_SleepCondition, NULL); |
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8) |
pthread_create(&s_loadingThread, NULL, loadImage, NULL); |
if (0 == s_nAsyncRefCount) |
CCDirector::sharedDirector()->getScheduler()->scheduleSelector(schedule_selector(CCTextureCache::addImageAsyncCallBack), this , 0, false ); |
AsyncStruct *data = new AsyncStruct(); |
data->filename = fullpath.c_str(); |
data->selector = selector; |
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8) |
pthread_mutex_lock(&s_asyncStructQueueMutex); |
s_pAsyncStructQueue->push(data); |
pthread_mutex_unlock(&s_asyncStructQueueMutex); |
pthread_cond_signal(&s_SleepCondition); |
create_task([ this , data] { |
void CCTextureCache::addImageAsyncCallBack( float dt) |
std::queue<ImageInfo*> *imagesQueue = s_pImageQueue; |
pthread_mutex_lock(&s_ImageInfoMutex); |
if (imagesQueue->empty()) |
pthread_mutex_unlock(&s_ImageInfoMutex); |
ImageInfo *pImageInfo = imagesQueue->front(); |
pthread_mutex_unlock(&s_ImageInfoMutex); |
AsyncStruct *pAsyncStruct = pImageInfo->asyncStruct; |
CCImage *pImage = pImageInfo->image; |
CCObject *target = pAsyncStruct->target; |
SEL_CallFuncO selector = pAsyncStruct->selector; |
const char * filename = pAsyncStruct->filename.c_str(); |
CCTexture2D *texture = new CCTexture2D(); |
#if 0 //TODO: (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) |
texture->initWithImage(pImage, kCCResolutioniPhone); |
texture->initWithImage(pImage); |
#if CC_ENABLE_CACHE_TEXTURE_DATA |
VolatileTexture::addImageTexture(texture, filename, pImageInfo->imageType); |
m_pTextures->setObject(texture, filename); |
(target->*selector)(texture); |
if (0 == s_nAsyncRefCount) |
CCDirector::sharedDirector()->getScheduler()->unscheduleSelector(schedule_selector(CCTextureCache::addImageAsyncCallBack), this ); |
CCTexture2D * CCTextureCache::addImage( const char * path) |
CCAssert(path != NULL, "TextureCache: fileimage MUST not be NULL" ); |
CCTexture2D * texture = NULL; |
std::string pathKey = path; |
pathKey = CCFileUtils::sharedFileUtils()->fullPathForFilename(pathKey.c_str()); |
texture = (CCTexture2D*)m_pTextures->objectForKey(pathKey.c_str()); |
std::string fullpath = pathKey; |
std::string lowerCase(pathKey); |
for (unsigned int i = 0; i < lowerCase.length(); ++i) |
lowerCase[i] = tolower (lowerCase[i]); |
CC_BREAK_IF(NULL == pImage); |
bool bRet = pImage->initWithImageFile(fullpath.c_str(), eImageFormat); |
texture = new CCTexture2D(); |
texture->initWithImage(pImage) ) |
#if CC_ENABLE_CACHE_TEXTURE_DATA |
VolatileTexture::addImageTexture(texture, fullpath.c_str(), eImageFormat); |
m_pTextures->setObject(texture, pathKey.c_str()); |
CCLOG( "cocos2d: Couldn't create texture for file:%s in CCTextureCache" , path); |
CCTexture2D * CCTextureCache::addPVRImage( const char * path) |
CCTexture2D* CCTextureCache::addETCImage( const char * path) |
发表评论