mirror of https://github.com/axmolengine/axmol.git
Merge pull request #12002 from WenhaiLin/v3-texturecache-unbindfix
Fixed TextureCache::unbindImageAsync fails to unbind all asynchronous callback for a specified bound image.
This commit is contained in:
commit
273ac5d00a
|
@ -115,8 +115,8 @@ void TextureCache::addImageAsync(const std::string &path, const std::function<vo
|
||||||
// lazy init
|
// lazy init
|
||||||
if (_asyncStructQueue == nullptr)
|
if (_asyncStructQueue == nullptr)
|
||||||
{
|
{
|
||||||
_asyncStructQueue = new queue<AsyncStruct*>();
|
_asyncStructQueue = new (std::nothrow) deque<AsyncStruct*>();
|
||||||
_imageInfoQueue = new deque<ImageInfo*>();
|
_imageInfoQueue = new (std::nothrow) deque<ImageInfo*>();
|
||||||
|
|
||||||
// create a new thread to load images
|
// create a new thread to load images
|
||||||
_loadingThread = new std::thread(&TextureCache::loadImage, this);
|
_loadingThread = new std::thread(&TextureCache::loadImage, this);
|
||||||
|
@ -135,36 +135,62 @@ void TextureCache::addImageAsync(const std::string &path, const std::function<vo
|
||||||
AsyncStruct *data = new (std::nothrow) AsyncStruct(fullpath, callback);
|
AsyncStruct *data = new (std::nothrow) AsyncStruct(fullpath, callback);
|
||||||
|
|
||||||
// add async struct into queue
|
// add async struct into queue
|
||||||
_asyncStructQueueMutex.lock();
|
_asyncMutex.lock();
|
||||||
_asyncStructQueue->push(data);
|
_asyncStructQueue->push_back(data);
|
||||||
_asyncStructQueueMutex.unlock();
|
_asyncMutex.unlock();
|
||||||
|
|
||||||
_sleepCondition.notify_one();
|
_sleepCondition.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::unbindImageAsync(const std::string& filename)
|
void TextureCache::unbindImageAsync(const std::string& filename)
|
||||||
{
|
{
|
||||||
_imageInfoMutex.lock();
|
std::string fullpath = FileUtils::getInstance()->fullPathForFilename(filename);
|
||||||
if (_imageInfoQueue && !_imageInfoQueue->empty())
|
|
||||||
|
_asyncMutex.lock();
|
||||||
|
|
||||||
|
if (_asyncStructQueue && !_asyncStructQueue->empty())
|
||||||
{
|
{
|
||||||
std::string fullpath = FileUtils::getInstance()->fullPathForFilename(filename);
|
for (auto it = _asyncStructQueue->begin(); it != _asyncStructQueue->end(); ++it)
|
||||||
auto found = std::find_if(_imageInfoQueue->begin(), _imageInfoQueue->end(), [&fullpath](ImageInfo* ptr)->bool{ return ptr->asyncStruct->filename == fullpath; });
|
|
||||||
if (found != _imageInfoQueue->end())
|
|
||||||
{
|
{
|
||||||
(*found)->asyncStruct->callback = nullptr;
|
if ((*it)->filename == fullpath)
|
||||||
|
{
|
||||||
|
(*it)->callback = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_imageInfoMutex.unlock();
|
|
||||||
|
if (_imageInfoQueue && !_imageInfoQueue->empty())
|
||||||
|
{
|
||||||
|
for (auto it = _imageInfoQueue->begin(); it != _imageInfoQueue->end(); ++it)
|
||||||
|
{
|
||||||
|
if ((*it)->asyncStruct->filename == fullpath)
|
||||||
|
{
|
||||||
|
(*it)->asyncStruct->callback = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_asyncMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::unbindAllImageAsync()
|
void TextureCache::unbindAllImageAsync()
|
||||||
{
|
{
|
||||||
_imageInfoMutex.lock();
|
_asyncMutex.lock();
|
||||||
|
if (_asyncStructQueue && !_asyncStructQueue->empty())
|
||||||
|
{
|
||||||
|
for (auto it = _asyncStructQueue->begin(); it != _asyncStructQueue->end(); ++it)
|
||||||
|
{
|
||||||
|
(*it)->callback = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (_imageInfoQueue && !_imageInfoQueue->empty())
|
if (_imageInfoQueue && !_imageInfoQueue->empty())
|
||||||
{
|
{
|
||||||
std::for_each(_imageInfoQueue->begin(), _imageInfoQueue->end(), [](ImageInfo* ptr) { ptr->asyncStruct->callback = nullptr; });
|
for (auto it = _imageInfoQueue->begin(); it != _imageInfoQueue->end(); ++it)
|
||||||
|
{
|
||||||
|
(*it)->asyncStruct->callback = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_imageInfoMutex.unlock();
|
_asyncMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureCache::loadImage()
|
void TextureCache::loadImage()
|
||||||
|
@ -173,11 +199,10 @@ void TextureCache::loadImage()
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
std::queue<AsyncStruct*> *pQueue = _asyncStructQueue;
|
_asyncMutex.lock();
|
||||||
_asyncStructQueueMutex.lock();
|
if (_asyncStructQueue->empty())
|
||||||
if (pQueue->empty())
|
|
||||||
{
|
{
|
||||||
_asyncStructQueueMutex.unlock();
|
_asyncMutex.unlock();
|
||||||
if (_needQuit) {
|
if (_needQuit) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -189,9 +214,8 @@ void TextureCache::loadImage()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
asyncStruct = pQueue->front();
|
asyncStruct = _asyncStructQueue->front();
|
||||||
pQueue->pop();
|
_asyncMutex.unlock();
|
||||||
_asyncStructQueueMutex.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Image *image = nullptr;
|
Image *image = nullptr;
|
||||||
|
@ -200,9 +224,9 @@ void TextureCache::loadImage()
|
||||||
auto it = _textures.find(asyncStruct->filename);
|
auto it = _textures.find(asyncStruct->filename);
|
||||||
if( it == _textures.end() )
|
if( it == _textures.end() )
|
||||||
{
|
{
|
||||||
_imageInfoMutex.lock();
|
|
||||||
ImageInfo *imageInfo;
|
ImageInfo *imageInfo;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
|
_asyncMutex.lock();
|
||||||
size_t infoSize = _imageInfoQueue->size();
|
size_t infoSize = _imageInfoQueue->size();
|
||||||
for (; pos < infoSize; pos++)
|
for (; pos < infoSize; pos++)
|
||||||
{
|
{
|
||||||
|
@ -210,7 +234,7 @@ void TextureCache::loadImage()
|
||||||
if(imageInfo->asyncStruct->filename.compare(asyncStruct->filename) == 0)
|
if(imageInfo->asyncStruct->filename.compare(asyncStruct->filename) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_imageInfoMutex.unlock();
|
_asyncMutex.unlock();
|
||||||
if(infoSize == 0 || pos == infoSize)
|
if(infoSize == 0 || pos == infoSize)
|
||||||
generateImage = true;
|
generateImage = true;
|
||||||
}
|
}
|
||||||
|
@ -224,6 +248,9 @@ void TextureCache::loadImage()
|
||||||
{
|
{
|
||||||
CC_SAFE_RELEASE(image);
|
CC_SAFE_RELEASE(image);
|
||||||
CCLOG("can not load %s", filename.c_str());
|
CCLOG("can not load %s", filename.c_str());
|
||||||
|
_asyncMutex.lock();
|
||||||
|
_asyncStructQueue->pop_front();
|
||||||
|
_asyncMutex.unlock();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,9 +261,10 @@ void TextureCache::loadImage()
|
||||||
imageInfo->image = image;
|
imageInfo->image = image;
|
||||||
|
|
||||||
// put the image info into the queue
|
// put the image info into the queue
|
||||||
_imageInfoMutex.lock();
|
_asyncMutex.lock();
|
||||||
|
_asyncStructQueue->pop_front();
|
||||||
_imageInfoQueue->push_back(imageInfo);
|
_imageInfoQueue->push_back(imageInfo);
|
||||||
_imageInfoMutex.unlock();
|
_asyncMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_asyncStructQueue != nullptr)
|
if(_asyncStructQueue != nullptr)
|
||||||
|
@ -253,16 +281,16 @@ void TextureCache::addImageAsyncCallBack(float dt)
|
||||||
// the image is generated in loading thread
|
// the image is generated in loading thread
|
||||||
std::deque<ImageInfo*> *imagesQueue = _imageInfoQueue;
|
std::deque<ImageInfo*> *imagesQueue = _imageInfoQueue;
|
||||||
|
|
||||||
_imageInfoMutex.lock();
|
_asyncMutex.lock();
|
||||||
if (imagesQueue->empty())
|
if (imagesQueue->empty())
|
||||||
{
|
{
|
||||||
_imageInfoMutex.unlock();
|
_asyncMutex.unlock();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ImageInfo *imageInfo = imagesQueue->front();
|
ImageInfo *imageInfo = imagesQueue->front();
|
||||||
imagesQueue->pop_front();
|
imagesQueue->pop_front();
|
||||||
_imageInfoMutex.unlock();
|
_asyncMutex.unlock();
|
||||||
|
|
||||||
AsyncStruct *asyncStruct = imageInfo->asyncStruct;
|
AsyncStruct *asyncStruct = imageInfo->asyncStruct;
|
||||||
Image *image = imageInfo->image;
|
Image *image = imageInfo->image;
|
||||||
|
|
|
@ -227,11 +227,10 @@ protected:
|
||||||
|
|
||||||
std::thread* _loadingThread;
|
std::thread* _loadingThread;
|
||||||
|
|
||||||
std::queue<AsyncStruct*>* _asyncStructQueue;
|
std::deque<AsyncStruct*>* _asyncStructQueue;
|
||||||
std::deque<ImageInfo*>* _imageInfoQueue;
|
std::deque<ImageInfo*>* _imageInfoQueue;
|
||||||
|
|
||||||
std::mutex _asyncStructQueueMutex;
|
std::mutex _asyncMutex;
|
||||||
std::mutex _imageInfoMutex;
|
|
||||||
|
|
||||||
std::mutex _sleepMutex;
|
std::mutex _sleepMutex;
|
||||||
std::condition_variable _sleepCondition;
|
std::condition_variable _sleepCondition;
|
||||||
|
|
Loading…
Reference in New Issue