axmol/cocos/editor-support/cocostudio/ext/SpineSkeletonDataCache.cpp

137 lines
3.4 KiB
C++

#include "SpineSkeletonDataCache.h"
static auto error_log = &cocos2d::log;
namespace spine {
extern void(*onLoadTextureFailed)(const char* format, ...);
}
void SpineSkeletonDataCache::setErrorLogFunc(void(*errorfunc)(const char* pszFormat, ...))
{
error_log = errorfunc;
spine::onLoadTextureFailed = errorfunc;
}
SpineSkeletonDataCache* SpineSkeletonDataCache::getInstance()
{
static SpineSkeletonDataCache internalShared;
return &internalShared;
}
void SpineSkeletonDataCache::removeData(const char* dataFile)
{
auto target = _cacheTable.find(dataFile);
if (target != _cacheTable.end()) {
target->second->release();
_cacheTable.erase(target);
}
}
SpineSkeletonDataCache::SkeletonData* SpineSkeletonDataCache::addData(const char* dataFile, const char* atlasFile, float scale)
{
auto target = _cacheTable.find(dataFile);
if (target != _cacheTable.end()) {
return target->second;
}
spSkeletonData* skeletonData = nullptr;
spAttachmentLoader* loader = nullptr;
bool ok = false;
auto fileExtension = cocos2d::FileUtils::getInstance()->getFileExtension(dataFile);
do {
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.
*/
if (fileExtension == ".skel") {
auto binary = spSkeletonBinary_createWithLoader(loader);
if (nullptr == binary) {
spAtlas_dispose(atlas);
break;
}
binary->scale = scale;
skeletonData = spSkeletonBinary_readSkeletonDataFile(binary, dataFile);
if ((binary->error != nullptr)) {
++failed;
error_log("#parse spine .skel data file failed, error:%s", binary->error);
}
spSkeletonBinary_dispose(binary);
}
else {
spSkeletonJson* json = spSkeletonJson_createWithLoader(loader);
if (nullptr == json) {
spAtlas_dispose(atlas);
break;
}
json->scale = scale;
skeletonData = spSkeletonJson_readSkeletonDataFile(json, dataFile);
if ((json->error != nullptr)) {
++failed;
error_log("#parse spine .json data file failed, error:%s", json->error);
}
spSkeletonJson_dispose(json);
}
if ((loader->error1 != nullptr)) {
++failed;
error_log("#parse spine attachment failed, error:%s%s", loader->error1, loader->error2);
}
if (failed > 0) {
if (skeletonData != nullptr)
spSkeletonData_dispose(skeletonData);
spAtlas_dispose(atlas);
spAttachmentLoader_dispose(loader);
break;
}
ok = true;
} while (false);
if (ok) {
auto newData = new SkeletonData(skeletonData, loader);
_cacheTable.emplace(dataFile, newData);
return newData;
}
return nullptr;
}
void SpineSkeletonDataCache::removeAllData(void)
{
for (auto & e : _cacheTable)
{
e.second->release();
}
_cacheTable.clear();
}
void SpineSkeletonDataCache::removeAllUnusedData(void)
{
auto _First = _cacheTable.begin();
auto _Last = _cacheTable.end();
for (; _First != _Last; ) {
if ((*_First).second->getReferenceCount() == 1) {
(*_First).second->release();
_cacheTable.erase(_First++);
continue;
}
++_First;
}
}