1 /* 2 Copyright © 2019 by The qTox Project Contributors 3 4 This file is part of qTox, a Qt-based graphical interface for Tox. 5 6 qTox is libre software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 qTox is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with qTox. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef INTERFACE_H 21 #define INTERFACE_H 22 23 #include <QMetaObject> 24 25 #include <functional> 26 27 /** 28 * @file interface.h 29 * 30 * Qt doesn't support QObject multiple inheritance. But for declaring signals 31 * in class, it should be inherit QObject. To avoid this issue, interface can 32 * provide some pure virtual methods, which allow to connect to some signal. 33 * 34 * This file provides macros to make signals declaring easly. With this macros 35 * signal-like method will be declared and implemented in one line each. 36 * 37 * @example 38 * class IExample { 39 * public: 40 * // Like signal: void valueChanged(int value) const; 41 * // Declare `connectTo_valueChanged` method. 42 * DECLARE_SIGNAL(valueChanged, int value); 43 * }; 44 * 45 * class Example : public QObject, public IExample { 46 * public: 47 * // Declare real signal and implement `connectTo_valueChanged` 48 * SIGNAL_IMPL(Example, valueChanged, int value); 49 * }; 50 */ 51 #define DECLARE_SIGNAL(name, ...) \ 52 using Slot_##name = std::function<void (__VA_ARGS__)>; \ 53 virtual QMetaObject::Connection connectTo_##name(QObject *receiver, Slot_##name slot) const = 0 54 55 /** 56 * @def DECLARE_SIGNAL 57 * @brief Decalre signal-like method. Should be used in interface 58 */ 59 #define DECLARE_SIGNAL(name, ...) \ 60 using Slot_##name = std::function<void (__VA_ARGS__)>; \ 61 virtual QMetaObject::Connection connectTo_##name(QObject *receiver, Slot_##name slot) const = 0 62 63 /** 64 * @def SIGNAL_IMPL 65 * @brief Declare signal and implement signal-like method. 66 */ 67 #define SIGNAL_IMPL(classname, name, ...) \ 68 using Slot_##name = std::function<void (__VA_ARGS__)>; \ 69 Q_SIGNAL void name(__VA_ARGS__); \ 70 QMetaObject::Connection connectTo_##name(QObject *receiver, Slot_##name slot) const override { \ 71 return connect(this, &classname::name, receiver, slot); \ 72 } 73 74 #endif // INTERFACE_H 75