2026-03-20 17:08:06 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "Core/GameObject.h"
|
|
|
|
|
#include <unordered_map>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <optional>
|
|
|
|
|
|
2026-03-20 17:28:06 +08:00
|
|
|
#include <XCEngine/Core/Event.h>
|
|
|
|
|
|
2026-03-20 17:08:06 +08:00
|
|
|
namespace UI {
|
|
|
|
|
|
|
|
|
|
struct ClipboardData {
|
|
|
|
|
std::string name;
|
|
|
|
|
std::vector<std::unique_ptr<Component>> components;
|
|
|
|
|
std::vector<ClipboardData> children;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class SceneManager {
|
|
|
|
|
public:
|
|
|
|
|
static SceneManager& Get() {
|
|
|
|
|
static SceneManager instance;
|
|
|
|
|
return instance;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-20 17:28:06 +08:00
|
|
|
EntityID CreateEntity(const std::string& name, EntityID parent = INVALID_ENTITY_ID);
|
2026-03-20 17:08:06 +08:00
|
|
|
|
|
|
|
|
Entity* GetEntity(EntityID id) {
|
|
|
|
|
auto it = m_entities.find(id);
|
|
|
|
|
if (it != m_entities.end()) {
|
|
|
|
|
return &it->second;
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Entity* GetEntity(EntityID id) const {
|
|
|
|
|
auto it = m_entities.find(id);
|
|
|
|
|
if (it != m_entities.end()) {
|
|
|
|
|
return &it->second;
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::vector<EntityID>& GetRootEntities() const {
|
|
|
|
|
return m_rootEntities;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DeleteEntity(EntityID id);
|
|
|
|
|
|
|
|
|
|
void RenameEntity(EntityID id, const std::string& newName) {
|
|
|
|
|
auto* entity = GetEntity(id);
|
|
|
|
|
if (entity) {
|
|
|
|
|
entity->name = newName;
|
|
|
|
|
OnEntityChanged.Invoke(id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CopyEntity(EntityID id);
|
|
|
|
|
|
2026-03-20 17:28:06 +08:00
|
|
|
EntityID PasteEntity(EntityID parent = INVALID_ENTITY_ID);
|
2026-03-20 17:08:06 +08:00
|
|
|
|
|
|
|
|
EntityID DuplicateEntity(EntityID id);
|
|
|
|
|
|
|
|
|
|
void MoveEntity(EntityID id, EntityID newParent);
|
|
|
|
|
|
|
|
|
|
void CreateDemoScene();
|
|
|
|
|
|
|
|
|
|
bool HasClipboardData() const { return m_clipboard.has_value(); }
|
|
|
|
|
|
2026-03-20 17:28:06 +08:00
|
|
|
XCEngine::Core::Event<EntityID> OnEntityCreated;
|
|
|
|
|
XCEngine::Core::Event<EntityID> OnEntityDeleted;
|
|
|
|
|
XCEngine::Core::Event<EntityID> OnEntityChanged;
|
|
|
|
|
XCEngine::Core::Event<> OnSceneChanged;
|
2026-03-20 17:08:06 +08:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
SceneManager() = default;
|
|
|
|
|
|
|
|
|
|
ClipboardData CopyEntityRecursive(const Entity* entity);
|
|
|
|
|
EntityID PasteEntityRecursive(const ClipboardData& data, EntityID parent);
|
|
|
|
|
|
|
|
|
|
EntityID m_nextEntityId = 1;
|
|
|
|
|
std::unordered_map<EntityID, Entity> m_entities;
|
|
|
|
|
std::vector<EntityID> m_rootEntities;
|
|
|
|
|
std::optional<ClipboardData> m_clipboard;
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-20 17:28:06 +08:00
|
|
|
}
|