DataNode* DataNode::AddNode(const WString& name) { int delPos = name.Find("/"); if (delPos >= 0) { WString namePart = name.SubStr(0, delPos); DataNode* node = GetNode(namePart); if (!node) { node = mnew DataNode(); node->SetName(namePart); node->mParent = this; mChildNodes.Add(node); } return node->AddNode(name.SubStr(delPos + 1)); } DataNode* newNode = mnew DataNode(); newNode->SetName(name); newNode->mParent = this; mChildNodes.Add(newNode); return newNode; }
static void WriteObject(void* object, void* source, const ObjectType& type, DataNode& node) { for (auto baseType : type.GetBaseTypes()) { const ObjectType* baseObjectType = dynamic_cast<const ObjectType*>(baseType.type); if (!baseObjectType) continue; void* baseObject = (*baseType.dynamicCastUpFunc)(object); void* baseSourceObject = (*baseType.dynamicCastUpFunc)(source); WriteObject(baseObject, baseSourceObject, *baseObjectType, node); } for (auto field : type.GetFields()) { if (!field->GetAttribute<SerializableAttribute>()) continue; if (field->GetType()->IsBasedOn(TypeOf(IObject))) { bool usedConverter = false; for (auto conv : mDataConverters) { if (conv->IsConvertsType(&type)) { if (!field->IsValueEquals(object, source)) conv->ToData(&object, *node.AddNode(field->GetName())); usedConverter = true; break; } } if (usedConverter) continue; DataNode* newFieldNode = mnew DataNode(); newFieldNode->SetName(field->GetName()); newFieldNode->SetValueDelta(*(IObject*)field->GetValuePtr(object), *(IObject*)field->GetValuePtr(source)); if (!newFieldNode->IsEmpty()) node.AddNode(newFieldNode); else delete newFieldNode; continue; } if (!field->IsValueEquals(object, source)) { DataNode* newFieldNode = mnew DataNode(); newFieldNode->SetName(field->GetName()); field->SerializeFromObject(object, *newFieldNode); if (!newFieldNode->IsEmpty()) node.AddNode(newFieldNode); else delete newFieldNode; } } }