Merge pull request #4496 from Dhilan007/addImageAsync_IncorrectError

issue #3341:fix Incorrect at TextureCache::addImageAsync for repeatedly ...
This commit is contained in:
minggo 2013-12-17 00:32:50 -08:00
commit 85ba3ee1a9
2 changed files with 60 additions and 25 deletions

View File

@ -112,7 +112,7 @@ void TextureCache::addImageAsync(const std::string &path, Object *target, SEL_Ca
if (_asyncStructQueue == NULL)
{
_asyncStructQueue = new queue<AsyncStruct*>();
_imageInfoQueue = new queue<ImageInfo*>();
_imageInfoQueue = new deque<ImageInfo*>();
// create a new thread to load images
_loadingThread = new std::thread(&TextureCache::loadImage, this);
@ -170,17 +170,40 @@ void TextureCache::loadImage()
_asyncStructQueueMutex.unlock();
}
const char *filename = asyncStruct->filename.c_str();
// generate image
Image *image = new Image();
if (image && !image->initWithImageFileThreadSafe(filename))
Image *image = nullptr;
bool generateImage = false;
auto it = _textures.find(asyncStruct->filename);
if( it == _textures.end() )
{
CC_SAFE_RELEASE(image);
CCLOG("can not load %s", filename);
continue;
_imageInfoMutex.lock();
ImageInfo *imageInfo;
size_t pos = 0;
size_t infoSize = _imageInfoQueue->size();
for (; pos < infoSize; pos++)
{
imageInfo = (*_imageInfoQueue)[pos];
if(imageInfo->asyncStruct->filename.compare(asyncStruct->filename))
break;
}
_imageInfoMutex.unlock();
if(infoSize > 0 && pos < infoSize)
generateImage = true;
}
if (generateImage)
{
const char *filename = asyncStruct->filename.c_str();
// generate image
image = new Image();
if (image && !image->initWithImageFileThreadSafe(filename))
{
CC_SAFE_RELEASE(image);
CCLOG("can not load %s", filename);
continue;
}
}
// generate image info
ImageInfo *imageInfo = new ImageInfo();
imageInfo->asyncStruct = asyncStruct;
@ -188,7 +211,7 @@ void TextureCache::loadImage()
// put the image info into the queue
_imageInfoMutex.lock();
_imageInfoQueue->push(imageInfo);
_imageInfoQueue->push_back(imageInfo);
_imageInfoMutex.unlock();
}
@ -204,7 +227,7 @@ void TextureCache::loadImage()
void TextureCache::addImageAsyncCallBack(float dt)
{
// the image is generated in loading thread
std::queue<ImageInfo*> *imagesQueue = _imageInfoQueue;
std::deque<ImageInfo*> *imagesQueue = _imageInfoQueue;
_imageInfoMutex.lock();
if (imagesQueue->empty())
@ -214,7 +237,7 @@ void TextureCache::addImageAsyncCallBack(float dt)
else
{
ImageInfo *imageInfo = imagesQueue->front();
imagesQueue->pop();
imagesQueue->pop_front();
_imageInfoMutex.unlock();
AsyncStruct *asyncStruct = imageInfo->asyncStruct;
@ -224,28 +247,40 @@ void TextureCache::addImageAsyncCallBack(float dt)
SEL_CallFuncO selector = asyncStruct->selector;
const char* filename = asyncStruct->filename.c_str();
// generate texture in render thread
Texture2D *texture = new Texture2D();
Texture2D *texture = nullptr;
if (image)
{
// generate texture in render thread
texture = new Texture2D();
texture->initWithImage(image);
texture->initWithImage(image);
#if CC_ENABLE_CACHE_TEXTURE_DATA
// cache the texture file name
VolatileTextureMgr::addImageTexture(texture, filename);
// cache the texture file name
VolatileTextureMgr::addImageTexture(texture, filename);
#endif
// cache the texture. retain it, since it is added in the map
_textures.insert( std::make_pair(filename, texture) );
texture->retain();
texture->autorelease();
// cache the texture. retain it, since it is added in the map
_textures.insert( std::make_pair(filename, texture) );
texture->retain();
texture->autorelease();
}
else
{
auto it = _textures.find(asyncStruct->filename);
if(it != _textures.end())
texture = it->second;
}
if (target && selector)
{
(target->*selector)(texture);
target->release();
}
image->release();
if(image)
{
image->release();
}
delete asyncStruct;
delete imageInfo;

View File

@ -192,7 +192,7 @@ protected:
std::thread* _loadingThread;
std::queue<AsyncStruct*>* _asyncStructQueue;
std::queue<ImageInfo*>* _imageInfoQueue;
std::deque<ImageInfo*>* _imageInfoQueue;
std::mutex _asyncStructQueueMutex;
std::mutex _imageInfoMutex;