fix signals

This commit is contained in:
2025-08-21 20:32:47 +02:00
parent 165ebf7b2e
commit fd08833f3f
2 changed files with 14 additions and 10 deletions

View File

@@ -15,7 +15,7 @@ template <typename... Args>
class SignalRaw : private NonCopyable { class SignalRaw : private NonCopyable {
public: public:
using FnType = void(Args...); using FnType = void(Args...);
using CallBack = std::function<FnType>; using CallBack = std::shared_ptr<std::function<FnType>>;
private: private:
std::vector<CallBack> m_Callbacks; std::vector<CallBack> m_Callbacks;
@@ -26,14 +26,13 @@ class SignalRaw : private NonCopyable {
} }
void Disconnect(const CallBack& a_Callback) { void Disconnect(const CallBack& a_Callback) {
auto it = std::find_if(m_Callbacks.begin(), m_Callbacks.end(), auto it = std::find(m_Callbacks.begin(), m_Callbacks.end(), a_Callback);
[&a_Callback](CallBack& callback) { return a_Callback.template target<FnType>() == callback.template target<FnType>(); });
m_Callbacks.erase(it); m_Callbacks.erase(it);
} }
void operator()(Args... args) const { void operator()(Args... args) const {
for (const CallBack& callback : m_Callbacks) { for (const CallBack& callback : m_Callbacks) {
callback(args...); callback->operator()(args...);
} }
} }
}; };
@@ -46,6 +45,7 @@ class Signal {
public: public:
using SignalBase = SignalRaw<Args...>; using SignalBase = SignalRaw<Args...>;
using CallBack = typename SignalBase::CallBack; using CallBack = typename SignalBase::CallBack;
using CallBackRaw = typename CallBack::element_type;
using SignalPtr = std::shared_ptr<SignalBase>; using SignalPtr = std::shared_ptr<SignalBase>;
class ConnectionGuard; class ConnectionGuard;
@@ -56,12 +56,15 @@ class Signal {
Signal() : m_Signal(std::make_shared<SignalBase>()) {} Signal() : m_Signal(std::make_shared<SignalBase>()) {}
Signal(const Signal&) = default; Signal(const Signal&) = default;
void Connect(const CallBack& a_Callback) { /**
m_Signal->Connect(a_Callback); * \warning The callback won't be disconnectable, use it wisely!
*/
void Connect(const CallBackRaw& a_Callback) {
m_Signal->Connect(std::make_shared<CallBackRaw>(a_Callback));
} }
[[nodiscard]] std::unique_ptr<ConnectionGuard> ConnectSafe(const CallBack& a_Callback) { [[nodiscard]] std::unique_ptr<ConnectionGuard> ConnectSafe(const CallBack& a_Callback) {
Connect(a_Callback); m_Signal->Connect(a_Callback);
return std::make_unique<ConnectionGuard>(*this, a_Callback); return std::make_unique<ConnectionGuard>(*this, a_Callback);
} }

View File

@@ -19,8 +19,9 @@ class SlotGuard {
* \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::element_type& a_Callback) {
m_Connections.push_back(a_Signal.ConnectSafe(a_Callback)); auto ptr = std::make_shared<typename Signal<Args...>::CallBack::element_type>(a_Callback);
m_Connections.push_back(a_Signal.ConnectSafe(ptr));
} }
void Disconnect() { void Disconnect() {