util: Signal::connectSingleShot
refs #2331
Change-Id: I96e6c362c07c8d962e59ebba2cf338761a4f110a
diff --git a/src/util/signal-signal.hpp b/src/util/signal-signal.hpp
index e1c01df..7f91e15 100644
--- a/src/util/signal-signal.hpp
+++ b/src/util/signal-signal.hpp
@@ -63,6 +63,13 @@
Connection
connect(const Handler& handler);
+ /** \brief connects a single-shot handler to the signal
+ *
+ * After the handler is executed once, it is automatically disconnected.
+ */
+ Connection
+ connectSingleShot(const Handler& handler);
+
private: // API for owner
/** \retval true if there is no connection
*/
@@ -164,6 +171,22 @@
}
template<typename Owner, typename ...TArgs>
+inline Connection
+Signal<Owner, TArgs...>::connectSingleShot(const Handler& handler)
+{
+ typename SlotList::iterator it = m_slots.insert(m_slots.end(), {nullptr, nullptr});
+ it->disconnect = make_shared<function<void()>>(bind(&Self::disconnect, this, it));
+ signal::Connection conn(weak_ptr<function<void()>>(it->disconnect));
+
+ it->handler = [conn, handler] (const TArgs&... args) mutable {
+ handler(args...);
+ conn.disconnect();
+ };
+
+ return conn;
+}
+
+template<typename Owner, typename ...TArgs>
inline void
Signal<Owner, TArgs...>::disconnect(typename SlotList::iterator it)
{