CCNode * CCBReader::readNodeGraph(CCNode * pParent) { /* Read class name. */ CCString * className = this->readCachedString(); int memberVarAssignmentType = this->readInt(false); CCString * memberVarAssignmentName; if(memberVarAssignmentType != kCCBTargetTypeNone) { memberVarAssignmentName = this->readCachedString(); } CCNodeLoader * ccNodeLoader = this->mCCNodeLoaderLibrary->getCCNodeLoader(className); CCNode * node = ccNodeLoader->loadCCNode(pParent, this); /* Set root node, if not set yet. */ if(this->mRootNode == NULL) { this->mRootNode = node; this->mRootNode->retain(); } if(memberVarAssignmentType != kCCBTargetTypeNone) { CCObject * target = NULL; if(memberVarAssignmentType == kCCBTargetTypeDocumentRoot) { target = this->mRootNode; } else if(memberVarAssignmentType == kCCBTargetTypeOwner) { target = this->mOwner; } if(target != NULL) { bool assigned = false; CCBMemberVariableAssigner * targetAsCCBMemberVariableAssigner = dynamic_cast<CCBMemberVariableAssigner *>(target); if(targetAsCCBMemberVariableAssigner != NULL) { assigned = targetAsCCBMemberVariableAssigner->onAssignCCBMemberVariable(target, memberVarAssignmentName, node); } if(!assigned && this->mCCBMemberVariableAssigner != NULL) { this->mCCBMemberVariableAssigner->onAssignCCBMemberVariable(target, memberVarAssignmentName, node); } } } /* Read and add children. */ int numChildren = this->readInt(false); for(int i = 0; i < numChildren; i++) { CCNode * child = this->readNodeGraph(node); node->addChild(child); } CCNodeLoaderListener * nodeAsCCNodeLoaderListener = dynamic_cast<CCNodeLoaderListener *>(node); if(nodeAsCCNodeLoaderListener != NULL) { nodeAsCCNodeLoaderListener->onNodeLoaded(node, ccNodeLoader); } else if(this->mCCNodeLoaderListener != NULL) { this->mCCNodeLoaderListener->onNodeLoaded(node, ccNodeLoader); } return node; }
Node * CCBReader::readNodeGraph(Node * pParent) { /* Read class name. */ std::string className = this->readCachedString(); std::string _jsControlledName; if(_jsControlled) { _jsControlledName = this->readCachedString(); } // Read assignment type and name TargetType memberVarAssignmentType = static_cast<TargetType>(this->readInt(false)); std::string memberVarAssignmentName; if(memberVarAssignmentType != TargetType::NONE) { memberVarAssignmentName = this->readCachedString(); } NodeLoader *ccNodeLoader = this->_nodeLoaderLibrary->getNodeLoader(className.c_str()); if (! ccNodeLoader) { log("no corresponding node loader for %s", className.c_str()); return nullptr; } Node *node = ccNodeLoader->loadNode(pParent, this); // Set root node if (! _animationManager->getRootNode()) { _animationManager->setRootNode(node); } // Assign controller if(_jsControlled && node == _animationManager->getRootNode()) { _animationManager->setDocumentControllerName(_jsControlledName); } // Read animated properties std::unordered_map<int, Map<std::string, CCBSequenceProperty*>> seqs; _animatedProps = new (std::nothrow) std::set<std::string>(); int numSequence = readInt(false); for (int i = 0; i < numSequence; ++i) { int seqId = readInt(false); Map<std::string, CCBSequenceProperty*> seqNodeProps; int numProps = readInt(false); for (int j = 0; j < numProps; ++j) { CCBSequenceProperty *seqProp = new (std::nothrow) CCBSequenceProperty(); seqProp->autorelease(); seqProp->setName(readCachedString().c_str()); seqProp->setType(readInt(false)); _animatedProps->insert(seqProp->getName()); int numKeyframes = readInt(false); for (int k = 0; k < numKeyframes; ++k) { CCBKeyframe *keyframe = readKeyframe(static_cast<PropertyType>(seqProp->getType())); seqProp->getKeyframes().pushBack(keyframe); } seqNodeProps.insert(seqProp->getName(), seqProp); } seqs[seqId] = seqNodeProps; } if (!seqs.empty()) { _animationManager->addNode(node, seqs); } // Read properties ccNodeLoader->parseProperties(node, pParent, this); bool isCCBFileNode = (nullptr == dynamic_cast<CCBFile*>(node)) ? false : true; // Handle sub ccb files (remove middle node) if (isCCBFileNode) { CCBFile *ccbFileNode = (CCBFile*)node; Node *embeddedNode = ccbFileNode->getCCBFileNode(); embeddedNode->setPosition(ccbFileNode->getPosition()); embeddedNode->setRotation(ccbFileNode->getRotation()); embeddedNode->setScaleX(ccbFileNode->getScaleX()); embeddedNode->setScaleY(ccbFileNode->getScaleY()); embeddedNode->setTag(ccbFileNode->getTag()); embeddedNode->setVisible(true); //embeddedNode->ignoreAnchorPointForPosition(ccbFileNode->isIgnoreAnchorPointForPosition()); _animationManager->moveAnimationsFromNode(ccbFileNode, embeddedNode); ccbFileNode->setCCBFileNode(nullptr); node = embeddedNode; } #ifdef CCB_ENABLE_JAVASCRIPT /* if (memberVarAssignmentType && memberVarAssignmentName && ![memberVarAssignmentName isEqualToString:@""]) { [[JSCocoa sharedController] setObject:node withName:memberVarAssignmentName]; }*/ #else if (memberVarAssignmentType != TargetType::NONE) { if(!_jsControlled) { Ref* target = nullptr; if(memberVarAssignmentType == TargetType::DOCUMENT_ROOT) { target = _animationManager->getRootNode(); } else if(memberVarAssignmentType == TargetType::OWNER) { target = this->_owner; } if(target != nullptr) { CCBMemberVariableAssigner * targetAsCCBMemberVariableAssigner = dynamic_cast<CCBMemberVariableAssigner *>(target); bool assigned = false; if (memberVarAssignmentType != TargetType::NONE) { if(targetAsCCBMemberVariableAssigner != nullptr) { assigned = targetAsCCBMemberVariableAssigner->onAssignCCBMemberVariable(target, memberVarAssignmentName.c_str(), node); } if(!assigned && this->_CCBMemberVariableAssigner != nullptr) { _CCBMemberVariableAssigner->onAssignCCBMemberVariable(target, memberVarAssignmentName.c_str(), node); } } } } else { if(memberVarAssignmentType == TargetType::DOCUMENT_ROOT) { _animationManager->addDocumentOutletName(memberVarAssignmentName); _animationManager->addDocumentOutletNode(node); } else { _ownerOutletNames.push_back(memberVarAssignmentName); _ownerOutletNodes.pushBack(node); } } } // Assign custom properties. if (!ccNodeLoader->getCustomProperties().empty()) { bool customAssigned = false; if(!_jsControlled) { Ref* target = node; if(target != nullptr) { CCBMemberVariableAssigner * targetAsCCBMemberVariableAssigner = dynamic_cast<CCBMemberVariableAssigner *>(target); if(targetAsCCBMemberVariableAssigner != nullptr) { auto& customPropeties = ccNodeLoader->getCustomProperties(); for (auto iter = customPropeties.begin(); iter != customPropeties.end(); ++iter) { customAssigned = targetAsCCBMemberVariableAssigner->onAssignCCBCustomProperty(target, iter->first.c_str(), iter->second); if(!customAssigned && this->_CCBMemberVariableAssigner != nullptr) { _CCBMemberVariableAssigner->onAssignCCBCustomProperty(target, iter->first.c_str(), iter->second); } } } } } } #endif // CCB_ENABLE_JAVASCRIPT delete _animatedProps; _animatedProps = nullptr; /* Read and add children. */ int numChildren = this->readInt(false); for(int i = 0; i < numChildren; i++) { Node * child = this->readNodeGraph(node); node->addChild(child); } // FIX ISSUE #1860: "onNodeLoaded will be called twice if ccb was added as a CCBFile". // If it's a sub-ccb node, skip notification to NodeLoaderListener since it will be // notified at LINE #734: Node * child = this->readNodeGraph(node); if (!isCCBFileNode) { // Call onNodeLoaded NodeLoaderListener * nodeAsNodeLoaderListener = dynamic_cast<NodeLoaderListener *>(node); if(nodeAsNodeLoaderListener != nullptr) { nodeAsNodeLoaderListener->onNodeLoaded(node, ccNodeLoader); } else if(this->_nodeLoaderListener != nullptr) { this->_nodeLoaderListener->onNodeLoaded(node, ccNodeLoader); } } return node; }