Skip to content

Commit

Permalink
#6107: Implement recursion detection when setting parent layers
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Oct 1, 2022
1 parent 63ba87c commit 919d108
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
28 changes: 28 additions & 0 deletions radiantcore/layers/LayerManager.cpp
Expand Up @@ -393,13 +393,41 @@ void LayerManager::setParentLayer(int childLayerId, int parentLayerId)
throw std::invalid_argument("Cannot assign a layer as parent of itself");
}

// Detect recursions, if any parent layer has this layer in its hierarchy, we should throw
if (layerIsChildOf(parentLayerId, childLayerId))
{
throw std::invalid_argument("This relationship change would result in a recursion");
}

if (_layerParentIds.at(childLayerId) != parentLayerId)
{
_layerParentIds.at(childLayerId) = parentLayerId;
_layerHierarchyChangedSignal.emit();
}
}

bool LayerManager::layerIsChildOf(int candidateLayerId, int parentLayerId)
{
// Nothing is a parent of the null layer
if (candidateLayerId == NO_PARENT_ID || parentLayerId == NO_PARENT_ID)
{
return false;
}

// Check the hierarchy of the candidate
for (int immediateParentId = getParentLayer(candidateLayerId);
immediateParentId != NO_PARENT_ID;
immediateParentId = getParentLayer(immediateParentId))
{
if (immediateParentId == parentLayerId)
{
return true;
}
}

return false;
}

sigc::signal<void> LayerManager::signal_layersChanged()
{
return _layersChangedSignal;
Expand Down
3 changes: 3 additions & 0 deletions radiantcore/layers/LayerManager.h
Expand Up @@ -136,6 +136,9 @@ class LayerManager :

// Returns the lowest unused layer ID
int getLowestUnusedLayerID();

// Returns true if the given candidateLayerId is a child of the given parentLayer
bool layerIsChildOf(int candidateLayerId, int parentLayerId);
};

} // namespace scene

0 comments on commit 919d108

Please sign in to comment.