Extra2D/include/scene/node.h

323 lines
6.5 KiB
C
Raw Normal View History

#pragma once
#include <scene/component.h>
#include <types/math/transform.h>
#include <types/math/vec2.h>
#include <types/math/mat4.h>
#include <types/ptr/intrusive_ptr.h>
#include <string>
#include <vector>
namespace extra2d {
// 前向声明
class Scene;
class TransformComponent;
/**
* @brief
*
*
*/
class Node : public RefCounted {
public:
/**
* @brief
*/
Node();
/**
* @brief
*/
~Node() override;
// 禁止拷贝
Node(const Node&) = delete;
Node& operator=(const Node&) = delete;
// ========================================
// 层级关系
// ========================================
/**
* @brief
* @param child
*/
void addChild(Ptr<Node> child);
/**
* @brief
* @param child
*/
void removeChild(Node* child);
/**
* @brief
*/
void removeFromParent();
/**
* @brief
* @return
*/
Node* getParent() const { return parent_; }
/**
* @brief
* @return
*/
const std::vector<Ptr<Node>>& getChildren() const { return children_; }
/**
* @brief
*/
void removeAllChildren();
// ========================================
// 组件管理
// ========================================
/**
* @brief
* @tparam T
* @param component
* @return
*/
template<typename T>
T* addComponent(Ptr<T> component) {
static_assert(std::is_base_of<Component, T>::value, "T must be derived from Component");
T* ptr = component.get();
components_.push_back(component);
ptr->onAttach(this);
// 如果是 TransformComponent缓存它
if (auto* transform = dynamic_cast<TransformComponent*>(ptr)) {
transform_ = transform;
}
return ptr;
}
/**
* @brief
* @tparam T
* @return nullptr
*/
template<typename T>
T* getComponent() const {
for (const auto& comp : components_) {
if (auto* ptr = dynamic_cast<T*>(comp.get())) {
return ptr;
}
}
return nullptr;
}
/**
* @brief
* @tparam T
*/
template<typename T>
void removeComponent() {
for (auto it = components_.begin(); it != components_.end(); ++it) {
if (dynamic_cast<T*>(it->get())) {
(*it)->onDetach();
components_.erase(it);
return;
}
}
}
// ========================================
// 变换便捷接口
// ========================================
/**
* @brief
* @param pos
*/
void setPosition(const Vec2& pos);
/**
* @brief
* @param x X坐标
* @param y Y坐标
*/
void setPosition(float x, float y);
/**
* @brief
* @return
*/
Vec2 getPosition() const;
/**
* @brief
* @param rot
*/
void setRotation(float rot);
/**
* @brief
* @return
*/
float getRotation() const;
/**
* @brief
* @param scale
*/
void setScale(const Vec2& scale);
/**
* @brief
* @param scale
*/
void setScale(float scale);
/**
* @brief
* @param x X轴缩放
* @param y Y轴缩放
*/
void setScale(float x, float y);
/**
* @brief
* @return
*/
Vec2 getScale() const;
/**
* @brief
* @param size
*/
void setSize(const Vec2& size);
/**
* @brief
* @param width
* @param height
*/
void setSize(float width, float height);
/**
* @brief
* @return
*/
Vec2 getSize() const;
/**
* @brief
* @param anchor [0,1]
*/
void setAnchor(const Vec2& anchor);
/**
* @brief
* @param x X锚点
* @param y Y锚点
*/
void setAnchor(float x, float y);
/**
* @brief
* @return
*/
Vec2 getAnchor() const;
/**
* @brief
* @return
*/
Transform getWorldTransform() const;
/**
* @brief
* @return
*/
Mat4 getWorldMatrix() const;
// ========================================
// 属性
// ========================================
/**
* @brief
* @param name
*/
void setName(const std::string& name) { name_ = name; }
/**
* @brief
* @return
*/
const std::string& getName() const { return name_; }
/**
* @brief
* @param tag
*/
void setTag(int32 tag) { tag_ = tag; }
/**
* @brief
* @return
*/
int32 getTag() const { return tag_; }
/**
* @brief
* @param visible
*/
void setVisible(bool visible) { visible_ = visible; }
/**
* @brief
* @return
*/
bool isVisible() const { return visible_; }
/**
* @brief TransformComponent
* @return TransformComponent
*/
TransformComponent* getTransform() const { return transform_; }
// ========================================
// 生命周期
// ========================================
/**
* @brief
*/
void onEnter();
/**
* @brief
*/
void onExit();
/**
* @brief
* @param dt
*/
void update(float dt);
/**
* @brief
*/
void render();
private:
std::string name_;
int32 tag_ = 0;
bool visible_ = true;
Node* parent_ = nullptr;
std::vector<Ptr<Node>> children_;
std::vector<Ptr<Component>> components_;
TransformComponent* transform_ = nullptr;
};
} // namespace extra2d