- Containers: String, Array, HashMap 容器实现及测试 - Memory: Allocator, LinearAllocator, PoolAllocator, ProxyAllocator, MemoryManager 实现及测试 - Threading: Mutex, SpinLock, ReadWriteLock, Thread, Task, TaskSystem 实现及测试 - 修复Windows平台兼容性: _aligned_malloc, std::hash特化 - 修复构建错误和测试用例问题
80 lines
2.2 KiB
C++
80 lines
2.2 KiB
C++
#pragma once
|
|
|
|
#include <functional>
|
|
#include <vector>
|
|
#include <mutex>
|
|
#include <algorithm>
|
|
|
|
namespace XCEngine {
|
|
namespace Core {
|
|
|
|
template<typename... Args>
|
|
class Event {
|
|
public:
|
|
using Callback = std::function<void(Args...)>;
|
|
using Listener = std::pair<uint64_t, Callback>;
|
|
using Iterator = typename std::vector<Listener>::iterator;
|
|
|
|
uint64_t Subscribe(Callback callback) {
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
uint64_t id = ++m_nextId;
|
|
m_listeners.emplace_back(id, std::move(callback));
|
|
return id;
|
|
}
|
|
|
|
void Unsubscribe(uint64_t id) {
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
m_pendingUnsubscribes.push_back(id);
|
|
}
|
|
|
|
void ProcessUnsubscribes() {
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
for (uint64_t id : m_pendingUnsubscribes) {
|
|
m_listeners.erase(
|
|
std::remove_if(m_listeners.begin(), m_listeners.end(),
|
|
[id](const auto& pair) { return pair.first == id; }),
|
|
m_listeners.end()
|
|
);
|
|
}
|
|
m_pendingUnsubscribes.clear();
|
|
}
|
|
|
|
void Invoke(Args... args) {
|
|
std::vector<Listener> listenersCopy;
|
|
{
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
if (!m_pendingUnsubscribes.empty()) {
|
|
for (uint64_t id : m_pendingUnsubscribes) {
|
|
m_listeners.erase(
|
|
std::remove_if(m_listeners.begin(), m_listeners.end(),
|
|
[id](const auto& pair) { return pair.first == id; }),
|
|
m_listeners.end()
|
|
);
|
|
}
|
|
m_pendingUnsubscribes.clear();
|
|
}
|
|
listenersCopy = m_listeners;
|
|
}
|
|
for (const auto& [id, callback] : listenersCopy) {
|
|
callback(args...);
|
|
}
|
|
}
|
|
|
|
void Clear() {
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
m_listeners.clear();
|
|
}
|
|
|
|
Iterator begin() { return m_listeners.begin(); }
|
|
Iterator end() { return m_listeners.end(); }
|
|
|
|
private:
|
|
mutable std::mutex m_mutex;
|
|
std::vector<Listener> m_listeners;
|
|
std::vector<uint64_t> m_pendingUnsubscribes;
|
|
uint64_t m_nextId = 0;
|
|
};
|
|
|
|
} // namespace Core
|
|
} // namespace XCEngine
|