You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1439 lines
31 KiB
C++

1 month ago
#include "stdafx.h"
#include "SigmaDoc.h"
#include "BlobSerializer.h"
#include "Util.h"
#include "ClassFactory.h"
#include "DrawOperator/XySerializerHelper.h"
#include <mutex>
static void PrintCOneIds(CXy* pXy)
{
auto* pValueList = pXy->GetValueList();
std::vector<CString> result;
for (POSITION pos = pValueList->GetHeadPosition(); pos != nullptr; pValueList->GetNext(pos))
{
COne* pOne = reinterpret_cast<COne*>(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<char> 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<int64_t> 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<int64_t> ids = positionsToIds(item.GetDoc()->m_pXy, item.m_eleList);
serialize(ids);
}
else
{
deserializeCActionItem(item);
std::vector<int64_t> 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 <20><><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5> COne<6E><65>ֻ<EFBFBD><D6BB>ָ<EFBFBD><D6B8> COne <20><>һ<EFBFBD><D2BB>ָ<EFBFBD><EFBFBD><EBA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD> 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);
// д<><D0B4> Action <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E9B3A4>
uint64_t count = item.ActionList.GetCount();
m_archive << count;
for (POSITION pos = item.ActionList.GetHeadPosition(); pos != nullptr; item.ActionList.GetNext(pos))
{
std::vector<char> actionData = SerializeAction((CAction *)item.ActionList.GetAt(pos));
uint64_t actionCount = actionData.size();
// Action <20><><EFBFBD><EFBFBD>Ҳ<EFBFBD>Ƕ<EFBFBD><C7B6><EFBFBD><EFBFBD>ƽ<C6BD><E1B9B9><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
m_archive << actionCount;
// д<><D0B4> Action <20><><EFBFBD><EFBFBD>
m_archive.Write(actionData.data(), static_cast<UINT>(actionData.size()));
}
}
else
{
deserializeCActionItem(item);
// <20><>ȡ Action <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E9B3A4>
uint64_t count = getCountFromArchive();
for (uint64_t i = 0; i < count; i++)
{
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD> Action <20><><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
uint64_t actionCount = getCountFromArchive();
// <20><>ȡ Action <20><><EFBFBD><EFBFBD>
std::vector<char> actionData(actionCount);
m_archive.Read(actionData.data(), static_cast<UINT>(actionData.size()));
// ת<><D7AA>Ϊ 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<int64_t> ids;
deserialize(ids);
idsToPositions(item.GetDoc()->m_pXy, ids, item.m_selectionSet);
}
}
void BlobSerializer::visit(CActionModifiedMesh& item)
{
if (m_archive.IsStoring())
{
visit(static_cast<CActionModifiedItem&>(item));
}
else
{
visit(static_cast<CActionModifiedItem&>(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<int64_t> 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<int64_t> 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<int64_t> ids;
deserialize(ids);
idsToPositions(item.GetDoc()->m_pXy, ids, item.m_elements);
}
}
void BlobSerializer::visit(CAtionBackupEditCurveInName& item)
{
if (m_archive.IsStoring())
{
visit(static_cast<CActionBackupItem&>(item));
}
else
{
visit(static_cast<CActionBackupItem&>(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<char> actionData = SerializeAction(action.get());
m_archive << static_cast<uint64_t>(actionData.size());
m_archive.Write(actionData.data(), static_cast<UINT>(actionData.size()));
}
}
else
{
deserializeCActionItem(item);
uint64_t count = getCountFromArchive();
for (uint64_t i = 0; i < count; i++)
{
uint64_t actionCount = getCountFromArchive();
std::vector<char> actionData(actionCount);
m_archive.Read(actionData.data(), static_cast<UINT>(actionData.size()));
CAction* pAction = DeserializeAction(item.GetDoc(), actionData);
if (pAction != nullptr)
{
std::shared_ptr<CActionItem> pActionItem(dynamic_cast<CActionItem*>(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<CActionLayerDeleteItem&>(item));
// LayerList <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CActionLayerDeleteItem <20><><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD> CActionLayerDeleteItem <20><><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5> CLayer <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><> CActionLayerAddItem <20><>ӵ<EFBFBD><D3B5> CLayer <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>ͻ<EFBFBD>ˣ<EFBFBD><CBA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<CLayer*>(item.LayerList.GetAt(pos));
serializeCLayer(pLayer);
}
m_archive << item.m_curLayerName;
}
else
{
visit(static_cast<CActionLayerDeleteItem&>(item));
// ԭ<><D4AD>ͬ<EFBFBD>ϣ<EFBFBD><CFA3>򲹶<EFBFBD><F2B2B9B6>Ĵ<EFBFBD><C4B4><EFBFBD>
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<CActionDeleteItem&>(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<CLayer *>(item.LayerList.GetAt(pos))->GetPathName();
}
}
else
{
visit(static_cast<CActionDeleteItem&>(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)
{
// <20><>д<EFBFBD><D0B4> COne <20><><EFBFBD><EFBFBD><E9B3A4>
m_archive << static_cast<uint64_t>(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<BYTE> byteArray = SerializeCOneToByteArray(pOne);
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
m_archive << static_cast<uint64_t>(byteArray.size());
m_archive.Write(byteArray.data(), static_cast<UINT>(byteArray.size()));
}
else
{
m_archive << static_cast<uint64_t>(0);
}
}
void BlobSerializer::deserializeOwnedCOne(CXy* pXy, COne*& pOne)
{
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
uint64_t count = getCountFromArchive();
if (count != 0)
{
std::vector<BYTE> buf(count);
m_archive.Read(buf.data(), count);
std::unique_ptr<COne> 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)
{
// <20><><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ѻ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD>ˣ<EFBFBD>Ϊ<EFBFBD>˶Գƣ<D4B3><C6A3><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD>ȥ
// serializeStdString(action.GetActionName()); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD>ǰ Action <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// m_archive << action.actionTarget; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ô<EFBFBD><C3B4><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6B4A2><EFBFBD><EFBFBD> CSigamDoc <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
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<std::chrono::seconds>(timeSinceEpoch).count();
}
void BlobSerializer::deserializeCAction(CAction& action)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD>ֱ<EFBFBD>Ӵ<EFBFBD><D3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>࣬Ȼ<E0A3AC><C8BB><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򵥵<EFBFBD><F2B5A5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//std::string actionName;
//deserializeStdString(actionName);
// m_archive >> action.actionTarget; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>Ȳ<EFBFBD><C8B2><EFBFBD> CSigmaDoc <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٴ<EFBFBD><D9B4>ݸ<EFBFBD> Action<6F><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E8B4A6>
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<BYTE> 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<BYTE> serializedData(count);
m_archive.Read(serializedData.data(), static_cast<UINT>(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<int64_t>& ids, CPositionList& posList) const
{
posList.RemoveAll();
for (int64_t id : ids)
{
POSITION pos = pXy->GetPositionById(id);
if (pos != nullptr)
{
posList.AddTail(pos);
}
}
}
std::vector<int64_t> BlobSerializer::positionsToIds(CXy* pXy, const CPositionList& positions) const
{
std::vector<int64_t> 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))
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>Ӵ洢<D3B4><E6B4A2>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFB2BB>Ҫ<EFBFBD><D2AA><EFBFBD>Ǵ<EFBFBD>Сͬ<D0A1><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (pLayer->GetPathName() == layerPath)
{
return pLayer;
}
}
return false;
}
std::vector<COne*> BlobSerializer::lookupCOneByIds(CXy* pXy, const std::vector<int64_t>& ids) const
{
std::vector<COne*> 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<CLayer*> BlobSerializer::flatmapCLayer(CXy* pXy) const
{
std::vector<CLayer*> 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<CLayer*>& result) const
{
for (POSITION pLayerPos = pLayerList->GetHeadPosition(); pLayerPos != nullptr; pLayerList->GetNext(pLayerPos))
{
result.push_back(pLayerList->GetAt(pLayerPos));
}
}
std::vector<char> SerializeAction(const CAction* action)
{
const UINT KB = 1024;
const UINT MB = 1024 * KB;
CMemFile memFile(1 * MB);
CArchive archive(&memFile, CArchive::store);
// <20><>д<EFBFBD><D0B4> Action <20><><EFBFBD><EFBFBD>
std::string name = action->GetActionName();
serializeStdStringImpl(archive, name);
BlobSerializer serializer(archive);
const_cast<CAction *>(action)->accept(serializer);
archive.Close();
std::vector<char> data(memFile.GetLength());
memFile.SeekToBegin();
memFile.Read(data.data(), memFile.GetLength());
return data;
}
CAction* DeserializeAction(CSigmaDoc *pDoc, const std::vector<char>& data)
{
static std::once_flag flag;
std::call_once(flag, []()
{
ClassFactory::getInstance().registerClass<CActionAddItem>();
ClassFactory::getInstance().registerClass<CActionBackupItem>();
ClassFactory::getInstance().registerClass<CActionBackupProjectionItem>();
ClassFactory::getInstance().registerClass<CActionBackupXYItem>();
ClassFactory::getInstance().registerClass<CActionChangeColorItem>();
ClassFactory::getInstance().registerClass<CActionChangeLayerItem>();
ClassFactory::getInstance().registerClass<CActionChangeNameItem>();
ClassFactory::getInstance().registerClass<CActionComboItem>();
ClassFactory::getInstance().registerClass<CActionCurveEdit>();
ClassFactory::getInstance().registerClass<CActionCurveEdit>();
ClassFactory::getInstance().registerClass<CActionCurveEditAddPoint>();
ClassFactory::getInstance().registerClass<CActionCurveEditDeletePoint>();
ClassFactory::getInstance().registerClass<CActionCurveReversalItem>();
ClassFactory::getInstance().registerClass<CActionCutOutItem>();
ClassFactory::getInstance().registerClass<CActionDeleteItem>();
ClassFactory::getInstance().registerClass<CActionEmbellishItem>();
ClassFactory::getInstance().registerClass<CActionExchangeXYItem>();
ClassFactory::getInstance().registerClass<CActionLayerAddItem>();
ClassFactory::getInstance().registerClass<CActionLayerDeleteItem>();
ClassFactory::getInstance().registerClass<CActionLayerDragDropItem>();
ClassFactory::getInstance().registerClass<CActionLayerRenameItem>();
ClassFactory::getInstance().registerClass<CActionListItem>();
ClassFactory::getInstance().registerClass<CActionMarkDeleteItem>();
ClassFactory::getInstance().registerClass<CActionMirrorItem>();
ClassFactory::getInstance().registerClass<CActionModifiedItem>();
ClassFactory::getInstance().registerClass<CActionModifiedMesh>();
ClassFactory::getInstance().registerClass<CActionModifiedMeshItem>();
ClassFactory::getInstance().registerClass<CActionMoveItem>();
ClassFactory::getInstance().registerClass<CActionOffsetItem>();
ClassFactory::getInstance().registerClass<CActionParamReplaceItem>();
ClassFactory::getInstance().registerClass<CActionReplaceColorItem>();
ClassFactory::getInstance().registerClass<CActionReplaceNameItem>();
ClassFactory::getInstance().registerClass<CActionReverseZItem>();
ClassFactory::getInstance().registerClass<CActionScaleProperty>();
ClassFactory::getInstance().registerClass<CActionSortItem>();
});
CMemFile memFile((BYTE*)(data.data()), static_cast<UINT>(data.size()));
CArchive archive(&memFile, CArchive::load);
std::string name;
deserializeStdStringImpl(archive, name);
CAction *action = reinterpret_cast<CAction *>(ClassFactory::getInstance().createObject(name));
if (action != nullptr)
{
// <20><><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>ʱ<EFBFBD>򣬶<EFBFBD><F2A3ACB6><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>õ<EFBFBD> Doc <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> id<69><64>postion <20>Ⱥܶණ<DCB6><E0B6AB><EFBFBD>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>
action->SetActionTarget(pDoc);
BlobSerializer serializer(archive);
action->accept(serializer);
}
return action;
}