Skip to content

Commit

Permalink
Added the 'preserveOrder' argument to SceneGraph::Detach to allow fas…
Browse files Browse the repository at this point in the history
…ter erases from very long vectors.

Added some comments.
  • Loading branch information
apanteleev committed Sep 4, 2024
1 parent e427373 commit 44004ad
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
18 changes: 16 additions & 2 deletions include/donut/engine/SceneGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -556,11 +556,25 @@ namespace donut::engine
[[nodiscard]] bool HasPendingStructureChanges() const { return m_Root && (m_Root->m_Dirty & SceneGraphNode::DirtyFlags::SubgraphStructure) != 0; }
[[nodiscard]] bool HasPendingTransformChanges() const { return m_Root && (m_Root->m_Dirty & (SceneGraphNode::DirtyFlags::SubgraphTransforms | SceneGraphNode::DirtyFlags::SubgraphPrevTransforms)) != 0; }

// Replaces the current root node of the graph with the new one.
std::shared_ptr<SceneGraphNode> SetRootNode(const std::shared_ptr<SceneGraphNode>& root);

// Attaches a node and its subgraph to the parent.
// If the node is already attached to this or other graph, a deep copy of the subgraph is made first.
std::shared_ptr<SceneGraphNode> Attach(const std::shared_ptr<SceneGraphNode>& parent, const std::shared_ptr<SceneGraphNode>& child);

// Creates a node holding the provided leaf and attaches it to the parent.
std::shared_ptr<SceneGraphNode> AttachLeafNode(const std::shared_ptr<SceneGraphNode>& parent, const std::shared_ptr<SceneGraphLeaf>& leaf);
std::shared_ptr<SceneGraphNode> Detach(const std::shared_ptr<SceneGraphNode>& node);


// Removes the node and its subgraph from the graph.
// When preserveOrder is 'false', the order of node's siblings may be changed during this operation to improve performance.
std::shared_ptr<SceneGraphNode> Detach(const std::shared_ptr<SceneGraphNode>& node, bool preserveOrder = false);

// Finds a node whose path (sequence of nested node names) matches the provided path,
// relative to the 'context' node or the root if 'context' is NULL.
// If the path starts with / the search starts at the root, and the 'context' parameter is ignored.
// Parent references with .. are supported.
// If multiple nodes within one parent have the same name matching that component of the path, only the first node will be considered.
[[nodiscard]] std::shared_ptr<SceneGraphNode> FindNode(const std::filesystem::path& path, SceneGraphNode* context = nullptr) const;

void Refresh(uint32_t frameIndex);
Expand Down
18 changes: 14 additions & 4 deletions src/engine/SceneGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,7 @@ std::shared_ptr<SceneGraphNode> SceneGraph::AttachLeafNode(const std::shared_ptr
return Attach(parent, node);
}

std::shared_ptr<SceneGraphNode> SceneGraph::Detach(const std::shared_ptr<SceneGraphNode>& node)
std::shared_ptr<SceneGraphNode> SceneGraph::Detach(const std::shared_ptr<SceneGraphNode>& node, bool preserveOrder)
{
auto nodeGraph = node->m_Graph.lock();

Expand All @@ -869,12 +869,22 @@ std::shared_ptr<SceneGraphNode> SceneGraph::Detach(const std::shared_ptr<SceneGr

node->m_Parent->PropagateDirtyFlags(SceneGraphNode::DirtyFlags::SubgraphStructure);

auto it = std::find(siblings.begin(), siblings.end(), node);
auto found = std::find(siblings.begin(), siblings.end(), node);

// ensure that the parent actually contains this node
if (it != siblings.end())
if (found != siblings.end())
{
siblings.erase(it);
auto last = siblings.end() - 1;

if (preserveOrder || found == last)
{
siblings.erase(found);
}
else
{
std::swap(*found, *last);
siblings.erase(last);
}
}
else
{
Expand Down

0 comments on commit 44004ad

Please sign in to comment.