1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
/***************************************************************************************************
Copyright (C) 2023 The Qt Company Ltd.
SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
***************************************************************************************************/
#pragma once
#include "qdotnetadapter.h"
class QDotNetRef
{
public:
static inline const QString &AssemblyQualifiedName = QStringLiteral("System.Object");
const void *gcHandle() const { return objectRef; }
bool isValid() const { return gcHandle() != nullptr; }
template<typename T, std::enable_if_t<std::is_base_of_v<QDotNetRef, T>, bool> = true>
T cast(bool copy = false)
{
T newObj(nullptr);
if (copy)
newObj.copyFrom(*this);
else
newObj.moveFrom(*this);
return newObj;
}
QDotNetRef(const void *objectRef = nullptr)
: objectRef(objectRef)
{}
QDotNetRef(const QDotNetRef &cpySrc)
{
copyFrom(cpySrc);
}
QDotNetRef(QDotNetRef &&movSrc) noexcept
{
moveFrom(movSrc);
}
virtual ~QDotNetRef()
{
freeObjectRef();
}
QDotNetRef &operator=(const QDotNetRef &cpySrc)
{
return copyFrom(cpySrc);
}
QDotNetRef &operator=(QDotNetRef &&movSrc) noexcept
{
return moveFrom(movSrc);
}
template<typename T, std::enable_if_t<std::is_base_of_v<QDotNetRef, T>, bool> = true>
class Null
{};
QString toString() const
{
if (!fnToString.isValid()) {
const QList<QDotNetParameter> parameters
{
QDotNetInbound<QString>::Parameter
};
fnToString = adapter().resolveInstanceMethod(*this, "ToString", parameters);
}
return fnToString();
}
bool equals(const QDotNetRef &obj) const
{
if (!fnEquals.isValid()) {
const QList<QDotNetParameter> parameters
{
QDotNetInbound<bool>::Parameter,
QDotNetOutbound<QDotNetRef>::Parameter
};
fnEquals = adapter().resolveInstanceMethod(*this, "Equals", parameters);
}
return fnEquals(obj);
}
protected:
static QDotNetAdapter &adapter() { return QDotNetAdapter::instance(); }
void attach(const void *objectRef)
{
this->objectRef = objectRef;
}
QDotNetRef ©From(const QDotNetRef &that)
{
freeObjectRef();
if (that.isValid())
objectRef = adapter().addObjectRef(that);
return *this;
}
QDotNetRef &moveFrom(QDotNetRef &that)
{
freeObjectRef();
objectRef = that.objectRef;
that.objectRef = nullptr;
return *this;
}
private:
void freeObjectRef()
{
if (!isValid())
return;
adapter().freeObjectRef(*this);
objectRef = nullptr;
}
const void *objectRef = nullptr;
mutable QDotNetFunction<QString> fnToString = nullptr;
mutable QDotNetFunction<bool, QDotNetRef> fnEquals = nullptr;
};
template<typename T>
struct QDotNetOutbound<QDotNetRef::Null<T>, std::enable_if_t<std::is_base_of_v<QDotNetRef, T>>>
{
using SourceType = nullptr_t;
using OutboundType = const void*;
static inline const QDotNetParameter Parameter =
QDotNetParameter(QDotNetTypeOf<T>::TypeName, QDotNetTypeOf<T>::MarshalAs);
static OutboundType convert(SourceType dotNetObj)
{
return nullptr;
}
};
|