Files
XCEngine/engine/include/XCEngine/Scene/Scene.h
ssdfasd b0d0576763 Fix editor selection system: SelectionManager ID types and Scene lookup
- SelectionManager now implements ISelectionManager interface with uint64_t IDs
- Remove SelectionManager/SceneManager circular dependency via EventBus
- Add Scene::FindByID() for proper ID-based entity lookup
- SceneManager::GetEntity() now uses FindByID instead of name-based Find
- Fix editor CMakeLists.txt XCEngine.lib path
- EventBus now thread-safe with shared_mutex
2026-03-25 17:51:15 +08:00

115 lines
3.4 KiB
C++

#pragma once
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <fstream>
#include <XCEngine/Core/Event.h>
#include <XCEngine/Components/GameObject.h>
namespace XCEngine {
namespace Components {
class Scene {
public:
using GameObjectID = uint64_t;
static constexpr GameObjectID INVALID_GAMEOBJECT_ID = 0;
Scene();
explicit Scene(const std::string& name);
~Scene();
const std::string& GetName() const { return m_name; }
void SetName(const std::string& name) { m_name = name; }
bool IsActive() const { return m_active; }
void SetActive(bool active) { m_active = active; }
GameObject* CreateGameObject(const std::string& name, GameObject* parent = nullptr);
void DestroyGameObject(GameObject* gameObject);
GameObject* Find(const std::string& name) const;
GameObject* FindByID(GameObjectID id) const;
GameObject* FindGameObjectWithTag(const std::string& tag) const;
template<typename T>
T* FindObjectOfType() const {
for (auto* go : GetRootGameObjects()) {
if (T* comp = go->GetComponent<T>()) {
return comp;
}
if (T* comp = FindInChildren<T>(go)) {
return comp;
}
}
return nullptr;
}
template<typename T>
std::vector<T*> FindObjectsOfType() const {
std::vector<T*> results;
for (auto* go : GetRootGameObjects()) {
if (T* comp = go->GetComponent<T>()) {
results.push_back(comp);
}
FindInChildren<T>(go, results);
}
return results;
}
std::vector<GameObject*> GetRootGameObjects() const;
void Update(float deltaTime);
void FixedUpdate(float fixedDeltaTime);
void LateUpdate(float deltaTime);
void Save(const std::string& filePath);
void Load(const std::string& filePath);
Core::Event<GameObject*>& OnGameObjectCreated() { return m_onGameObjectCreated; }
Core::Event<GameObject*>& OnGameObjectDestroyed() { return m_onGameObjectDestroyed; }
private:
GameObject* FindInChildren(GameObject* parent, const std::string& name) const;
template<typename T>
T* FindInChildren(GameObject* parent) const {
for (size_t i = 0; i < parent->GetChildCount(); ++i) {
GameObject* child = parent->GetChild(i);
if (T* comp = child->GetComponent<T>()) {
return comp;
}
if (T* comp = FindInChildren<T>(child)) {
return comp;
}
}
return nullptr;
}
template<typename T>
void FindInChildren(GameObject* parent, std::vector<T*>& results) const {
for (size_t i = 0; i < parent->GetChildCount(); ++i) {
GameObject* child = parent->GetChild(i);
if (T* comp = child->GetComponent<T>()) {
results.push_back(comp);
}
FindInChildren<T>(child, results);
}
}
std::string m_name;
bool m_active = true;
std::unordered_map<GameObjectID, std::unique_ptr<GameObject>> m_gameObjects;
std::vector<GameObjectID> m_rootGameObjects;
std::unordered_set<GameObjectID> m_gameObjectIDs;
Core::Event<GameObject*> m_onGameObjectCreated;
Core::Event<GameObject*> m_onGameObjectDestroyed;
friend class GameObject;
friend class SceneManager;
};
} // namespace Components
} // namespace XCEngine