Extra2D/Extra2D/include/extra2d/node/node.h

177 lines
4.2 KiB
C++

#pragma once
#include <extra2d/core/types.h>
#include <extra2d/core/math_types.h>
#include <extra2d/core/math_extended.h>
#include <algorithm>
#include <vector>
#include <memory>
#include <functional>
namespace extra2d {
class Node;
class Comp;
class Act;
namespace Anchor {
constexpr Vec2 BottomLeft = Vec2(0.0f, 0.0f);
constexpr Vec2 Bottom = Vec2(0.5f, 0.0f);
constexpr Vec2 BottomRight = Vec2(1.0f, 0.0f);
constexpr Vec2 Left = Vec2(0.0f, 0.5f);
constexpr Vec2 Center = Vec2(0.5f, 0.5f);
constexpr Vec2 Right = Vec2(1.0f, 0.5f);
constexpr Vec2 TopLeft = Vec2(0.0f, 1.0f);
constexpr Vec2 Top = Vec2(0.5f, 1.0f);
constexpr Vec2 TopRight = Vec2(1.0f, 1.0f);
}
class Comp {
public:
virtual ~Comp() = default;
virtual const char* type() const = 0;
virtual void onAttach(Node* o) { owner_ = o; }
virtual void onDetach() { owner_ = nullptr; }
virtual void onEnable() {}
virtual void onDisable() {}
virtual void update(f32 dt) {}
virtual void lateUpdate(f32 dt) {}
Node* owner() const { return owner_; }
bool enabled() const { return enabled_; }
void setEnabled(bool e);
protected:
Node* owner_ = nullptr;
bool enabled_ = true;
};
class Node : public std::enable_shared_from_this<Node> {
friend class SceneGraph;
public:
virtual ~Node();
Vec2 pos = Vec2(0, 0);
Vec2 scale = Vec2(1, 1);
f32 rot = 0.0f;
Vec2 anchor = Vec2(0.5f, 0.5f);
void setAnchor(f32 x, f32 y) { anchor = Vec2(x, y); }
void setAnchor(const Vec2& a) { anchor = a; }
void setPos(f32 x, f32 y) { pos = Vec2(x, y); }
void setPos(const Vec2& p) { pos = p; }
void setScale(f32 x, f32 y) { scale = Vec2(x, y); }
void setScale(const Vec2& s) { scale = s; }
void setScale(f32 s) { scale = Vec2(s, s); }
void setRot(f32 r) { rot = r; }
Mat3 local() const;
Mat3 world() const;
Mat4 world4x4() const;
Vec2 worldPos() const;
f32 worldRot() const;
Vec2 worldScale() const;
template<typename T, typename... Args>
T* add(Args&&... args) {
auto c = std::make_unique<T>(std::forward<Args>(args)...);
T* p = c.get();
addInternal(std::move(c));
return p;
}
template<typename T>
T* get() {
for (auto& c : comps_) {
if (auto* p = dynamic_cast<T*>(c.get())) {
return p;
}
}
return nullptr;
}
template<typename T>
const T* get() const {
for (auto& c : comps_) {
if (auto* p = dynamic_cast<const T*>(c.get())) {
return p;
}
}
return nullptr;
}
template<typename T>
void remove() {
comps_.erase(
std::remove_if(comps_.begin(), comps_.end(),
[](const auto& c) { return dynamic_cast<T*>(c.get()) != nullptr; }),
comps_.end()
);
}
void updateComps(f32 dt);
void lateUpdateComps(f32 dt);
void addChild(Ref<Node> child);
void removeChild(Ref<Node> child);
void removeFromParent();
Node* parent() const { return parent_; }
const std::vector<Ref<Node>>& children() const { return children_; }
virtual void onInit() {}
virtual void onUpdate(f32 dt) {}
virtual void onRender() {}
const std::string& name() const { return name_; }
void setName(const std::string& n) { name_ = n; }
bool visible() const { return visible_; }
void setVisible(bool v) { visible_ = v; }
i32 tag() const { return tag_; }
void setTag(i32 t) { tag_ = t; }
Act* run(Act* a);
void stop(Act* a);
void stopByTag(i32 tag);
void stopAll();
Act* getActByTag(i32 tag);
i32 runningActs() const;
void updateActs(f32 dt);
protected:
virtual Vec2 defaultAnchor() const { return Vec2(0.5f, 0.5f); }
std::vector<Unique<Comp>> comps_;
Node* parent_ = nullptr;
std::vector<Ref<Node>> children_;
std::string name_;
bool visible_ = true;
i32 tag_ = 0;
std::vector<Act*> acts_;
void addInternal(Unique<Comp> c);
};
inline void Comp::setEnabled(bool e) {
if (enabled_ != e) {
enabled_ = e;
if (enabled_) {
onEnable();
} else {
onDisable();
}
}
}
}