Last active
May 24, 2022 12:09
Revisions
-
Alia5 revised this gist
Dec 14, 2016 . 1 changed file with 10 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -89,27 +89,31 @@ template<typename... Args> class SConnection { typedef Connection<Args...> Connection; public: SConnection() : signal_(nullptr) { } SConnection(Signal<Args...>& signal, Connection connection) : signal_(&signal), connection_(connection) { hasConnection = true; } ~SConnection() { if (hasConnection && signal_) { signal_->disconnect(connection_); } } private: bool hasConnection = false; Connection connection_; Signal<Args...> *signal_; }; template <typename... Args> @@ -163,7 +167,7 @@ class Signal } } bool disconnect(Connection &connection) { for (const auto & item : items_) @@ -200,7 +204,7 @@ Signal sig; void stuff() { auto conn = Signal::ScopedConnection(sig, sig.connect([](std::string s, int a){ std::cout << s << a << "\n"; })); sig("stuff", 0); -
Alia5 revised this gist
Dec 14, 2016 . 1 changed file with 33 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,7 +5,6 @@ #include <list> #include <memory> template <typename... Args> class ConnectionItem { @@ -42,9 +41,15 @@ class ConnectionItem bool connected_ = false; Slot slot_; }; template<typename... Args> class Signal; template<typename... Args> class SConnection; template<typename... Args> class Connection @@ -62,13 +67,22 @@ class Connection return item_->connected_; } private: Item item_; void disconnect() { item_->disconnect(); } bool operator==(const Item &item) { return item == item_; } friend class Signal<Args...>; friend class SConnection<Args...>; }; template<typename... Args> @@ -143,12 +157,26 @@ class Signal void operator()(Args... args) { for (const auto & item : items_) { (*item)(args...); } } bool disconnect(Connection connection) { for (const auto & item : items_) { if (connection == item) { connection.disconnect(); removeDisconnected(); return true; } } return false; } private: @@ -191,7 +219,7 @@ int main() sig("The answer: ", 42); sig.disconnect(conn); return 0; -
Alia5 revised this gist
Dec 14, 2016 . 1 changed file with 5 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,11 @@ #ifndef SIGNALS_H #define SIGNALS_H #include <functional> #include <list> #include <memory> template <typename... Args> class ConnectionItem { -
Alia5 created this gist
Dec 14, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,195 @@ #ifndef SIGNALS_H #define SIGNALS_H template <typename... Args> class ConnectionItem { typedef std::function<void(Args...)> Slot; public: ConnectionItem(Slot slot) : slot_(slot) { connected_ = true; } ~ConnectionItem() { connected_ = false; } void operator()(Args... args) { if (connected_ && slot_) slot_(args...); } bool isConnected() const { return connected_; } void disconnect() { connected_ = false; } private: bool connected_ = false; Slot slot_; }; template<typename... Args> class Connection { typedef std::shared_ptr<ConnectionItem<Args...>> Item; public: Connection(Item item) : item_(item) { } bool isConnected() const { return item_->connected_; } void disconnect() { item_->disconnect(); } private: Item item_; }; template<typename... Args> class SConnection { typedef Connection<Args...> Connection; public: SConnection() { } SConnection(Connection connection) : connection_(connection) { hasConnection = true; } ~SConnection() { if (hasConnection) connection_.disconnect(); } private: bool hasConnection = false; Connection connection_; }; template <typename... Args> class Signal { typedef std::shared_ptr<ConnectionItem<Args...>> Item; public: typedef std::function<void(Args...)> Slot; typedef Connection<Args...> Connection; typedef SConnection<Args...> ScopedConnection; Signal() { } ~Signal() { for (const auto & item : items_) { item->disconnect(); } items_.clear(); } template <typename SlotF> Connection connect(SlotF&& slot) { Item item = std::make_shared<ConnectionItem<Args...>>(std::forward<SlotF>(slot)); items_.push_back(item); return Connection(item); } //Binding with placeholders is tedious... //Don't want i.e. this: sig.Connect(std::bind(&DummyObject::test, this, std::placeholders::_1, std::placeholders::_2)); template<class O, typename R, typename ... A> Connection connect(O* o, R(O::*f)(A...)) { Item item = std::make_shared<ConnectionItem<Args...>>(std::forward<Slot>([=](A... args) { return (o->*f)(args...); })); items_.push_back(item); return Connection(item); } void operator()(Args... args) { removeDisconnected(); for (const auto & item : items_) { (*item)(args...); } } private: std::list<Item> items_; void removeDisconnected() { items_.erase(std::remove_if(items_.begin(), items_.end(), [](Item &item) { return !item->isConnected(); }), items_.end()); } }; #endif // !SIGNALS_H /* EXAMPLE USAGE typedef Signal<std::string, int> Signal; Signal sig; void stuff() { auto conn = Signal::ScopedConnection(sig.connect([](std::string s, int a){ std::cout << s << a << "\n"; })); sig("stuff", 0); } void differentStuff(std::string s, int a) { std::cout "differentStuff: " << s << a << "\n"; } int main() { Signal::Connection conn = sig.connect(differentStuff); stuff(); sig("The answer: ", 42); conn.disconnect(); return 0; } */