axmol/extensions/CocoStudio/Armature/utils/CCDataReaderHelper.cpp

1534 lines
44 KiB
C++
Raw Normal View History

2013-06-06 12:02:54 +08:00
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
2013-06-07 17:10:53 +08:00
#include "support/tinyxml2/tinyxml2.h"
2013-06-06 12:02:54 +08:00
#include "CCDataReaderHelper.h"
#include "CCArmatureDataManager.h"
#include "CCTransformHelp.h"
2013-09-13 18:07:37 +08:00
#include "CCUtilMath.h"
2013-06-06 12:02:54 +08:00
#include "CCArmatureDefine.h"
#include "../datas/CCDatas.h"
static const char *VERSION = "version";
static const float VERSION_2_0 = 2.0f;
static const char *ARMATURES = "armatures";
static const char *ARMATURE = "armature";
static const char *BONE = "b";
static const char *DISPLAY = "d";
static const char *ANIMATIONS = "animations";
static const char *ANIMATION = "animation";
static const char *MOVEMENT = "mov";
static const char *FRAME = "f";
static const char *TEXTURE_ATLAS = "TextureAtlas";
static const char *SUB_TEXTURE = "SubTexture";
static const char *A_NAME = "name";
static const char *A_DURATION = "dr";
2013-09-13 18:07:37 +08:00
static const char *A_FRAME_INDEX = "fi";
static const char *A_DURATION_TO = "to";
static const char *A_DURATION_TWEEN = "drTW";
static const char *A_LOOP = "lp";
static const char *A_MOVEMENT_SCALE = "sc";
static const char *A_MOVEMENT_DELAY = "dl";
static const char *A_DISPLAY_INDEX = "dI";
2013-09-13 18:07:37 +08:00
// static const char *A_VERT = "vert";
// static const char *A_FRAG = "frag";
static const char *A_PLIST = "plist";
static const char *A_PARENT = "parent";
static const char *A_SKEW_X = "kX";
static const char *A_SKEW_Y = "kY";
static const char *A_SCALE_X = "cX";
static const char *A_SCALE_Y = "cY";
static const char *A_Z = "z";
static const char *A_EVENT = "evt";
static const char *A_SOUND = "sd";
static const char *A_SOUND_EFFECT = "sdE";
static const char *A_TWEEN_EASING = "twE";
//static const char *A_TWEEN_ROTATE = "twR";
static const char *A_IS_ARMATURE = "isArmature";
static const char *A_DISPLAY_TYPE = "displayType";
static const char *A_MOVEMENT = "mov";
static const char *A_X = "x";
static const char *A_Y = "y";
static const char *A_COCOS2DX_X = "cocos2d_x";
static const char *A_COCOS2DX_Y = "cocos2d_y";
static const char *A_WIDTH = "width";
static const char *A_HEIGHT = "height";
static const char *A_PIVOT_X = "pX";
static const char *A_PIVOT_Y = "pY";
static const char *A_COCOS2D_PIVOT_X = "cocos2d_pX";
static const char *A_COCOS2D_PIVOT_Y = "cocos2d_pY";
2013-09-13 18:07:37 +08:00
static const char *A_BLEND_TYPE = "bd";
static const char *A_ALPHA = "a";
static const char *A_RED = "r";
static const char *A_GREEN = "g";
static const char *A_BLUE = "b";
static const char *A_ALPHA_OFFSET = "aM";
static const char *A_RED_OFFSET = "rM";
static const char *A_GREEN_OFFSET = "gM";
static const char *A_BLUE_OFFSET = "bM";
static const char *A_COLOR_TRANSFORM = "colorTransform";
//static const char *A_ROTATION = "rotation";
//static const char *A_USE_COLOR_INFO = "uci";
static const char *CONTOUR = "con";
static const char *CONTOUR_VERTEX = "con_vt";
//static const char *MOVEMENT_EVENT_FRAME = "movementEventFrame";
//static const char *SOUND_FRAME = "soundFrame";
static const char *FL_NAN = "NaN";
static const char *FRAME_DATA = "frame_data";
static const char *MOVEMENT_BONE_DATA = "mov_bone_data";
static const char *MOVEMENT_DATA = "mov_data";
static const char *ANIMATION_DATA = "animation_data";
static const char *DISPLAY_DATA = "display_data";
2013-09-13 18:07:37 +08:00
static const char *SKIN_DATA = "skin_data";
static const char *BONE_DATA = "bone_data";
static const char *ARMATURE_DATA = "armature_data";
static const char *CONTOUR_DATA = "contour_data";
static const char *TEXTURE_DATA = "texture_data";
static const char *VERTEX_POINT = "vertex";
static const char *COLOR_INFO = "color";
2013-09-13 18:07:37 +08:00
static const char *CONFIG_FILE_PATH = "config_file_path";
NS_CC_EXT_ARMATURE_BEGIN
2013-06-06 12:02:54 +08:00
2013-09-13 18:07:37 +08:00
std::vector<std::string> s_arrConfigFileList;
2013-06-06 12:02:54 +08:00
float s_PositionReadScale = 1;
static float s_FlashToolVersion = VERSION_2_0;
2013-09-13 18:07:37 +08:00
static float s_CocoStudioVersion = VERSION_COMBINED;
static std::string s_BasefilePath = "";
CCDataReaderHelper *CCDataReaderHelper::s_DataReaderHelper = NULL;
2013-06-06 12:02:54 +08:00
2013-09-13 18:07:37 +08:00
//! Async load
void CCDataReaderHelper::loadData()
{
AsyncStruct *pAsyncStruct = NULL;
while (true)
{
// create autorelease pool for iOS
Thread thread;
thread.createAutoreleasePool();
std::queue<AsyncStruct *> *pQueue = s_pAsyncStructQueue;
s_AsyncStructQueueMutex.lock(); // get async struct from queue
if (pQueue->empty())
{
s_AsyncStructQueueMutex.unlock();
if (need_quit)
{
break;
}
else
{
std::unique_lock<std::mutex> lk(s_SleepMutex);
s_SleepCondition.wait(lk);
continue;
}
}
else
{
pAsyncStruct = pQueue->front();
pQueue->pop();
s_AsyncStructQueueMutex.unlock();
}
// generate image info
DataInfo *pDataInfo = new DataInfo();
pDataInfo->asyncStruct = pAsyncStruct;
if (pAsyncStruct->configType == DragonBone_XML)
{
CCDataReaderHelper::addDataFromCache(pAsyncStruct->fileContent.c_str(), pDataInfo);
}
else if(pAsyncStruct->configType == CocoStudio_JSON)
{
CCDataReaderHelper::addDataFromJsonCache(pAsyncStruct->fileContent.c_str(), pDataInfo);
}
// put the image info into the queue
s_DataInfoMutex.lock();
s_pDataQueue->push(pDataInfo);
s_DataInfoMutex.unlock();
}
if( s_pAsyncStructQueue != NULL )
{
delete s_pAsyncStructQueue;
s_pAsyncStructQueue = NULL;
delete s_pDataQueue;
s_pDataQueue = NULL;
}
}
CCDataReaderHelper *CCDataReaderHelper::sharedDataReaderHelper()
{
if(!s_DataReaderHelper)
{
s_DataReaderHelper = new CCDataReaderHelper();
}
return s_DataReaderHelper;
}
void CCDataReaderHelper::setPositionReadScale(float scale)
2013-06-06 12:02:54 +08:00
{
2013-06-07 10:52:32 +08:00
s_PositionReadScale = scale;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
float CCDataReaderHelper::getPositionReadScale()
2013-06-06 12:02:54 +08:00
{
2013-06-07 10:52:32 +08:00
return s_PositionReadScale;
2013-06-06 12:02:54 +08:00
}
2013-06-07 10:52:32 +08:00
2013-09-13 18:07:37 +08:00
void CCDataReaderHelper::purge()
{
CCDataReaderHelper::clear();
CC_SAFE_RELEASE_NULL(s_DataReaderHelper);
}
void CCDataReaderHelper::clear()
2013-06-06 12:02:54 +08:00
{
2013-06-07 10:52:32 +08:00
s_arrConfigFileList.clear();
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCDataReaderHelper::CCDataReaderHelper()
: s_LoadingThread(nullptr)
, s_pAsyncStructQueue(nullptr)
, s_pDataQueue(nullptr)
, need_quit(false)
, s_nAsyncRefCount(0)
, s_nAsyncRefTotalCount(0)
{
}
CCDataReaderHelper::~CCDataReaderHelper()
{
need_quit = true;
if (s_LoadingThread) s_LoadingThread->join();
CC_SAFE_DELETE(s_LoadingThread);
s_SleepCondition.notify_one();
s_DataReaderHelper = NULL;
}
void CCDataReaderHelper::addDataFromFile(const char *filePath)
2013-06-06 12:02:54 +08:00
{
2013-06-07 10:52:32 +08:00
/*
2013-09-13 18:07:37 +08:00
* Check if file is already added to CCArmatureDataManager, if then return.
2013-06-07 10:52:32 +08:00
*/
for(unsigned int i = 0; i < s_arrConfigFileList.size(); i++)
{
if (s_arrConfigFileList[i].compare(filePath) == 0)
{
return;
}
}
s_arrConfigFileList.push_back(filePath);
2013-09-13 18:07:37 +08:00
//! find the base file path
s_BasefilePath = filePath;
size_t pos = s_BasefilePath.find_last_of("/");
if (pos != std::string::npos)
{
s_BasefilePath = s_BasefilePath.substr(0, pos + 1);
}
else
{
s_BasefilePath = "";
}
std::string filePathStr = filePath;
2013-06-07 10:52:32 +08:00
size_t startPos = filePathStr.find_last_of(".");
std::string str = &filePathStr[startPos];
2013-09-13 18:07:37 +08:00
unsigned long size;
std::string fullPath = CCFileUtils::getInstance()->fullPathForFilename(filePath);
const char *pFileContent = (char *)CCFileUtils::getInstance()->getFileData(fullPath.c_str() , "r", &size);
2013-06-07 10:52:32 +08:00
if (str.compare(".xml") == 0)
{
2013-09-13 18:07:37 +08:00
CCDataReaderHelper::addDataFromCache(pFileContent);
2013-06-07 10:52:32 +08:00
}
else if(str.compare(".json") == 0 || str.compare(".ExportJson") == 0)
{
2013-09-13 18:07:37 +08:00
CCDataReaderHelper::addDataFromJsonCache(pFileContent);
2013-06-07 10:52:32 +08:00
}
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
void CCDataReaderHelper::addDataFromFileAsync(const char *filePath, Object *target, SEL_SCHEDULE selector)
2013-06-06 12:02:54 +08:00
{
2013-06-07 10:52:32 +08:00
/*
2013-09-13 18:07:37 +08:00
* Check if file is already added to CCArmatureDataManager, if then return.
2013-06-07 10:52:32 +08:00
*/
2013-09-13 18:07:37 +08:00
for(unsigned int i = 0; i < s_arrConfigFileList.size(); i++)
{
if (s_arrConfigFileList[i].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);
2013-06-07 10:52:32 +08:00
2013-09-13 18:07:37 +08:00
//! find the base file path
s_BasefilePath = filePath;
size_t pos = s_BasefilePath.find_last_of("/");
if (pos != std::string::npos)
{
s_BasefilePath = s_BasefilePath.substr(0, pos + 1);
}
else
{
s_BasefilePath = "";
}
// lazy init
if (s_pAsyncStructQueue == NULL)
{
s_pAsyncStructQueue = new std::queue<AsyncStruct *>();
s_pDataQueue = new std::queue<DataInfo *>();
// create a new thread to load images
s_LoadingThread = new std::thread(&CCDataReaderHelper::loadData, this);
need_quit = false;
}
if (0 == s_nAsyncRefCount)
{
Director::getInstance()->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 = s_BasefilePath;
data->target = target;
data->selector = selector;
data->autoLoadSpriteFile = CCArmatureDataManager::sharedArmatureDataManager()->isAutoLoadSpriteFile();
std::string filePathStr = filePath;
size_t startPos = filePathStr.find_last_of(".");
std::string str = &filePathStr[startPos];
std::string fullPath = CCFileUtils::getInstance()->fullPathForFilename(filePath);
2013-06-07 10:52:32 +08:00
unsigned long size;
2013-09-13 18:07:37 +08:00
data->fileContent = (char *)CCFileUtils::getInstance()->getFileData(fullPath.c_str() , "r", &size);
2013-06-07 10:52:32 +08:00
2013-09-13 18:07:37 +08:00
if (str.compare(".xml") == 0)
2013-06-07 10:52:32 +08:00
{
2013-09-13 18:07:37 +08:00
data->configType = DragonBone_XML;
2013-06-07 10:52:32 +08:00
}
2013-09-13 18:07:37 +08:00
else if(str.compare(".json") == 0 || str.compare(".ExportJson") == 0)
{
data->configType = CocoStudio_JSON;
}
// add async struct into queue
s_AsyncStructQueueMutex.lock();
s_pAsyncStructQueue->push(data);
s_AsyncStructQueueMutex.unlock();
s_SleepCondition.notify_one();
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
void CCDataReaderHelper::addDataAsyncCallBack(float dt)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
// the data is generated in loading thread
std::queue<DataInfo *> *dataQueue = s_pDataQueue;
s_DataInfoMutex.lock();
if (dataQueue->empty())
{
s_DataInfoMutex.unlock();
}
else
{
DataInfo *pDataInfo = dataQueue->front();
dataQueue->pop();
s_DataInfoMutex.unlock();
AsyncStruct *pAsyncStruct = pDataInfo->asyncStruct;
while (!pDataInfo->configFileQueue.empty())
{
std::string configPath = pDataInfo->configFileQueue.front();
CCArmatureDataManager::sharedArmatureDataManager()->addSpriteFrameFromFile((pAsyncStruct->baseFilePath + configPath + ".plist").c_str(), (pAsyncStruct->baseFilePath + configPath + ".png").c_str());
pDataInfo->configFileQueue.pop();
}
Object *target = pAsyncStruct->target;
SEL_SCHEDULE selector = pAsyncStruct->selector;
--s_nAsyncRefCount;
if (target && selector)
{
(target->*selector)((s_nAsyncRefTotalCount - s_nAsyncRefCount) / (float)s_nAsyncRefTotalCount);
target->release();
}
delete pAsyncStruct;
delete pDataInfo;
if (0 == s_nAsyncRefCount)
{
s_nAsyncRefTotalCount = 0;
CCDirector::getInstance()->getScheduler()->unscheduleSelector(schedule_selector(CCDataReaderHelper::addDataAsyncCallBack), this);
}
}
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
void CCDataReaderHelper::addDataFromCache(const char *pFileContent, DataInfo *dataInfo)
2013-06-06 12:02:54 +08:00
{
2013-06-07 10:52:32 +08:00
tinyxml2::XMLDocument document;
document.Parse(pFileContent);
tinyxml2::XMLElement *root = document.RootElement();
2013-09-13 18:07:37 +08:00
CCAssert(root, "XML error or XML is empty.");
2013-06-07 10:52:32 +08:00
root->QueryFloatAttribute(VERSION, &s_FlashToolVersion);
2013-09-13 18:07:37 +08:00
2013-06-07 10:52:32 +08:00
/*
* Begin decode armature data from xml
*/
tinyxml2::XMLElement *armaturesXML = root->FirstChildElement(ARMATURES);
tinyxml2::XMLElement *armatureXML = armaturesXML->FirstChildElement(ARMATURE);
while(armatureXML)
{
2013-09-13 18:07:37 +08:00
CCArmatureData *armatureData = CCDataReaderHelper::decodeArmature(armatureXML);
if (dataInfo)
{
s_DataReaderHelper->s_AddDataMutex.lock();
}
CCArmatureDataManager::sharedArmatureDataManager()->addArmatureData(armatureData->name.c_str(), armatureData);
armatureData->release();
if (dataInfo)
{
s_DataReaderHelper->s_AddDataMutex.unlock();
}
2013-06-07 10:52:32 +08:00
armatureXML = armatureXML->NextSiblingElement(ARMATURE);
}
2013-09-13 18:07:37 +08:00
2013-06-07 10:52:32 +08:00
/*
* Begin decode animation data from xml
*/
tinyxml2::XMLElement *animationsXML = root->FirstChildElement(ANIMATIONS);
tinyxml2::XMLElement *animationXML = animationsXML->FirstChildElement(ANIMATION);
while(animationXML)
{
2013-09-13 18:07:37 +08:00
CCAnimationData *animationData = CCDataReaderHelper::decodeAnimation(animationXML);
if (dataInfo)
{
s_DataReaderHelper->s_AddDataMutex.lock();
}
CCArmatureDataManager::sharedArmatureDataManager()->addAnimationData(animationData->name.c_str(), animationData);
animationData->release();
if (dataInfo)
{
s_DataReaderHelper->s_AddDataMutex.unlock();
}
2013-06-07 10:52:32 +08:00
animationXML = animationXML->NextSiblingElement(ANIMATION);
}
2013-09-13 18:07:37 +08:00
2013-06-07 10:52:32 +08:00
/*
* Begin decode texture data from xml
*/
tinyxml2::XMLElement *texturesXML = root->FirstChildElement(TEXTURE_ATLAS);
tinyxml2::XMLElement *textureXML = texturesXML->FirstChildElement(SUB_TEXTURE);
while(textureXML)
{
2013-09-13 18:07:37 +08:00
CCTextureData *textureData = CCDataReaderHelper::decodeTexture(textureXML);
2013-06-07 10:52:32 +08:00
2013-09-13 18:07:37 +08:00
if (dataInfo)
{
s_DataReaderHelper->s_AddDataMutex.lock();
}
CCArmatureDataManager::sharedArmatureDataManager()->addTextureData(textureData->name.c_str(), textureData);
textureData->release();
if (dataInfo)
{
s_DataReaderHelper->s_AddDataMutex.unlock();
}
2013-06-07 10:52:32 +08:00
textureXML = textureXML->NextSiblingElement(SUB_TEXTURE);
}
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCArmatureData *CCDataReaderHelper::decodeArmature(tinyxml2::XMLElement *armatureXML)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCArmatureData *armatureData = new CCArmatureData();
armatureData->init();
2013-06-07 10:52:32 +08:00
2013-09-13 18:07:37 +08:00
const char *name = armatureXML->Attribute(A_NAME);
2013-06-07 10:52:32 +08:00
armatureData->name = name;
tinyxml2::XMLElement *boneXML = armatureXML->FirstChildElement(BONE);
while( boneXML )
{
/*
* If this bone have parent, then get the parent bone xml
*/
const char *parentName = boneXML->Attribute(A_PARENT);
tinyxml2::XMLElement *parentXML = NULL;
if (parentName)
{
parentXML = armatureXML->FirstChildElement(BONE);
std::string name = parentName;
while (parentXML)
{
if (name.compare(parentXML->Attribute(A_NAME)) == 0)
{
break;
}
parentXML = parentXML->NextSiblingElement(BONE);
}
}
2013-09-13 18:07:37 +08:00
CCBoneData *boneData = decodeBone(boneXML, parentXML);
2013-06-07 10:52:32 +08:00
armatureData->addBoneData(boneData);
2013-09-13 18:07:37 +08:00
boneData->release();
2013-06-07 10:52:32 +08:00
boneXML = boneXML->NextSiblingElement(BONE);
}
return armatureData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCBoneData *CCDataReaderHelper::decodeBone(tinyxml2::XMLElement *boneXML, tinyxml2::XMLElement *parentXml)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCBoneData *boneData = new CCBoneData();
boneData->init();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
std::string name = boneXML->Attribute(A_NAME);
boneData->name = name;
if( boneXML->Attribute(A_PARENT) != NULL )
{
boneData->parentName = boneXML->Attribute(A_PARENT);
}
2013-09-13 18:07:37 +08:00
boneXML->QueryIntAttribute(A_Z, &boneData->zOrder);
2013-06-07 10:52:32 +08:00
tinyxml2::XMLElement *displayXML = boneXML->FirstChildElement(DISPLAY);
while(displayXML)
{
2013-09-13 18:07:37 +08:00
CCDisplayData *displayData = decodeBoneDisplay(displayXML);
2013-06-07 10:52:32 +08:00
boneData->addDisplayData(displayData);
2013-09-13 18:07:37 +08:00
displayData->release();
2013-06-07 10:52:32 +08:00
displayXML = displayXML->NextSiblingElement(DISPLAY);
}
return boneData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCDisplayData *CCDataReaderHelper::decodeBoneDisplay(tinyxml2::XMLElement *displayXML)
2013-06-06 12:02:54 +08:00
{
2013-06-07 10:52:32 +08:00
int _isArmature = 0;
2013-09-13 18:07:37 +08:00
CCDisplayData *displayData;
2013-06-07 10:52:32 +08:00
if( displayXML->QueryIntAttribute(A_IS_ARMATURE, &(_isArmature)) == tinyxml2::XML_SUCCESS )
{
if(!_isArmature)
{
2013-09-13 18:07:37 +08:00
displayData = new CCSpriteDisplayData();
2013-06-07 10:52:32 +08:00
displayData->displayType = CS_DISPLAY_SPRITE;
}
else
{
2013-09-13 18:07:37 +08:00
displayData = new CCArmatureDisplayData();
2013-06-07 10:52:32 +08:00
displayData->displayType = CS_DISPLAY_ARMATURE;
}
}
else
{
2013-09-13 18:07:37 +08:00
displayData = new CCSpriteDisplayData();
2013-06-07 10:52:32 +08:00
displayData->displayType = CS_DISPLAY_SPRITE;
}
2013-09-13 18:07:37 +08:00
2013-06-07 10:52:32 +08:00
if(displayXML->Attribute(A_NAME) != NULL )
{
if(!_isArmature)
{
2013-09-13 18:07:37 +08:00
((CCSpriteDisplayData *)displayData)->displayName = displayXML->Attribute(A_NAME);
2013-06-07 10:52:32 +08:00
}
else
{
2013-09-13 18:07:37 +08:00
((CCArmatureDisplayData *)displayData)->displayName = displayXML->Attribute(A_NAME);
2013-06-07 10:52:32 +08:00
}
}
return displayData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCAnimationData *CCDataReaderHelper::decodeAnimation(tinyxml2::XMLElement *animationXML)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCAnimationData *aniData = new CCAnimationData();
2013-06-06 12:02:54 +08:00
2013-09-13 18:07:37 +08:00
const char *name = animationXML->Attribute(A_NAME);
2013-06-06 12:02:54 +08:00
2013-09-13 18:07:37 +08:00
CCArmatureData *armatureData = CCArmatureDataManager::sharedArmatureDataManager()->getArmatureData(name);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
aniData->name = name;
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
tinyxml2::XMLElement *movementXML = animationXML->FirstChildElement(MOVEMENT);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
while( movementXML )
{
2013-09-13 18:07:37 +08:00
CCMovementData *movementData = decodeMovement(movementXML, armatureData);
2013-06-07 10:52:32 +08:00
aniData->addMovement(movementData);
2013-09-13 18:07:37 +08:00
movementData->release();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
movementXML = movementXML->NextSiblingElement(MOVEMENT);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
return aniData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCMovementData *CCDataReaderHelper::decodeMovement(tinyxml2::XMLElement *movementXML, CCArmatureData *armatureData)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCMovementData *movementData = new CCMovementData();
2013-06-07 10:52:32 +08:00
2013-09-13 18:07:37 +08:00
const char *movName = movementXML->Attribute(A_NAME);
2013-06-07 10:52:32 +08:00
movementData->name = movName;
int duration, durationTo, durationTween, loop, tweenEasing = 0;
if( movementXML->QueryIntAttribute(A_DURATION, &(duration)) == tinyxml2::XML_SUCCESS)
{
movementData->duration = duration;
}
if( movementXML->QueryIntAttribute(A_DURATION_TO, &(durationTo)) == tinyxml2::XML_SUCCESS)
{
movementData->durationTo = durationTo;
}
if( movementXML->QueryIntAttribute(A_DURATION_TWEEN, &(durationTween)) == tinyxml2::XML_SUCCESS)
{
movementData->durationTween = durationTween;
}
if( movementXML->QueryIntAttribute(A_LOOP, &(loop)) == tinyxml2::XML_SUCCESS)
{
2013-09-13 18:07:37 +08:00
movementData->loop = (bool)loop;
2013-06-07 10:52:32 +08:00
}
const char *_easing = movementXML->Attribute(A_TWEEN_EASING);
if(_easing != NULL)
{
std::string str = _easing;
if(str.compare(FL_NAN) != 0)
{
if( movementXML->QueryIntAttribute(A_TWEEN_EASING, &(tweenEasing)) == tinyxml2::XML_SUCCESS)
{
2013-09-13 18:07:37 +08:00
movementData->tweenEasing = (CCTweenType)tweenEasing;
2013-06-07 10:52:32 +08:00
}
}
else
{
movementData->tweenEasing = TWEEN_EASING_MAX;
}
}
tinyxml2::XMLElement *movBoneXml = movementXML->FirstChildElement(BONE);
while(movBoneXml)
{
const char *boneName = movBoneXml->Attribute(A_NAME);
2013-06-07 10:52:32 +08:00
if (movementData->getMovementBoneData(boneName))
2013-06-07 10:52:32 +08:00
{
movBoneXml = movBoneXml->NextSiblingElement();
continue;
}
2013-09-13 18:07:37 +08:00
CCBoneData *boneData = (CCBoneData *)armatureData->getBoneData(boneName);
2013-06-07 10:52:32 +08:00
std::string parentName = boneData->parentName;
2013-06-07 10:52:32 +08:00
tinyxml2::XMLElement *parentXml = NULL;
if (parentName.length() != 0)
2013-06-07 10:52:32 +08:00
{
parentXml = movementXML->FirstChildElement(BONE);
while (parentXml)
{
if (parentName.compare(parentXml->Attribute(A_NAME)) == 0)
2013-06-07 10:52:32 +08:00
{
break;
}
parentXml = parentXml->NextSiblingElement(BONE);
}
}
2013-09-13 18:07:37 +08:00
CCMovementBoneData *moveBoneData = decodeMovementBone(movBoneXml, parentXml, boneData);
movementData->addMovementBoneData(moveBoneData);
moveBoneData->release();
2013-06-07 10:52:32 +08:00
movBoneXml = movBoneXml->NextSiblingElement(BONE);
}
return movementData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCMovementBoneData *CCDataReaderHelper::decodeMovementBone(tinyxml2::XMLElement *movBoneXml, tinyxml2::XMLElement *parentXml, CCBoneData *boneData)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCMovementBoneData *movBoneData = new CCMovementBoneData();
movBoneData->init();
2013-06-07 10:52:32 +08:00
float scale, delay;
if( movBoneXml )
{
if( movBoneXml->QueryFloatAttribute(A_MOVEMENT_SCALE, &scale) == tinyxml2::XML_SUCCESS )
{
movBoneData->scale = scale;
}
if( movBoneXml->QueryFloatAttribute(A_MOVEMENT_DELAY, &delay) == tinyxml2::XML_SUCCESS )
{
if(delay > 0)
{
delay -= 1;
}
movBoneData->delay = delay;
}
}
int length = 0;
int i = 0;
int parentTotalDuration = 0;
int currentDuration = 0;
tinyxml2::XMLElement *parentFrameXML = NULL;
std::vector<tinyxml2::XMLElement *> parentXmlList;
/*
* get the parent frame xml list, we need get the origin data
*/
if( parentXml != NULL )
{
parentFrameXML = parentXml->FirstChildElement(FRAME);
while (parentFrameXML)
{
parentXmlList.push_back(parentFrameXML);
parentFrameXML = parentFrameXML->NextSiblingElement(FRAME);
}
parentFrameXML = NULL;
length = parentXmlList.size();
}
int totalDuration = 0;
std::string name = movBoneXml->Attribute(A_NAME);
movBoneData->name = name;
tinyxml2::XMLElement *frameXML = movBoneXml->FirstChildElement(FRAME);
while( frameXML )
{
if(parentXml)
{
/*
* in this loop we get the corresponding parent frame xml
*/
while(i < length && (parentFrameXML ? (totalDuration < parentTotalDuration || totalDuration >= parentTotalDuration + currentDuration) : true))
{
parentFrameXML = parentXmlList[i];
parentTotalDuration += currentDuration;
parentFrameXML->QueryIntAttribute(A_DURATION, &currentDuration);
i++;
}
}
2013-09-13 18:07:37 +08:00
CCFrameData *frameData = decodeFrame( frameXML, parentFrameXML, boneData);
2013-06-07 10:52:32 +08:00
movBoneData->addFrameData(frameData);
2013-09-13 18:07:37 +08:00
frameData->release();
2013-06-07 10:52:32 +08:00
2013-09-13 18:07:37 +08:00
frameData->frameID = totalDuration;
2013-06-07 10:52:32 +08:00
totalDuration += frameData->duration;
2013-09-13 18:07:37 +08:00
movBoneData->duration = totalDuration;
2013-06-07 10:52:32 +08:00
frameXML = frameXML->NextSiblingElement(FRAME);
}
2013-09-13 18:07:37 +08:00
//
CCFrameData *frameData = new CCFrameData();
frameData->copy((CCFrameData *)movBoneData->frameList.getLastObject());
frameData->frameID = movBoneData->duration;
movBoneData->addFrameData(frameData);
frameData->release();
2013-06-07 10:52:32 +08:00
return movBoneData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCFrameData *CCDataReaderHelper::decodeFrame(tinyxml2::XMLElement *frameXML, tinyxml2::XMLElement *parentFrameXml, CCBoneData *boneData)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
float x, y, scale_x, scale_y, skew_x, skew_y = 0;
int duration, displayIndex, zOrder, tweenEasing, blendType = 0;
2013-06-07 10:52:32 +08:00
2013-09-13 18:07:37 +08:00
CCFrameData *frameData = new CCFrameData();
2013-06-07 10:52:32 +08:00
if(frameXML->Attribute(A_MOVEMENT) != NULL)
{
2013-09-13 18:07:37 +08:00
frameData->strMovement = frameXML->Attribute(A_MOVEMENT);
2013-06-07 10:52:32 +08:00
}
if(frameXML->Attribute(A_EVENT) != NULL)
{
2013-09-13 18:07:37 +08:00
frameData->strEvent = frameXML->Attribute(A_EVENT);
2013-06-07 10:52:32 +08:00
}
if(frameXML->Attribute(A_SOUND) != NULL)
{
2013-09-13 18:07:37 +08:00
frameData->strSound = frameXML->Attribute(A_SOUND);
2013-06-07 10:52:32 +08:00
}
if(frameXML->Attribute(A_SOUND_EFFECT) != NULL)
{
2013-09-13 18:07:37 +08:00
frameData->strSoundEffect = frameXML->Attribute(A_SOUND_EFFECT);
2013-06-07 10:52:32 +08:00
}
if (s_FlashToolVersion >= VERSION_2_0)
{
2013-09-13 18:07:37 +08:00
if(frameXML->QueryFloatAttribute(A_COCOS2DX_X, &x) == tinyxml2::XML_SUCCESS)
2013-06-07 10:52:32 +08:00
{
2013-09-13 18:07:37 +08:00
frameData->x = x;
2013-06-07 10:52:32 +08:00
frameData->x *= s_PositionReadScale;
}
2013-09-13 18:07:37 +08:00
if(frameXML->QueryFloatAttribute(A_COCOS2DX_Y, &y) == tinyxml2::XML_SUCCESS)
2013-06-07 10:52:32 +08:00
{
2013-09-13 18:07:37 +08:00
frameData->y = -y;
2013-06-07 10:52:32 +08:00
frameData->y *= s_PositionReadScale;
}
}
else
{
2013-09-13 18:07:37 +08:00
if(frameXML->QueryFloatAttribute(A_X, &x) == tinyxml2::XML_SUCCESS)
2013-06-07 10:52:32 +08:00
{
2013-09-13 18:07:37 +08:00
frameData->x = x;
2013-06-07 10:52:32 +08:00
frameData->x *= s_PositionReadScale;
}
2013-09-13 18:07:37 +08:00
if(frameXML->QueryFloatAttribute(A_Y, &y) == tinyxml2::XML_SUCCESS)
2013-06-07 10:52:32 +08:00
{
2013-09-13 18:07:37 +08:00
frameData->y = -y;
2013-06-07 10:52:32 +08:00
frameData->y *= s_PositionReadScale;
}
}
2013-09-13 18:07:37 +08:00
if( frameXML->QueryFloatAttribute(A_SCALE_X, &scale_x) == tinyxml2::XML_SUCCESS )
2013-06-07 10:52:32 +08:00
{
2013-09-13 18:07:37 +08:00
frameData->scaleX = scale_x;
2013-06-07 10:52:32 +08:00
}
2013-09-13 18:07:37 +08:00
if( frameXML->QueryFloatAttribute(A_SCALE_Y, &scale_y) == tinyxml2::XML_SUCCESS )
2013-06-07 10:52:32 +08:00
{
2013-09-13 18:07:37 +08:00
frameData->scaleY = scale_y;
2013-06-07 10:52:32 +08:00
}
2013-09-13 18:07:37 +08:00
if( frameXML->QueryFloatAttribute(A_SKEW_X, &skew_x) == tinyxml2::XML_SUCCESS )
2013-06-07 10:52:32 +08:00
{
2013-09-13 18:07:37 +08:00
frameData->skewX = CC_DEGREES_TO_RADIANS(skew_x);
2013-06-07 10:52:32 +08:00
}
2013-09-13 18:07:37 +08:00
if( frameXML->QueryFloatAttribute(A_SKEW_Y, &skew_y) == tinyxml2::XML_SUCCESS )
2013-06-07 10:52:32 +08:00
{
2013-09-13 18:07:37 +08:00
frameData->skewY = CC_DEGREES_TO_RADIANS(-skew_y);
2013-06-07 10:52:32 +08:00
}
2013-09-13 18:07:37 +08:00
if( frameXML->QueryIntAttribute(A_DURATION, &duration) == tinyxml2::XML_SUCCESS )
2013-06-07 10:52:32 +08:00
{
2013-09-13 18:07:37 +08:00
frameData->duration = duration;
2013-06-07 10:52:32 +08:00
}
2013-09-13 18:07:37 +08:00
if( frameXML->QueryIntAttribute(A_DISPLAY_INDEX, &displayIndex) == tinyxml2::XML_SUCCESS )
2013-06-07 10:52:32 +08:00
{
2013-09-13 18:07:37 +08:00
frameData->displayIndex = displayIndex;
2013-06-07 10:52:32 +08:00
}
2013-09-13 18:07:37 +08:00
if( frameXML->QueryIntAttribute(A_Z, &zOrder) == tinyxml2::XML_SUCCESS )
2013-06-07 10:52:32 +08:00
{
2013-09-13 18:07:37 +08:00
frameData->zOrder = zOrder;
}
if ( frameXML->QueryIntAttribute(A_BLEND_TYPE, &blendType) == tinyxml2::XML_SUCCESS )
{
frameData->blendType = (CCBlendType)blendType;
2013-06-07 10:52:32 +08:00
}
tinyxml2::XMLElement *colorTransformXML = frameXML->FirstChildElement(A_COLOR_TRANSFORM);
if (colorTransformXML)
{
int alpha, red, green, blue = 100;
int alphaOffset, redOffset, greenOffset, blueOffset = 0;
colorTransformXML->QueryIntAttribute(A_ALPHA, &alpha);
colorTransformXML->QueryIntAttribute(A_RED, &red);
colorTransformXML->QueryIntAttribute(A_GREEN, &green);
colorTransformXML->QueryIntAttribute(A_BLUE, &blue) ;
colorTransformXML->QueryIntAttribute(A_ALPHA_OFFSET, &alphaOffset);
colorTransformXML->QueryIntAttribute(A_RED_OFFSET, &redOffset);
colorTransformXML->QueryIntAttribute(A_GREEN_OFFSET, &greenOffset);
colorTransformXML->QueryIntAttribute(A_BLUE_OFFSET, &blueOffset) ;
frameData->a = 2.55 * alphaOffset + alpha;
frameData->r = 2.55 * redOffset + red;
frameData->g = 2.55 * greenOffset + green;
frameData->b = 2.55 * blueOffset + blue;
frameData->isUseColorInfo = true;
}
const char *_easing = frameXML->Attribute(A_TWEEN_EASING);
if(_easing != NULL)
{
std::string str = _easing;
if(str.compare(FL_NAN) != 0)
{
2013-09-13 18:07:37 +08:00
if( frameXML->QueryIntAttribute(A_TWEEN_EASING, &(tweenEasing)) == tinyxml2::XML_SUCCESS)
2013-06-07 10:52:32 +08:00
{
2013-09-13 18:07:37 +08:00
frameData->tweenEasing = (CCTweenType)tweenEasing;
2013-06-07 10:52:32 +08:00
}
}
else
{
frameData->tweenEasing = TWEEN_EASING_MAX;
}
}
if(parentFrameXml)
{
/*
* recalculate frame data from parent frame data, use for translate matrix
*/
2013-09-13 18:07:37 +08:00
CCBaseData helpNode;
2013-06-07 10:52:32 +08:00
if (s_FlashToolVersion >= VERSION_2_0)
{
parentFrameXml->QueryFloatAttribute(A_COCOS2DX_X, &helpNode.x);
parentFrameXml->QueryFloatAttribute(A_COCOS2DX_Y, &helpNode.y);
}
else
{
parentFrameXml->QueryFloatAttribute(A_X, &helpNode.x);
parentFrameXml->QueryFloatAttribute(A_Y, &helpNode.y);
}
parentFrameXml->QueryFloatAttribute(A_SKEW_X, &helpNode.skewX);
parentFrameXml->QueryFloatAttribute(A_SKEW_Y, &helpNode.skewY);
helpNode.y = -helpNode.y;
helpNode.skewX = CC_DEGREES_TO_RADIANS(helpNode.skewX);
helpNode.skewY = CC_DEGREES_TO_RADIANS(-helpNode.skewY);
2013-09-13 18:07:37 +08:00
CCTransformHelp::transformFromParent(*frameData, helpNode);
2013-06-07 10:52:32 +08:00
}
return frameData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCTextureData *CCDataReaderHelper::decodeTexture(tinyxml2::XMLElement *textureXML)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCTextureData *textureData = new CCTextureData();
textureData->init();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
if( textureXML->Attribute(A_NAME) != NULL)
{
textureData->name = textureXML->Attribute(A_NAME);
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
float px, py, width, height = 0;
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
if(s_FlashToolVersion >= VERSION_2_0)
{
textureXML->QueryFloatAttribute(A_COCOS2D_PIVOT_X, &px);
textureXML->QueryFloatAttribute(A_COCOS2D_PIVOT_Y, &py);
}
else
{
textureXML->QueryFloatAttribute(A_PIVOT_X, &px);
textureXML->QueryFloatAttribute(A_PIVOT_Y, &py);
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
textureXML->QueryFloatAttribute(A_WIDTH, &width);
textureXML->QueryFloatAttribute(A_HEIGHT, &height);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
float anchorPointX = px / width;
float anchorPointY = (height - py) / height;
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
textureData->pivotX = anchorPointX;
textureData->pivotY = anchorPointY;
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
tinyxml2::XMLElement *contourXML = textureXML->FirstChildElement(CONTOUR);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
while (contourXML)
{
2013-09-13 18:07:37 +08:00
CCContourData *contourData = decodeContour(contourXML);
2013-06-07 10:52:32 +08:00
textureData->addContourData(contourData);
2013-09-13 18:07:37 +08:00
contourData->release();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
contourXML = contourXML->NextSiblingElement(CONTOUR);
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
return textureData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCContourData *CCDataReaderHelper::decodeContour(tinyxml2::XMLElement *contourXML)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCContourData *contourData = new CCContourData();
contourData->init();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
tinyxml2::XMLElement *vertexDataXML = contourXML->FirstChildElement(CONTOUR_VERTEX);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
while (vertexDataXML)
{
2013-09-13 18:07:37 +08:00
CCContourVertex2 *vertex = new CCContourVertex2(0, 0);
vertex->release();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
vertexDataXML->QueryFloatAttribute(A_X, &vertex->x);
vertexDataXML->QueryFloatAttribute(A_Y, &vertex->y);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
vertex->y = -vertex->y;
2013-09-13 18:07:37 +08:00
contourData->vertexList.addObject(vertex);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
vertexDataXML = vertexDataXML->NextSiblingElement(CONTOUR_VERTEX);
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
return contourData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
void CCDataReaderHelper::addDataFromJsonCache(const char *fileContent, DataInfo *dataInfo)
2013-06-06 12:02:54 +08:00
{
cs::JsonDictionary json;
2013-06-07 10:52:32 +08:00
json.initWithDescription(fileContent);
// Decode armatures
int length = json.getArrayItemCount(ARMATURE_DATA);
for (int i = 0; i < length; i++)
{
cs::JsonDictionary *armatureDic = json.getSubItemFromArray(ARMATURE_DATA, i);
2013-09-13 18:07:37 +08:00
CCArmatureData *armatureData = decodeArmature(*armatureDic);
2013-06-07 10:52:32 +08:00
2013-09-13 18:07:37 +08:00
if (dataInfo)
{
s_DataReaderHelper->s_AddDataMutex.lock();
}
CCArmatureDataManager::sharedArmatureDataManager()->addArmatureData(armatureData->name.c_str(), armatureData);
armatureData->release();
if (dataInfo)
{
s_DataReaderHelper->s_AddDataMutex.unlock();
}
2013-06-07 10:52:32 +08:00
delete armatureDic;
}
// Decode animations
length = json.getArrayItemCount(ANIMATION_DATA);
for (int i = 0; i < length; i++)
{
cs::JsonDictionary *animationDic = json.getSubItemFromArray(ANIMATION_DATA, i);
2013-09-13 18:07:37 +08:00
CCAnimationData *animationData = decodeAnimation(*animationDic);
2013-06-07 10:52:32 +08:00
2013-09-13 18:07:37 +08:00
if (dataInfo)
{
s_DataReaderHelper->s_AddDataMutex.lock();
}
CCArmatureDataManager::sharedArmatureDataManager()->addAnimationData(animationData->name.c_str(), animationData);
animationData->release();
if (dataInfo)
{
s_DataReaderHelper->s_AddDataMutex.unlock();
}
2013-06-07 10:52:32 +08:00
delete animationDic;
}
// Decode textures
length = json.getArrayItemCount(TEXTURE_DATA);
for (int i = 0; i < length; i++)
{
cs::JsonDictionary *textureDic = json.getSubItemFromArray(TEXTURE_DATA, i);
2013-09-13 18:07:37 +08:00
CCTextureData *textureData = decodeTexture(*textureDic);
2013-06-07 10:52:32 +08:00
2013-09-13 18:07:37 +08:00
if (dataInfo)
{
s_DataReaderHelper->s_AddDataMutex.lock();
}
CCArmatureDataManager::sharedArmatureDataManager()->addTextureData(textureData->name.c_str(), textureData);
textureData->release();
if (dataInfo)
{
s_DataReaderHelper->s_AddDataMutex.unlock();
}
2013-06-07 10:52:32 +08:00
delete textureDic;
}
2013-09-13 18:07:37 +08:00
// Auto load sprite file
bool autoLoad = dataInfo == NULL ? CCArmatureDataManager::sharedArmatureDataManager()->isAutoLoadSpriteFile() : dataInfo->asyncStruct->autoLoadSpriteFile;
if (autoLoad)
{
length = json.getArrayItemCount(CONFIG_FILE_PATH);
for (int i = 0; i < length; i++)
{
const char *path = json.getStringValueFromArray(CONFIG_FILE_PATH, i);
if (path == NULL)
{
CCLOG("load CONFIG_FILE_PATH error.");
return;
}
std::string filePath = path;
filePath = filePath.erase(filePath.find_last_of("."));
if (dataInfo != NULL)
{
dataInfo->configFileQueue.push(filePath);
}
else
{
std::string plistPath = filePath + ".plist";
std::string pngPath = filePath + ".png";
CCArmatureDataManager::sharedArmatureDataManager()->addSpriteFrameFromFile((s_BasefilePath + plistPath).c_str(), (s_BasefilePath + pngPath).c_str());
}
}
}
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCArmatureData *CCDataReaderHelper::decodeArmature(cs::JsonDictionary &json)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCArmatureData *armatureData = new CCArmatureData();
armatureData->init();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
const char *name = json.getItemStringValue(A_NAME);
if(name != NULL)
{
armatureData->name = name;
}
2013-06-06 12:02:54 +08:00
2013-09-13 18:07:37 +08:00
s_CocoStudioVersion = armatureData->dataVersion = json.getItemFloatValue(VERSION, 0.1f);
2013-06-07 10:52:32 +08:00
int length = json.getArrayItemCount(BONE_DATA);
for (int i = 0; i < length; i++)
{
cs::JsonDictionary *dic = json.getSubItemFromArray(BONE_DATA, i);
2013-09-13 18:07:37 +08:00
CCBoneData *boneData = decodeBone(*dic);
armatureData->addBoneData(boneData);
boneData->release();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
delete dic;
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
return armatureData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCBoneData *CCDataReaderHelper::decodeBone(cs::JsonDictionary &json)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCBoneData *boneData = new CCBoneData();
boneData->init();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
decodeNode(boneData, json);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
const char *str = json.getItemStringValue(A_NAME);
if(str != NULL)
{
boneData->name = str;
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
str = json.getItemStringValue(A_PARENT);
if(str != NULL)
{
boneData->parentName = str;
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
int length = json.getArrayItemCount(DISPLAY_DATA);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
for (int i = 0; i < length; i++)
{
cs::JsonDictionary *dic = json.getSubItemFromArray(DISPLAY_DATA, i);
2013-09-13 18:07:37 +08:00
CCDisplayData *displayData = decodeBoneDisplay(*dic);
boneData->addDisplayData(displayData);
displayData->release();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
delete dic;
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
return boneData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCDisplayData *CCDataReaderHelper::decodeBoneDisplay(cs::JsonDictionary &json)
2013-06-06 12:02:54 +08:00
{
2013-06-07 10:52:32 +08:00
DisplayType displayType = (DisplayType)json.getItemIntValue(A_DISPLAY_TYPE, CS_DISPLAY_SPRITE);
2013-09-13 18:07:37 +08:00
CCDisplayData *displayData = NULL;
2013-06-07 10:52:32 +08:00
switch (displayType)
{
case CS_DISPLAY_SPRITE:
{
2013-09-13 18:07:37 +08:00
displayData = new CCSpriteDisplayData();
2013-06-07 10:52:32 +08:00
const char *name = json.getItemStringValue(A_NAME);
if(name != NULL)
{
2013-09-13 18:07:37 +08:00
((CCSpriteDisplayData *)displayData)->displayName = name;
}
cs::JsonDictionary *dic = json.getSubItemFromArray(SKIN_DATA, 0);
if (dic != NULL)
{
CCSpriteDisplayData *sdd = (CCSpriteDisplayData *)displayData;
sdd->skinData.x = dic->getItemFloatValue(A_X, 0) * s_PositionReadScale;
sdd->skinData.y = dic->getItemFloatValue(A_Y, 0) * s_PositionReadScale;
sdd->skinData.scaleX = dic->getItemFloatValue(A_SCALE_X, 1);
sdd->skinData.scaleY = dic->getItemFloatValue(A_SCALE_Y, 1);
sdd->skinData.skewX = dic->getItemFloatValue(A_SKEW_X, 0);
sdd->skinData.skewY = dic->getItemFloatValue(A_SKEW_Y, 0);
delete dic;
2013-06-07 10:52:32 +08:00
}
}
break;
case CS_DISPLAY_ARMATURE:
{
2013-09-13 18:07:37 +08:00
displayData = new CCArmatureDisplayData();
2013-06-07 10:52:32 +08:00
const char *name = json.getItemStringValue(A_NAME);
if(name != NULL)
{
2013-09-13 18:07:37 +08:00
((CCArmatureDisplayData *)displayData)->displayName = name;
2013-06-07 10:52:32 +08:00
}
}
break;
case CS_DISPLAY_PARTICLE:
{
2013-09-13 18:07:37 +08:00
displayData = new CCParticleDisplayData();
2013-06-07 10:52:32 +08:00
const char *plist = json.getItemStringValue(A_PLIST);
if(plist != NULL)
{
2013-09-13 18:07:37 +08:00
((CCParticleDisplayData *)displayData)->plist = s_BasefilePath + plist;
2013-06-07 10:52:32 +08:00
}
}
break;
default:
2013-09-13 18:07:37 +08:00
displayData = new CCSpriteDisplayData();
2013-06-07 10:52:32 +08:00
break;
}
2013-09-13 18:07:37 +08:00
2013-06-07 10:52:32 +08:00
displayData->displayType = displayType;
return displayData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCAnimationData *CCDataReaderHelper::decodeAnimation(cs::JsonDictionary &json)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCAnimationData *aniData = new CCAnimationData();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
const char *name = json.getItemStringValue(A_NAME);
if(name != NULL)
{
aniData->name = name;
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
int length = json.getArrayItemCount(MOVEMENT_DATA);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
for (int i = 0; i < length; i++)
{
cs::JsonDictionary *dic = json.getSubItemFromArray(MOVEMENT_DATA, i);
2013-09-13 18:07:37 +08:00
CCMovementData *movementData = decodeMovement(*dic);
aniData->addMovement(movementData);
movementData->release();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
delete dic;
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
return aniData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCMovementData *CCDataReaderHelper::decodeMovement(cs::JsonDictionary &json)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCMovementData *movementData = new CCMovementData();
2013-06-07 10:52:32 +08:00
movementData->loop = json.getItemBoolvalue(A_LOOP, true);
movementData->durationTween = json.getItemIntValue(A_DURATION_TWEEN, 0);
movementData->durationTo = json.getItemIntValue(A_DURATION_TO, 0);
movementData->duration = json.getItemIntValue(A_DURATION, 0);
2013-09-13 18:07:37 +08:00
movementData->scale = json.getItemFloatValue(A_MOVEMENT_SCALE, 1);
movementData->tweenEasing = (CCTweenType)json.getItemIntValue(A_TWEEN_EASING, Linear);
2013-06-07 10:52:32 +08:00
const char *name = json.getItemStringValue(A_NAME);
if(name != NULL)
{
movementData->name = name;
}
int length = json.getArrayItemCount(MOVEMENT_BONE_DATA);
for (int i = 0; i < length; i++)
{
cs::JsonDictionary *dic = json.getSubItemFromArray(MOVEMENT_BONE_DATA, i);
2013-09-13 18:07:37 +08:00
CCMovementBoneData *movementBoneData = decodeMovementBone(*dic);
movementData->addMovementBoneData(movementBoneData);
movementBoneData->release();
2013-06-07 10:52:32 +08:00
delete dic;
}
return movementData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCMovementBoneData *CCDataReaderHelper::decodeMovementBone(cs::JsonDictionary &json)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCMovementBoneData *movementBoneData = new CCMovementBoneData();
movementBoneData->init();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
movementBoneData->delay = json.getItemFloatValue(A_MOVEMENT_DELAY, 0);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
const char *name = json.getItemStringValue(A_NAME);
if(name != NULL)
{
movementBoneData->name = name;
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
int length = json.getArrayItemCount(FRAME_DATA);
for (int i = 0; i < length; i++)
{
cs::JsonDictionary *dic = json.getSubItemFromArray(FRAME_DATA, i);
2013-09-13 18:07:37 +08:00
CCFrameData *frameData = decodeFrame(*dic);
2013-06-07 10:52:32 +08:00
movementBoneData->addFrameData(frameData);
2013-09-13 18:07:37 +08:00
frameData->release();
if (s_CocoStudioVersion < VERSION_COMBINED)
{
frameData->frameID = movementBoneData->duration;
movementBoneData->duration += frameData->duration;
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
delete dic;
}
2013-06-06 12:02:54 +08:00
2013-09-13 18:07:37 +08:00
if (s_CocoStudioVersion < VERSION_COMBINED)
{
if (movementBoneData->frameList.count() > 0)
{
CCFrameData *frameData = new CCFrameData();
frameData->copy((CCFrameData *)movementBoneData->frameList.getLastObject());
movementBoneData->addFrameData(frameData);
frameData->release();
frameData->frameID = movementBoneData->duration;
}
}
2013-06-07 10:52:32 +08:00
return movementBoneData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCFrameData *CCDataReaderHelper::decodeFrame(cs::JsonDictionary &json)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCFrameData *frameData = new CCFrameData();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
decodeNode(frameData, json);
2013-06-06 12:02:54 +08:00
2013-09-13 18:07:37 +08:00
frameData->tweenEasing = (CCTweenType)json.getItemIntValue(A_TWEEN_EASING, Linear);
2013-06-07 10:52:32 +08:00
frameData->displayIndex = json.getItemIntValue(A_DISPLAY_INDEX, 0);
2013-09-13 18:07:37 +08:00
frameData->blendType = (CCBlendType)json.getItemIntValue(A_BLEND_TYPE, 0);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
const char *event = json.getItemStringValue(A_EVENT);
if (event != NULL)
{
2013-09-13 18:07:37 +08:00
frameData->strEvent = event;
}
if (s_CocoStudioVersion < VERSION_COMBINED)
{
frameData->duration = json.getItemIntValue(A_DURATION, 1);
}
else
{
frameData->frameID = json.getItemIntValue(A_FRAME_INDEX, 0);
2013-06-07 10:52:32 +08:00
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
return frameData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCTextureData *CCDataReaderHelper::decodeTexture(cs::JsonDictionary &json)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCTextureData *textureData = new CCTextureData();
textureData->init();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
const char *name = json.getItemStringValue(A_NAME);
if(name != NULL)
{
textureData->name = name;
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
textureData->width = json.getItemFloatValue(A_WIDTH, 0);
textureData->height = json.getItemFloatValue(A_HEIGHT, 0);
textureData->pivotX = json.getItemFloatValue(A_PIVOT_X, 0);
textureData->pivotY = json.getItemFloatValue(A_PIVOT_Y, 0);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
int length = json.getArrayItemCount(CONTOUR_DATA);
for (int i = 0; i < length; i++)
{
cs::JsonDictionary *dic = json.getSubItemFromArray(CONTOUR_DATA, i);
2013-09-13 18:07:37 +08:00
CCContourData *contourData = decodeContour(*dic);
textureData->contourDataList.addObject(contourData);
contourData->release();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
delete dic;
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
return textureData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
CCContourData *CCDataReaderHelper::decodeContour(cs::JsonDictionary &json)
2013-06-06 12:02:54 +08:00
{
2013-09-13 18:07:37 +08:00
CCContourData *contourData = new CCContourData();
contourData->init();
2013-06-07 10:52:32 +08:00
int length = json.getArrayItemCount(VERTEX_POINT);
for (int i = length - 1; i >= 0; i--)
{
cs::JsonDictionary *dic = json.getSubItemFromArray(VERTEX_POINT, i);
2013-06-06 12:02:54 +08:00
2013-09-13 18:07:37 +08:00
CCContourVertex2 *vertex = new CCContourVertex2(0, 0);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
vertex->x = dic->getItemFloatValue(A_X, 0);
vertex->y = dic->getItemFloatValue(A_Y, 0);
2013-06-06 12:02:54 +08:00
2013-09-13 18:07:37 +08:00
contourData->vertexList.addObject(vertex);
2013-06-07 10:52:32 +08:00
vertex->release();
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
delete dic;
}
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
return contourData;
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
void CCDataReaderHelper::decodeNode(CCBaseData *node, cs::JsonDictionary &json)
2013-06-06 12:02:54 +08:00
{
2013-06-07 10:52:32 +08:00
node->x = json.getItemFloatValue(A_X, 0) * s_PositionReadScale;
node->y = json.getItemFloatValue(A_Y, 0) * s_PositionReadScale;
node->zOrder = json.getItemIntValue(A_Z, 0);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
node->skewX = json.getItemFloatValue(A_SKEW_X, 0);
node->skewY = json.getItemFloatValue(A_SKEW_Y, 0);
node->scaleX = json.getItemFloatValue(A_SCALE_X, 1);
node->scaleY = json.getItemFloatValue(A_SCALE_Y, 1);
2013-06-06 12:02:54 +08:00
cs::JsonDictionary *colorDic = json.getSubItemFromArray(COLOR_INFO, 0);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
if (colorDic)
{
node->a = colorDic->getItemIntValue(A_ALPHA, 255);
node->r = colorDic->getItemIntValue(A_RED, 255);
node->g = colorDic->getItemIntValue(A_GREEN, 255);
node->b = colorDic->getItemIntValue(A_BLUE, 255);
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
node->isUseColorInfo = true;
2013-06-06 12:02:54 +08:00
2013-06-07 10:52:32 +08:00
delete colorDic;
}
2013-06-06 12:02:54 +08:00
}
2013-09-13 18:07:37 +08:00
NS_CC_EXT_ARMATURE_END