bool CCBReader::readSoundKeyframesForSeq(CCBSequence* seq) { int numKeyframes = readInt(false); if(!numKeyframes) return true; CCBSequenceProperty* channel = new (std::nothrow) CCBSequenceProperty(); channel->autorelease(); for(int i = 0; i < numKeyframes; ++i) { float time = readFloat(); std::string soundFile = readCachedString(); float pitch = readFloat(); float pan = readFloat(); float gain = readFloat(); ValueVector vec; vec.push_back(Value(soundFile)); vec.push_back(Value(pitch)); vec.push_back(Value(pan)); vec.push_back(Value(gain)); CCBKeyframe* keyframe = new (std::nothrow) CCBKeyframe(); keyframe->setTime(time); keyframe->setValue(Value(vec)); channel->getKeyframes().pushBack(keyframe); keyframe->release(); } seq->setSoundChannel(channel); return true; }
bool CCBReader::readSequences() { auto& sequences = _animationManager->getSequences(); int numSeqs = readInt(false); for (int i = 0; i < numSeqs; i++) { CCBSequence *seq = new (std::nothrow) CCBSequence(); seq->autorelease(); seq->setDuration(readFloat()); seq->setName(readCachedString().c_str()); seq->setSequenceId(readInt(false)); seq->setChainedSequenceId(readInt(true)); if(!readCallbackKeyframesForSeq(seq)) return false; if(!readSoundKeyframesForSeq(seq)) return false; sequences.pushBack(seq); } _animationManager->setAutoPlaySequenceId(readInt(true)); return true; }
bool CCBReader::readCallbackKeyframesForSeq(CCBSequence* seq) { int numKeyframes = readInt(false); if(!numKeyframes) return true; CCBSequenceProperty* channel = new (std::nothrow) CCBSequenceProperty(); channel->autorelease(); for(int i = 0; i < numKeyframes; ++i) { float time = readFloat(); std::string callbackName = readCachedString(); int callbackType = readInt(false); ValueVector valueVector; valueVector.push_back(Value(callbackName)); valueVector.push_back(Value(callbackType)); CCBKeyframe* keyframe = new (std::nothrow) CCBKeyframe(); keyframe->autorelease(); keyframe->setTime(time); keyframe->setValue(Value(valueVector)); if(_jsControlled) { std::stringstream callbackIdentifier; callbackIdentifier << callbackType; callbackIdentifier << ":" + callbackName; _animationManager->getKeyframeCallbacks().push_back(Value(callbackIdentifier.str())); } channel->getKeyframes().pushBack(keyframe); } seq->setCallbackChannel(channel); return true; }
CCBKeyframe* CCBReader::readKeyframe(PropertyType type) { CCBKeyframe *keyframe = new (std::nothrow) CCBKeyframe(); keyframe->autorelease(); keyframe->setTime(readFloat()); CCBKeyframe::EasingType easingType = static_cast<CCBKeyframe::EasingType>(readInt(false)); float easingOpt = 0; Value value; if (easingType == CCBKeyframe::EasingType::CUBIC_IN || easingType == CCBKeyframe::EasingType::CUBIC_OUT || easingType == CCBKeyframe::EasingType::CUBIC_INOUT || easingType == CCBKeyframe::EasingType::ELASTIC_IN || easingType == CCBKeyframe::EasingType::ELASTIC_OUT || easingType == CCBKeyframe::EasingType::ELASTIC_INOUT) { easingOpt = readFloat(); } keyframe->setEasingType(easingType); keyframe->setEasingOpt(easingOpt); if (type == PropertyType::CHECK) { value = readBool(); } else if (type == PropertyType::BYTE) { value = readByte(); } else if (type == PropertyType::COLOR3) { unsigned char r = readByte(); unsigned char g = readByte(); unsigned char b = readByte(); ValueMap colorMap; colorMap["r"] = r; colorMap["g"] = g; colorMap["b"] = b; value = colorMap; } else if (type == PropertyType::DEGREES) { value = readFloat(); } else if (type == PropertyType::SCALE_LOCK || type == PropertyType::POSITION || type == PropertyType::FLOAT_XY) { float a = readFloat(); float b = readFloat(); ValueVector ab; ab.push_back(Value(a)); ab.push_back(Value(b)); value = ab; } else if (type == PropertyType::SPRITEFRAME) { std::string spriteSheet = readCachedString(); std::string spriteFile = readCachedString(); SpriteFrame* spriteFrame; if (spriteSheet.empty()) { spriteFile = _CCBRootPath + spriteFile; Texture2D *texture = Director::DirectorInstance->getTextureCache()->addImage(spriteFile); Rect bounds = Rect(0, 0, texture->getContentSize().width, texture->getContentSize().height); spriteFrame = SpriteFrame::createWithTexture(texture, bounds); } else { spriteSheet = _CCBRootPath + spriteSheet; SpriteFrameCache* frameCache = SpriteFrameCache::getInstance(); // Load the sprite sheet only if it is not loaded if (_loadedSpriteSheets.find(spriteSheet) == _loadedSpriteSheets.end()) { frameCache->addSpriteFramesWithFile(spriteSheet); _loadedSpriteSheets.insert(spriteSheet); } spriteFrame = frameCache->getSpriteFrameByName(spriteFile); } keyframe->setObject(spriteFrame); } if (!value.isNull()) keyframe->setValue(value); return keyframe; }
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 ccbiReader::readCachedString(char * pBuf) { const std::string & rStr = readCachedString(); strcpy(pBuf, rStr.c_str()); }
void ccbiReader::readCachedString(wchar_t * pBuf) { const std::string & rStr = readCachedString(); wcscpy(pBuf, ConvertToWString(rStr).c_str()); }