/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/internal/update/manager/scene-graph-traveler.h>
// INTERNAL INCLUDES
+#include <dali/internal/update/manager/update-manager.h>
#include <dali/internal/update/nodes/node.h>
namespace Dali
{
namespace Internal
{
-SceneGraphTraveler::SceneGraphTraveler(SceneGraph::Node& rootNode)
-: mRootNode(rootNode),
- mNodeStack{},
+SceneGraphTraveler::SceneGraphTraveler(SceneGraph::UpdateManager& updateManager, SceneGraph::Node& rootNode)
+: SceneGraphTravelerInterface(updateManager),
+ mRootNode(rootNode),
mInvalidated{false}
{
mRootNode.AddObserver(*this);
{
SceneGraph::Node* node = nullptr;
- // Find node in cached map
- auto iter = mTravledNodeMap.find(id);
- if(iter != mTravledNodeMap.end())
- {
- node = iter->second;
- }
- else
+ if(!mInvalidated)
{
- while(!FullSearched())
+ // Find node in cached map
+ auto iter = mTravledNodeMap.find(id);
+ if(iter != mTravledNodeMap.end())
+ {
+ node = iter->second;
+ }
+ else
{
- SceneGraph::Node& currentNode = GetCurrentNode();
- IterateNextNode();
+ SceneGraph::Node* currentNode = mUpdateManager.GetNodePointerById(id);
+
+ bool isNodeUnderRootNode = false;
+
+ std::vector<std::pair<uint32_t, SceneGraph::Node*>> nodeStack;
- // Cache traveled node and id pair.
- mTravledNodeMap.insert({currentNode.mId, ¤tNode});
+ SceneGraph::Node* iterateNode = currentNode;
- if(currentNode.mId == id)
+ while(iterateNode)
{
- node = ¤tNode;
- break;
+ uint32_t iterateNodeId = iterateNode->GetId();
+
+ auto iter = mTravledNodeMap.find(iterateNodeId);
+ if(iter != mTravledNodeMap.end())
+ {
+ // iter->second could be nullptr if it was failed item before.
+ if(iter->second != nullptr)
+ {
+ isNodeUnderRootNode = true;
+ }
+ break;
+ }
+ nodeStack.push_back({iterateNodeId, iterateNode});
+
+ // Go to parent.
+ iterateNode = iterateNode->GetParent();
+ }
+
+ // Store current found result.
+ for(auto&& idPair : nodeStack)
+ {
+ mTravledNodeMap.insert({idPair.first, isNodeUnderRootNode ? idPair.second : nullptr});
+ }
+
+ if(isNodeUnderRootNode)
+ {
+ node = currentNode;
}
}
}
{
mTravledNodeMap.clear();
mTravledNodeMap.rehash(0u); ///< Note : We have to reduce capacity of hash map. Without this line, clear() API will be slow downed.
- mNodeStack.clear();
if(!mInvalidated)
{
- mNodeStack.emplace_back(&mRootNode, 0u);
- }
-}
-
-bool SceneGraphTraveler::FullSearched() const
-{
- return mNodeStack.empty();
-}
-
-SceneGraph::Node& SceneGraphTraveler::GetCurrentNode()
-{
- DALI_ASSERT_DEBUG(!FullSearched());
-
- return *(mNodeStack.back().first);
-}
-
-void SceneGraphTraveler::IterateNextNode()
-{
- while(!mNodeStack.empty())
- {
- auto& currentNode = *(mNodeStack.back().first);
- uint32_t currentChildIndex = mNodeStack.back().second;
-
- if(currentNode.GetChildren().Count() <= currentChildIndex)
- {
- mNodeStack.pop_back();
- continue;
- }
- else
- {
- // Stack current child, and increase index
- ++mNodeStack.back().second;
- mNodeStack.emplace_back(currentNode.GetChildren()[currentChildIndex], 0u);
- break;
- }
+ mTravledNodeMap.insert({mRootNode.GetId(), &mRootNode});
}
}