217 lines
4.5 KiB
C++
217 lines
4.5 KiB
C++
#include <scene/node.h>
|
||
#include <scene/components/transform_component.h>
|
||
|
||
namespace extra2d {
|
||
|
||
Node::Node() {
|
||
// 自动添加 TransformComponent
|
||
auto transform = makePtr<TransformComponent>();
|
||
transform_ = transform.get();
|
||
components_.push_back(transform);
|
||
transform_->onAttach(this);
|
||
}
|
||
|
||
Node::~Node() {
|
||
// 先分离所有组件
|
||
for (auto& comp : components_) {
|
||
comp->onDetach();
|
||
}
|
||
components_.clear();
|
||
|
||
// 移除所有子节点
|
||
removeAllChildren();
|
||
|
||
// 从父节点移除
|
||
if (parent_) {
|
||
parent_->removeChild(this);
|
||
}
|
||
}
|
||
|
||
void Node::addChild(Ptr<Node> child) {
|
||
if (!child || child.get() == this) return;
|
||
if (childIndices_.find(child.get()) != childIndices_.end()) return;
|
||
|
||
// 从原父节点移除
|
||
if (child->parent_) {
|
||
child->parent_->removeChild(child.get());
|
||
}
|
||
|
||
child->parent_ = this;
|
||
childIndices_[child.get()] = children_.size();
|
||
children_.push_back(child);
|
||
}
|
||
|
||
void Node::removeChild(Node* child) {
|
||
if (!child) 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;
|
||
}
|
||
}
|
||
|
||
void Node::removeFromParent() {
|
||
if (parent_) {
|
||
parent_->removeChild(this);
|
||
}
|
||
}
|
||
|
||
void Node::removeAllChildren() {
|
||
for (auto& child : children_) {
|
||
child->parent_ = nullptr;
|
||
}
|
||
children_.clear();
|
||
childIndices_.clear();
|
||
}
|
||
|
||
// ========================================
|
||
// 变换便捷接口
|
||
// ========================================
|
||
|
||
void Node::setPosition(const Vec2& pos) {
|
||
if (transform_) {
|
||
transform_->setPosition(pos);
|
||
}
|
||
}
|
||
|
||
void Node::setPosition(float x, float y) {
|
||
setPosition(Vec2(x, y));
|
||
}
|
||
|
||
Vec2 Node::getPosition() const {
|
||
return transform_ ? transform_->getPosition() : Vec2(0, 0);
|
||
}
|
||
|
||
void Node::setRotation(float rot) {
|
||
if (transform_) {
|
||
transform_->setRotation(rot);
|
||
}
|
||
}
|
||
|
||
float Node::getRotation() const {
|
||
return transform_ ? transform_->getRotation() : 0.0f;
|
||
}
|
||
|
||
void Node::setScale(const Vec2& scale) {
|
||
if (transform_) {
|
||
transform_->setScale(scale);
|
||
}
|
||
}
|
||
|
||
void Node::setScale(float scale) {
|
||
setScale(Vec2(scale, scale));
|
||
}
|
||
|
||
void Node::setScale(float x, float y) {
|
||
setScale(Vec2(x, y));
|
||
}
|
||
|
||
Vec2 Node::getScale() const {
|
||
return transform_ ? transform_->getScale() : Vec2(1, 1);
|
||
}
|
||
|
||
void Node::setSize(const Vec2& size) {
|
||
if (transform_) {
|
||
transform_->setSize(size);
|
||
}
|
||
}
|
||
|
||
void Node::setSize(float width, float height) {
|
||
setSize(Vec2(width, height));
|
||
}
|
||
|
||
Vec2 Node::getSize() const {
|
||
return transform_ ? transform_->getSize() : Vec2(100, 100);
|
||
}
|
||
|
||
void Node::setAnchor(const Vec2& anchor) {
|
||
if (transform_) {
|
||
transform_->setAnchor(anchor);
|
||
}
|
||
}
|
||
|
||
void Node::setAnchor(float x, float y) {
|
||
setAnchor(Vec2(x, y));
|
||
}
|
||
|
||
Vec2 Node::getAnchor() const {
|
||
return transform_ ? transform_->getAnchor() : Vec2(0.5f, 0.5f);
|
||
}
|
||
|
||
Transform Node::getWorldTransform() const {
|
||
return transform_ ? transform_->getWorldTransform() : Transform();
|
||
}
|
||
|
||
Mat4 Node::getWorldMatrix() const {
|
||
return transform_ ? transform_->getWorldMatrix() : Mat4();
|
||
}
|
||
|
||
// ========================================
|
||
// 生命周期
|
||
// ========================================
|
||
|
||
void Node::onEnter() {
|
||
// 通知所有组件
|
||
for (auto& comp : components_) {
|
||
// 组件没有 onEnter,可以在这里扩展
|
||
}
|
||
|
||
// 递归通知子节点
|
||
for (auto& child : children_) {
|
||
child->onEnter();
|
||
}
|
||
}
|
||
|
||
void Node::onExit() {
|
||
// 递归通知子节点
|
||
for (auto& child : children_) {
|
||
child->onExit();
|
||
}
|
||
|
||
// 通知所有组件
|
||
for (auto& comp : components_) {
|
||
// 组件没有 onExit,可以在这里扩展
|
||
}
|
||
}
|
||
|
||
void Node::update(float dt) {
|
||
for (auto& comp : components_) {
|
||
if (comp.get() != transform_ && comp->isEnabled()) {
|
||
comp->update(dt);
|
||
}
|
||
}
|
||
|
||
for (auto& child : children_) {
|
||
child->update(dt);
|
||
}
|
||
}
|
||
|
||
void Node::render() {
|
||
if (!visible_) return;
|
||
|
||
if (children_.empty() && components_.size() == 1) {
|
||
return;
|
||
}
|
||
|
||
for (auto& comp : components_) {
|
||
if (comp.get() != transform_ && comp->isEnabled()) {
|
||
comp->render();
|
||
}
|
||
}
|
||
|
||
for (auto& child : children_) {
|
||
child->render();
|
||
}
|
||
}
|
||
|
||
} // namespace extra2d
|