refactor(editor): Phase 1 architecture refactoring
- Decouple Panel from Core::Layer (P0 issue resolved) - Add EventBus with type-safe event system - Add ISelectionManager interface with SelectionManagerImpl - Add IEditorContext for dependency injection - Update EditorLayer to use new architecture - Update Application to create and inject EditorContext New files: - editor/src/Core/EventBus.h - editor/src/Core/EditorEvents.h - editor/src/Core/ISelectionManager.h - editor/src/Core/SelectionManagerImpl.h - editor/src/Core/IEditorContext.h - editor/src/Core/EditorContextImpl.h This enables future improvements: Undo/Redo, serialization, component extensibility.
This commit is contained in:
83
editor/src/Core/EventBus.h
Normal file
83
editor/src/Core/EventBus.h
Normal file
@@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
class EventBus {
|
||||
public:
|
||||
using EventHandler = std::function<void()>;
|
||||
|
||||
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++;
|
||||
|
||||
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);
|
||||
|
||||
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();
|
||||
|
||||
auto it = m_handlers.find(typeId);
|
||||
if (it != m_handlers.end()) {
|
||||
auto& handlers = it->second;
|
||||
handlers.erase(
|
||||
std::remove_if(handlers.begin(), handlers.end(),
|
||||
[handlerId](const HandlerEntry& entry) { return entry.id == handlerId; }),
|
||||
handlers.end()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
auto it = m_handlers.find(typeId);
|
||||
if (it != m_handlers.end()) {
|
||||
for (const auto& entry : it->second) {
|
||||
entry.handler(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
m_handlers.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
struct HandlerEntry {
|
||||
uint64_t id;
|
||||
std::function<void(const void*)> handler;
|
||||
};
|
||||
|
||||
std::unordered_map<size_t, std::vector<HandlerEntry>> m_handlers;
|
||||
uint64_t m_nextHandlerId = 0;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user