#include "stdafx.h" #include "SigmaDoc.h" #include "BlobSerializer.h" #include "Util.h" #include "ClassFactory.h" #include "DrawOperator/XySerializerHelper.h" #include static void PrintCOneIds(CXy* pXy) { auto* pValueList = pXy->GetValueList(); std::vector result; for (POSITION pos = pValueList->GetHeadPosition(); pos != nullptr; pValueList->GetNext(pos)) { COne* pOne = reinterpret_cast(pValueList->GetAt(pos)); CString str; str.Format("%lld ", pOne->GetId()); result.push_back(str); } CString printText; for (const CString& str : result) { printText += str; } TRACE("%s\n", printText); } static void serializeStdStringImpl(CArchive& archive, std::string& str) { uint64_t count = str.size(); archive << count; archive.Write(str.c_str(), count); } static void deserializeStdStringImpl(CArchive& archive, std::string& str) { uint64_t count = 0; archive >> count; std::vector buf(count); archive.Read(buf.data(), count); str = std::string(buf.begin(), buf.end()); } BlobSerializer::BlobSerializer(CArchive &archive) : m_archive(archive) { } void BlobSerializer::visit(CActionAddItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); serialize(item.m_pos); m_archive << item.m_bAdded; } else { deserializeCActionItem(item); deserialize(item.m_pos); m_archive >> item.m_bAdded; } } void BlobSerializer::visit(CActionBackupItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); uint64_t count = item.GetCount(); m_archive << count; for (const auto& entry : item.m_entries) { m_archive << entry.id; serializeCOne(entry.pOldOne.get(), true); serializeCOne(entry.pNewOne.get(), true); } } else { deserializeCActionItem(item); uint64_t count = 0; m_archive >> count; for (uint64_t i = 0; i < count; i++) { CActionBackupItem::BackupEntry entry; m_archive >> entry.id; COne* pOldOne = nullptr; deserializeCOne(item.GetDoc()->GetDraw(), pOldOne, true); entry.pOldOne.reset(pOldOne); COne* pNewOne = nullptr; deserializeCOne(item.GetDoc()->GetDraw(), pNewOne, true); entry.pNewOne.reset(pNewOne); item.m_entries.push_back(std::move(entry)); } } } void BlobSerializer::visit(CActionBackupProjectionItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); m_archive << item.m_strOldProjection; m_archive << item.m_strNewProjection; } else { deserializeCActionItem(item); m_archive >> item.m_strOldProjection; m_archive >> item.m_strNewProjection; } } void BlobSerializer::visit(CActionBackupXYItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); serializeCXy(item.m_pPrevXY); } else { deserializeCActionItem(item); deserializeCXy(item.m_pPrevXY); } } void BlobSerializer::visit(CActionChangeColorItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); m_archive << item.oldColor; m_archive << item.newColor; m_archive << getIdByPosition(item.GetDoc()->m_pXy, item.m_elePos); } else { deserializeCActionItem(item); m_archive >> item.oldColor; m_archive >> item.newColor; int64_t id = getIdFromArchive(); item.m_elePos = item.GetDoc()->m_pXy->GetPositionById(id); } } void BlobSerializer::visit(CActionChangeLayerItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); m_archive << item.m_strOldLayer; m_archive << item.m_strNewLayer; serialize(positionsToIds(item.GetDoc()->m_pXy, item.m_eleList)); } else { deserializeCActionItem(item); m_archive >> item.m_strOldLayer; m_archive >> item.m_strNewLayer; std::vector ids; deserialize(ids); idsToPositions(item.GetDoc()->m_pXy, ids, item.m_eleList); } } void BlobSerializer::visit(CActionCurveEdit& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); int64_t id = getIdByPosition(item.GetDoc()->m_pXy, item.m_posOfCurve); m_archive << id; m_archive << item.m_indexOfNodeForUndo; m_archive << item.m_nodeXForUndo; m_archive << item.m_nodeYForUndo; m_archive << item.m_indexOfNodeForRedo; m_archive << item.m_nodeXForRedo; m_archive << item.m_nodeYForRedo; } else { deserializeCActionItem(item); int64_t id = getIdFromArchive(); item.m_posOfCurve = item.GetDoc()->GetDraw()->GetPositionById(id); m_archive >> item.m_indexOfNodeForUndo; m_archive >> item.m_nodeXForUndo; m_archive >> item.m_nodeYForUndo; m_archive >> item.m_indexOfNodeForRedo; m_archive >> item.m_nodeXForRedo; m_archive >> item.m_nodeYForRedo; } } void BlobSerializer::visit(CActionCurveEditAddPoint& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); m_archive << getIdByPosition(item.GetDoc()->m_pXy, item.m_posOfCurve); m_archive << item.m_index; serializeDfPoint(item.nodeAdded); } else { deserializeCActionItem(item); item.GetDoc()->m_pXy->GetPositionById(getIdFromArchive()); m_archive >> item.m_index; deserializeDfPoint(item.nodeAdded); } } void BlobSerializer::visit(CActionCurveEditDeletePoint& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); m_archive << getIdByPosition(item.GetDoc()->m_pXy, item.m_posOfCurve); m_archive << item.m_index; serializeDfPoint(item.nodeAdded); } else { deserializeCActionItem(item); item.GetDoc()->m_pXy->GetPositionById(getIdFromArchive()); m_archive >> item.m_index; deserializeDfPoint(item.nodeAdded); } } void BlobSerializer::visit(CActionCurveReversalItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); std::vector ids = positionsToIds(item.GetDoc()->m_pXy, item.m_eleList); serialize(ids); } else { deserializeCActionItem(item); std::vector ids; deserialize(ids); idsToPositions(item.GetDoc()->GetDraw(), ids, item.m_eleList); } } void BlobSerializer::visit(CActionCutOutItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); serializeCXy(item.m_pBakXY); } else { deserializeCActionItem(item); deserializeCXy(item.m_pBakXY); } } void BlobSerializer::visit(CActionDeleteItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); m_archive << item.m_bDeleted; serialize(item.m_pos); } else { deserializeCActionItem(item); m_archive >> item.m_bDeleted; deserialize(item.m_pos); } } void BlobSerializer::visit(CActionEmbellishItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); bool pOneNotNull = (item.m_pOne != nullptr); m_archive << pOneNotNull; if (pOneNotNull) { // CActionEmbellishItem 并不拥有 COne,只是指向 COne 的一个指针,所以这里只标记是哪个 COne int64_t id = item.m_pOne->GetId(); m_archive << id; } bool pLayerNotNull = (item.m_pLayer != nullptr); m_archive << pLayerNotNull; if (pLayerNotNull) { m_archive << item.m_pLayer->GetPathName(); } serializeHowToViewCurve(item.m_pOldViewCurve); serializeHowToViewCurve(item.m_pNewViewCurve); serializeHowToViewPoint(item.m_pOldViewPoint); serializeHowToViewPoint(item.m_pNewViewPoint); } else { deserializeCActionItem(item); bool pOneNotNull = false; m_archive >> pOneNotNull; if (pOneNotNull) { int64_t id = 0; m_archive >> id; item.m_pOne = lookupCOneById(item.GetDoc()->GetDraw(), id); } bool pLayerNotNull = false; m_archive >> pLayerNotNull; if (pLayerNotNull) { CString layerPath; m_archive >> layerPath; item.m_pLayer = lookupCLayerByPath(item.GetDoc()->GetDraw(), layerPath); } deserializeHowToViewCurve(item.m_pOldViewCurve); deserializeHowToViewCurve(item.m_pNewViewCurve); deserializeHowToViewPoint(item.m_pOldViewPoint); deserializeHowToViewPoint(item.m_pNewViewPoint); } } void BlobSerializer::visit(CActionExchangeXYItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); } else { deserializeCActionItem(item); } } void BlobSerializer::visit(CActionLayerRenameItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); m_archive << item.m_strSourceLayerName; m_archive << item.m_strNewLayerName; } else { deserializeCActionItem(item); m_archive >> item.m_strSourceLayerName; m_archive >> item.m_strNewLayerName; } } void BlobSerializer::visit(CActionListItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); // 写入 Action 数据数组长度 uint64_t count = item.ActionList.GetCount(); m_archive << count; for (POSITION pos = item.ActionList.GetHeadPosition(); pos != nullptr; item.ActionList.GetNext(pos)) { std::vector actionData = SerializeAction((CAction *)item.ActionList.GetAt(pos)); uint64_t actionCount = actionData.size(); // Action 数据也是二进制结构,先写入数据长度 m_archive << actionCount; // 写入 Action 内容 m_archive.Write(actionData.data(), static_cast(actionData.size())); } } else { deserializeCActionItem(item); // 读取 Action 数据数组长度 uint64_t count = getCountFromArchive(); for (uint64_t i = 0; i < count; i++) { // 读取单个 Action 数据长度 uint64_t actionCount = getCountFromArchive(); // 读取 Action 数据 std::vector actionData(actionCount); m_archive.Read(actionData.data(), static_cast(actionData.size())); // 转换为 Action CAction* pAction = DeserializeAction(item.GetDoc(), actionData); if (pAction != nullptr) { item.ActionList.AddTail(pAction); } } } } void BlobSerializer::visit(CActionMarkDeleteItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); // TODO: mark m_archive << item.m_bDelete; m_archive << item.m_bRePosition; } else { deserializeCActionItem(item); // TODO: mark m_archive >> item.m_bDelete; m_archive >> item.m_bRePosition; } } void BlobSerializer::visit(CActionMirrorItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); // TODO: m_moveItem m_archive << item.m_originX; m_archive << item.m_originY; serialize(positionsToIds(item.GetDoc()->m_pXy, item.m_selectionSet)); } else { deserializeCActionItem(item); // TODO: m_moveItem m_archive >> item.m_originX; m_archive >> item.m_originY; std::vector ids; deserialize(ids); idsToPositions(item.GetDoc()->m_pXy, ids, item.m_selectionSet); } } void BlobSerializer::visit(CActionModifiedMesh& item) { if (m_archive.IsStoring()) { visit(static_cast(item)); } else { visit(static_cast(item)); } } void BlobSerializer::visit(CActionMoveItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); for (int i = 0; i < 6; i++) { m_archive << item.matrix[i]; } // TODO: m_pXyDC } else { deserializeCActionItem(item); for (int i = 0; i < 6; i++) { m_archive >> item.matrix[i]; } // TODO: m_pXyDC } } void BlobSerializer::visit(CActionOffsetItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); serialize(item.offset_x); serialize(item.offset_y); } else { deserializeCActionItem(item); deserialize(item.offset_x); deserialize(item.offset_y); } } void BlobSerializer::visit(CActionParamReplaceItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); serializeCOne(item.m_pBakOne); serializeCOne(item.m_pOne); } else { deserializeCActionItem(item); deserializeCOne(item.GetDoc()->m_pXy, item.m_pBakOne); deserializeCOne(item.GetDoc()->m_pXy, item.m_pOne); } } void BlobSerializer::visit(CActionReplaceNameItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); m_archive << item.m_strOldName; m_archive << item.m_strNewName; serializeCOne(item.m_pOne); } else { deserializeCActionItem(item); m_archive >> item.m_strOldName; m_archive >> item.m_strNewName; deserializeCOne(item.GetDoc()->m_pXy, item.m_pOne); } } void BlobSerializer::visit(CActionScaleProperty& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); serializeCOne(item.m_pOne); m_archive << item.m_dxScale; m_archive << item.m_dyScale; m_archive << item.m_bPersonalEmbellish; m_archive << item.m_bOwnerProperties; } else { deserializeCActionItem(item); deserializeCOne(item.GetDoc()->m_pXy, item.m_pOne); m_archive >> item.m_dxScale; m_archive >> item.m_dyScale; m_archive >> item.m_bPersonalEmbellish; m_archive >> item.m_bOwnerProperties; } } void BlobSerializer::visit(CActionSortItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); serialize(item.m_oldPos); std::vector ids = positionsToIds(item.GetDoc()->m_pXy, item.m_eleList); serialize(ids); m_archive << item.m_nModeSel; } else { deserializeCActionItem(item); deserialize(item.m_oldPos); std::vector ids; deserialize(ids); idsToPositions(item.GetDoc()->m_pXy, ids, item.m_eleList); m_archive >> item.m_nModeSel; } } void BlobSerializer::visit(CActionReverseZItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); serialize(positionsToIds(item.GetDoc()->m_pXy, item.m_elements)); } else { deserializeCActionItem(item); std::vector ids; deserialize(ids); idsToPositions(item.GetDoc()->m_pXy, ids, item.m_elements); } } void BlobSerializer::visit(CAtionBackupEditCurveInName& item) { if (m_archive.IsStoring()) { visit(static_cast(item)); } else { visit(static_cast(item)); } } void BlobSerializer::visit(CActionProjectionItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); m_archive << item.m_oldProjection; m_archive << item.m_newProjection; } else { deserializeCActionItem(item); m_archive >> item.m_oldProjection; m_archive >> item.m_newProjection; } } void BlobSerializer::visit(CActionChangeNameItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); m_archive << item.m_strOldName; m_archive << item.m_strNewName; int64_t id = (item.m_elePos != nullptr ? item.GetDoc()->GetDraw()->GetAt(item.m_elePos)->GetId() : -1); m_archive << id; } else { deserializeCActionItem(item); m_archive >> item.m_strOldName; m_archive >> item.m_strNewName; int64_t id = -1; m_archive >> id; item.m_elePos = item.GetDoc()->GetDraw()->GetPositionById(id); } } void BlobSerializer::visit(CActionLayerDragDropItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); m_archive << item.m_oldLocation.layer; m_archive << item.m_oldLocation.prevLayer; m_archive << item.m_newLocation.layer; m_archive << item.m_newLocation.prevLayer; } else { deserializeCActionItem(item); m_archive >> item.m_oldLocation.layer; m_archive >> item.m_oldLocation.prevLayer; m_archive >> item.m_newLocation.layer; m_archive >> item.m_newLocation.prevLayer; } } void BlobSerializer::visit(CActionComboItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); uint64_t count = item.m_actionItems.size(); m_archive << count; for (auto &action : item.m_actionItems) { std::vector actionData = SerializeAction(action.get()); m_archive << static_cast(actionData.size()); m_archive.Write(actionData.data(), static_cast(actionData.size())); } } else { deserializeCActionItem(item); uint64_t count = getCountFromArchive(); for (uint64_t i = 0; i < count; i++) { uint64_t actionCount = getCountFromArchive(); std::vector actionData(actionCount); m_archive.Read(actionData.data(), static_cast(actionData.size())); CAction* pAction = DeserializeAction(item.GetDoc(), actionData); if (pAction != nullptr) { std::shared_ptr pActionItem(dynamic_cast(pAction)); if (pActionItem != nullptr) { item.m_actionItems.push_back(pActionItem); } } } } } void BlobSerializer::visit(CActionModifiedItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); uint64_t count = item.GetCount(); m_archive << count; for (const auto& entry : item.m_entries) { m_archive << entry.id; serializeCOne(entry.pOldOne.get(), true); serializeCOne(entry.pNewOne.get(), true); } } else { deserializeCActionItem(item); uint64_t count = 0; m_archive >> count; for (uint64_t i = 0; i < count; i++) { CActionModifiedItem::ModifiedEntry entry; m_archive >> entry.id; COne* pOldOne = nullptr; deserializeCOne(item.GetDoc()->GetDraw(), pOldOne, true); entry.pOldOne.reset(pOldOne); COne* pNewOne = nullptr; deserializeCOne(item.GetDoc()->GetDraw(), pNewOne, true); entry.pNewOne.reset(pNewOne); item.m_entries.push_back(std::move(entry)); } } } void BlobSerializer::visit(CActionModifiedMeshItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); serializeCOne(item.m_pOne, false); m_archive << item.m_oldArguments; m_archive << item.m_newArguments; } else { deserializeCActionItem(item); deserializeCOne(item.GetDoc()->GetDraw(), item.m_pOne, false); m_archive >> item.m_oldArguments; m_archive >> item.m_newArguments; } } void BlobSerializer::visit(CActionReplaceColorItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); m_archive << item.oldColor; m_archive << item.newColor; m_archive << item.m_bOwnerProperties; m_archive << item.m_bLayerEmbellish; } else { deserializeCActionItem(item); m_archive >> item.oldColor; m_archive >> item.newColor; m_archive >> item.m_bOwnerProperties; m_archive >> item.m_bLayerEmbellish; } } void BlobSerializer::visit(CActionLayerAddItem& item) { if (m_archive.IsStoring()) { visit(static_cast(item)); // LayerList 本来是 CActionLayerDeleteItem 的数据,但是 CActionLayerDeleteItem 并不拥有 CLayer 对象, // 而 CActionLayerAddItem 又拥有 CLayer 对象,两者冲突了,在这里打个补丁 uint64_t count = item.LayerList.GetCount(); m_archive << count; for (POSITION pos = item.LayerList.GetHeadPosition(); pos != nullptr; item.LayerList.GetNext(pos)) { CLayer* pLayer = reinterpret_cast(item.LayerList.GetAt(pos)); serializeCLayer(pLayer); } m_archive << item.m_curLayerName; } else { visit(static_cast(item)); // 原因同上,打补丁的代码 item.LayerList.RemoveAll(); uint64_t count = 0; m_archive >> count; for (uint64_t i = 0; i < count; i++) { CLayer* pLayer = new CLayer(); deserializeCLayer(pLayer); item.LayerList.AddTail(pLayer); } m_archive >> item.m_curLayerName; } } void BlobSerializer::visit(CActionLayerDeleteItem& item) { if (m_archive.IsStoring()) { visit(static_cast(item)); uint64_t count = item.LayerList.GetCount(); m_archive << count; for (POSITION pos = item.LayerList.GetHeadPosition(); pos != nullptr; item.LayerList.GetNext(pos)) { m_archive << reinterpret_cast(item.LayerList.GetAt(pos))->GetPathName(); } } else { visit(static_cast(item)); uint64_t count = getCountFromArchive(); for (uint64_t i = 0; i < count; i++) { CString layerPath; m_archive >> layerPath; CLayer* pLayer = item.GetDoc()->GetDraw()->FindLayer(layerPath, FALSE); if (pLayer != nullptr) { item.LayerList.AddTail(pLayer); } } } } void BlobSerializer::visit(CActionRotationItem& item) { if (m_archive.IsStoring()) { serializeCActionItem(item); m_archive << item.m_x; m_archive << item.m_y; m_archive << item.m_angle; } else { deserializeCActionItem(item); m_archive >> item.m_x; m_archive >> item.m_y; m_archive >> item.m_angle; } } void BlobSerializer::assignParentClass(CXy* pXy, CLayer* pLayer) { CLayerList* pLayerList = pXy->GetClass(pLayer->GetClassNameA()); if (pLayerList != nullptr) { pLayer->SetParentClass(pLayerList); } } void BlobSerializer::serializeCOnes(CPtrList& ptrList, bool owned) { // 先写入 COne 数组长度 m_archive << static_cast(ptrList.GetCount()); for (POSITION pos = ptrList.GetHeadPosition(); pos != nullptr; ptrList.GetNext(pos)) { COne* pOne = (COne*)ptrList.GetAt(pos); serializeCOne(pOne, owned); } } void BlobSerializer::deserializeCOnes(CXy* pXy, CPtrList& ptrList, bool owned) { uint64_t count = getCountFromArchive(); for (int i = 0; i < count; i++) { COne* pOne = nullptr; deserializeCOne(pXy, pOne, owned); if (pOne != nullptr) { ptrList.AddTail(pOne); } } } void BlobSerializer::serializeCOne(COne* pOne, bool owned) { if (owned) { serializeOwnedCOne(pOne); } else { serializeUnownedCOne(pOne); } } void BlobSerializer::serializeOwnedCOne(COne* pOne) { if (pOne != nullptr) { std::vector byteArray = SerializeCOneToByteArray(pOne); // 写入二进制数据长度 m_archive << static_cast(byteArray.size()); m_archive.Write(byteArray.data(), static_cast(byteArray.size())); } else { m_archive << static_cast(0); } } void BlobSerializer::deserializeOwnedCOne(CXy* pXy, COne*& pOne) { // 读取二进制数据长度 uint64_t count = getCountFromArchive(); if (count != 0) { std::vector buf(count); m_archive.Read(buf.data(), count); std::unique_ptr one = DeserializeCOneFromByteArray(buf); if (one != nullptr) { CLayer* pLayer = pXy->FindLayer(one->GetLayerName()); if (pLayer == nullptr) { pOne = nullptr; return; } one->SetLayer(pLayer); } pOne = one.release(); } else { pOne = nullptr; } } void BlobSerializer::serializeUnownedCOne(COne* pOne) { if (pOne != nullptr) { int64_t id = pOne->GetId(); m_archive << id; } else { int64_t id = -1; m_archive << id; } } void BlobSerializer::deserializeUnownedCOne(CXy* pXy, COne*& pOne) { int64_t id = getIdFromArchive(); if (id != -1) { pOne = lookupCOneById(pXy, id); } else { pOne = nullptr; } } void BlobSerializer::deserializeCOne(CXy *pXy, COne*& pOne, bool owned) { if (owned) { deserializeOwnedCOne(pXy, pOne); } else { deserializeUnownedCOne(pXy, pOne); } } void BlobSerializer::serializeCLayer(CLayer* pLayer) { serializeElement(pLayer); } void BlobSerializer::deserializeCLayer(CLayer*& pLayer) { deserializeElement(pLayer); } void BlobSerializer::serializeHowToViewCurve(CHowToViewCurve* viewCurve) { serializeElement(viewCurve); } void BlobSerializer::deserializeHowToViewCurve(CHowToViewCurve*& viewCurve) { deserializeElement(viewCurve); } void BlobSerializer::serializeHowToViewPoint(CHowToViewPoint* viewPoint) { serializeElement(viewPoint); } void BlobSerializer::deserializeHowToViewPoint(CHowToViewPoint*& viewPoint) { deserializeElement(viewPoint); } void BlobSerializer::serializeCAction(CAction& action) { // 反序列化的时候把获取类名搬出去了,为了对称,这里也搬出去 // serializeStdString(action.GetActionName()); // 用来标记当前 Action 具体类 // m_archive << action.actionTarget; 这玩意儿要怎么序列化?不需要,这里面存储的是 CSigamDoc 对象指针 serializeStdStringImpl(m_archive, action.m_uuid); m_archive << action.autoNotify; m_archive << action.finished; m_archive << action.undone; m_archive << action.success; m_archive << action.actionType; m_archive << action.name; m_archive << action.done; auto timeSinceEpoch = action.m_timepoint.time_since_epoch(); m_archive << std::chrono::duration_cast(timeSinceEpoch).count(); } void BlobSerializer::deserializeCAction(CAction& action) { // 这句必须搬出去,我们需要拿到类名之后,直接创建子类,然后才能调用这里的反序列化,否则单单反序列化出一个基类没有意义 //std::string actionName; //deserializeStdString(actionName); // m_archive >> action.actionTarget; 这玩意儿要怎么反序列化?反序列化时,先产生 CSigmaDoc 对象,再传递给 Action,这里无需处理 deserializeStdStringImpl(m_archive, action.m_uuid); m_archive >> action.autoNotify; m_archive >> action.finished; m_archive >> action.undone; m_archive >> action.success; m_archive >> action.actionType; m_archive >> action.name; m_archive >> action.done; long long time = 0; m_archive >> time; action.m_timepoint = std::chrono::system_clock::from_time_t(time); } void BlobSerializer::serializeCActionItem(CActionItem& item) { serializeCAction(item); serializeCOnes(item.value, item.IsOwnCOnes()); } void BlobSerializer::deserializeCActionItem(CActionItem& item) { deserializeCAction(item); deserializeCOnes(item.GetDoc()->m_pXy, item.value, item.IsOwnCOnes()); } void BlobSerializer::serializeCXy(CXy* pXy) { if (pXy == nullptr) { m_archive << uint64_t(0); return; } std::vector serializedData = CXySerializerHelper::SerializeCXy(pXy); uint64_t count = serializedData.size(); m_archive << count; m_archive.Write(serializedData.data(), count); } void BlobSerializer::deserializeCXy(CXy*& pXy) { uint64_t count = getCountFromArchive(); if (count == 0) { pXy = nullptr; return; } std::vector serializedData(count); m_archive.Read(serializedData.data(), static_cast(count)); pXy = CXySerializerHelper::DeserializeCXy(serializedData).release(); } void BlobSerializer::serializeDfPoint(dfPoint& point) { m_archive << point.x0; m_archive << point.y0; m_archive << point.z0; m_archive << point.l; m_archive << point.no; } void BlobSerializer::deserializeDfPoint(dfPoint& point) { m_archive >> point.x0; m_archive >> point.y0; m_archive >> point.z0; m_archive >> point.l; m_archive >> point.no; } void BlobSerializer::serializeStdString(std::string& str) { serializeStdStringImpl(m_archive, str); } void BlobSerializer::deserializeStdString(std::string& str) { deserializeStdStringImpl(m_archive, str); } void BlobSerializer::idsToPositions(CXy* pXy, const std::vector& ids, CPositionList& posList) const { posList.RemoveAll(); for (int64_t id : ids) { POSITION pos = pXy->GetPositionById(id); if (pos != nullptr) { posList.AddTail(pos); } } } std::vector BlobSerializer::positionsToIds(CXy* pXy, const CPositionList& positions) const { std::vector ids; for (POSITION pos = positions.GetHeadPosition(); pos != nullptr; positions.GetNext(pos)) { POSITION pt = positions.GetAt(pos); ids.push_back(pXy->GetAt(pt)->GetId()); } return ids; } int64_t BlobSerializer::getIdByPosition(CXy* pXy, POSITION pos) const { COne* pOne = pXy->GetAt(pos); return (pOne != nullptr) ? pOne->GetId() : -1; } int64_t BlobSerializer::getIdFromArchive() { int64_t id = 0; m_archive >> id; return id; } uint64_t BlobSerializer::getCountFromArchive() { uint64_t count = 0; m_archive >> count; return count; } COne* BlobSerializer::lookupCOneById(CXy* pXy, int64_t id) const { POSITION pos = pXy->GetPositionById(id); if (pos != nullptr) { return pXy->GetAt(pos); } return nullptr; } CLayer* BlobSerializer::lookupCLayerByPath(CXy* pXy, const CString& layerPath) const { for (CLayer* pLayer : flatmapCLayer(pXy)) { // 考虑我们直接存储的图层名,这里不需要考虑大小同的情况 if (pLayer->GetPathName() == layerPath) { return pLayer; } } return false; } std::vector BlobSerializer::lookupCOneByIds(CXy* pXy, const std::vector& ids) const { std::vector result; for (int64_t id : ids) { POSITION pos = pXy->GetPositionById(id); if (pos == nullptr) { result.push_back(nullptr); } else { result.push_back(pXy->GetAt(pos)); } } return result; } std::vector BlobSerializer::flatmapCLayer(CXy* pXy) const { std::vector result; CClassList* pClassList = pXy->GetClassList(); for (POSITION pos = pClassList->GetHeadPosition(); pos != nullptr; pClassList->GetNext(pos)) { CLayerList* pLayerList = pClassList->GetAt(pos); addLayersFromList(pLayerList, result); } return result; } void BlobSerializer::addLayersFromList(CLayerList* pLayerList, std::vector& result) const { for (POSITION pLayerPos = pLayerList->GetHeadPosition(); pLayerPos != nullptr; pLayerList->GetNext(pLayerPos)) { result.push_back(pLayerList->GetAt(pLayerPos)); } } std::vector SerializeAction(const CAction* action) { const UINT KB = 1024; const UINT MB = 1024 * KB; CMemFile memFile(1 * MB); CArchive archive(&memFile, CArchive::store); // 先写入 Action 名称 std::string name = action->GetActionName(); serializeStdStringImpl(archive, name); BlobSerializer serializer(archive); const_cast(action)->accept(serializer); archive.Close(); std::vector data(memFile.GetLength()); memFile.SeekToBegin(); memFile.Read(data.data(), memFile.GetLength()); return data; } CAction* DeserializeAction(CSigmaDoc *pDoc, const std::vector& data) { static std::once_flag flag; std::call_once(flag, []() { ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); ClassFactory::getInstance().registerClass(); }); CMemFile memFile((BYTE*)(data.data()), static_cast(data.size())); CArchive archive(&memFile, CArchive::load); std::string name; deserializeStdStringImpl(archive, name); CAction *action = reinterpret_cast(ClassFactory::getInstance().createObject(name)); if (action != nullptr) { // 反序列的时候,对象需要先拿到 Doc 信息,否则诸如 id、postion 等很多东西无法反序列化 action->SetActionTarget(pDoc); BlobSerializer serializer(archive); action->accept(serializer); } return action; }