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
This commit is contained in:
@@ -6,11 +6,25 @@
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <typeinfo>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
template<typename T>
|
||||
struct EventTypeId {
|
||||
static uint32_t Get() {
|
||||
static const uint32_t id = s_nextId++;
|
||||
return id;
|
||||
}
|
||||
private:
|
||||
static uint32_t s_nextId;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
uint32_t EventTypeId<T>::s_nextId = 0;
|
||||
|
||||
class EventBus {
|
||||
public:
|
||||
using EventHandler = std::function<void()>;
|
||||
@@ -18,29 +32,35 @@ public:
|
||||
template<typename T>
|
||||
uint64_t Subscribe(std::function<void(const T&)> handler) {
|
||||
static_assert(sizeof(T) > 0, "Event type must be defined");
|
||||
size_t typeId = typeid(T).hash_code();
|
||||
uint64_t handlerId = m_nextHandlerId++;
|
||||
uint32_t typeId = EventTypeId<T>::Get();
|
||||
uint64_t handlerId = 0;
|
||||
|
||||
auto it = m_handlers.find(typeId);
|
||||
if (it == m_handlers.end()) {
|
||||
m_handlers[typeId] = std::vector<HandlerEntry>();
|
||||
{
|
||||
std::lock_guard<std::shared_mutex> lock(m_mutex);
|
||||
handlerId = m_nextHandlerId++;
|
||||
|
||||
auto it = m_handlers.find(typeId);
|
||||
if (it == m_handlers.end()) {
|
||||
m_handlers[typeId] = std::vector<HandlerEntry>();
|
||||
}
|
||||
|
||||
HandlerEntry entry;
|
||||
entry.id = handlerId;
|
||||
entry.handler = [handler](const void* data) {
|
||||
handler(*static_cast<const T*>(data));
|
||||
};
|
||||
m_handlers[typeId].push_back(entry);
|
||||
}
|
||||
|
||||
HandlerEntry entry;
|
||||
entry.id = handlerId;
|
||||
entry.handler = [handler](const void* data) {
|
||||
handler(*static_cast<const T*>(data));
|
||||
};
|
||||
m_handlers[typeId].push_back(entry);
|
||||
|
||||
return handlerId;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Unsubscribe(uint64_t handlerId) {
|
||||
static_assert(sizeof(T) > 0, "Event type must be defined");
|
||||
size_t typeId = typeid(T).hash_code();
|
||||
uint32_t typeId = EventTypeId<T>::Get();
|
||||
|
||||
std::lock_guard<std::shared_mutex> lock(m_mutex);
|
||||
auto it = m_handlers.find(typeId);
|
||||
if (it != m_handlers.end()) {
|
||||
auto& handlers = it->second;
|
||||
@@ -55,8 +75,9 @@ public:
|
||||
template<typename T>
|
||||
void Publish(const T& event) {
|
||||
static_assert(sizeof(T) > 0, "Event type must be defined");
|
||||
size_t typeId = typeid(T).hash_code();
|
||||
uint32_t typeId = EventTypeId<T>::Get();
|
||||
|
||||
std::shared_lock<std::shared_mutex> lock(m_mutex);
|
||||
auto it = m_handlers.find(typeId);
|
||||
if (it != m_handlers.end()) {
|
||||
for (const auto& entry : it->second) {
|
||||
@@ -66,6 +87,7 @@ public:
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
std::lock_guard<std::shared_mutex> lock(m_mutex);
|
||||
m_handlers.clear();
|
||||
}
|
||||
|
||||
@@ -75,8 +97,9 @@ private:
|
||||
std::function<void(const void*)> handler;
|
||||
};
|
||||
|
||||
std::unordered_map<size_t, std::vector<HandlerEntry>> m_handlers;
|
||||
std::unordered_map<uint32_t, std::vector<HandlerEntry>> m_handlers;
|
||||
uint64_t m_nextHandlerId = 0;
|
||||
std::shared_mutex m_mutex;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user