190 lines
5.0 KiB
C++
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
|