Navigation Menu

Skip to content

Commit

Permalink
#5623: Add child node merge actions
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed May 24, 2021
1 parent 253e95e commit a95f159
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 21 deletions.
2 changes: 2 additions & 0 deletions libs/scene/merge/MergeAction.h
Expand Up @@ -15,6 +15,8 @@ enum class ActionType
AddKeyValue,
RemoveKeyValue,
ChangeKeyValue,
AddChildNode,
RemoveChildNode,
};

// Represents a single step of a merge process, like adding a brush,
Expand Down
98 changes: 78 additions & 20 deletions libs/scene/merge/MergeOperation.cpp
Expand Up @@ -10,44 +10,64 @@ namespace scene
namespace merge
{

class RemoveEntityAction :
class RemoveNodeFromParentAction :
public MergeAction
{
private:
scene::INodePtr _node;
scene::INodePtr _child;

public:
RemoveEntityAction(const scene::INodePtr& node) :
MergeAction(ActionType::RemoveEntity),
_node(node)
protected:
RemoveNodeFromParentAction(const scene::INodePtr& child, ActionType type) :
MergeAction(type),
_child(child)
{
assert(_node);
assert(_child);
}

public:
void applyChanges() override
{
removeNodeFromParent(_node);
removeNodeFromParent(_child);
}
};

class AddEntityAction :
class RemoveChildAction :
public RemoveNodeFromParentAction
{
public:
RemoveChildAction(const scene::INodePtr& node) :
RemoveNodeFromParentAction(node, ActionType::RemoveChildNode)
{}
};

class RemoveEntityAction :
public RemoveNodeFromParentAction
{
public:
RemoveEntityAction(const scene::INodePtr& node) :
RemoveNodeFromParentAction(node, ActionType::RemoveEntity)
{}
};

class AddCloneToParentAction :
public MergeAction
{
private:
scene::INodePtr _node;
scene::IMapRootNodePtr _targetRoot;
scene::INodePtr _parent;

public:
// Will add the given node to the targetRoot when applyChanges() is called
AddEntityAction(const scene::INodePtr& node, const scene::IMapRootNodePtr& targetRoot) :
MergeAction(ActionType::AddEntity),
protected:
// Will add the given node to the parent when applyChanges() is called
AddCloneToParentAction(const scene::INodePtr& node, const scene::INodePtr& parent, ActionType type) :
MergeAction(type),
_node(node),
_targetRoot(targetRoot)
_parent(parent)
{
assert(_node);
assert(Node_getCloneable(node));
}

public:
void applyChanges() override
{
// No post-clone callback since we don't care about selection groups right now
Expand All @@ -58,10 +78,28 @@ class AddEntityAction :
throw std::runtime_error("Node " + _node->name() + " is not cloneable");
}

addNodeToContainer(cloned, _targetRoot);
addNodeToContainer(cloned, _parent);
}
};

class AddEntityAction :
public AddCloneToParentAction
{
public:
AddEntityAction(const scene::INodePtr& node, const scene::IMapRootNodePtr& targetRoot) :
AddCloneToParentAction(node, targetRoot, ActionType::AddEntity)
{}
};

class AddChildAction :
public AddCloneToParentAction
{
public:
AddChildAction(const scene::INodePtr& node, const scene::INodePtr& parent) :
AddCloneToParentAction(node, parent, ActionType::AddChildNode)
{}
};

class SetEntityKeyValueAction :
public MergeAction
{
Expand Down Expand Up @@ -129,20 +167,35 @@ void MergeOperation::addAction(const MergeAction::Ptr& action)
}

void MergeOperation::createActionsForKeyValueDiff(const ComparisonResult::KeyValueDifference& difference,
const scene::INodePtr& targetNode)
const scene::INodePtr& targetEntity)
{
switch (difference.type)
{
case ComparisonResult::KeyValueDifference::Type::KeyValueAdded:
addAction(std::make_shared<AddEntityKeyValueAction>(targetNode, difference.key, difference.value));
addAction(std::make_shared<AddEntityKeyValueAction>(targetEntity, difference.key, difference.value));
break;

case ComparisonResult::KeyValueDifference::Type::KeyValueRemoved:
addAction(std::make_shared<RemoveEntityKeyValueAction>(targetNode, difference.key));
addAction(std::make_shared<RemoveEntityKeyValueAction>(targetEntity, difference.key));
break;

case ComparisonResult::KeyValueDifference::Type::KeyValueChanged:
addAction(std::make_shared<ChangeEntityKeyValueAction>(targetNode, difference.key, difference.value));
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;
}
}
Expand All @@ -165,6 +218,11 @@ void MergeOperation::createActionsForEntity(const ComparisonResult::EntityDiffer
{
createActionsForKeyValueDiff(keyValueDiff, difference.baseNode);
}

for (const auto& primitiveDiff : difference.differingChildren)
{
createActionsForPrimitiveDiff(primitiveDiff, difference.baseNode);
}
break;
}
};
Expand Down
4 changes: 3 additions & 1 deletion libs/scene/merge/MergeOperation.h
Expand Up @@ -36,7 +36,9 @@ class MergeOperation
private:
void createActionsForEntity(const ComparisonResult::EntityDifference& difference);
void createActionsForKeyValueDiff(const ComparisonResult::KeyValueDifference& difference,
const scene::INodePtr& targetNode);
const scene::INodePtr& targetEntity);
void createActionsForPrimitiveDiff(const ComparisonResult::PrimitiveDifference& difference,
const scene::INodePtr& targetEntity);
};

}
Expand Down

0 comments on commit a95f159

Please sign in to comment.