Extra2D/src/scene/scene.cpp

138 lines
2.7 KiB
C++

#include <scene/scene.h>
#include <scene/components/camera_component.h>
#include <queue>
namespace extra2d {
Scene::Scene() {
}
Scene::~Scene() {
if (entered_) {
onExit();
}
removeAllChildren();
}
void Scene::addChild(Ptr<Node> 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;
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;
}
}
void Scene::removeAllChildren() {
for (auto& node : rootNodes_) {
node->onExit();
}
rootNodes_.clear();
rootNodeIndices_.clear();
}
Node* Scene::findNode(const std::string& name) {
// 广度优先搜索
std::queue<Node*> queue;
for (auto& node : rootNodes_) {
queue.push(node.get());
}
while (!queue.empty()) {
Node* current = queue.front();
queue.pop();
if (current->getName() == name) {
return current;
}
for (auto& child : current->getChildren()) {
queue.push(child.get());
}
}
return nullptr;
}
Node* Scene::findNodeByTag(int32 tag) {
// 广度优先搜索
std::queue<Node*> queue;
for (auto& node : rootNodes_) {
queue.push(node.get());
}
while (!queue.empty()) {
Node* current = queue.front();
queue.pop();
if (current->getTag() == tag) {
return current;
}
for (auto& child : current->getChildren()) {
queue.push(child.get());
}
}
return nullptr;
}
void Scene::setMainCamera(CameraComponent* camera) {
mainCamera_ = camera;
}
void Scene::onEnter() {
entered_ = true;
// 通知所有根节点
for (auto& node : rootNodes_) {
node->onEnter();
}
}
void Scene::onExit() {
entered_ = false;
// 通知所有根节点
for (auto& node : rootNodes_) {
node->onExit();
}
}
void Scene::update(float dt) {
// 更新所有根节点
for (auto& node : rootNodes_) {
node->update(dt);
}
}
void Scene::render() {
// 渲染所有根节点
for (auto& node : rootNodes_) {
node->render();
}
}
} // namespace extra2d