CCBReader.cpp 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  1. #include <ctype.h>
  2. #include <algorithm>
  3. #include "base/CCDirector.h"
  4. #include "platform/CCFileUtils.h"
  5. #include "2d/CCScene.h"
  6. #include "2d/CCSpriteFrameCache.h"
  7. #include "renderer/CCTextureCache.h"
  8. #include "editor-support/cocosbuilder/CCBReader.h"
  9. #include "editor-support/cocosbuilder/CCNodeLoader.h"
  10. #include "editor-support/cocosbuilder/CCNodeLoaderLibrary.h"
  11. #include "editor-support/cocosbuilder/CCNodeLoaderListener.h"
  12. #include "editor-support/cocosbuilder/CCBMemberVariableAssigner.h"
  13. #include "editor-support/cocosbuilder/CCBSelectorResolver.h"
  14. #include "editor-support/cocosbuilder/CCBAnimationManager.h"
  15. #include "editor-support/cocosbuilder/CCBSequenceProperty.h"
  16. #include "editor-support/cocosbuilder/CCBKeyframe.h"
  17. #include <sstream>
  18. #include "common/CocosConfig.h"
  19. using namespace cocos2d;
  20. using namespace cocos2d::extension;
  21. namespace cocosbuilder {
  22. /*************************************************************************
  23. Implementation of CCBFile
  24. *************************************************************************/
  25. //add by yutao
  26. std::unordered_map<std::string, std::shared_ptr<cocos2d::Data>> s_ccbFileCacheMap;
  27. std::shared_ptr<cocos2d::Data> CCBReader::getBytesFromCCBFileByName(std::string ccbFullFilePath)
  28. {
  29. std::string ccbfileStr(ccbFullFilePath);
  30. auto p = s_ccbFileCacheMap.find(ccbfileStr);
  31. if( p != s_ccbFileCacheMap.end() && strcmp(ccbFullFilePath.c_str(), "RedInterstitialAd.ccbi") != 0 && strcmp(ccbFullFilePath.c_str(), "BulldogTableViewLayer.ccbi") != 0 && strcmp(ccbFullFilePath.c_str(), "BulldogTableViewCell.ccbi") != 0)
  32. {
  33. //CCLOG("从缓存中读ccb文件%s",ccbfileStr.c_str());
  34. return p->second;
  35. }
  36. else
  37. {
  38. auto data = std::make_shared<Data>(FileUtils::getInstance()->getDataFromFile(ccbFullFilePath));
  39. s_ccbFileCacheMap.insert(make_pair(ccbfileStr, data));
  40. //CCLOG("从文件读ccb文件%s",ccbfileStr.c_str());
  41. return data;
  42. }
  43. }
  44. void CCBReader::releaseAllCCBFileCache()
  45. {
  46. s_ccbFileCacheMap.erase(s_ccbFileCacheMap.begin(),s_ccbFileCacheMap.end());
  47. }
  48. CCBFile::CCBFile():_CCBFileNode(nullptr) {}
  49. CCBFile* CCBFile::create()
  50. {
  51. CCBFile *ret = new (std::nothrow) CCBFile();
  52. if (ret)
  53. {
  54. ret->autorelease();
  55. }
  56. return ret;
  57. }
  58. Node* CCBFile::getCCBFileNode()
  59. {
  60. return _CCBFileNode;
  61. }
  62. void CCBFile::setCCBFileNode(Node *pNode)
  63. {
  64. CC_SAFE_RELEASE(_CCBFileNode);
  65. _CCBFileNode = pNode;
  66. CC_SAFE_RETAIN(_CCBFileNode);
  67. }
  68. /*************************************************************************
  69. Implementation of CCBReader
  70. *************************************************************************/
  71. CCBReader::CCBReader(NodeLoaderLibrary * pNodeLoaderLibrary, CCBMemberVariableAssigner * pCCBMemberVariableAssigner, CCBSelectorResolver * pCCBSelectorResolver, NodeLoaderListener * pNodeLoaderListener)
  72. : _data(nullptr)
  73. , _bytes(nullptr)
  74. , _currentByte(-1)
  75. , _currentBit(-1)
  76. , _owner(nullptr)
  77. , _animationManager(nullptr)
  78. , _animatedProps(nullptr)
  79. {
  80. this->_nodeLoaderLibrary = pNodeLoaderLibrary;
  81. this->_nodeLoaderLibrary->retain();
  82. this->_CCBMemberVariableAssigner = pCCBMemberVariableAssigner;
  83. this->_CCBSelectorResolver = pCCBSelectorResolver;
  84. this->_nodeLoaderListener = pNodeLoaderListener;
  85. init();
  86. }
  87. CCBReader::CCBReader(CCBReader * ccbReader)
  88. : _data(nullptr)
  89. , _bytes(nullptr)
  90. , _currentByte(-1)
  91. , _currentBit(-1)
  92. , _owner(nullptr)
  93. , _animationManager(nullptr)
  94. , _animatedProps(nullptr)
  95. {
  96. this->_loadedSpriteSheets = ccbReader->_loadedSpriteSheets;
  97. this->_nodeLoaderLibrary = ccbReader->_nodeLoaderLibrary;
  98. this->_nodeLoaderLibrary->retain();
  99. this->_CCBMemberVariableAssigner = ccbReader->_CCBMemberVariableAssigner;
  100. this->_CCBSelectorResolver = ccbReader->_CCBSelectorResolver;
  101. this->_nodeLoaderListener = ccbReader->_nodeLoaderListener;
  102. this->_CCBRootPath = ccbReader->getCCBRootPath();
  103. init();
  104. }
  105. CCBReader::CCBReader()
  106. : _data(nullptr)
  107. , _bytes(nullptr)
  108. , _currentByte(-1)
  109. , _currentBit(-1)
  110. , _owner(nullptr)
  111. , _animationManager(nullptr)
  112. , _nodeLoaderLibrary(nullptr)
  113. , _nodeLoaderListener(nullptr)
  114. , _CCBMemberVariableAssigner(nullptr)
  115. , _CCBSelectorResolver(nullptr)
  116. {
  117. init();
  118. }
  119. CCBReader::~CCBReader()
  120. {
  121. CC_SAFE_RELEASE_NULL(_owner);
  122. this->_nodeLoaderLibrary->release();
  123. _ownerOutletNames.clear();
  124. _ownerCallbackNames.clear();
  125. // Clear string cache.
  126. this->_stringCache.clear();
  127. setAnimationManager(nullptr);
  128. }
  129. void CCBReader::setCCBRootPath(const char* ccbRootPath)
  130. {
  131. CCASSERT(ccbRootPath != nullptr, "ccbRootPath can't be nullptr!");
  132. _CCBRootPath = ccbRootPath;
  133. }
  134. const std::string& CCBReader::getCCBRootPath() const
  135. {
  136. return _CCBRootPath;
  137. }
  138. bool CCBReader::init()
  139. {
  140. // Setup action manager
  141. CCBAnimationManager *pActionManager = new (std::nothrow) CCBAnimationManager();
  142. setAnimationManager(pActionManager);
  143. pActionManager->release();
  144. // Setup resolution scale and container size
  145. _animationManager->setRootContainerSize(Director::getInstance()->getWinSize());
  146. return true;
  147. }
  148. CCBAnimationManager* CCBReader::getAnimationManager()
  149. {
  150. return _animationManager;
  151. }
  152. void CCBReader::setAnimationManager(CCBAnimationManager *pAnimationManager)
  153. {
  154. CC_SAFE_RELEASE(_animationManager);
  155. _animationManager = pAnimationManager;
  156. CC_SAFE_RETAIN(_animationManager);
  157. }
  158. CCBReader::CCBAnimationManagerMapPtr CCBReader::getAnimationManagers()
  159. {
  160. return _animationManagers;
  161. }
  162. void CCBReader::setAnimationManagers(CCBAnimationManagerMapPtr x)
  163. {
  164. _animationManagers = x;
  165. }
  166. CCBMemberVariableAssigner * CCBReader::getCCBMemberVariableAssigner() {
  167. return this->_CCBMemberVariableAssigner;
  168. }
  169. CCBSelectorResolver * CCBReader::getCCBSelectorResolver() {
  170. return this->_CCBSelectorResolver;
  171. }
  172. std::set<std::string>* CCBReader::getAnimatedProperties()
  173. {
  174. return _animatedProps;
  175. }
  176. std::set<std::string>& CCBReader::getLoadedSpriteSheet()
  177. {
  178. return _loadedSpriteSheets;
  179. }
  180. Ref* CCBReader::getOwner()
  181. {
  182. return _owner;
  183. }
  184. Node* CCBReader::readNodeGraphFromFile(const char *pCCBFileName)
  185. {
  186. return this->readNodeGraphFromFile(pCCBFileName, nullptr);
  187. }
  188. Node* CCBReader::readNodeGraphFromFile(const char* pCCBFileName, Ref* pOwner)
  189. {
  190. return this->readNodeGraphFromFile(pCCBFileName, pOwner, Director::getInstance()->getWinSize());
  191. }
  192. Node* CCBReader::readNodeGraphFromFile(const char *pCCBFileName, Ref *pOwner, const Size &parentSize)
  193. {
  194. if (nullptr == pCCBFileName || strlen(pCCBFileName) == 0)
  195. {
  196. return nullptr;
  197. }
  198. std::string strCCBFileName(pCCBFileName);
  199. std::string strSuffix(".ccbi");
  200. // Add ccbi suffix
  201. if (!CCBReader::endsWith(strCCBFileName.c_str(), strSuffix.c_str()))
  202. {
  203. strCCBFileName += strSuffix;
  204. }
  205. this->getAnimationManager()->setCCBFileName(strCCBFileName);
  206. std::string strPath = FileUtils::getInstance()->fullPathForFilename(strCCBFileName);
  207. // auto dataPtr = std::make_shared<Data>(FileUtils::getInstance()->getDataFromFile(strPath));
  208. auto dataPtr = this->getBytesFromCCBFileByName(strPath);
  209. Node *ret = this->readNodeGraphFromData(dataPtr, pOwner, parentSize);
  210. return ret;
  211. }
  212. Node* CCBReader::readNodeGraphFromData(std::shared_ptr<cocos2d::Data> data, Ref *pOwner, const Size &parentSize)
  213. {
  214. _data = data;
  215. _bytes =_data->getBytes();
  216. _currentByte = 0;
  217. _currentBit = 0;
  218. _owner = pOwner;
  219. CC_SAFE_RETAIN(_owner);
  220. _animationManager->setRootContainerSize(parentSize);
  221. _animationManager->_owner = _owner;
  222. Node *pNodeGraph = readFileWithCleanUp(true, std::make_shared<CCBAnimationManagerMap>());
  223. int id = _animationManager->getAutoPlaySequenceId();
  224. // log("error_getAutoPlaySequenceId:%d", id);
  225. // log("error_getReferenceCount:%d", _animationManager->getReferenceCount());
  226. if(_animationManager->getReferenceCount()<=1){
  227. return nullptr;
  228. }
  229. if (pNodeGraph && id != -1)
  230. {
  231. // Auto play animations
  232. _animationManager->runAnimationsForSequenceIdTweenDuration(id, 0);
  233. }
  234. // Assign actionManagers to userObject
  235. for (auto iter = _animationManagers->begin(); iter != _animationManagers->end(); ++iter)
  236. {
  237. Node* pNode = iter->first;
  238. if (CocosConfig::getOpacityCCBEnable()) {
  239. pNode->setCascadeOpacityEnabled(true);//打开透明度
  240. }
  241. if(CocosConfig::getColorCCBEnable()){
  242. pNode->setCascadeColorEnabled(true);//打开颜色穿透
  243. }
  244. CCBAnimationManager* manager = iter->second;
  245. pNode->setUserObject(manager);
  246. if (_jsControlled)
  247. {
  248. _nodesWithAnimationManagers.pushBack(pNode);
  249. _animationManagersForNodes.pushBack(manager);
  250. }
  251. }
  252. return pNodeGraph;
  253. }
  254. Scene* CCBReader::createSceneWithNodeGraphFromFile(const char *pCCBFileName)
  255. {
  256. return createSceneWithNodeGraphFromFile(pCCBFileName, nullptr);
  257. }
  258. Scene* CCBReader::createSceneWithNodeGraphFromFile(const char *pCCBFileName, Ref *pOwner)
  259. {
  260. return createSceneWithNodeGraphFromFile(pCCBFileName, pOwner, Director::getInstance()->getWinSize());
  261. }
  262. Scene* CCBReader::createSceneWithNodeGraphFromFile(const char *pCCBFileName, Ref *pOwner, const Size &parentSize)
  263. {
  264. Node *pNode = readNodeGraphFromFile(pCCBFileName, pOwner, parentSize);
  265. Scene *pScene = Scene::create();
  266. pScene->addChild(pNode);
  267. return pScene;
  268. }
  269. void CCBReader::cleanUpNodeGraph(Node *node)
  270. {
  271. node->setUserObject(nullptr);
  272. auto& children = node->getChildren();
  273. for(const auto &obj : children) {
  274. cleanUpNodeGraph(obj);
  275. }
  276. }
  277. Node* CCBReader::readFileWithCleanUp(bool bCleanUp, CCBAnimationManagerMapPtr am)
  278. {
  279. if (! readHeader())
  280. {
  281. return nullptr;
  282. }
  283. if (! readStringCache())
  284. {
  285. return nullptr;
  286. }
  287. if (! readSequences())
  288. {
  289. return nullptr;
  290. }
  291. setAnimationManagers(am);
  292. Node *pNode = readNodeGraph(nullptr);
  293. _animationManagers->insert(pNode, _animationManager);
  294. if (bCleanUp)
  295. {
  296. cleanUpNodeGraph(pNode);
  297. }
  298. return pNode;
  299. }
  300. bool CCBReader::readStringCache() {
  301. int numStrings = this->readInt(false);
  302. for(int i = 0; i < numStrings; i++) {
  303. this->_stringCache.push_back(this->readUTF8());
  304. }
  305. return true;
  306. }
  307. bool CCBReader::readHeader()
  308. {
  309. /* If no bytes loaded, don't crash about it. */
  310. if(this->_bytes == nullptr) {
  311. return false;
  312. }
  313. /* Read magic bytes */
  314. int magicBytes = *((int*)(this->_bytes + this->_currentByte));
  315. this->_currentByte += 4;
  316. if(CC_SWAP_INT32_BIG_TO_HOST(magicBytes) != (*reinterpret_cast<const int*>("ccbi"))) {
  317. return false;
  318. }
  319. /* Read version. */
  320. int version = this->readInt(false);
  321. if(version != CCB_VERSION) {
  322. log("WARNING! Incompatible ccbi file version (file: %d reader: %d)", version, CCB_VERSION);
  323. return false;
  324. }
  325. // Read JS check
  326. _jsControlled = this->readBool();
  327. _animationManager->_jsControlled = _jsControlled;
  328. return true;
  329. }
  330. unsigned char CCBReader::readByte()
  331. {
  332. unsigned char byte = this->_bytes[this->_currentByte];
  333. this->_currentByte++;
  334. return byte;
  335. }
  336. bool CCBReader::readBool()
  337. {
  338. return 0 == this->readByte() ? false : true;
  339. }
  340. std::string CCBReader::readUTF8()
  341. {
  342. std::string ret;
  343. int b0 = this->readByte();
  344. int b1 = this->readByte();
  345. int numBytes = b0 << 8 | b1;
  346. char* pStr = (char*)malloc(numBytes+1);
  347. memcpy(pStr, _bytes+_currentByte, numBytes);
  348. pStr[numBytes] = '\0';
  349. ret = pStr;
  350. free(pStr);
  351. _currentByte += numBytes;
  352. return ret;
  353. }
  354. bool CCBReader::getBit() {
  355. bool bit;
  356. unsigned char byte = *(this->_bytes + this->_currentByte);
  357. if(byte & (1 << this->_currentBit)) {
  358. bit = true;
  359. } else {
  360. bit = false;
  361. }
  362. this->_currentBit++;
  363. if(this->_currentBit >= 8) {
  364. this->_currentBit = 0;
  365. this->_currentByte++;
  366. }
  367. return bit;
  368. }
  369. void CCBReader::alignBits() {
  370. if(this->_currentBit) {
  371. this->_currentBit = 0;
  372. this->_currentByte++;
  373. }
  374. }
  375. int CCBReader::readInt(bool pSigned) {
  376. // Read encoded int
  377. int numBits = 0;
  378. while(!this->getBit()) {
  379. numBits++;
  380. }
  381. long long current = 0;
  382. for(int a = numBits - 1; a >= 0; a--) {
  383. if(this->getBit()) {
  384. current |= 1LL << a;
  385. }
  386. }
  387. current |= 1LL << numBits;
  388. int num;
  389. if(pSigned) {
  390. int s = current % 2;
  391. if(s) {
  392. num = static_cast<int>(current / 2);
  393. } else {
  394. num = static_cast<int>(-current / 2);
  395. }
  396. } else {
  397. num = static_cast<int>(current - 1);
  398. }
  399. this->alignBits();
  400. return num;
  401. }
  402. float CCBReader::readFloat()
  403. {
  404. FloatType type = static_cast<FloatType>(this->readByte());
  405. switch (type)
  406. {
  407. case FloatType::_0:
  408. return 0;
  409. case FloatType::_1:
  410. return 1;
  411. case FloatType::MINUS1:
  412. return -1;
  413. case FloatType::_05:
  414. return 0.5f;
  415. case FloatType::INTEGER:
  416. return (float)this->readInt(true);
  417. default:
  418. {
  419. /* using a memcpy since the compiler isn't
  420. * doing the float ptr math correctly on device.
  421. * TODO: still applies in C++ ? */
  422. unsigned char* pF = (this->_bytes + this->_currentByte);
  423. float f = 0;
  424. // N.B - in order to avoid an unaligned memory access crash on 'memcpy()' the the (void*) casts of the source and
  425. // destination pointers are EXTREMELY important for the ARM compiler.
  426. //
  427. // Without a (void*) cast, the ARM compiler makes the assumption that the float* pointer is naturally aligned
  428. // according to it's type size (aligned along 4 byte boundaries) and thus tries to call a more optimized
  429. // version of memcpy() which makes this alignment assumption also. When reading back from a file of course our pointers
  430. // may not be aligned, hence we need to avoid the compiler making this assumption. The (void*) cast serves this purpose,
  431. // and causes the ARM compiler to choose the slower, more generalized (unaligned) version of memcpy()
  432. //
  433. // For more about this compiler behavior, see:
  434. // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3934.html
  435. memcpy((void*) &f, (const void*) pF, sizeof(float));
  436. this->_currentByte += sizeof(float);
  437. return f;
  438. }
  439. }
  440. }
  441. std::string CCBReader::readCachedString()
  442. {
  443. int n = this->readInt(false);
  444. return this->_stringCache[n];
  445. }
  446. Node * CCBReader::readNodeGraph(Node * pParent)
  447. {
  448. /* Read class name. */
  449. std::string className = this->readCachedString();
  450. std::string _jsControlledName;
  451. if(_jsControlled) {
  452. _jsControlledName = this->readCachedString();
  453. }
  454. // Read assignment type and name
  455. TargetType memberVarAssignmentType = static_cast<TargetType>(this->readInt(false));
  456. std::string memberVarAssignmentName;
  457. if(memberVarAssignmentType != TargetType::NONE)
  458. {
  459. memberVarAssignmentName = this->readCachedString();
  460. }
  461. NodeLoader *ccNodeLoader = this->_nodeLoaderLibrary->getNodeLoader(className.c_str());
  462. if (! ccNodeLoader)
  463. {
  464. log("no corresponding node loader for %s", className.c_str());
  465. return nullptr;
  466. }
  467. Node *node = ccNodeLoader->loadNode(pParent, this);
  468. // Set root node
  469. if (! _animationManager->getRootNode())
  470. {
  471. _animationManager->setRootNode(node);
  472. }
  473. // Assign controller
  474. if(_jsControlled && node == _animationManager->getRootNode())
  475. {
  476. _animationManager->setDocumentControllerName(_jsControlledName);
  477. }
  478. // Read animated properties
  479. std::unordered_map<int, Map<std::string, CCBSequenceProperty*>> seqs;
  480. _animatedProps = new std::set<std::string>();
  481. int numSequence = readInt(false);// 时间线数量
  482. for (int i = 0; i < numSequence; ++i)
  483. {
  484. int seqId = readInt(false);
  485. Map<std::string, CCBSequenceProperty*> seqNodeProps;
  486. int numProps = readInt(false);// 变化属性的数量
  487. for (int j = 0; j < numProps; ++j)
  488. {
  489. CCBSequenceProperty *seqProp = new (std::nothrow) CCBSequenceProperty();
  490. seqProp->autorelease();
  491. seqProp->setName(readCachedString().c_str());
  492. seqProp->setType(readInt(false));
  493. _animatedProps->insert(seqProp->getName());
  494. int numKeyframes = readInt(false); // 关键帧的数量
  495. for (int k = 0; k < numKeyframes; ++k)
  496. {
  497. CCBKeyframe *keyframe = readKeyframe(static_cast<PropertyType>(seqProp->getType()));
  498. seqProp->getKeyframes().pushBack(keyframe);
  499. }
  500. seqNodeProps.insert(seqProp->getName(), seqProp);
  501. }
  502. seqs[seqId] = seqNodeProps;
  503. }
  504. if (!seqs.empty())
  505. {
  506. _animationManager->addNode(node, seqs);
  507. }
  508. // Read properties
  509. ccNodeLoader->parseProperties(node, pParent, this);
  510. bool isCCBFileNode = (nullptr == dynamic_cast<CCBFile*>(node)) ? false : true;
  511. // Handle sub ccb files (remove middle node)
  512. if (isCCBFileNode)
  513. {
  514. CCBFile *ccbFileNode = (CCBFile*)node;
  515. Node *embeddedNode = ccbFileNode->getCCBFileNode();
  516. embeddedNode->setPosition(ccbFileNode->getPosition());
  517. embeddedNode->setRotation(ccbFileNode->getRotation());
  518. embeddedNode->setScaleX(ccbFileNode->getScaleX());
  519. embeddedNode->setScaleY(ccbFileNode->getScaleY());
  520. embeddedNode->setTag(ccbFileNode->getTag());
  521. embeddedNode->setVisible(ccbFileNode->isVisible());
  522. //embeddedNode->setIgnoreAnchorPointForPosition(ccbFileNode->isIgnoreAnchorPointForPosition());
  523. _animationManager->moveAnimationsFromNode(ccbFileNode, embeddedNode);
  524. ccbFileNode->setCCBFileNode(nullptr);
  525. node = embeddedNode;
  526. }
  527. //如果父类打开透明度默认子类也打开透明度
  528. if(pParent){
  529. auto parentNode = pParent->getParent();
  530. if(parentNode&&parentNode->isCascadeOpacityEnabled()){
  531. parentNode->setCascadeOpacityEnabled(true);
  532. }
  533. if(pParent->isCascadeOpacityEnabled()){
  534. node->setCascadeOpacityEnabled(true);
  535. }
  536. }
  537. if (memberVarAssignmentType != TargetType::NONE)
  538. {
  539. if(!_jsControlled)
  540. {
  541. Ref* target = nullptr;
  542. if(memberVarAssignmentType == TargetType::DOCUMENT_ROOT)
  543. {
  544. target = _animationManager->getRootNode();
  545. }
  546. else if(memberVarAssignmentType == TargetType::OWNER)
  547. {
  548. target = this->_owner;
  549. }
  550. if(target != nullptr)
  551. {
  552. CCBMemberVariableAssigner * targetAsCCBMemberVariableAssigner = dynamic_cast<CCBMemberVariableAssigner *>(target);
  553. bool assigned = false;
  554. if (memberVarAssignmentType != TargetType::NONE)
  555. {
  556. if(targetAsCCBMemberVariableAssigner != nullptr)
  557. {
  558. assigned = targetAsCCBMemberVariableAssigner->onAssignCCBMemberVariable(target, memberVarAssignmentName.c_str(), node);
  559. }
  560. if(!assigned && this->_CCBMemberVariableAssigner != nullptr)
  561. {
  562. assigned = this->_CCBMemberVariableAssigner->onAssignCCBMemberVariable(target, memberVarAssignmentName.c_str(), node);
  563. }
  564. }
  565. }
  566. }
  567. else
  568. {
  569. if(memberVarAssignmentType == TargetType::DOCUMENT_ROOT)
  570. {
  571. _animationManager->addDocumentOutletName(memberVarAssignmentName);
  572. _animationManager->addDocumentOutletNode(node);
  573. }
  574. else
  575. {
  576. _ownerOutletNames.push_back(memberVarAssignmentName);
  577. _ownerOutletNodes.pushBack(node);
  578. }
  579. }
  580. }
  581. // Assign custom properties.
  582. if (!ccNodeLoader->getCustomProperties().empty())
  583. {
  584. bool customAssigned = false;
  585. if(!_jsControlled)
  586. {
  587. Ref* target = node;
  588. if(target != nullptr)
  589. {
  590. CCBMemberVariableAssigner * targetAsCCBMemberVariableAssigner = dynamic_cast<CCBMemberVariableAssigner *>(target);
  591. if(targetAsCCBMemberVariableAssigner != nullptr)
  592. {
  593. auto& customPropeties = ccNodeLoader->getCustomProperties();
  594. for (auto iter = customPropeties.begin(); iter != customPropeties.end(); ++iter)
  595. {
  596. customAssigned = targetAsCCBMemberVariableAssigner->onAssignCCBCustomProperty(target, iter->first.c_str(), iter->second);
  597. //ccb添加字段可打开透明度
  598. if(strcmp(iter->first.c_str(), "CascadeOpacityEnabled") == 0){
  599. Value value = iter->second;
  600. int isCascadeOpacityEnabled = value.asInt();
  601. if(isCascadeOpacityEnabled == 1){
  602. node->setCascadeOpacityEnabled(true);
  603. }
  604. }
  605. if(!customAssigned && this->_CCBMemberVariableAssigner != nullptr)
  606. {
  607. customAssigned = this->_CCBMemberVariableAssigner->onAssignCCBCustomProperty(target, iter->first.c_str(), iter->second);
  608. }
  609. }
  610. }
  611. }
  612. }
  613. }
  614. delete _animatedProps;
  615. _animatedProps = nullptr;
  616. /* Read and add children. */
  617. int numChildren = this->readInt(false);
  618. for(int i = 0; i < numChildren; i++)
  619. {
  620. Node * child = this->readNodeGraph(node);
  621. //如果配置为激活ccb透明度,则打开所有ccb透明度
  622. if (CocosConfig::getOpacityCCBEnable()) {
  623. child->setCascadeOpacityEnabled(true); //打开透明度
  624. }
  625. if (CocosConfig::getColorCCBEnable()) {
  626. child->setCascadeColorEnabled(true); //打开颜色
  627. }
  628. //如果父类打开透明度默认子类也打开透明度
  629. if(node->isCascadeOpacityEnabled()){
  630. child->setCascadeOpacityEnabled(true);
  631. }
  632. //如果父类打开颜色默认子类也打开透明度
  633. if(node->isCascadeColorEnabled()){
  634. child->setCascadeColorEnabled(true);
  635. }
  636. node->addChild(child);
  637. }
  638. // FIX ISSUE #1860: "onNodeLoaded will be called twice if ccb was added as a CCBFile".
  639. // If it's a sub-ccb node, skip notification to NodeLoaderListener since it will be
  640. // notified at LINE #734: Node * child = this->readNodeGraph(node);
  641. if (!isCCBFileNode)
  642. {
  643. // Call onNodeLoaded
  644. NodeLoaderListener * nodeAsNodeLoaderListener = dynamic_cast<NodeLoaderListener *>(node);
  645. if(nodeAsNodeLoaderListener != nullptr)
  646. {
  647. nodeAsNodeLoaderListener->onNodeLoaded(node, ccNodeLoader);
  648. }
  649. else if(this->_nodeLoaderListener != nullptr)
  650. {
  651. this->_nodeLoaderListener->onNodeLoaded(node, ccNodeLoader);
  652. }
  653. }
  654. return node;
  655. }
  656. CCBKeyframe* CCBReader::readKeyframe(PropertyType type)
  657. {
  658. CCBKeyframe *keyframe = new (std::nothrow) CCBKeyframe();
  659. keyframe->autorelease();
  660. keyframe->setTime(readFloat());
  661. CCBKeyframe::EasingType easingType = static_cast<CCBKeyframe::EasingType>(readInt(false));
  662. float easingOpt = 0;
  663. Value value;
  664. if (easingType == CCBKeyframe::EasingType::CUBIC_IN
  665. || easingType == CCBKeyframe::EasingType::CUBIC_OUT
  666. || easingType == CCBKeyframe::EasingType::CUBIC_INOUT
  667. || easingType == CCBKeyframe::EasingType::ELASTIC_IN
  668. || easingType == CCBKeyframe::EasingType::ELASTIC_OUT
  669. || easingType == CCBKeyframe::EasingType::ELASTIC_INOUT)
  670. {
  671. easingOpt = readFloat();
  672. }
  673. keyframe->setEasingType(easingType);
  674. keyframe->setEasingOpt(easingOpt);
  675. if (type == PropertyType::CHECK)
  676. {
  677. value = readBool();
  678. }
  679. else if (type == PropertyType::BYTE)
  680. {
  681. value = readByte();
  682. }
  683. else if (type == PropertyType::COLOR3)
  684. {
  685. unsigned char r = readByte();
  686. unsigned char g = readByte();
  687. unsigned char b = readByte();
  688. ValueMap colorMap;
  689. colorMap["r"] = r;
  690. colorMap["g"] = g;
  691. colorMap["b"] = b;
  692. value = colorMap;
  693. }
  694. else if (type == PropertyType::COLOR4F_VAR)
  695. {
  696. float red = readFloat();
  697. float green = readFloat();
  698. float blue = readFloat();
  699. float alpha = readFloat();
  700. float redVar = readFloat();
  701. float greenVar = readFloat();
  702. float blueVar = readFloat();
  703. float alphaVar = readFloat();
  704. // readUTF8();
  705. // int test = readInt(false);
  706. // readByte();
  707. // CCLOG("test %d",test);
  708. // unsigned char r = readFloat();
  709. // unsigned char g = readFloat();
  710. // unsigned char b = readFloat();
  711. // unsigned char a = readFloat();
  712. //
  713. // unsigned char rvar = readFloat();
  714. // unsigned char gvar = readFloat();
  715. // unsigned char bvar = readFloat();
  716. // unsigned char avar = readFloat();
  717. CCLOG("%f, %f, %f, %f, || %f, %f, %f, %f",red,green,blue,alpha,redVar,greenVar,blueVar,alphaVar);
  718. // ValueMap colorMap;
  719. // colorMap["r"] = r;
  720. // colorMap["g"] = g;
  721. // colorMap["b"] = b;
  722. // value = colorMap;
  723. }
  724. else if (type == PropertyType::DEGREES)
  725. {
  726. value = readFloat();
  727. }
  728. else if (type == PropertyType::SCALE_LOCK || type == PropertyType::POSITION
  729. || type == PropertyType::FLOAT_XY || type == PropertyType::POINT
  730. || type == PropertyType::FLOAT_VAR)
  731. {
  732. float a = readFloat();
  733. float b = readFloat();
  734. ValueVector ab;
  735. ab.push_back(Value(a));
  736. ab.push_back(Value(b));
  737. value = ab;
  738. }
  739. else if (type == PropertyType::SPRITEFRAME)
  740. {
  741. std::string spriteSheet = readCachedString();
  742. std::string spriteFile = readCachedString();
  743. SpriteFrame* spriteFrame;
  744. if (CocosConfig::getIgnoreCCBPath()) {
  745. SpriteFrameCache * frameCache = SpriteFrameCache::getInstance();
  746. spriteFrame = frameCache->getSpriteFrameByName(spriteFile.c_str());
  747. if (!spriteFrame) {
  748. spriteFile = _CCBRootPath + spriteFile;
  749. Texture2D * texture = Director::getInstance()->getTextureCache()->addImage(spriteFile.c_str());
  750. if(texture != NULL) {
  751. Rect bounds = Rect(0, 0, texture->getContentSize().width, texture->getContentSize().height);
  752. spriteFrame = SpriteFrame::createWithTexture(texture, bounds);
  753. }
  754. }
  755. }else{
  756. if (spriteSheet.empty())
  757. {
  758. SpriteFrameCache * frameCache = SpriteFrameCache::getInstance();
  759. spriteFrame = frameCache->getSpriteFrameByName(spriteFile.c_str());
  760. if (!spriteFrame) {
  761. spriteFile = _CCBRootPath + spriteFile;
  762. Texture2D * texture = Director::getInstance()->getTextureCache()->addImage(spriteFile.c_str());
  763. if(texture != NULL) {
  764. Rect bounds = Rect(0, 0, texture->getContentSize().width, texture->getContentSize().height);
  765. spriteFrame = SpriteFrame::createWithTexture(texture, bounds);
  766. }
  767. }
  768. }
  769. else
  770. {
  771. spriteSheet = _CCBRootPath + spriteSheet;
  772. SpriteFrameCache* frameCache = SpriteFrameCache::getInstance();
  773. // Load the sprite sheet only if it is not loaded
  774. if (_loadedSpriteSheets.find(spriteSheet) == _loadedSpriteSheets.end())
  775. {
  776. frameCache->addSpriteFramesWithFile(spriteSheet);
  777. _loadedSpriteSheets.insert(spriteSheet);
  778. }
  779. spriteFrame = frameCache->getSpriteFrameByName(spriteFile);
  780. }
  781. }
  782. //add by djd 防止崩溃,用默认空白图
  783. if (!spriteFrame) {
  784. spriteFile = CocosConfig::getDefaultEmptyPic();
  785. Texture2D * texture = Director::getInstance()->getTextureCache()->addImage(spriteFile.c_str());
  786. if(texture != NULL) {
  787. Rect bounds = Rect(0, 0, texture->getContentSize().width, texture->getContentSize().height);
  788. spriteFrame = SpriteFrame::createWithTexture(texture, bounds);
  789. }
  790. }
  791. keyframe->setObject(spriteFrame);
  792. }
  793. if (!value.isNull())
  794. keyframe->setValue(value);
  795. return keyframe;
  796. }
  797. bool CCBReader::readCallbackKeyframesForSeq(CCBSequence* seq)
  798. {
  799. int numKeyframes = readInt(false);
  800. if(!numKeyframes) return true;
  801. CCBSequenceProperty* channel = new (std::nothrow) CCBSequenceProperty();
  802. channel->autorelease();
  803. for(int i = 0; i < numKeyframes; ++i) {
  804. float time = readFloat();
  805. std::string callbackName = readCachedString();
  806. int callbackType = readInt(false);
  807. ValueVector valueVector;
  808. valueVector.push_back(Value(callbackName));
  809. valueVector.push_back(Value(callbackType));
  810. CCBKeyframe* keyframe = new (std::nothrow) CCBKeyframe();
  811. keyframe->autorelease();
  812. keyframe->setTime(time);
  813. keyframe->setValue(Value(valueVector));
  814. if(_jsControlled) {
  815. std::stringstream callbackIdentifier;
  816. callbackIdentifier << callbackType;
  817. callbackIdentifier << ":" + callbackName;
  818. _animationManager->getKeyframeCallbacks().push_back(Value(callbackIdentifier.str()));
  819. }
  820. channel->getKeyframes().pushBack(keyframe);
  821. }
  822. seq->setCallbackChannel(channel);
  823. return true;
  824. }
  825. bool CCBReader::readSoundKeyframesForSeq(CCBSequence* seq) {
  826. int numKeyframes = readInt(false);
  827. if(!numKeyframes) return true;
  828. CCBSequenceProperty* channel = new (std::nothrow) CCBSequenceProperty();
  829. channel->autorelease();
  830. for(int i = 0; i < numKeyframes; ++i) {
  831. float time = readFloat();
  832. std::string soundFile = readCachedString();
  833. float pitch = readFloat();
  834. float pan = readFloat();
  835. float gain = readFloat();
  836. ValueVector vec;
  837. vec.push_back(Value(soundFile));
  838. vec.push_back(Value(pitch));
  839. vec.push_back(Value(pan));
  840. vec.push_back(Value(gain));
  841. CCBKeyframe* keyframe = new (std::nothrow) CCBKeyframe();
  842. keyframe->setTime(time);
  843. keyframe->setValue(Value(vec));
  844. channel->getKeyframes().pushBack(keyframe);
  845. keyframe->release();
  846. }
  847. seq->setSoundChannel(channel);
  848. return true;
  849. }
  850. Node * CCBReader::readNodeGraph() {
  851. return this->readNodeGraph(nullptr);
  852. }
  853. bool CCBReader::readSequences()
  854. {
  855. auto& sequences = _animationManager->getSequences();
  856. int numSeqs = readInt(false);
  857. for (int i = 0; i < numSeqs; i++)
  858. {
  859. CCBSequence *seq = new (std::nothrow) CCBSequence();
  860. seq->autorelease();
  861. seq->setDuration(readFloat());
  862. seq->setName(readCachedString().c_str());
  863. seq->setSequenceId(readInt(false));
  864. seq->setChainedSequenceId(readInt(true));
  865. if(!readCallbackKeyframesForSeq(seq)) return false;
  866. if(!readSoundKeyframesForSeq(seq)) return false;
  867. sequences.pushBack(seq);
  868. }
  869. _animationManager->setAutoPlaySequenceId(readInt(true));
  870. return true;
  871. }
  872. std::string CCBReader::lastPathComponent(const char* pPath) {
  873. std::string path(pPath);
  874. size_t slashPos = path.find_last_of("/");
  875. if(slashPos != std::string::npos) {
  876. return path.substr(slashPos + 1, path.length() - slashPos);
  877. }
  878. return path;
  879. }
  880. std::string CCBReader::deletePathExtension(const char* pPath) {
  881. std::string path(pPath);
  882. size_t dotPos = path.find_last_of(".");
  883. if(dotPos != std::string::npos) {
  884. return path.substr(0, dotPos);
  885. }
  886. return path;
  887. }
  888. std::string CCBReader::toLowerCase(const char* pString) {
  889. std::string copy(pString);
  890. std::transform(copy.begin(), copy.end(), copy.begin(), ::tolower);
  891. return copy;
  892. }
  893. bool CCBReader::endsWith(const char* pString, const char* pEnding) {
  894. std::string string(pString);
  895. std::string ending(pEnding);
  896. if(string.length() >= ending.length()) {
  897. return (string.compare(string.length() - ending.length(), ending.length(), ending) == 0);
  898. } else {
  899. return false;
  900. }
  901. }
  902. bool CCBReader::isJSControlled()
  903. {
  904. return _jsControlled;
  905. }
  906. void CCBReader::addOwnerCallbackName(const std::string& name)
  907. {
  908. _ownerCallbackNames.push_back(name);
  909. }
  910. void CCBReader::addOwnerCallbackNode(Node *node)
  911. {
  912. _ownerCallbackNodes.pushBack(node);
  913. }
  914. void CCBReader::addOwnerCallbackControlEvents(Control::EventType type)
  915. {
  916. _ownerOwnerCallbackControlEvents.push_back(Value((int)type));
  917. }
  918. void CCBReader::addDocumentCallbackName(const std::string& name)
  919. {
  920. _animationManager->addDocumentCallbackName(name);
  921. }
  922. void CCBReader::addDocumentCallbackNode(Node *node)
  923. {
  924. _animationManager->addDocumentCallbackNode(node);
  925. }
  926. void CCBReader::addDocumentCallbackControlEvents(Control::EventType eventType)
  927. {
  928. _animationManager->addDocumentCallbackControlEvents(eventType);
  929. }
  930. ValueVector CCBReader::getOwnerCallbackNames()
  931. {
  932. ValueVector ret;
  933. ret.reserve(_ownerCallbackNames.size());
  934. std::vector<std::string>::iterator it = _ownerCallbackNames.begin();
  935. for (; it != _ownerCallbackNames.end(); ++it)
  936. {
  937. ret.push_back(Value(*it));
  938. }
  939. return ret;
  940. }
  941. Vector<Node*>& CCBReader::getOwnerCallbackNodes()
  942. {
  943. return _ownerCallbackNodes;
  944. }
  945. ValueVector& CCBReader::getOwnerCallbackControlEvents()
  946. {
  947. return _ownerOwnerCallbackControlEvents;
  948. }
  949. ValueVector CCBReader::getOwnerOutletNames()
  950. {
  951. ValueVector ret;
  952. ret.reserve(_ownerOutletNames.size());
  953. std::vector<std::string>::iterator it = _ownerOutletNames.begin();
  954. for (; it != _ownerOutletNames.end(); ++it)
  955. {
  956. ret.push_back(Value(*it));
  957. }
  958. return ret;
  959. }
  960. Vector<Node*>& CCBReader::getOwnerOutletNodes()
  961. {
  962. return _ownerOutletNodes;
  963. }
  964. Vector<Node*>& CCBReader::getNodesWithAnimationManagers()
  965. {
  966. return _nodesWithAnimationManagers;
  967. }
  968. Vector<CCBAnimationManager*>& CCBReader::getAnimationManagersForNodes()
  969. {
  970. return _animationManagersForNodes;
  971. }
  972. void CCBReader::addOwnerOutletName(std::string name)
  973. {
  974. _ownerOutletNames.push_back(name);
  975. }
  976. void CCBReader::addOwnerOutletNode(Node *node)
  977. {
  978. if (nullptr == node)
  979. return;
  980. _ownerOutletNodes.pushBack(node);
  981. }
  982. /************************************************************************
  983. Static functions
  984. ************************************************************************/
  985. static float __ccbResolutionScale = 1.0f;
  986. float CCBReader::getResolutionScale()
  987. {
  988. return __ccbResolutionScale;
  989. }
  990. void CCBReader::setResolutionScale(float scale)
  991. {
  992. __ccbResolutionScale = scale;
  993. }
  994. };