#pragma once #include #include #include #include #include #include #include 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 children; std::vector> components; bool selected = false; template T* AddComponent(Args&&... args) { auto comp = std::make_unique(std::forward(args)...); comp->m_gameObject = this; T* ptr = comp.get(); components.push_back(std::move(comp)); return ptr; } template T* GetComponent() { for (auto& comp : components) { if (auto casted = dynamic_cast(comp.get())) { return casted; } } return nullptr; } template std::vector GetComponents() { std::vector result; for (auto& comp : components) { if (auto casted = dynamic_cast(comp.get())) { result.push_back(casted); } } return result; } TransformComponent* GetTransform() { return GetComponent(); } }; 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; struct ComponentInspectorInfo { std::string name; ComponentInspectorFn renderFn; }; class ComponentRegistry { public: static ComponentRegistry& Get() { static ComponentRegistry instance; return instance; } template void RegisterComponent(const std::string& name, ComponentInspectorFn inspectorFn) { m_inspectors[name] = {name, inspectorFn}; m_factories[name] = []() -> std::unique_ptr { return std::make_unique(); }; } 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 m_inspectors; std::unordered_map()>> m_factories; }; }