139 lines
3.4 KiB
C++
139 lines
3.4 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
#include <functional>
|
|
#include <cstdint>
|
|
|
|
#include <XCEngine/Core/Event.h>
|
|
|
|
namespace UI {
|
|
|
|
using EntityID = uint64_t;
|
|
constexpr EntityID INVALID_ENTITY_ID = 0;
|
|
|
|
class Component;
|
|
class TransformComponent;
|
|
|
|
class GameObject {
|
|
public:
|
|
EntityID id = INVALID_ENTITY_ID;
|
|
std::string name;
|
|
EntityID parent = INVALID_ENTITY_ID;
|
|
std::vector<EntityID> children;
|
|
std::vector<std::unique_ptr<Component>> components;
|
|
bool selected = false;
|
|
|
|
template<typename T, typename... Args>
|
|
T* AddComponent(Args&&... args) {
|
|
auto comp = std::make_unique<T>(std::forward<Args>(args)...);
|
|
comp->m_gameObject = this;
|
|
T* ptr = comp.get();
|
|
components.push_back(std::move(comp));
|
|
return ptr;
|
|
}
|
|
|
|
template<typename T>
|
|
T* GetComponent() {
|
|
for (auto& comp : components) {
|
|
if (auto casted = dynamic_cast<T*>(comp.get())) {
|
|
return casted;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
template<typename T>
|
|
std::vector<T*> GetComponents() {
|
|
std::vector<T*> result;
|
|
for (auto& comp : components) {
|
|
if (auto casted = dynamic_cast<T*>(comp.get())) {
|
|
result.push_back(casted);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
TransformComponent* GetTransform() {
|
|
return GetComponent<TransformComponent>();
|
|
}
|
|
};
|
|
|
|
class Component {
|
|
public:
|
|
virtual ~Component() = default;
|
|
virtual std::string GetName() const = 0;
|
|
|
|
virtual void Awake() {}
|
|
virtual void Start() {}
|
|
virtual void Update(float deltaTime) {}
|
|
virtual void OnDestroy() {}
|
|
|
|
GameObject* GetGameObject() const { return m_gameObject; }
|
|
bool IsEnabled() const { return m_enabled; }
|
|
void SetEnabled(bool enabled) { m_enabled = enabled; }
|
|
|
|
protected:
|
|
GameObject* m_gameObject = nullptr;
|
|
bool m_enabled = true;
|
|
|
|
friend class GameObject;
|
|
};
|
|
|
|
class TransformComponent : public Component {
|
|
public:
|
|
float position[3] = {0.0f, 0.0f, 0.0f};
|
|
float rotation[3] = {0.0f, 0.0f, 0.0f};
|
|
float scale[3] = {1.0f, 1.0f, 1.0f};
|
|
|
|
std::string GetName() const override { return "Transform"; }
|
|
};
|
|
|
|
class MeshRendererComponent : public Component {
|
|
public:
|
|
std::string materialName = "Default-Material";
|
|
std::string meshName = "";
|
|
|
|
std::string GetName() const override { return "Mesh Renderer"; }
|
|
};
|
|
|
|
using ComponentInspectorFn = std::function<void(Component*)>;
|
|
|
|
struct ComponentInspectorInfo {
|
|
std::string name;
|
|
ComponentInspectorFn renderFn;
|
|
};
|
|
|
|
class ComponentRegistry {
|
|
public:
|
|
static ComponentRegistry& Get() {
|
|
static ComponentRegistry instance;
|
|
return instance;
|
|
}
|
|
|
|
template<typename T>
|
|
void RegisterComponent(const std::string& name, ComponentInspectorFn inspectorFn) {
|
|
m_inspectors[name] = {name, inspectorFn};
|
|
m_factories[name] = []() -> std::unique_ptr<Component> {
|
|
return std::make_unique<T>();
|
|
};
|
|
}
|
|
|
|
ComponentInspectorInfo* GetInspector(const std::string& name) {
|
|
auto it = m_inspectors.find(name);
|
|
if (it != m_inspectors.end()) {
|
|
return &it->second;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
private:
|
|
ComponentRegistry() = default;
|
|
std::unordered_map<std::string, ComponentInspectorInfo> m_inspectors;
|
|
std::unordered_map<std::string, std::function<std::unique_ptr<Component>()>> m_factories;
|
|
};
|
|
|
|
}
|