diff --git a/src/blackmisc/slot.h b/src/blackmisc/slot.h new file mode 100644 index 000000000..fbe7047ea --- /dev/null +++ b/src/blackmisc/slot.h @@ -0,0 +1,88 @@ +/* Copyright (C) 2016 + * swift Project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISC_SLOT_H +#define BLACKMISC_SLOT_H + +#include +#include +#include +#include + +namespace BlackMisc +{ + /*! + * Callable wrapper for a member function with function signature F. General template, not + * implemented; the partial specialization for function signatures is what does the actual work + * (similar to how std::function is defined). + */ + template + class CSlot; + + /*! + * Callable wrapper for a member function with function signature R(Args...). + * Allows for easy manipulation of slots to be used as callbacks. + * + * \todo Use perfect forwarding with C++14 generic lambda. + */ + template + class CSlot + { + public: + //! Construct an empty slot. + CSlot() {} + + //! Construct a slot from the given member function of the given object. + template + CSlot(T *object, R(U::* function)(Args...)) : + m_object(object), + m_function([ = ](Args... args) { return (object->*function)(args...); }) + {} + + //! Call the slot. The behaviour is undefined if the slot is empty. + R operator()(Args... args) const + { + Q_ASSERT_X(m_function, Q_FUNC_INFO, "Empty CSlot was called"); + return m_function(args...); + } + + //! Returns the object which the slot belongs to. + //! Use this as the third argument to QObject::connect to ensure the slot is called in the correct thread. + QObject *object() const + { + return m_object.data(); + } + + //! True if the slot can be called, false if it is empty. + operator bool() const + { + return !this->isEmpty(); + } + + //! True if the slot is empty, false if it can be called. + bool operator !() const + { + return this->isEmpty(); + } + + //! True if the slot is empty, false if it can be called. + bool isEmpty() const + { + return ! m_function; + } + + private: + QPointer m_object; + std::function m_function; + }; +} + +#endif