From c3365a4654d334981ee918f90d0e496f21d7745b Mon Sep 17 00:00:00 2001 From: pipu Date: Mon, 8 Dec 2014 14:32:33 +0800 Subject: [PATCH] Add interface that create node with flat buffers object for simulator --- .../ActionTimeline/CCActionTimelineCache.cpp | 37 +++ .../ActionTimeline/CCActionTimelineCache.h | 2 + .../cocostudio/ActionTimeline/CSLoader.cpp | 137 ++++++++++ .../cocostudio/ActionTimeline/CSLoader.h | 3 + .../cocostudio/FlatBuffersSerialize.cpp | 253 ++++++++++++++++++ .../cocostudio/FlatBuffersSerialize.h | 7 + 6 files changed, 439 insertions(+) diff --git a/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.cpp b/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.cpp index 571ab61083..8b8cc58684 100644 --- a/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.cpp +++ b/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.cpp @@ -37,6 +37,8 @@ THE SOFTWARE. #include "flatbuffers/flatbuffers.h" #include "flatbuffers/util.h" +#include "cocostudio/FlatBuffersSerialize.h" + #include using namespace cocos2d; @@ -690,6 +692,41 @@ Frame* ActionTimelineCache::loadTextureFrameWithFlatBuffers(const flatbuffers::T return frame; } + +ActionTimeline* ActionTimelineCache::createActionWithFlatBuffersForSimulator(const std::string& fileName) +{ + FlatBuffersSerialize* fbs = FlatBuffersSerialize::getInstance(); + fbs->_isSimulator = true; + auto builder = fbs->createFlatBuffersWithXMLFileForSimulator(fileName); + + ActionTimeline* action = ActionTimeline::create(); + + auto csparsebinary = GetCSParseBinary(builder->GetBufferPointer()); + auto nodeAction = csparsebinary->action(); + + action = ActionTimeline::create(); + + int duration = nodeAction->duration(); + action->setDuration(duration); + + float speed = nodeAction->speed(); + action->setTimeSpeed(speed); + + auto timeLines = nodeAction->timeLines(); + int timelineLength = timeLines->size(); + for (int i = 0; i < timelineLength; i++) + { + auto timelineFlatBuf = timeLines->Get(i); + Timeline* timeline = loadTimelineWithFlatBuffers(timelineFlatBuf); + + if (timeline) + action->addTimeline(timeline); + } + + fbs->deleteFlatBufferBuilder(); + + return action; +} } } diff --git a/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.h b/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.h index e730ad87b7..7151498a85 100644 --- a/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.h +++ b/cocos/editor-support/cocostudio/ActionTimeline/CCActionTimelineCache.h @@ -79,6 +79,8 @@ public: ActionTimeline* createActionWithFlatBuffersFile(const std::string& fileName); ActionTimeline* loadAnimationActionWithFlatBuffersFile(const std::string& fileName); + ActionTimeline* createActionWithFlatBuffersForSimulator(const std::string& fileName); + protected: Timeline* loadTimeline(const rapidjson::Value& json); diff --git a/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.cpp b/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.cpp index 4cb0c16669..93192d41de 100644 --- a/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.cpp +++ b/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.cpp @@ -61,6 +61,8 @@ #include "flatbuffers/flatbuffers.h" #include "flatbuffers/util.h" +#include "cocostudio/FlatBuffersSerialize.h" + #include "cocostudio/WidgetCallBackHandlerProtocol.h" #include @@ -1060,4 +1062,139 @@ void CSLoader::registReaderObject(const std::string &className, ObjectFactory::getInstance()->registerType(t); } +Node* CSLoader::createNodeWithFlatBuffersForSimulator(const std::string& filename) +{ + FlatBuffersSerialize* fbs = FlatBuffersSerialize::getInstance(); + fbs->_isSimulator = true; + FlatBufferBuilder* builder = fbs->createFlatBuffersWithXMLFileForSimulator(filename); + + auto csparsebinary = GetCSParseBinary(builder->GetBufferPointer()); + + // decode plist + auto textures = csparsebinary->textures(); + auto texturePngs = csparsebinary->texturePngs(); + int textureSize = csparsebinary->textures()->size(); + // CCLOG("textureSize = %d", textureSize); + for (int i = 0; i < textureSize; ++i) + { + std::string texture = textures->Get(i)->c_str(); + std::string texturePng = texturePngs->Get(i)->c_str(); + SpriteFrameCache::getInstance()->addSpriteFramesWithFile(texture, + texturePng); + } + + auto nodeTree = csparsebinary->nodeTree(); + Node* node = nodeWithFlatBuffersForSimulator(nodeTree); + + _rootNode = nullptr; + + fbs->deleteFlatBufferBuilder(); + + return node; +} + +Node* CSLoader::nodeWithFlatBuffersForSimulator(const flatbuffers::NodeTree *nodetree) +{ + Node* node = nullptr; + + std::string classname = nodetree->classname()->c_str(); + CCLOG("classname = %s", classname.c_str()); + + auto options = nodetree->options(); + + if (classname == "ProjectNode") + { + auto reader = ProjectNodeReader::getInstance(); + auto projectNodeOptions = (ProjectNodeOptions*)options->data(); + std::string filePath = projectNodeOptions->fileName()->c_str(); + CCLOG("filePath = %s", filePath.c_str()); + + if (filePath != "" && FileUtils::getInstance()->isFileExist(filePath)) + { + node = createNodeWithFlatBuffersForSimulator(filePath); + reader->setPropsWithFlatBuffers(node, options->data()); + + cocostudio::timeline::ActionTimeline* action = cocostudio::timeline::ActionTimelineCache::getInstance()->createActionWithFlatBuffersForSimulator(filePath); + if (action) + { + node->runAction(action); + action->gotoFrameAndPlay(0); + } + } + } + else if (classname == "SimpleAudio") + { + node = Node::create(); + auto reader = ComAudioReader::getInstance(); + Component* component = reader->createComAudioWithFlatBuffers(options->data()); + if (component) + { + node->addComponent(component); + reader->setPropsWithFlatBuffers(node, options->data()); + } + } + else + { + std::string readername = getGUIClassName(classname); + readername.append("Reader"); + + NodeReaderProtocol* reader = dynamic_cast(ObjectFactory::getInstance()->createObject(readername)); + node = reader->createNodeWithFlatBuffers(options->data()); + + Widget* widget = dynamic_cast(node); + if (widget) + { + std::string callbackName = widget->getCallbackName(); + std::string callbackType = widget->getCallbackType(); + + bindCallback(callbackName, callbackType, widget, _rootNode); + } + + if (_rootNode == nullptr) + { + _rootNode = node; + } +// _loadingNodeParentHierarchy.push_back(node); + } + + auto children = nodetree->children(); + int size = children->size(); + CCLOG("size = %d", size); + for (int i = 0; i < size; ++i) + { + auto subNodeTree = children->Get(i); + Node* child = nodeWithFlatBuffersForSimulator(subNodeTree); + CCLOG("child = %p", child); + if (child) + { + PageView* pageView = dynamic_cast(node); + ListView* listView = dynamic_cast(node); + if (pageView) + { + Layout* layout = dynamic_cast(child); + if (layout) + { + pageView->addPage(layout); + } + } + else if (listView) + { + Widget* widget = dynamic_cast(child); + if (widget) + { + listView->pushBackCustomItem(widget); + } + } + else + { + node->addChild(child); + } + } + } + +// _loadingNodeParentHierarchy.pop_back(); + + return node; +} + NS_CC_END diff --git a/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.h b/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.h index 96ec2368c9..5192f563eb 100644 --- a/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.h +++ b/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.h @@ -98,6 +98,9 @@ public: void registReaderObject(const std::string& className, ObjectFactory::Instance ins); + cocos2d::Node* createNodeWithFlatBuffersForSimulator(const std::string& filename); + cocos2d::Node* nodeWithFlatBuffersForSimulator(const flatbuffers::NodeTree* nodetree); + protected: cocos2d::Node* loadNode(const rapidjson::Value& json); diff --git a/cocos/editor-support/cocostudio/FlatBuffersSerialize.cpp b/cocos/editor-support/cocostudio/FlatBuffersSerialize.cpp index c88b516fd1..e1dcb3cfbb 100644 --- a/cocos/editor-support/cocostudio/FlatBuffersSerialize.cpp +++ b/cocos/editor-support/cocostudio/FlatBuffersSerialize.cpp @@ -369,6 +369,259 @@ Offset FlatBuffersSerialize::createNodeTree(const tinyxml2::XMLElement options, _builder->CreateString(customClassName)); } + +FlatBufferBuilder* FlatBuffersSerialize::createFlatBuffersWithXMLFileForSimulator(const std::string &xmlFileName) +{ + std::string inFullpath = FileUtils::getInstance()->fullPathForFilename(xmlFileName).c_str(); + + // xml read + if (!FileUtils::getInstance()->isFileExist(inFullpath)) + { + CCLOG(".csd file doesn not exists "); + } + + ssize_t size; + std::string content =(char*)FileUtils::getInstance()->getFileData(inFullpath, "r", &size); + + // xml parse + tinyxml2::XMLDocument* document = new tinyxml2::XMLDocument(); + document->Parse(content.c_str()); + + const tinyxml2::XMLElement* rootElement = document->RootElement();// Root + CCLOG("rootElement name = %s", rootElement->Name()); + + const tinyxml2::XMLElement* element = rootElement->FirstChildElement(); + + bool serializeEnabled = false; + std::string rootType = ""; + + while (element) + { + CCLOG("entity name = %s", element->Name()); + + if (strcmp("Content", element->Name()) == 0) + { + const tinyxml2::XMLAttribute* attribute = element->FirstAttribute(); + + // + if (!attribute) + { + serializeEnabled = true; + rootType = "NodeObjectData"; + } + } + + if (serializeEnabled) + { + break; + } + + const tinyxml2::XMLElement* child = element->FirstChildElement(); + if (child) + { + element = child; + } + else + { + element = element->NextSiblingElement(); + } + } + + if (serializeEnabled) + { + _builder = new FlatBufferBuilder(); + + Offset nodeTree; + Offset aciton; + + + const tinyxml2::XMLElement* child = element->FirstChildElement(); + + while (child) + { + std::string name = child->Name(); + + if (name == "Animation") // action + { + const tinyxml2::XMLElement* animation = child; + aciton = createNodeAction(animation); + } + else if (name == "ObjectData") // nodeTree + { + const tinyxml2::XMLElement* objectData = child; + nodeTree = createNodeTreeForSimulator(objectData, rootType); + } + + child = child->NextSiblingElement(); + } + + auto csparsebinary = CreateCSParseBinary(*_builder, + _builder->CreateVector(_textures), + _builder->CreateVector(_texturePngs), + nodeTree, + aciton); + _builder->Finish(csparsebinary); + + _textures.clear(); + _texturePngs.clear(); + } + return _builder; +} + +Offset FlatBuffersSerialize::createNodeTreeForSimulator(const tinyxml2::XMLElement *objectData, + std::string classType) +{ + std::string classname = classType.substr(0, classType.find("ObjectData")); + CCLOG("classname = %s", classname.c_str()); + + std::string name = ""; + + Offset options; + std::vector> children; + + if (classname == "ProjectNode") + { + auto projectNodeOptions = createProjectNodeOptionsForSimulator(objectData); + options = CreateOptions(*_builder, *(Offset*)(&projectNodeOptions)); + } + else if (classname == "SimpleAudio") + { + auto reader = ComAudioReader::getInstance(); + options = CreateOptions(*_builder, reader->createOptionsWithFlatBuffers(objectData, _builder)); + } + else + { + std::string readername = getGUIClassName(classname); + readername.append("Reader"); + + NodeReaderProtocol* reader = dynamic_cast(ObjectFactory::getInstance()->createObject(readername)); + options = CreateOptions(*_builder, reader->createOptionsWithFlatBuffers(objectData, _builder)); + } + + + // children + bool containChildrenElement = false; + const tinyxml2::XMLElement* child = objectData->FirstChildElement(); + + while (child) + { + CCLOG("child name = %s", child->Name()); + + if (strcmp("Children", child->Name()) == 0) + { + containChildrenElement = true; + break; + } + + child = child->NextSiblingElement(); + } + + if (containChildrenElement) + { + child = child->FirstChildElement(); + CCLOG("element name = %s", child->Name()); + + while (child) + { + const tinyxml2::XMLAttribute* attribute = child->FirstAttribute(); + bool bHasType = false; + while (attribute) + { + std::string attriname = attribute->Name(); + std::string value = attribute->Value(); + + if (attriname == "ctype") + { + children.push_back(createNodeTreeForSimulator(child, value)); + + bHasType = true; + break; + } + + attribute = attribute->Next(); + } + + if(!bHasType) + { + children.push_back(createNodeTreeForSimulator(child, "NodeObjectData")); + } + + child = child->NextSiblingElement(); + } + } + // + + + std::string customClassName = ""; + const tinyxml2::XMLAttribute* attribute = objectData->FirstAttribute(); + while (attribute) + { + std::string attriname = attribute->Name(); + std::string value = attribute->Value(); + + if (attriname == "CustomClassName") + { + customClassName = value; + break; + } + + attribute = attribute->Next(); + } + + return CreateNodeTree(*_builder, + _builder->CreateString(classname), + _builder->CreateVector(children), + options, + _builder->CreateString(customClassName)); +} + +Offset FlatBuffersSerialize::createProjectNodeOptionsForSimulator(const tinyxml2::XMLElement *objectData) +{ + auto temp = NodeReader::getInstance()->createOptionsWithFlatBuffers(objectData, _builder); + auto nodeOptions = *(Offset*)(&temp); + + std::string filename = ""; + + // FileData + const tinyxml2::XMLElement* child = objectData->FirstChildElement(); + while (child) + { + std::string name = child->Name(); + + if (name == "FileData") + { + const tinyxml2::XMLAttribute* attribute = child->FirstAttribute(); + + while (attribute) + { + name = attribute->Name(); + std::string value = attribute->Value(); + + if (name == "Path") + { + filename = value; + } + + attribute = attribute->Next(); + } + } + + child = child->NextSiblingElement(); + } + + return CreateProjectNodeOptions(*_builder, + nodeOptions, + _builder->CreateString(filename)); +} + +void FlatBuffersSerialize::deleteFlatBufferBuilder() +{ + if (_builder != nullptr) + { + _builder->Clear(); + CC_SAFE_DELETE(_builder); + } +} int FlatBuffersSerialize::getResourceType(std::string key) { diff --git a/cocos/editor-support/cocostudio/FlatBuffersSerialize.h b/cocos/editor-support/cocostudio/FlatBuffersSerialize.h index 4e50826a49..a1fb2f82a1 100644 --- a/cocos/editor-support/cocostudio/FlatBuffersSerialize.h +++ b/cocos/editor-support/cocostudio/FlatBuffersSerialize.h @@ -110,6 +110,13 @@ public: flatbuffers::Offset createTimeLineTextureFrame(const tinyxml2::XMLElement* objectData); /**/ + flatbuffers::FlatBufferBuilder* createFlatBuffersWithXMLFileForSimulator(const std::string& xmlFileName); + flatbuffers::Offset createNodeTreeForSimulator(const tinyxml2::XMLElement* objectData, + std::string classType); + flatbuffers::Offset createProjectNodeOptionsForSimulator(const tinyxml2::XMLElement* objectData); + + void deleteFlatBufferBuilder(); + int getResourceType(std::string key); std::string getGUIClassName(const std::string &name); std::string getWidgetReaderClassName(cocos2d::ui::Widget *widget);