1 #pragma once 2 3 #include "nodiscard.h" 4 5 #include <algorithm> 6 #include <cassert> 7 #include <mutex> 8 #include <memory> 9 #include <vector> 10 #include <functional> 11 12 namespace Framework 13 { 14 template<typename> class CSignal; 15 template<typename T, typename... Args> 16 class CSignal<T (Args...)> 17 { 18 public: 19 class CConnection; 20 21 typedef std::shared_ptr<CConnection> Connection; 22 typedef std::weak_ptr<CConnection> WeakConnection; 23 typedef std::function<T (Args...)> SlotFunction; 24 25 CSignal() = default; 26 27 FRAMEWORK_NODISCARD 28 Connection Connect(const SlotFunction& func, bool oneShot = false) 29 { 30 assert(func); 31 32 std::unique_lock<std::mutex> lock(m_lock); 33 34 auto connection = std::make_shared<CConnection>(func, oneShot); 35 m_connections.push_back(connection); 36 37 return connection; 38 } 39 40 FRAMEWORK_NODISCARD ConnectOnce(const SlotFunction & func)41 Connection ConnectOnce(const SlotFunction& func) 42 { 43 return Connect(func, true); 44 } 45 Reset()46 void Reset() 47 { 48 std::unique_lock<std::mutex> lock(m_lock); 49 50 m_connections.clear(); 51 } 52 operator()53 void operator()(Args... args) 54 { 55 std::unique_lock<std::mutex> lock(m_lock); 56 57 m_connections.erase( 58 std::remove_if( 59 m_connections.begin(), 60 m_connections.end(), 61 [&](WeakConnection& connection) 62 { 63 auto connectionPtr = connection.lock(); 64 if(connectionPtr) 65 { 66 (*connectionPtr)(args...); 67 } 68 return !connectionPtr || (*connectionPtr).IsOneShot(); 69 } 70 ), 71 m_connections.end() 72 ); 73 } 74 75 class CConnection 76 { 77 public: CConnection(const SlotFunction slot,bool oneShot)78 CConnection(const SlotFunction slot, bool oneShot) 79 : m_slot(slot) 80 , m_oneShot(oneShot) 81 { 82 } 83 operator()84 void operator()(Args... args) 85 { 86 (m_slot)(args...); 87 } 88 IsOneShot()89 bool IsOneShot() const 90 { 91 return m_oneShot; 92 } 93 94 private: 95 SlotFunction m_slot; 96 bool m_oneShot; 97 }; 98 private: 99 std::vector<WeakConnection> m_connections; 100 std::mutex m_lock; 101 }; 102 } 103