fix Signal
This commit is contained in:
@@ -8,8 +8,11 @@
|
|||||||
namespace td {
|
namespace td {
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Signal class
|
||||||
|
*/
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
class Signal : private NonCopyable {
|
class SignalRaw : private NonCopyable {
|
||||||
public:
|
public:
|
||||||
using FnType = void(Args...);
|
using FnType = void(Args...);
|
||||||
using CallBack = std::function<FnType>;
|
using CallBack = std::function<FnType>;
|
||||||
@@ -35,5 +38,63 @@ class Signal : private NonCopyable {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Memory managed Signal class
|
||||||
|
*/
|
||||||
|
template <typename... Args>
|
||||||
|
class Signal {
|
||||||
|
public:
|
||||||
|
using SignalBase = SignalRaw<Args...>;
|
||||||
|
using CallBack = typename SignalBase::CallBack;
|
||||||
|
using SignalPtr = std::shared_ptr<SignalBase>;
|
||||||
|
class ConnectionGuard;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SignalPtr m_Signal;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Signal() : m_Signal(std::make_shared<SignalBase>()) {}
|
||||||
|
Signal(const Signal&) = default;
|
||||||
|
|
||||||
|
void Connect(const CallBack& a_Callback) {
|
||||||
|
m_Signal->Connect(a_Callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] std::unique_ptr<ConnectionGuard> ConnectSafe(const CallBack& a_Callback) {
|
||||||
|
Connect(a_Callback);
|
||||||
|
return std::make_unique<ConnectionGuard>(*this, a_Callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Disconnect(const CallBack& a_Callback) {
|
||||||
|
m_Signal->Disconnect(a_Callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(Args... args) const {
|
||||||
|
m_Signal->operator()(args...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Connection {
|
||||||
|
public:
|
||||||
|
virtual ~Connection() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
class Signal<Args...>::ConnectionGuard : public Connection {
|
||||||
|
private:
|
||||||
|
using CallBack = typename Signal<Args...>::CallBack;
|
||||||
|
|
||||||
|
std::weak_ptr<SignalRaw<Args...>> m_Signal;
|
||||||
|
CallBack m_Callback;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ConnectionGuard(const Signal<Args...>& a_Signal, const CallBack& a_Callback) : m_Signal(a_Signal.m_Signal), m_Callback(a_Callback) {}
|
||||||
|
|
||||||
|
~ConnectionGuard() {
|
||||||
|
if (!m_Signal.expired())
|
||||||
|
m_Signal.lock()->Disconnect(m_Callback);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <td/misc/SlotGuard.h>
|
#include <td/misc/Signal.h>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
namespace utils {
|
namespace utils {
|
||||||
@@ -12,22 +12,19 @@ namespace utils {
|
|||||||
*/
|
*/
|
||||||
class SlotGuard {
|
class SlotGuard {
|
||||||
private:
|
private:
|
||||||
std::vector<std::function<void()>> m_Deleters;
|
std::vector<std::unique_ptr<Connection>> m_Connections;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* \brief Connect a signal to a function (with the same signature)
|
* \brief Connect a signal to a function (with the same signature)
|
||||||
*/
|
*/
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void Connect(Signal<Args...>& a_Signal, const typename Signal<Args...>::CallBack& a_Callback) {
|
void Connect(Signal<Args...> a_Signal, const typename Signal<Args...>::CallBack& a_Callback) {
|
||||||
a_Signal.Connect(a_Callback);
|
m_Connections.push_back(a_Signal.ConnectSafe(a_Callback));
|
||||||
m_Deleters.push_back([&a_Signal, &a_Callback]() { a_Signal.Disconnect(a_Callback); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~SlotGuard() {
|
void Disconnect() {
|
||||||
for (auto& deleter : m_Deleters) {
|
m_Connections.clear();
|
||||||
deleter();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user