Mercurial > code
changeset 601:1e23b6f0d605
Signals: use Boost.Signals2 instead
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 02 Dec 2016 22:21:32 +0100 |
parents | af299c1729cf |
children | f322e5fcc099 |
files | CMakeLists.txt modules/signals/CMakeLists.txt modules/signals/signals.hpp modules/signals/test/main.cpp |
diffstat | 4 files changed, 0 insertions(+), 333 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Fri Dec 02 22:21:03 2016 +0100 +++ b/CMakeLists.txt Fri Dec 02 22:21:32 2016 +0100 @@ -51,7 +51,6 @@ add_subdirectory(modules/js) add_subdirectory(modules/net) -add_subdirectory(modules/signals) add_subdirectory(modules/unicode) add_subdirectory(modules/xdg)
--- a/modules/signals/CMakeLists.txt Fri Dec 02 22:21:03 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -# -# CMakeLists.txt -- code building for common code -# -# Copyright (c) 2016 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. -# - -code_define_module( - NAME signals - SOURCES signals.hpp -)
--- a/modules/signals/signals.hpp Fri Dec 02 22:21:03 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +0,0 @@ -/* - * signals.h -- synchronous observer mechanism - * - * Copyright (c) 2016 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 SIGNALS_HPP -#define SIGNALS_HPP - -/** - * \file signals.hpp - * \brief Synchronous callbacks. - */ - -#include <algorithm> -#include <cstdint> -#include <functional> -#include <iterator> -#include <utility> -#include <vector> - -/** - * \brief utilities for basic signal management. - */ -namespace sig { - -/** - * Add a new handler for the given signal. - * - * \param sig the signal container - * \param callable the callable object - * \return the signal position - * \throw exceptions if the container cannot allocate more memory - */ -template <typename Signal, typename Callable> -std::uintmax_t connect(Signal& sig, Callable&& callable) -{ - auto it = std::find_if(sig.begin(), sig.end(), [&] (auto &f) { - return f == nullptr; - }); - - if (it != sig.end()) - *it = std::forward<Callable>(callable); - else { - sig.push_back(std::move(callable)); - it = sig.end() - 1; - } - - return std::distance(sig.begin(), it); -} - -/** - * Remove an handler from the given signal. - * - * If the id is out of bounds, does nothing. - * - * \param sig the signal container - * \param id the id - * \return true if a signal has been removed - */ -template <typename Signal> -bool disconnect(Signal& sig, std::uintmax_t id) noexcept -{ - if (id < 0 || id > sig.size() || sig[id] == nullptr) - return false; - - sig[id] = nullptr; - - return true; -} - -/** - * Disable all handlers in the given signal. - * - * \param sig the signal - */ -template <typename Signal> -void clear(Signal& sig) noexcept -{ - for (auto &f : sig) - f = nullptr; -} - -/** - * Call all handlers from the given signal. - * - * It's not allowed to throw in handlers. - * - * Undefined behaviour if the signal is modified while iterating the handlers. - * - * \param sig the signal - * \param args the arguments to pass - */ -template <typename Signal, typename... Args> -void emit(Signal& sig, Args&&... args) noexcept -{ - for (auto &f : sig) - if (f) - f(std::forward<Args>(args)...); -} - -/** - * \brief Convenient type for most purposes. - */ -template <typename... Args> -using signal = std::vector<std::function<void (Args...)>>; - -} // !sig - -#endif // !SIGNALS_HPP
--- a/modules/signals/test/main.cpp Fri Dec 02 22:21:03 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,188 +0,0 @@ -/* - * main.cpp -- main test file for signals - * - * Copyright (c) 2016 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. - */ - -#include <gtest/gtest.h> - -#include "signals.hpp" - -using namespace testing; - -TEST(Connect, none) -{ - sig::signal<> sig; - sig::emit(sig); -} - -TEST(Connect, simple) -{ - sig::signal<> sig; - - bool called = false; - - sig::connect(sig, [&] () { - called = true; - }); - sig::emit(sig); - - ASSERT_TRUE(called); -} - -TEST(Connect, more) -{ - sig::signal<> sig; - - bool f1 = false, f2 = false; - - sig::connect(sig, [&] () { - f1 = true; - }); - sig::connect(sig, [&] () { - f2 = true; - }); - sig::emit(sig); - - ASSERT_TRUE(f1); - ASSERT_TRUE(f2); -} - -TEST(Disconnect, simple) -{ - sig::signal<> sig; - - auto called = false; - auto index = sig::connect(sig, [&] () { - called = true; - }); - sig::disconnect(sig, index); - sig::emit(sig); - - ASSERT_FALSE(called); -} - -TEST(Disconnect, more) -{ - sig::signal<> sig; - - auto called = false; - auto index = sig::connect(sig, [&] () { - called = true; - }); - sig::disconnect(sig, index); - sig::emit(sig); - - ASSERT_FALSE(called); -} - -TEST(Disconnect, middle) -{ - sig::signal<> sig; - - bool f1 = false, f2 = false, f3 = false; - - sig::connect(sig, [&] () { - f1 = true; - }); - auto idx = sig::connect(sig, [&] () { - f2 = true; - }); - sig::connect(sig, [&] () { - f3 = true; - }); - sig::disconnect(sig, idx); - sig::emit(sig); - - ASSERT_TRUE(f1); - ASSERT_FALSE(f2); - ASSERT_TRUE(f3); -} - -TEST(Disconnect, two) -{ - sig::signal<> sig; - - bool f1 = false, f2 = false, f3 = false; - - sig::connect(sig, [&] () { - f1 = true; - }); - auto idx1 = sig::connect(sig, [&] () { - f2 = true; - }); - auto idx2 = sig::connect(sig, [&] () { - f3 = true; - }); - sig::disconnect(sig, idx1); - sig::disconnect(sig, idx2); - sig::emit(sig); - - ASSERT_TRUE(f1); - ASSERT_FALSE(f2); - ASSERT_FALSE(f3); -} - -TEST(Disconnect, reuse) -{ - sig::signal<> sig; - - bool f1 = false, f2 = false, f3 = false; - - sig::connect(sig, [&] () { - f1 = true; - }); - auto idx = sig::connect(sig, [&] () { - f2 = true; - }); - sig::connect(sig, [&] () { - f3 = true; - }); - sig::disconnect(sig, idx); - sig::connect(sig, [&] () { - f2 = true; - }); - sig::emit(sig); - - ASSERT_TRUE(f1); - ASSERT_TRUE(f2); - ASSERT_TRUE(f3); -} - -TEST(Clear, basics) -{ - sig::signal<> sig; - - bool f1 = false, f2 = false; - - sig::connect(sig, [&] () { - f1 = true; - }); - sig::connect(sig, [&] () { - f2 = true; - }); - sig::clear(sig); - sig::emit(sig); - - ASSERT_FALSE(f1); - ASSERT_FALSE(f2); -} - -int main(int argc, char **argv) -{ - InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -}