/
MergeOperation.cpp
107 lines (88 loc) · 3.01 KB
/
MergeOperation.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "MergeOperation.h"
#include "MergeAction.h"
namespace scene
{
namespace merge
{
void MergeOperation::addAction(const MergeAction::Ptr& action)
{
_actions.push_back(action);
}
void MergeOperation::createActionsForKeyValueDiff(const ComparisonResult::KeyValueDifference& difference,
const scene::INodePtr& targetEntity)
{
switch (difference.type)
{
case ComparisonResult::KeyValueDifference::Type::KeyValueAdded:
addAction(std::make_shared<AddEntityKeyValueAction>(targetEntity, difference.key, difference.value));
break;
case ComparisonResult::KeyValueDifference::Type::KeyValueRemoved:
addAction(std::make_shared<RemoveEntityKeyValueAction>(targetEntity, difference.key));
break;
case ComparisonResult::KeyValueDifference::Type::KeyValueChanged:
addAction(std::make_shared<ChangeEntityKeyValueAction>(targetEntity, difference.key, difference.value));
break;
}
}
void MergeOperation::createActionsForPrimitiveDiff(const ComparisonResult::PrimitiveDifference& difference,
const scene::INodePtr& targetEntity)
{
switch (difference.type)
{
case ComparisonResult::PrimitiveDifference::Type::PrimitiveAdded:
addAction(std::make_shared<AddChildAction>(difference.node, targetEntity));
break;
case ComparisonResult::PrimitiveDifference::Type::PrimitiveRemoved:
addAction(std::make_shared<RemoveChildAction>(difference.node));
break;
}
}
void MergeOperation::createActionsForEntity(const ComparisonResult::EntityDifference& difference)
{
switch (difference.type)
{
case ComparisonResult::EntityDifference::Type::EntityMissingInSource:
addAction(std::make_shared<RemoveEntityAction>(difference.baseNode));
break;
case ComparisonResult::EntityDifference::Type::EntityMissingInBase:
addAction(std::make_shared<AddEntityAction>(difference.sourceNode, _baseRoot));
break;
case ComparisonResult::EntityDifference::Type::EntityPresentButDifferent:
{
for (const auto& keyValueDiff : difference.differingKeyValues)
{
createActionsForKeyValueDiff(keyValueDiff, difference.baseNode);
}
for (const auto& primitiveDiff : difference.differingChildren)
{
createActionsForPrimitiveDiff(primitiveDiff, difference.baseNode);
}
break;
}
};
}
MergeOperation::Ptr MergeOperation::CreateFromComparisonResult(const ComparisonResult& result)
{
auto operation = std::make_shared<MergeOperation>(result.getSourceRootNode(), result.getBaseRootNode());
for (const auto& difference : result.differingEntities)
{
operation->createActionsForEntity(difference);
}
return operation;
}
void MergeOperation::applyActions()
{
for (auto& action : _actions)
{
action->applyChanges();
}
}
void MergeOperation::foreachAction(const std::function<void(const MergeAction::Ptr&)>& visitor)
{
for (const auto& action : _actions)
{
visitor(action);
}
}
}
}