Files
XCEngine/engine/include/XCEngine/Components/GameObject.h

190 lines
5.0 KiB
C++

#pragma once
#include "Component.h"
#include "TransformComponent.h"
#include <string>
#include <vector>
#include <memory>
#include <unordered_map>
#include <istream>
#include <ostream>
#include <random>
namespace XCEngine {
namespace Components {
class Scene;
class GameObject {
public:
using ID = uint64_t;
static constexpr ID INVALID_ID = 0;
GameObject();
explicit GameObject(const std::string& name);
~GameObject();
ID GetID() const { return m_id; }
uint64_t GetUUID() const { return m_uuid; }
const std::string& GetName() const { return m_name; }
void SetName(const std::string& name) { m_name = name; }
void DetachFromParent();
Scene* GetScene() const { return m_scene; }
TransformComponent* GetTransform() { return m_transform; }
const TransformComponent* GetTransform() const { return m_transform; }
template<typename T, typename... Args>
T* AddComponent(Args&&... args) {
auto component = std::make_unique<T>(std::forward<Args>(args)...);
component->m_gameObject = this;
T* ptr = component.get();
m_components.emplace_back(std::move(component));
return ptr;
}
template<typename T>
T* GetComponent() {
for (auto& comp : m_components) {
if (T* casted = dynamic_cast<T*>(comp.get())) {
return casted;
}
}
return nullptr;
}
template<typename T>
const T* GetComponent() const {
for (auto& comp : m_components) {
if (T* casted = dynamic_cast<T*>(comp.get())) {
return casted;
}
}
return nullptr;
}
template<typename T>
std::vector<T*> GetComponents() {
std::vector<T*> result;
for (auto& comp : m_components) {
if (T* casted = dynamic_cast<T*>(comp.get())) {
result.push_back(casted);
}
}
return result;
}
template<typename T>
std::vector<const T*> GetComponents() const {
std::vector<const T*> result;
for (auto& comp : m_components) {
if (const T* casted = dynamic_cast<const T*>(comp.get())) {
result.push_back(casted);
}
}
return result;
}
template<typename T>
void RemoveComponent() {
for (auto it = m_components.begin(); it != m_components.end(); ++it) {
if (T* casted = dynamic_cast<T*>(it->get())) {
m_components.erase(it);
return;
}
}
}
template<typename T>
T* GetComponentInChildren() {
T* comp = GetComponent<T>();
if (comp) {
return comp;
}
for (auto* child : m_children) {
comp = child->GetComponentInChildren<T>();
if (comp) {
return comp;
}
}
return nullptr;
}
template<typename T>
T* GetComponentInParent() {
if (m_parent) {
T* comp = m_parent->GetComponent<T>();
if (comp) {
return comp;
}
return m_parent->GetComponentInParent<T>();
}
return nullptr;
}
template<typename T>
std::vector<T*> GetComponentsInChildren() {
std::vector<T*> result;
std::vector<T*> comps = GetComponents<T>();
result.insert(result.end(), comps.begin(), comps.end());
for (auto* child : m_children) {
std::vector<T*> childComps = child->GetComponentsInChildren<T>();
result.insert(result.end(), childComps.begin(), childComps.end());
}
return result;
}
GameObject* GetParent() const { return m_parent; }
void SetParent(GameObject* parent);
void SetParent(GameObject* parent, bool worldPositionStays);
size_t GetChildCount() const { return m_children.size(); }
GameObject* GetChild(size_t index) const;
std::vector<GameObject*> GetChildren() const;
void DetachChildren();
bool IsActive() const { return m_activeSelf; }
void SetActive(bool active);
bool IsActiveInHierarchy() const;
static GameObject* Find(const std::string& name);
static std::vector<GameObject*> FindObjectsOfType();
static std::vector<GameObject*> FindGameObjectsWithTag(const std::string& tag);
void Awake();
void Start();
void Update(float deltaTime);
void FixedUpdate();
void LateUpdate(float deltaTime);
void OnDestroy();
void Destroy();
void Serialize(std::ostream& os) const;
void Deserialize(std::istream& is);
private:
ID m_id = INVALID_ID;
uint64_t m_uuid = 0;
std::string m_name;
bool m_activeSelf = true;
GameObject* m_parent = nullptr;
std::vector<GameObject*> m_children;
Scene* m_scene = nullptr;
TransformComponent* m_transform = nullptr;
std::vector<std::unique_ptr<Component>> m_components;
static ID s_nextID;
static std::unordered_map<ID, GameObject*>& GetGlobalRegistry();
friend class Scene;
friend class SceneManager;
};
} // namespace Components
} // namespace XCEngine