1 /*
2   enumrepositoryserver.h
3 
4   This file is part of GammaRay, the Qt application inspection and
5   manipulation tool.
6 
7   Copyright (C) 2016-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
8   Author: Volker Krause <volker.krause@kdab.com>
9 
10   Licensees holding valid commercial KDAB GammaRay licenses may use this file in
11   accordance with GammaRay Commercial License Agreement provided with the Software.
12 
13   Contact info@kdab.com if any conditions of this licensing are not clear to you.
14 
15   This program is free software; you can redistribute it and/or modify
16   it under the terms of the GNU General Public License as published by
17   the Free Software Foundation, either version 2 of the License, or
18   (at your option) any later version.
19 
20   This program is distributed in the hope that it will be useful,
21   but WITHOUT ANY WARRANTY; without even the implied warranty of
22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23   GNU General Public License for more details.
24 
25   You should have received a copy of the GNU General Public License
26   along with this program.  If not, see <http://www.gnu.org/licenses/>.
27 */
28 
29 #ifndef GAMMARAY_ENUMREPOSITORYSERVER_H
30 #define GAMMARAY_ENUMREPOSITORYSERVER_H
31 
32 #include "gammaray_core_export.h"
33 #include "metaenum.h"
34 
35 #include <common/enumrepository.h>
36 
37 #include <QHash>
38 
39 QT_BEGIN_NAMESPACE
40 class QMetaEnum;
41 QT_END_NAMESPACE
42 
43 namespace GammaRay {
44 
45 /*! Probe-side enum definition management.
46  * Use this to obtain enum value representations that can be safely transferred to the client.
47  */
48 class EnumRepositoryServer : public EnumRepository
49 {
50     Q_OBJECT
51 public:
52     ~EnumRepositoryServer() override;
53 
54     /*! Creates an EnumValue instance for the given numeric value and QMetaEnum.
55      *  If not yet present, the enum definition with be registered
56      *  with the EnumRepositoryServer, so that the client has access
57      *  to the key/value mappings of the enum if needed.
58      */
59     static GAMMARAY_CORE_EXPORT EnumValue valueFromMetaEnum(int value, const QMetaEnum &me);
60 
61     /*! Creates an EnumValue instance for a given QVariant containing a registered
62      *  GammaRay::MetaEnum value.
63      */
64     static GAMMARAY_CORE_EXPORT EnumValue valueFromVariant(const QVariant &value);
65 
66     /*! Check if the given meta type id is a known enum. */
67     static GAMMARAY_CORE_EXPORT bool isEnum(int metaTypeId);
68 
69     //! @cond internal
70     static GAMMARAY_CORE_EXPORT EnumRepository* create(QObject *parent); // only exported for unit tests
71 
72     template <typename Enum, typename V, std::size_t N>
registerEnum(const MetaEnum::Value<V> (& lookup_table)[N],const char * name,bool flag)73     static void registerEnum(const MetaEnum::Value<V>(&lookup_table)[N], const char* name, bool flag)
74     {
75         if (isEnum(qMetaTypeId<Enum>()))
76             return;
77         QVector<EnumDefinitionElement> elements;
78         elements.reserve(N);
79         for (std::size_t i = 0; i < N; ++i)
80             elements.push_back(EnumDefinitionElement(lookup_table[i].value, lookup_table[i].name));
81         registerEnum(qMetaTypeId<Enum>(), name, elements, flag);
82     }
83     static GAMMARAY_CORE_EXPORT void registerEnum(int metaTypeId, const char *name, const QVector<EnumDefinitionElement> &elems, bool flag);
84 
definitionForId(EnumId id)85     static inline EnumDefinition definitionForId(EnumId id)
86     {
87         return s_instance->definition(id);
88     }
89     //! @endcond
90 private:
91     explicit EnumRepositoryServer(QObject *parent = nullptr);
92     void requestDefinition(EnumId id) override;
93 
94     EnumId m_nextId;
95 
96     static EnumRepositoryServer *s_instance;
97 
98     QHash<QByteArray, EnumId> m_nameToIdMap;
99     QHash<int, EnumId> m_typeIdToIdMap;
100 };
101 }
102 
103 /*! Register a MetaEnum lookup table with the EnumRepository. */
104 #define ER_REGISTER_ENUM(Class, Name, LookupTable) { \
105     EnumRepositoryServer::registerEnum<Class::Name>(LookupTable, #Class "::" #Name, false); \
106 }
107 
108 /*! Register a MetaEnum lookup table with the EnumRepository. */
109 #define ER_REGISTER_FLAGS(Class, Name, LookupTable) { \
110     EnumRepositoryServer::registerEnum<Class::Name>(LookupTable, #Class "::" #Name, true); \
111 }
112 
113 #endif // GAMMARAY_ENUMREPOSITORYSERVER_H
114