void CCNodeLoader::parseProperties(CCNode * pNode, CCNode * pParent, CCBReader * pCCBReader) { m_pCustomProperties->removeAllObjects(); int numRegularProps = pCCBReader->readInt(false); int numExturaProps = pCCBReader->readInt(false); int propertyCount = numRegularProps + numExturaProps; for(int i = 0; i < propertyCount; i++) { bool isExtraProp = (i >= numRegularProps); int type = pCCBReader->readInt(false); std::string propertyName = pCCBReader->readCachedString(); // Check if the property can be set for this platform bool setProp = false; int platform = pCCBReader->readByte(); if(platform == kCCBPlatformAll) { setProp = true; } // Cocos2d-x is using touch event callback for all platforms, // it's different from cocos2d-iphone which uses mouse event for Mac port. // So we just need to touch event by using kCCBPlatformIOS. //#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) if(platform == kCCBPlatformIOS) { setProp = true; } // #elif (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) // if(platform == kCCBPlatformMac) // { // setProp = true; // } // #endif // Forward properties for sub ccb files if (dynamic_cast<CCBFile*>(pNode) != NULL) { CCBFile *ccbNode = (CCBFile*)pNode; if (ccbNode->getCCBFileNode() && isExtraProp) { pNode = ccbNode->getCCBFileNode(); // Skip properties that doesn't have a value to override CCArray *extraPropsNames = (CCArray*)pNode->getUserObject(); CCObject* pObj = NULL; bool bFound = false; CCARRAY_FOREACH(extraPropsNames, pObj) { CCString* pStr = (CCString*)pObj; if (0 == pStr->compare(propertyName.c_str())) { bFound = true; break; } } setProp &= bFound; }
void NodeLoader::parseProperties(Node * pNode, Node * pParent, CCBReader * ccbReader) { int numRegularProps = ccbReader->readInt(false); int numExturaProps = ccbReader->readInt(false); int propertyCount = numRegularProps + numExturaProps; for(int i = 0; i < propertyCount; i++) { bool isExtraProp = (i >= numRegularProps); CCBReader::PropertyType type = (CCBReader::PropertyType)ccbReader->readInt(false); std::string propertyName = ccbReader->readCachedString(); // Check if the property can be set for this platform bool setProp = true; // Forward properties for sub ccb files if (dynamic_cast<CCBFile*>(pNode) != NULL) { CCBFile *ccbNode = (CCBFile*)pNode; if (ccbNode->getCCBFileNode() && isExtraProp) { pNode = ccbNode->getCCBFileNode(); // Skip properties that doesn't have a value to override __Array *extraPropsNames = (__Array*)pNode->getUserObject(); Ref* pObj = NULL; bool bFound = false; CCARRAY_FOREACH(extraPropsNames, pObj) { __String* pStr = static_cast<__String*>(pObj); if (0 == pStr->compare(propertyName.c_str())) { bFound = true; break; } } setProp &= bFound; }
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; }
void NodeLoader::parseProperties(Node * pNode, Node * pParent, CCBReader * ccbReader) { int numRegularProps = ccbReader->readIntWithSign(false); int numExturaProps = ccbReader->readIntWithSign(false); int propertyCount = numRegularProps + numExturaProps; for(int i = 0; i < propertyCount; i++) { bool isExtraProp = (i >= numRegularProps); CCBReader::PropertyType type = (CCBReader::PropertyType)ccbReader->readIntWithSign(false); std::string propertyName = ccbReader->readCachedString(); // Check if the property can be set for this platform bool setProp = true; if (dynamic_cast<CCBFile*>(pNode)) { CCBFile* ccbNode = (CCBFile*) pNode; if (ccbNode->getCCBFileNode() && isExtraProp) { pNode = ccbNode->getCCBFileNode(); // Skip properties that doesn't have a value to override __Set* extraPropsNames = (__Set*)pNode->getUserObject(); //setProp &= extraPropsNames->containsObject(CCString::create(propertyName)); bool foundProperty = false; __SetIterator it; for( it = extraPropsNames->begin(); it != extraPropsNames->end(); ++it) { __String* propName = (__String*)*it; if (strcmp(propertyName.c_str(), propName->getCString()) == 0) { foundProperty = true; break; } } setProp = foundProperty; } } else if (isExtraProp && pNode == ccbReader->getAnimationManager()->getRootNode()) { __Set* extraPropsNames = (__Set*)pNode->getUserObject(); if (!extraPropsNames) { extraPropsNames = CCSet::create(); pNode->setUserObject(extraPropsNames); } extraPropsNames->addObject(CCString::create(propertyName)); } /* CCBReader::PlatformType platform = (CCBReader::PlatformType)ccbReader->readByte(); if(platform == CCBReader::PlatformType::ALL) { setProp = true; } // Cocos2d-x is using touch event callback for all platforms, // it's different from cocos2d-iphone which uses mouse event for Mac port. // So we just need to touch event by using CCBReader::PlatformType::IOS. //#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) if(platform == CCBReader::PlatformType::IOS) { setProp = true; } // #elif (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) // if(platform == CCBReader::PlatformType::MAC) // { // setProp = true; // } // #endif */ // Forward properties for sub ccb files if (dynamic_cast<CCBFile*>(pNode) != NULL) { CCBFile *ccbNode = (CCBFile*)pNode; if (ccbNode->getCCBFileNode() && isExtraProp) { pNode = ccbNode->getCCBFileNode(); // Skip properties that doesn't have a value to override __Array *extraPropsNames = (__Array*)pNode->getUserObject(); Ref* pObj = NULL; bool bFound = false; CCARRAY_FOREACH(extraPropsNames, pObj) { __String* pStr = static_cast<__String*>(pObj); if (0 == pStr->compare(propertyName.c_str())) { bFound = true; break; } } setProp &= bFound; }
void CCNodeLoader::parseProperties(CCNode * pNode, CCNode * pParent, CCBReader * pCCBReader) { int numRegularProps = pCCBReader->readInt(false); int numExturaProps = pCCBReader->readInt(false); int propertyCount = numRegularProps + numExturaProps; for(int i = 0; i < propertyCount; i++) { bool isExtraProp = (i >= numRegularProps); int type = pCCBReader->readInt(false); CCString * propertyName = pCCBReader->readCachedString(); // Check if the property can be set for this platform bool setProp = false; int platform = pCCBReader->readByte(); if(platform == kCCBPlatformAll) { setProp = true; } #ifdef __CC_PLATFORM_IOS if(platform == kCCBPlatformIOS) { setProp = true; } #elif defined(__CC_PLATFORM_MAC) if(platform == kCCBPlatformMac) { setProp = true; } #endif // Forward properties for sub ccb files if (dynamic_cast<CCBFile*>(pNode) != NULL) { CCBFile *ccbNode = (CCBFile*)pNode; if (ccbNode->getCCBFileNode() && isExtraProp) { pNode = ccbNode->getCCBFileNode(); // Skip properties that doesn't have a value to override CCArray *extraPropsNames = (CCArray*)pNode->getUserObject(); setProp &= extraPropsNames->containsObject(propertyName); } } else if (isExtraProp && pNode == pCCBReader->getAnimationManager()->getRootNode()) { CCArray *extraPropsNames = (CCArray*)pNode->getUserObject(); if (! extraPropsNames) { extraPropsNames = CCArray::create(); pNode->setUserObject(extraPropsNames); } extraPropsNames->addObject(propertyName); } switch(type) { case kCCBPropTypePosition: { CCPoint position = this->parsePropTypePosition(pNode, pParent, pCCBReader, propertyName->getCString()); if (setProp) { this->onHandlePropTypePosition(pNode, pParent, propertyName, position, pCCBReader); } break; } case kCCBPropTypePoint: { CCPoint point = this->parsePropTypePoint(pNode, pParent, pCCBReader); if (setProp) { this->onHandlePropTypePoint(pNode, pParent, propertyName, point, pCCBReader); } break; } case kCCBPropTypePointLock: { CCPoint pointLock = this->parsePropTypePointLock(pNode, pParent, pCCBReader); if (setProp) { this->onHandlePropTypePointLock(pNode, pParent, propertyName, pointLock, pCCBReader); } break; } case kCCBPropTypeSize: { CCSize size = this->parsePropTypeSize(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeSize(pNode, pParent, propertyName, size, pCCBReader); } break; } case kCCBPropTypeScaleLock: { float * scaleLock = this->parsePropTypeScaleLock(pNode, pParent, pCCBReader, propertyName->getCString()); if(setProp) { this->onHandlePropTypeScaleLock(pNode, pParent, propertyName, scaleLock, pCCBReader); } CC_SAFE_DELETE_ARRAY(scaleLock); break; } case kCCBPropTypeFloat: { float f = this->parsePropTypeFloat(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeFloat(pNode, pParent, propertyName, f, pCCBReader); } break; } case kCCBPropTypeDegrees: { float degrees = this->parsePropTypeDegrees(pNode, pParent, pCCBReader, propertyName->getCString()); if(setProp) { this->onHandlePropTypeDegrees(pNode, pParent, propertyName, degrees, pCCBReader); } break; } case kCCBPropTypeFloatScale: { float floatScale = this->parsePropTypeFloatScale(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeFloatScale(pNode, pParent, propertyName, floatScale, pCCBReader); } break; } case kCCBPropTypeInteger: { int integer = this->parsePropTypeInteger(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeInteger(pNode, pParent, propertyName, integer, pCCBReader); } break; } case kCCBPropTypeIntegerLabeled: { int integerLabeled = this->parsePropTypeIntegerLabeled(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeIntegerLabeled(pNode, pParent, propertyName, integerLabeled, pCCBReader); } break; } case kCCBPropTypeFloatVar: { float * floatVar = this->parsePropTypeFloatVar(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeFloatVar(pNode, pParent, propertyName, floatVar, pCCBReader); } CC_SAFE_DELETE_ARRAY(floatVar); break; } case kCCBPropTypeCheck: { bool check = this->parsePropTypeCheck(pNode, pParent, pCCBReader, propertyName->getCString()); if(setProp) { this->onHandlePropTypeCheck(pNode, pParent, propertyName, check, pCCBReader); } break; } case kCCBPropTypeSpriteFrame: { CCSpriteFrame * ccSpriteFrame = this->parsePropTypeSpriteFrame(pNode, pParent, pCCBReader, propertyName->getCString()); if(setProp) { this->onHandlePropTypeSpriteFrame(pNode, pParent, propertyName, ccSpriteFrame, pCCBReader); } break; } case kCCBPropTypeAnimation: { CCAnimation * ccAnimation = this->parsePropTypeAnimation(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeAnimation(pNode, pParent, propertyName, ccAnimation, pCCBReader); } break; } case kCCBPropTypeTexture: { CCTexture2D * ccTexture2D = this->parsePropTypeTexture(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeTexture(pNode, pParent, propertyName, ccTexture2D, pCCBReader); } break; } case kCCBPropTypeByte: { unsigned char byte = this->parsePropTypeByte(pNode, pParent, pCCBReader, propertyName->getCString()); if(setProp) { this->onHandlePropTypeByte(pNode, pParent, propertyName, byte, pCCBReader); } break; } case kCCBPropTypeColor3: { ccColor3B color3B = this->parsePropTypeColor3(pNode, pParent, pCCBReader, propertyName->getCString()); if(setProp) { this->onHandlePropTypeColor3(pNode, pParent, propertyName, color3B, pCCBReader); } break; } case kCCBPropTypeColor4FVar: { ccColor4F * color4FVar = this->parsePropTypeColor4FVar(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeColor4FVar(pNode, pParent, propertyName, color4FVar, pCCBReader); } CC_SAFE_DELETE_ARRAY(color4FVar); break; } case kCCBPropTypeFlip: { bool * flip = this->parsePropTypeFlip(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeFlip(pNode, pParent, propertyName, flip, pCCBReader); } CC_SAFE_DELETE_ARRAY(flip); break; } case kCCBPropTypeBlendmode: { ccBlendFunc blendFunc = this->parsePropTypeBlendFunc(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeBlendFunc(pNode, pParent, propertyName, blendFunc, pCCBReader); } break; } case kCCBPropTypeFntFile: { CCString * fntFile = this->parsePropTypeFntFile(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeFntFile(pNode, pParent, propertyName, fntFile, pCCBReader); } break; } case kCCBPropTypeFontTTF: { CCString * fontTTF = this->parsePropTypeFontTTF(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeFontTTF(pNode, pParent, propertyName, fontTTF, pCCBReader); } break; } case kCCBPropTypeString: { CCString * string = this->parsePropTypeString(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeString(pNode, pParent, propertyName, string, pCCBReader); } break; } case kCCBPropTypeText: { CCString * text = this->parsePropTypeText(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeText(pNode, pParent, propertyName, text, pCCBReader); } break; } case kCCBPropTypeBlock: { BlockData * blockData = this->parsePropTypeBlock(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeBlock(pNode, pParent, propertyName, blockData, pCCBReader); } CC_SAFE_DELETE(blockData); break; } case kCCBPropTypeBlockCCControl: { BlockCCControlData * blockCCControlData = this->parsePropTypeBlockCCControl(pNode, pParent, pCCBReader); if(setProp && blockCCControlData != NULL) { this->onHandlePropTypeBlockCCControl(pNode, pParent, propertyName, blockCCControlData, pCCBReader); } CC_SAFE_DELETE(blockCCControlData); break; } case kCCBPropTypeCCBFile: { CCNode * ccbFileNode = this->parsePropTypeCCBFile(pNode, pParent, pCCBReader); if(setProp) { this->onHandlePropTypeCCBFile(pNode, pParent, propertyName, ccbFileNode, pCCBReader); } break; } default: ASSERT_FAIL_UNEXPECTED_PROPERTYTYPE(type); break; } } }