Mercurial > irccd
changeset 559:525f246d632d
Common: get rid of signals.hpp
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 25 Nov 2017 17:01:53 +0100 |
parents | f1ad428208d3 |
children | 781e58cf49a0 |
files | libcommon/CMakeLists.txt libcommon/irccd/signals.hpp |
diffstat | 2 files changed, 0 insertions(+), 171 deletions(-) [+] |
line wrap: on
line diff
--- 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
--- 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 <markand@malikania.fr> - * - * 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 <functional> -#include <stack> -#include <unordered_map> -#include <vector> - -/** - * \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 <typename... Args> -class Signal { -private: - using Function = std::function<void (Args...)>; - using FunctionMap = std::unordered_map<unsigned, Function>; - using Stack = std::stack<unsigned>; - - 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<unsigned> 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