axmol/extensions/cocostudio/SpineSkeletonDataCache.cpp

286 lines
7.4 KiB
C++
Raw Normal View History

2019-11-24 23:15:56 +08:00
#include "SpineSkeletonDataCache.h"
2022-07-16 10:43:05 +08:00
#if !defined(AX_USE_SPINE_CPP) || AX_USE_SPINE_CPP
SpineSkeletonDataCache* SpineSkeletonDataCache::getInstance()
{
2021-12-25 10:04:45 +08:00
static SpineSkeletonDataCache internalShared;
return &internalShared;
2019-11-24 23:15:56 +08:00
}
SpineSkeletonDataCache::SpineSkeletonDataCache()
2019-11-24 23:15:56 +08:00
{
2022-08-08 18:02:17 +08:00
_reportError = &ax::log;
2019-11-24 23:15:56 +08:00
}
2021-12-25 10:04:45 +08:00
void SpineSkeletonDataCache::setErrorReportFunc(void (*errorfunc)(const char* pszFormat, ...))
2019-11-24 23:15:56 +08:00
{
_reportError = std::move(errorfunc);
2019-11-24 23:15:56 +08:00
}
void SpineSkeletonDataCache::removeData(const char* dataFile)
{
2021-12-25 10:04:45 +08:00
auto target = _cacheTable.find(dataFile);
if (target != _cacheTable.end())
{
target->second->release();
_cacheTable.erase(target);
}
2019-11-24 23:15:56 +08:00
}
2021-12-25 10:04:45 +08:00
SpineSkeletonDataCache::SkeletonData* SpineSkeletonDataCache::addData(const char* dataFile,
const char* atlasFile,
float scale)
2019-11-24 23:15:56 +08:00
{
2021-12-25 10:04:45 +08:00
auto target = _cacheTable.find(dataFile);
if (target != _cacheTable.end())
{
return target->second;
}
2019-11-24 23:15:56 +08:00
2021-12-25 10:04:45 +08:00
spine::SkeletonData* skeletonData = nullptr;
spine::AttachmentLoader* loader = nullptr;
bool ok = false;
2019-11-24 23:15:56 +08:00
2022-08-08 18:02:17 +08:00
auto fileExtension = ax::FileUtils::getInstance()->getFileExtension(dataFile);
2019-11-24 23:15:56 +08:00
2019-12-12 23:24:50 +08:00
static spine::Cocos2dTextureLoader s_textureLoader;
2021-12-25 10:04:45 +08:00
do
{
auto atlas = new (__FILE__, __LINE__) spine::Atlas(atlasFile, &s_textureLoader);
2019-11-24 23:15:56 +08:00
2021-12-25 10:04:45 +08:00
if (nullptr == (atlas))
break;
2019-11-24 23:15:56 +08:00
2021-12-25 10:04:45 +08:00
loader = new (__FILE__, __LINE__) spine::Cocos2dAtlasAttachmentLoader(atlas);
2019-11-24 23:15:56 +08:00
int failed = 0;
/*
** Atlas is used by shared attachment loader, temp json or binary should be dispose.
** Cache, we just need SkeletonData & atlas.
*/
2021-12-25 10:04:45 +08:00
if (fileExtension == ".skel")
{
2019-12-12 23:24:50 +08:00
spine::SkeletonBinary binary(loader);
2019-11-24 23:15:56 +08:00
2019-12-12 23:24:50 +08:00
binary.setScale(scale);
skeletonData = binary.readSkeletonDataFile(dataFile);
2021-12-25 10:04:45 +08:00
if ((!binary.getError().isEmpty()))
{
2019-11-24 23:15:56 +08:00
++failed;
2019-12-12 23:24:50 +08:00
_reportError("#parse spine .skel data file failed, error:%s", binary.getError().buffer());
2019-11-24 23:15:56 +08:00
}
}
2021-12-25 10:04:45 +08:00
else
{
2019-12-12 23:24:50 +08:00
spine::SkeletonJson json(loader);
2019-11-24 23:15:56 +08:00
2019-12-12 23:24:50 +08:00
json.setScale(scale);
skeletonData = json.readSkeletonDataFile(dataFile);
2021-12-25 10:04:45 +08:00
if ((!json.getError().isEmpty()))
{
2019-11-24 23:15:56 +08:00
++failed;
2019-12-12 23:24:50 +08:00
_reportError("#parse spine .json data file failed, error:%s", json.getError().buffer());
2019-11-24 23:15:56 +08:00
}
}
2021-12-25 10:04:45 +08:00
if (failed > 0)
{
if (skeletonData != nullptr)
delete (skeletonData);
delete (atlas);
delete (loader);
break;
}
ok = true;
} while (false);
if (ok)
{
auto newData = new SkeletonData(skeletonData, loader);
_cacheTable.emplace(dataFile, newData);
return newData;
}
return nullptr;
2019-11-24 23:15:56 +08:00
}
void SpineSkeletonDataCache::removeAllData(void)
{
for (auto&& e : _cacheTable)
2021-12-25 10:04:45 +08:00
{
e.second->release();
}
_cacheTable.clear();
2019-11-24 23:15:56 +08:00
}
void SpineSkeletonDataCache::removeAllUnusedData(void)
{
2021-12-25 10:04:45 +08:00
auto _First = _cacheTable.begin();
auto _Last = _cacheTable.end();
for (; _First != _Last;)
{
if ((*_First).second->getReferenceCount() == 1)
{
(*_First).second->release();
_cacheTable.erase(_First++);
continue;
}
++_First;
}
2019-11-24 23:15:56 +08:00
}
2020-11-04 19:09:30 +08:00
#else
SpineSkeletonDataCache* SpineSkeletonDataCache::getInstance()
{
static SpineSkeletonDataCache internalShared;
return &internalShared;
}
SpineSkeletonDataCache::SpineSkeletonDataCache()
{
2022-08-08 18:02:17 +08:00
_reportError = &ax::log;
2020-11-04 19:09:30 +08:00
}
2021-12-25 10:04:45 +08:00
void SpineSkeletonDataCache::setErrorReportFunc(void (*errorfunc)(const char* pszFormat, ...))
2020-11-04 19:09:30 +08:00
{
_reportError = errorfunc;
}
void SpineSkeletonDataCache::removeData(const char* dataFile)
{
auto target = _cacheTable.find(dataFile);
2021-12-25 10:04:45 +08:00
if (target != _cacheTable.end())
{
2020-11-04 19:09:30 +08:00
target->second->release();
_cacheTable.erase(target);
}
}
2021-12-25 10:04:45 +08:00
SpineSkeletonDataCache::SkeletonData* SpineSkeletonDataCache::addData(const char* dataFile,
const char* atlasFile,
float scale)
2020-11-04 19:09:30 +08:00
{
auto target = _cacheTable.find(dataFile);
2021-12-25 10:04:45 +08:00
if (target != _cacheTable.end())
{
2020-11-04 19:09:30 +08:00
return target->second;
}
spSkeletonData* skeletonData = nullptr;
2021-12-25 10:04:45 +08:00
spAttachmentLoader* loader = nullptr;
bool ok = false;
2020-11-04 19:09:30 +08:00
2022-08-08 18:02:17 +08:00
auto fileExtension = ax::FileUtils::getInstance()->getFileExtension(dataFile);
2020-11-04 19:09:30 +08:00
2021-12-25 10:04:45 +08:00
do
{
2020-11-04 19:09:30 +08:00
spAtlas* atlas = spAtlas_createFromFile(atlasFile, 0);
if (nullptr == (atlas))
break;
loader = (spAttachmentLoader*)Cocos2dAttachmentLoader_create(atlas);
int failed = 0;
/*
** Atlas is used by shared attachment loader, temp json or binary should be dispose.
** Cache, we just need SkeletonData & atlas.
*/
2021-12-25 10:04:45 +08:00
if (fileExtension == ".skel")
{
2020-11-04 19:09:30 +08:00
auto binary = spSkeletonBinary_createWithLoader(loader);
2021-12-25 10:04:45 +08:00
if (nullptr == binary)
{
2020-11-04 19:09:30 +08:00
spAtlas_dispose(atlas);
break;
}
binary->scale = scale;
2021-12-25 10:04:45 +08:00
skeletonData = spSkeletonBinary_readSkeletonDataFile(binary, dataFile);
if ((binary->error != nullptr))
{
2020-11-04 19:09:30 +08:00
++failed;
_reportError("#parse spine .skel data file failed, error:%s", binary->error);
}
spSkeletonBinary_dispose(binary);
}
2021-12-25 10:04:45 +08:00
else
{
2020-11-04 19:09:30 +08:00
spSkeletonJson* json = spSkeletonJson_createWithLoader(loader);
2021-12-25 10:04:45 +08:00
if (nullptr == json)
{
2020-11-04 19:09:30 +08:00
spAtlas_dispose(atlas);
break;
}
2021-12-25 10:04:45 +08:00
json->scale = scale;
2020-11-04 19:09:30 +08:00
skeletonData = spSkeletonJson_readSkeletonDataFile(json, dataFile);
2021-12-25 10:04:45 +08:00
if ((json->error != nullptr))
{
2020-11-04 19:09:30 +08:00
++failed;
_reportError("#parse spine .json data file failed, error:%s", json->error);
}
spSkeletonJson_dispose(json);
}
2021-12-25 10:04:45 +08:00
if ((loader->error1 != nullptr))
{
2020-11-04 19:09:30 +08:00
++failed;
_reportError("#parse spine attachment failed, error:%s%s", loader->error1, loader->error2);
}
2021-12-25 10:04:45 +08:00
if (failed > 0)
{
2020-11-04 19:09:30 +08:00
if (skeletonData != nullptr)
spSkeletonData_dispose(skeletonData);
spAtlas_dispose(atlas);
spAttachmentLoader_dispose(loader);
break;
}
ok = true;
} while (false);
2021-12-25 10:04:45 +08:00
if (ok)
{
2020-11-04 19:09:30 +08:00
auto newData = new SkeletonData(skeletonData, loader);
_cacheTable.emplace(dataFile, newData);
return newData;
}
return nullptr;
}
void SpineSkeletonDataCache::removeAllData(void)
{
for (auto&& e : _cacheTable)
2020-11-04 19:09:30 +08:00
{
e.second->release();
}
_cacheTable.clear();
}
void SpineSkeletonDataCache::removeAllUnusedData(void)
{
auto _First = _cacheTable.begin();
2021-12-25 10:04:45 +08:00
auto _Last = _cacheTable.end();
for (; _First != _Last;)
{
if ((*_First).second->getReferenceCount() == 1)
{
2020-11-04 19:09:30 +08:00
(*_First).second->release();
_cacheTable.erase(_First++);
continue;
}
++_First;
}
}
#endif