feat: add event library
This commit is contained in:
+1
-1
@@ -32,7 +32,7 @@ if (SEALLIB_ASSERT)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (SEALLIB_EVENTS)
|
if (SEALLIB_EVENTS)
|
||||||
list(APPEND SEALLIB_SOURCES "src/lib/seallib/events.cpp" "src/lib/seallib/events.h")
|
list(APPEND SEALLIB_SOURCES "src/lib/seallib/events.h")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (SEALLIB_LOG)
|
if (SEALLIB_LOG)
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
#include <mutex>
|
||||||
|
#include <atomic>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace seallib
|
||||||
|
{
|
||||||
|
template <typename... T> class Event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CallbackFunc = std::function<void(T...)>;
|
||||||
|
using ConnectionId = size_t;
|
||||||
|
|
||||||
|
ConnectionId addListener(CallbackFunc listener)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_mtx);
|
||||||
|
ConnectionId id = ++_nextId;
|
||||||
|
_listeners.push_back({id, std::move(listener)});
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool removeListener(ConnectionId id)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_mtx);
|
||||||
|
|
||||||
|
auto it =
|
||||||
|
std::find_if(_listeners.begin(), _listeners.end(), [id](const Listener& l) { return l.id == id; });
|
||||||
|
|
||||||
|
if (it != _listeners.end())
|
||||||
|
{
|
||||||
|
_listeners.erase(it);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args> void run(Args&&... args)
|
||||||
|
{
|
||||||
|
std::vector<CallbackFunc> snapshot;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_mtx);
|
||||||
|
snapshot.reserve(_listeners.size());
|
||||||
|
for (const auto& l : _listeners)
|
||||||
|
{
|
||||||
|
snapshot.push_back(l.func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& func : snapshot)
|
||||||
|
{
|
||||||
|
func(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_mtx);
|
||||||
|
_listeners.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Listener
|
||||||
|
{
|
||||||
|
ConnectionId id;
|
||||||
|
CallbackFunc func;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Listener> _listeners;
|
||||||
|
std::mutex _mtx;
|
||||||
|
std::atomic<ConnectionId> _nextId{0};
|
||||||
|
};
|
||||||
|
} // namespace seallib
|
||||||
Reference in New Issue
Block a user