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(); int textureSize = csparsebinary->textures()->size(); // CCLOG("textureSize = %d", textureSize); for (int i = 0; i < textureSize; ++i) { SpriteFrameCache::getInstance()->addSpriteFramesWithFile(textures->Get(i)->c_str()); } auto nodeTree = csparsebinary->nodeTree(); Node* node = nodeWithFlatBuffersForSimulator(nodeTree); _rootNode = nullptr; fbs->deleteFlatBufferBuilder(); return node; }
Offset<const Table *> CopyTable(FlatBufferBuilder &fbb, const reflection::Schema &schema, const reflection::Object &objectdef, const Table &table, bool use_string_pooling) { // Before we can construct the table, we have to first generate any // subobjects, and collect their offsets. std::vector<uoffset_t> offsets; auto fielddefs = objectdef.fields(); for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) { auto &fielddef = **it; // Skip if field is not present in the source. if (!table.CheckField(fielddef.offset())) continue; uoffset_t offset = 0; switch (fielddef.type()->base_type()) { case reflection::String: { offset = use_string_pooling ? fbb.CreateSharedString(GetFieldS(table, fielddef)).o : fbb.CreateString(GetFieldS(table, fielddef)).o; break; } case reflection::Obj: { auto &subobjectdef = *schema.objects()->Get(fielddef.type()->index()); if (!subobjectdef.is_struct()) { offset = CopyTable(fbb, schema, subobjectdef, *GetFieldT(table, fielddef)).o; } break; } case reflection::Union: { auto &subobjectdef = GetUnionType(schema, objectdef, fielddef, table); offset = CopyTable(fbb, schema, subobjectdef, *GetFieldT(table, fielddef)).o; break; } case reflection::Vector: { auto vec = table.GetPointer<const Vector<Offset<Table>> *>( fielddef.offset()); auto element_base_type = fielddef.type()->element(); auto elemobjectdef = element_base_type == reflection::Obj ? schema.objects()->Get(fielddef.type()->index()) : nullptr; switch (element_base_type) { case reflection::String: { std::vector<Offset<const String *>> elements(vec->size()); auto vec_s = reinterpret_cast<const Vector<Offset<String>> *>(vec); for (uoffset_t i = 0; i < vec_s->size(); i++) { elements[i] = use_string_pooling ? fbb.CreateSharedString(vec_s->Get(i)).o : fbb.CreateString(vec_s->Get(i)).o; } offset = fbb.CreateVector(elements).o; break; } case reflection::Obj: { if (!elemobjectdef->is_struct()) { std::vector<Offset<const Table *>> elements(vec->size()); for (uoffset_t i = 0; i < vec->size(); i++) { elements[i] = CopyTable(fbb, schema, *elemobjectdef, *vec->Get(i)); } offset = fbb.CreateVector(elements).o; break; } } // FALL-THRU default: { // Scalars and structs. auto element_size = GetTypeSize(element_base_type); if (elemobjectdef && elemobjectdef->is_struct()) element_size = elemobjectdef->bytesize(); fbb.StartVector(element_size, vec->size()); fbb.PushBytes(vec->Data(), element_size * vec->size()); offset = fbb.EndVector(vec->size()); break; } } break; } default: // Scalars. break; } if (offset) { offsets.push_back(offset); } } // Now we can build the actual table from either offsets or scalar data. auto start = objectdef.is_struct() ? fbb.StartStruct(objectdef.minalign()) : fbb.StartTable(); size_t offset_idx = 0; for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) { auto &fielddef = **it; if (!table.CheckField(fielddef.offset())) continue; auto base_type = fielddef.type()->base_type(); switch (base_type) { case reflection::Obj: { auto &subobjectdef = *schema.objects()->Get(fielddef.type()->index()); if (subobjectdef.is_struct()) { CopyInline(fbb, fielddef, table, subobjectdef.minalign(), subobjectdef.bytesize()); break; } } // ELSE FALL-THRU case reflection::Union: case reflection::String: case reflection::Vector: fbb.AddOffset(fielddef.offset(), Offset<void>(offsets[offset_idx++])); break; default: { // Scalars. auto size = GetTypeSize(base_type); CopyInline(fbb, fielddef, table, size, size); break; } } } assert(offset_idx == offsets.size()); if (objectdef.is_struct()) { fbb.ClearOffsets(); return fbb.EndStruct(); } else { return fbb.EndTable(start, static_cast<voffset_t>(fielddefs->size())); } }
std::string FlatBuffersSerialize::serializeFlatBuffersWithXMLFile(const std::string &xmlFileName, const std::string &flatbuffersFileName) { std::string inFullpath = FileUtils::getInstance()->fullPathForFilename(xmlFileName).c_str(); // xml read if (!FileUtils::getInstance()->isFileExist(inFullpath)) { return ".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"; } // // // while (attribute) // { // std::string name = attribute->Name(); // std::string value = attribute->Value(); // CCLOG("attribute name = %s, value = %s", name, value); // if (name == "") // { // serializeEnabled = true; // rootType = (strcmp("", value) == 0) ? "Node" : value; // } // // if (serializeEnabled) // { // break; // } // // attribute = attribute->Next(); // } // } if (serializeEnabled) { break; } const tinyxml2::XMLElement* child = element->FirstChildElement(); if (child) { element = child; } else { element = element->NextSiblingElement(); } } if (serializeEnabled) { FlatBufferBuilder builder; _builder = &builder; Offset<NodeTree> nodeTree; Offset<NodeAction> 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 = createNodeTree(objectData, rootType); } child = child->NextSiblingElement(); } auto csparsebinary = CreateCSParseBinary(builder, builder.CreateVector(_textures), builder.CreateVector(_texturePngs), nodeTree, aciton); builder.Finish(csparsebinary); _textures.clear(); _texturePngs.clear(); std::string outFullPath = FileUtils::getInstance()->fullPathForFilename(flatbuffersFileName); size_t pos = outFullPath.find_last_of('.'); std::string convert = outFullPath.substr(0, pos).append(".csb"); auto save = flatbuffers::SaveFile(convert.c_str(), reinterpret_cast<const char *>(builder.GetBufferPointer()), builder.GetSize(), true); if (!save) { return "couldn't save files!"; } } return ""; }
void CopyInline(FlatBufferBuilder &fbb, const reflection::Field &fielddef, const Table &table, size_t align, size_t size) { fbb.Align(align); fbb.PushBytes(table.GetStruct<const uint8_t *>(fielddef.offset()), size); fbb.TrackField(fielddef.offset(), fbb.GetSize()); }