diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | debian/control | 1 | ||||
-rw-r--r-- | include/CMakeLists.txt | 1 | ||||
-rw-r--r-- | include/core/CMakeLists.txt | 2 | ||||
-rw-r--r-- | include/core/connection.h | 162 | ||||
-rw-r--r-- | include/core/property.h | 181 | ||||
-rw-r--r-- | include/core/signal.h | 297 |
7 files changed, 2 insertions, 643 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index da97a6d..bf34ebb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ pkg_check_modules (SERVICE_DEPS REQUIRED libedataserver-1.2>=3.5 libnotify>=0.7.6 url-dispatcher-1>=1 + properties-cpp>=0.0.1 json-glib-1.0>=0.16.2) include_directories (SYSTEM ${SERVICE_DEPS_INCLUDE_DIRS}) diff --git a/debian/control b/debian/control index 357b099..3dc61c6 100644 --- a/debian/control +++ b/debian/control @@ -25,6 +25,7 @@ Build-Depends: cmake, libgnome-control-center-dev, libtimezonemap1-dev, liburl-dispatcher1-dev, + libproperties-cpp-dev, Standards-Version: 3.9.3 Homepage: https://launchpad.net/indicator-datetime # If you aren't a member of ~indicator-applet-developers but need to upload diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index cfef04b..486e9c7 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,2 +1 @@ -add_subdirectory(core) add_subdirectory(datetime) diff --git a/include/core/CMakeLists.txt b/include/core/CMakeLists.txt deleted file mode 100644 index 139597f..0000000 --- a/include/core/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/include/core/connection.h b/include/core/connection.h deleted file mode 100644 index 37b1355..0000000 --- a/include/core/connection.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright © 2013 Canonical Ltd. - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Authored by: Thomas Voß <thomas.voss@canonical.com> - */ -#ifndef COM_UBUNTU_CONNECTION_H_ -#define COM_UBUNTU_CONNECTION_H_ - -#include <functional> -#include <memory> -#include <mutex> - -namespace core -{ -/** - * @brief The Connection class models a signal-slot connection. - */ -class Connection -{ -public: - typedef std::function<void(const std::function<void()>&)> Dispatcher; - - /** - * @brief Checks if this instance corresponds to an active signal-slot connection. - * @return true iff the instance corresponds to an active signal-slot connection. - */ - inline bool is_connected() const - { - return (d->disconnector ? true : false); - } - - /** - * @brief End a signal-slot connection. - */ - inline void disconnect() - { - d->disconnect(); - } - - /** - * @brief Installs a dispatcher for this signal-slot connection. - * @param dispatcher The dispatcher to be used for signal emissions. - */ - inline void dispatch_via(const Dispatcher& dispatcher) - { - if (d->dispatcher_installer) - d->dispatcher_installer(dispatcher); - } - -private: - typedef std::function<void()> Disconnector; - typedef std::function<void(const Dispatcher&)> DispatcherInstaller; - - template<typename ... Arguments> friend class Signal; - - inline Connection(const Disconnector& disconnector, - const DispatcherInstaller& installer) - : d(std::make_shared<Private>(disconnector, installer)) - { - } - - inline void reset() - { - d->reset(); - } - - struct Private - { - Private(const Connection::Disconnector& disconnector_, - const Connection::DispatcherInstaller& dispatcher_installer_) - : disconnector(disconnector_), - dispatcher_installer(dispatcher_installer_) - { - } - - inline void reset() - { - std::lock_guard<std::mutex> lg(guard); - reset_locked(); - } - - inline void reset_locked() - { - static const Connection::Disconnector empty_disconnector{}; - static const Connection::DispatcherInstaller empty_dispatcher_installer{}; - - disconnector = empty_disconnector; - dispatcher_installer = empty_dispatcher_installer; - } - - inline void disconnect() - { - static const Connection::Disconnector empty_disconnector{}; - - std::lock_guard<std::mutex> lg(guard); - - if (disconnector) - disconnector(); - - reset_locked(); - } - - std::mutex guard; - Connection::Disconnector disconnector; - Connection::DispatcherInstaller dispatcher_installer; - }; - - // The whole class is implicitly shared and we thus forward our complete - // shared state to a private structure that is lifetime-managed by a shared_ptr. - std::shared_ptr<Private> d; -}; - -/** - * @brief Scoped helper class to map signal-slot connection mgmt. to RAII. - */ -class ScopedConnection -{ -public: - /** - * @brief Constructs an instance for an existing signal-slot connection. - * @param c The existing signal-slot connection. - */ - inline ScopedConnection(const Connection& c) : connection(c) - { - } - - ScopedConnection(const ScopedConnection&) = delete; - - /** - * @brief Disconnects the signal-slot connection. - */ - inline ~ScopedConnection() noexcept(true) - { - try - { - connection.disconnect(); - } catch(...) - { - } - } - - ScopedConnection& operator=(const ScopedConnection&) = delete; - bool operator==(const ScopedConnection&) = delete; - -private: - Connection connection; -}; -} - -#endif // COM_UBUNTU_CONNECTION_H_ diff --git a/include/core/property.h b/include/core/property.h deleted file mode 100644 index 996ba8a..0000000 --- a/include/core/property.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright © 2013 Canonical Ltd. - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Authored by: Thomas Voß <thomas.voss@canonical.com> - */ -#ifndef CORE_PROPERTY_H_ -#define CORE_PROPERTY_H_ - -#include <core/signal.h> - -#include <iostream> - -namespace core -{ -/** - * @brief A very simple, templated class that allows for uniform declaration of get-able/set-able/observable members. - * @tparam The type of the value contained within the property. - */ -template<typename T> -class Property -{ - public: - /** - * @brief ValueType refers to the type of the contained value. - */ - typedef T ValueType; - - /** - * @brief Property creates a new instance of property and initializes the contained value. - * @param t The initial value, defaults to Property<T>::default_value(). - */ - inline explicit Property(const T& t = T{}) : value{t} - { - } - - /** - * @brief Copy c'tor, only copies the contained value, not the changed signal and its connections. - * @param rhs - */ - inline Property(const Property<T>& rhs) : value{rhs.value} - { - } - - inline virtual ~Property() = default; - - /** - * @brief Assignment operator, only assigns to the contained value. - * @param rhs The right-hand-side, raw value to assign to this property. - */ - inline Property& operator=(const T& rhs) - { - set(rhs); - return *this; - } - - /** - * @brief Assignment operator, only assigns to the contained value, not the changed signal and its connections. - * @param rhs The right-hand-side property to assign from. - */ - inline Property& operator=(const Property<T>& rhs) - { - set(rhs.value); - return *this; - } - - /** - * @brief Explicit casting operator to the contained value type. - * @return A non-mutable reference to the contained value. - */ - inline operator const T&() const - { - return get(); - } - - /** - * @brief Provides access to a pointer to the contained value. - */ - inline const T* operator->() const - { - return &get(); - } - - /** - * @brief operator == checks if the value of a property and a raw value are equal. - * @param lhs Non-mutable reference to a property. - * @param rhs Non-mutable reference to a raw value. - * @return True iff the value contained in lhs equals rhs. - */ - friend inline bool operator==(const Property<T>& lhs, const T& rhs) - { - return lhs.get() == rhs; - } - - /** - * @brief operator == checks if the value of two properties are equal. - * @param lhs Non-mutable reference to a property. - * @param rhs Non-mutable reference to a property. - * @return True iff the value contained in lhs equals the value contained in rhs. - */ - friend inline bool operator==(const Property<T>& lhs, const Property<T>& rhs) - { - return lhs.get() == rhs.get(); - } - - /** - * @brief Set the contained value to the provided value. Notify observers of the change. - * @param [in] new_value The new value to assign to this property. - * @post get() == new_value; - */ - inline virtual void set(const T& new_value) - { - if (value != new_value) - { - value = new_value; - signal_changed(value); - } - } - - /** - * @brief Access the value contained within this property. - * @return A non-mutable reference to the property value. - */ - inline virtual const T& get() const - { - return value; - } - - /** - * @brief Access to the changed signal, allows observers to subscribe to change notifications. - * @return A non-mutable reference to the changed signal. - */ - inline const Signal<T>& changed() const - { - return signal_changed; - } - - /** - * @brief Provides in-place update facilities. - * - * The provided update_functor is applied to the contained value. If the update functor - * returns true, indicating that the value has been changed, the changed signal is emitted. - * - * @param update_functor The update function to be applied to the contained value. - * @return true iff application of the update functor has been successful. - */ - inline virtual bool update(const std::function<bool(T& t)>& update_functor) - { - if (update_functor(mutable_get())) - { - signal_changed(value); - return true; - } - - return false; - } - - protected: - inline T& mutable_get() const - { - return value; - } - - private: - mutable T value; - Signal<T> signal_changed; -}; -} - -#endif // CORE_PROPERTY_H_ diff --git a/include/core/signal.h b/include/core/signal.h deleted file mode 100644 index be2984b..0000000 --- a/include/core/signal.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright © 2013 Canonical Ltd. - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Authored by: Thomas Voß <thomas.voss@canonical.com> - */ -#ifndef COM_UBUNTU_SIGNAL_H_ -#define COM_UBUNTU_SIGNAL_H_ - -#include <core/connection.h> - -#include <functional> -#include <iostream> -#include <list> -#include <mutex> -#include <set> - -namespace core -{ -/** - * @brief A signal class that observers can subscribe to. - * @tparam Arguments List of argument types passed on to observers when the signal is emitted. - */ -template<typename ...Arguments> -class Signal -{ -public: - /** - * @brief Slot is the function type that observers have to provide to connect to this signal. - */ - typedef std::function<void(Arguments...)> Slot; - -private: - struct SlotWrapper - { - void operator()(Arguments... args) - { - dispatcher(std::bind(slot, args...)); - } - - Slot slot; - Connection::Dispatcher dispatcher; - Connection connection; - }; - -public: - /** - * @brief Signal constructs a new instance. Never throws. - */ - inline Signal() noexcept(true) : d(new Private()) - { - } - - inline ~Signal() - { - std::lock_guard<std::mutex> lg(d->guard); - for (auto slot : d->slots) - slot.connection.reset(); - } - - // Copy construction, assignment and equality comparison are disabled. - Signal(const Signal&) = delete; - Signal& operator=(const Signal&) = delete; - bool operator==(const Signal&) const = delete; - - /** - * @brief Connects the provided slot to this signal instance. - * - * Calling this method is thread-safe and synchronized with any - * other connect, signal emission or disconnect calls. - * - * @param slot The function to be called when the signal is emitted. - * @return A connection object corresponding to the signal-slot connection. - */ - inline Connection connect(const Slot& slot) const - { - // Helpers to initialize an invalid connection. - static const Connection::Disconnector empty_disconnector{}; - static const Connection::DispatcherInstaller empty_dispatcher_installer{}; - - // The default dispatcher immediately executes the function object - // provided as argument on whatever thread is currently running. - static const Connection::Dispatcher default_dispatcher - = [](const std::function<void()>& handler) { handler(); }; - - Connection conn{empty_disconnector, empty_dispatcher_installer}; - - std::lock_guard<std::mutex> lg(d->guard); - - auto result = d->slots.insert( - d->slots.end(), - SlotWrapper{slot, default_dispatcher, conn}); - - // We implicitly share our internal state with the connection here - // by passing in our private bits contained in 'd' to the std::bind call. - // This admittedly uncommon approach allows us to cleanly manage connection - // and signal lifetimes without the need to mark everything as mutable. - conn.d->disconnector = std::bind( - &Private::disconnect_slot_for_iterator, - d, - result); - conn.d->dispatcher_installer = std::bind( - &Private::install_dispatcher_for_iterator, - d, - std::placeholders::_1, - result); - - return conn; - } - - /** - * @brief operator () emits the signal with the provided parameters. - * - * Please note that signal emissions might not be delivered immediately to - * registered slots, depending on whether the respective connection is dispatched - * via a queueing dispatcher. For that reason, the lifetime of the arguments has to - * exceed the scope of the call to this operator and its surrounding scope. - * - * @param args The arguments to be passed on to registered slots. - */ - inline void operator()(Arguments... args) - { - std::lock_guard<std::mutex> lg(d->guard); - for(auto slot : d->slots) - { - slot(args...); - } - } - -private: - struct Private - { - typedef std::list<SlotWrapper> SlotContainer; - - inline void disconnect_slot_for_iterator(typename SlotContainer::iterator it) - { - std::lock_guard<std::mutex> lg(guard); - slots.erase(it); - } - - inline void install_dispatcher_for_iterator(const Connection::Dispatcher& dispatcher, - typename SlotContainer::iterator it) - { - std::lock_guard<std::mutex> lg(guard); - it->dispatcher = dispatcher; - } - - std::mutex guard; - SlotContainer slots; - }; - std::shared_ptr<Private> d; -}; - -/** - * @brief A signal class that observers can subscribe to, - * template specialization for signals without arguments. - */ -template<> -class Signal<void> -{ -public: - /** - * @brief Slot is the function type that observers have to provide to connect to this signal. - */ - typedef std::function<void()> Slot; - -private: - struct SlotWrapper - { - void operator()() - { - dispatcher(slot); - } - - Slot slot; - Connection::Dispatcher dispatcher; - Connection connection; - }; - -public: - /** - * @brief Signal constructs a new instance. Never throws. - */ - inline Signal() noexcept(true) : d(new Private()) - { - } - - inline ~Signal() - { - std::lock_guard<std::mutex> lg(d->guard); - for (auto slot : d->slots) - slot.connection.reset(); - } - - // Copy construction, assignment and equality comparison are disabled. - Signal(const Signal&) = delete; - Signal& operator=(const Signal&) = delete; - bool operator==(const Signal&) const = delete; - - /** - * @brief Connects the provided slot to this signal instance. - * - * Calling this method is thread-safe and synchronized with any - * other connect, signal emission or disconnect calls. - * - * @param slot The function to be called when the signal is emitted. - * @return A connection object corresponding to the signal-slot connection. - */ - inline Connection connect(const Slot& slot) const - { - // Helpers to initialize an invalid connection. - static const Connection::Disconnector empty_disconnector{}; - static const Connection::DispatcherInstaller empty_dispatcher_installer{}; - - // The default dispatcher immediately executes the function object - // provided as argument on whatever thread is currently running. - static const Connection::Dispatcher default_dispatcher - = [](const std::function<void()>& handler) { handler(); }; - - Connection conn{empty_disconnector, empty_dispatcher_installer}; - - std::lock_guard<std::mutex> lg(d->guard); - - auto result = d->slots.insert( - d->slots.end(), - SlotWrapper{slot, default_dispatcher, conn}); - - // We implicitly share our internal state with the connection here - // by passing in our private bits contained in 'd' to the std::bind call. - // This admittedly uncommon approach allows us to cleanly manage connection - // and signal lifetimes without the need to mark everything as mutable. - conn.d->disconnector = std::bind( - &Private::disconnect_slot_for_iterator, - d, - result); - conn.d->dispatcher_installer = std::bind( - &Private::install_dispatcher_for_iterator, - d, - std::placeholders::_1, - result); - - return conn; - } - - /** - * @brief operator () emits the signal. - * - * Please note that signal emissions might not be delivered immediately to - * registered slots, depending on whether the respective connection is dispatched - * via a queueing dispatcher. - */ - inline void operator()() - { - std::lock_guard<std::mutex> lg(d->guard); - for(auto slot : d->slots) - { - slot(); - } - } - -private: - struct Private - { - typedef std::list<SlotWrapper> SlotContainer; - - inline void disconnect_slot_for_iterator(typename SlotContainer::iterator it) - { - std::lock_guard<std::mutex> lg(guard); - slots.erase(it); - } - - inline void install_dispatcher_for_iterator(const Connection::Dispatcher& dispatcher, - typename SlotContainer::iterator it) - { - std::lock_guard<std::mutex> lg(guard); - it->dispatcher = dispatcher; - } - - std::mutex guard; - SlotContainer slots; - }; - std::shared_ptr<Private> d; -}; -} - -#endif // COM_UBUNTU_SIGNAL_H_ |