diff --git a/include/scene/node.h b/include/scene/node.h index ee10db9..e245f14 100644 --- a/include/scene/node.h +++ b/include/scene/node.h @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace extra2d { @@ -315,6 +316,7 @@ private: bool visible_ = true; Node* parent_ = nullptr; std::vector> children_; + std::unordered_map childIndices_; std::vector> components_; TransformComponent* transform_ = nullptr; }; diff --git a/include/scene/scene.h b/include/scene/scene.h index dea5f9b..a4979c9 100644 --- a/include/scene/scene.h +++ b/include/scene/scene.h @@ -3,6 +3,7 @@ #include #include #include +#include #include namespace extra2d { @@ -115,6 +116,7 @@ public: protected: std::vector> rootNodes_; + std::unordered_map rootNodeIndices_; CameraComponent* mainCamera_ = nullptr; bool entered_ = false; }; diff --git a/src/scene/node.cpp b/src/scene/node.cpp index f216b1e..3a69f2d 100644 --- a/src/scene/node.cpp +++ b/src/scene/node.cpp @@ -29,6 +29,7 @@ Node::~Node() { void Node::addChild(Ptr child) { if (!child || child.get() == this) return; + if (childIndices_.find(child.get()) != childIndices_.end()) return; // 从原父节点移除 if (child->parent_) { @@ -36,18 +37,25 @@ void Node::addChild(Ptr child) { } child->parent_ = this; + childIndices_[child.get()] = children_.size(); children_.push_back(child); } void Node::removeChild(Node* child) { if (!child) return; - for (auto it = children_.begin(); it != children_.end(); ++it) { - if (it->get() == child) { - child->parent_ = nullptr; - children_.erase(it); - return; - } + auto indexIt = childIndices_.find(child); + if (indexIt == childIndices_.end()) { + return; + } + + const size_t removeIndex = indexIt->second; + child->parent_ = nullptr; + children_.erase(children_.begin() + removeIndex); + childIndices_.erase(indexIt); + + for (size_t i = removeIndex; i < children_.size(); ++i) { + childIndices_[children_[i].get()] = i; } } @@ -62,6 +70,7 @@ void Node::removeAllChildren() { child->parent_ = nullptr; } children_.clear(); + childIndices_.clear(); } // ======================================== diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index eb9b879..ffd8487 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -16,21 +16,29 @@ Scene::~Scene() { void Scene::addChild(Ptr node) { if (!node) return; + if (rootNodeIndices_.find(node.get()) != rootNodeIndices_.end()) return; node->removeFromParent(); node->onEnter(); + rootNodeIndices_[node.get()] = rootNodes_.size(); rootNodes_.push_back(node); } void Scene::removeChild(Node* node) { if (!node) return; - for (auto it = rootNodes_.begin(); it != rootNodes_.end(); ++it) { - if (it->get() == node) { - node->onExit(); - rootNodes_.erase(it); - return; - } + auto indexIt = rootNodeIndices_.find(node); + if (indexIt == rootNodeIndices_.end()) { + return; + } + + const size_t removeIndex = indexIt->second; + node->onExit(); + rootNodes_.erase(rootNodes_.begin() + removeIndex); + rootNodeIndices_.erase(indexIt); + + for (size_t i = removeIndex; i < rootNodes_.size(); ++i) { + rootNodeIndices_[rootNodes_[i].get()] = i; } } @@ -39,6 +47,7 @@ void Scene::removeAllChildren() { node->onExit(); } rootNodes_.clear(); + rootNodeIndices_.clear(); } Node* Scene::findNode(const std::string& name) {