版本2.2.2
我是从最新的版本上扒下来的,我在论坛找了好久也没人解决我特此记录下
void CCDataReaderHelper::addDataFromFileAsync(const char *imagePath, const char *plistPath, const char *filePath, CCObject *target, SEL_SCHEDULE selector)
{
#ifdef EMSCRIPTEN
CCLOGWARN("Cannot load data %s asynchronously in Emscripten builds.", filePath);
return;
#endif // EMSCRIPTEN
/*
* Check if file is already added to CCArmatureDataManager, if then return.
*/
for(unsigned int i = 0; i < s_arrConfigFileList.size(); i++)
{
if (s_arrConfigFileList.compare(filePath) == 0)
{
if (target && selector)
{
if (s_nAsyncRefTotalCount == 0 && s_nAsyncRefCount == 0)
{
(target->*selector)(1);
}
else
{
(target->*selector)((s_nAsyncRefTotalCount - s_nAsyncRefCount) / (float)s_nAsyncRefTotalCount);
}
}
return;
}
}
s_arrConfigFileList.push_back(filePath);
//! find the base file path
std::string basefilePath = filePath;
size_t pos = basefilePath.find_last_of("/");
if (pos != std::string::npos)
{
basefilePath = basefilePath.substr(0, pos + 1);
}
else
{
basefilePath = "";
}
// lazy init
if (s_pAsyncStructQueue == NULL)
{
s_pAsyncStructQueue = new std::queue<AsyncStruct *>();
s_pDataQueue = new std::queue<DataInfo *>();
pthread_mutex_init(&s_asyncStructQueueMutex, NULL);
pthread_mutex_init(&s_DataInfoMutex, NULL);
pthread_mutex_init(&s_SleepMutex, NULL);
pthread_mutex_init(&s_addDataMutex, NULL);
pthread_mutex_init(&s_ReadFileMutex, NULL);
pthread_mutex_init(&s_GetFileDataMutex, 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, loadData, NULL);
#endif
need_quit = false;
}
if (0 == s_nAsyncRefCount)
{
CCDirector::sharedDirector()->getScheduler()->scheduleSelector(schedule_selector(CCDataReaderHelper::addDataAsyncCallBack), this, 0, false);
}
++s_nAsyncRefCount;
++s_nAsyncRefTotalCount;
if (target)
{
target->retain();
}
// generate async struct
AsyncStruct *data = new AsyncStruct();
data->filename = filePath;
data->baseFilePath = basefilePath;
data->target = target;
data->selector = selector;
data->autoLoadSpriteFile = CCArmatureDataManager::sharedArmatureDataManager()->isAutoLoadSpriteFile();
data->imagePath = imagePath;
data->plistPath = plistPath;
std::string filePathStr = filePath;
size_t startPos = filePathStr.find_last_of(".");
std::string str = &filePathStr;
std::string fullPath = CCFileUtils::sharedFileUtils()->fullPathForFilename(filePath);
unsigned long size;
// 加入这几行就好了
pthread_mutex_lock(&s_GetFileDataMutex);
unsigned char *pBytes = CCFileUtils::sharedFileUtils()->getFileData(fullPath.c_str() , "r", &size);
pthread_mutex_unlock(&s_GetFileDataMutex);
CCData bytecpy(pBytes, size);
data->fileContent = std::string((const char*)bytecpy.getBytes(), size);
CC_SAFE_DELETE_ARRAY(pBytes);
if (str.compare(".xml") == 0)
{
data->configType = DragonBone_XML;
}
else if(str.compare(".json") == 0 || str.compare(".ExportJson") == 0)
{
data->configType = CocoStudio_JSON;
}
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) && (CC_TARGET_PLATFORM != CC_PLATFORM_WP8)
// add async struct into queue
pthread_mutex_lock(&s_asyncStructQueueMutex);
s_pAsyncStructQueue->push(data);
pthread_mutex_unlock(&s_asyncStructQueueMutex);
pthread_cond_signal(&s_SleepCondition);
#else
// WinRT uses an Async Task to load the image since the ThreadPool has a limited number of threads
create_task( {
addData(data);
});
#endif
}
如果你研究过此问题那么一对比就出来了。