1 /*
2   objectid.h
3 
4   This file is part of GammaRay, the Qt application inspection and
5   manipulation tool.
6 
7   Copyright (C) 2013-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
8   Author: Kevin Funk <kevin.funk@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_OBJECTID_H
30 #define GAMMARAY_OBJECTID_H
31 
32 #include <QObject>
33 #include <QDataStream>
34 #include <QDebug>
35 #include <QMetaType>
36 #include <QVector>
37 
38 #if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
39 #include <algorithm>
40 #endif
41 
42 namespace GammaRay {
43 /** @brief Type-safe and cross-process object identifier vector. */
44 using ObjectIds = QVector<class ObjectId>;
45 
46 /** @brief Type-safe and cross-process object identifier. */
47 class ObjectId
48 {
49 public:
50     enum Type
51     {
52         Invalid,
53         QObjectType,
54         VoidStarType
55     };
56 
ObjectId(void * obj,const QByteArray & typeName)57     explicit ObjectId(void *obj, const QByteArray &typeName)
58         : m_type(VoidStarType)
59         , m_id(reinterpret_cast<quint64>(obj))
60         , m_typeName(typeName)
61     {}
ObjectId(QObject * obj)62     explicit ObjectId(QObject *obj)
63         : m_type(QObjectType)
64         , m_id(reinterpret_cast<quint64>(obj))
65     {}
66     explicit ObjectId() = default;
isNull()67     inline bool isNull() const { return m_id == 0; }
id()68     inline quint64 id() const { return m_id; }
type()69     inline Type type() const { return m_type; }
typeName()70     inline QByteArray typeName() const { return m_typeName; }
71 
asQObject()72     inline QObject *asQObject() const
73     {
74         Q_ASSERT(m_type == QObjectType);
75         return reinterpret_cast<QObject *>(m_id);
76     }
77 
78     template <typename T>
asQObjectType()79     inline T asQObjectType() const
80     {
81         return qobject_cast<T>(asQObject());
82     }
83 
asVoidStar()84     inline void *asVoidStar() const
85     {
86         Q_ASSERT(m_type == VoidStarType);
87         return reinterpret_cast<void *>(m_id);
88     }
89 
quint64()90     inline operator quint64() const { return m_id; }
91 
92 private:
93     friend QDataStream &operator<<(QDataStream &out, const ObjectId &id);
94     friend QDataStream &operator>>(QDataStream &out, ObjectId &id);
95 
96     Type m_type = Invalid;
97     quint64 m_id = 0;
98     QByteArray m_typeName;
99 };
100 
101 ///@cond internal
102 inline QDebug &operator<<(QDebug dbg, const ObjectId &id)
103 {
104     dbg.nospace() << "ObjectId(" << id.type() << ", " << id.id() << ", " << id.typeName() << ")";
105     return dbg.space();
106 }
107 
108 #if QT_VERSION < QT_VERSION_CHECK(5, 6, 0)
109 inline bool operator<(const ObjectIds &lhs, const ObjectIds &rhs)
110 {
111     return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
112 }
113 #endif
114 
115 inline QDataStream &operator<<(QDataStream &out, const ObjectId &id)
116 {
117     out << static_cast<quint8>(id.m_type);
118     out << id.m_id;
119     out << id.m_typeName;
120     return out;
121 }
122 
123 inline QDataStream &operator>>(QDataStream &in, ObjectId &id)
124 {
125     quint8 u;
126     in >> u;
127     id.m_type = static_cast<ObjectId::Type>(u);
128     in >> id.m_id;
129     in >> id.m_typeName;
130     return in;
131 }
132 ///@endcond
133 }
134 
135 Q_DECLARE_METATYPE(GammaRay::ObjectId)
136 Q_DECLARE_METATYPE(GammaRay::ObjectIds)
137 QT_BEGIN_NAMESPACE
138     Q_DECLARE_TYPEINFO(GammaRay::ObjectId, Q_MOVABLE_TYPE);
139     Q_DECLARE_TYPEINFO(GammaRay::ObjectIds, Q_MOVABLE_TYPE);
140 QT_END_NAMESPACE
141 
142 #endif // GAMMARAY_OBJECTID_H
143