# HG changeset patch # User David Demelier # Date 1511625713 -3600 # Node ID 525f246d632dd83982cd393429c37764e6011a87 # Parent f1ad428208d3de00b2d3ad9335252ca63f890ea9 Common: get rid of signals.hpp diff -r f1ad428208d3 -r 525f246d632d libcommon/CMakeLists.txt --- a/libcommon/CMakeLists.txt Sat Nov 25 17:00:24 2017 +0100 +++ b/libcommon/CMakeLists.txt Sat Nov 25 17:01:53 2017 +0100 @@ -29,7 +29,6 @@ ${libcommon_SOURCE_DIR}/irccd/network_errc.hpp ${libcommon_SOURCE_DIR}/irccd/network_stream.hpp ${libcommon_SOURCE_DIR}/irccd/options.hpp - ${libcommon_SOURCE_DIR}/irccd/signals.hpp ${libcommon_SOURCE_DIR}/irccd/string_util.hpp ${libcommon_SOURCE_DIR}/irccd/system.hpp ${libcommon_SOURCE_DIR}/irccd/util.hpp diff -r f1ad428208d3 -r 525f246d632d libcommon/irccd/signals.hpp --- a/libcommon/irccd/signals.hpp Sat Nov 25 17:00:24 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -/* - * signals.h -- synchronous observer mechanism - * - * Copyright (c) 2013-2017 David Demelier - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_SIGNALS_H -#define IRCCD_SIGNALS_H - -#include -#include -#include -#include - -/** - * \file signals.hpp - * \brief Similar Qt signal subsystem for irccd - */ - -namespace irccd { - -/** - * \brief Stores the reference to the callable - * - * This class can be stored to remove a registered function from a Signal, be careful to not mix connections between different signals as - * they are just referenced by ids. - */ -class SignalConnection { -private: - unsigned m_id; - -public: - /** - * Create a signal connection. - * - * \param id the id - */ - inline SignalConnection(unsigned id) noexcept - : m_id(id) - { - } - - /** - * Get the reference object. - * - * \return the id - */ - inline unsigned id() const noexcept - { - return m_id; - } -}; - -/** - * \brief Stores and call registered functions - * - * This class is intended to be use as a public field in the desired object. - * - * The user just have to call one of connect(), disconnect() or the call - * operator to use this class. - * - * It stores the callable as std::function so type-erasure is complete. - * - * The user is responsible of taking care that the object is still alive - * in case that the function takes a reference to the object. - */ -template -class Signal { -private: - using Function = std::function; - using FunctionMap = std::unordered_map; - using Stack = std::stack; - - FunctionMap m_functions; - Stack m_stack; - unsigned m_max{0}; - -public: - /** - * Register a new function to the signal. - * - * \param function the function - * \return the connection in case you want to remove it - */ - inline SignalConnection connect(Function function) noexcept - { - unsigned id; - - if (!m_stack.empty()) { - id = m_stack.top(); - m_stack.pop(); - } else - id = m_max ++; - - m_functions.emplace(id, std::move(function)); - - return SignalConnection{id}; - } - - /** - * Disconnect a connection. - * - * \param connection the connection - * \warning Be sure that the connection belongs to that signal - */ - inline void disconnect(const SignalConnection &connection) noexcept - { - auto value = m_functions.find(connection.id()); - - if (value != m_functions.end()) { - m_functions.erase(connection.id()); - m_stack.push(connection.id()); - } - } - - /** - * Remove all registered functions. - */ - inline void clear() - { - m_functions.clear(); - m_max = 0; - - while (!m_stack.empty()) - m_stack.pop(); - } - - /** - * Call every functions. - * - * \param args the arguments to pass to the signal - */ - void operator()(Args... args) const - { - /* - * Make a copy of the ids before iterating because the callbacks may eventually remove or modify the list. - */ - std::vector ids; - - for (auto &pair : m_functions) - ids.push_back(pair.first); - - /* - * Now iterate while checking if the next id is still available, however if any new signals were added while iterating, they - * will not be called immediately. - */ - for (unsigned i : ids) { - auto it = m_functions.find(i); - - if (it != m_functions.end()) - it->second(args...); - } - } -}; - -} // !irccd - -#endif // !IRCCD_SIGNALS_H