Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/core/variant/method_ptrcall.h
9898 views
1
/**************************************************************************/
2
/* method_ptrcall.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "core/object/object_id.h"
34
#include "core/templates/simple_type.h"
35
#include "core/typedefs.h"
36
#include "core/variant/variant.h"
37
38
namespace Internal {
39
40
template <typename T>
41
struct PtrToArgDirect {
42
_FORCE_INLINE_ static const T &convert(const void *p_ptr) {
43
return *reinterpret_cast<const T *>(p_ptr);
44
}
45
typedef T EncodeT;
46
_FORCE_INLINE_ static void encode(T p_val, void *p_ptr) {
47
*((T *)p_ptr) = p_val;
48
}
49
};
50
51
template <typename T, typename S>
52
struct PtrToArgConvert {
53
_FORCE_INLINE_ static T convert(const void *p_ptr) {
54
return static_cast<T>(*reinterpret_cast<const S *>(p_ptr));
55
}
56
typedef S EncodeT;
57
_FORCE_INLINE_ static void encode(T p_val, void *p_ptr) {
58
*((S *)p_ptr) = static_cast<S>(p_val);
59
}
60
};
61
62
template <typename T>
63
struct PtrToArgByReference {
64
_FORCE_INLINE_ static const T &convert(const void *p_ptr) {
65
return *reinterpret_cast<const T *>(p_ptr);
66
}
67
typedef T EncodeT;
68
_FORCE_INLINE_ static void encode(const T &p_val, void *p_ptr) {
69
*((T *)p_ptr) = p_val;
70
}
71
};
72
73
template <typename T, typename TAlt>
74
struct PtrToArgVectorConvert {
75
_FORCE_INLINE_ static Vector<TAlt> convert(const void *p_ptr) {
76
const Vector<T> *dvs = reinterpret_cast<const Vector<T> *>(p_ptr);
77
Vector<TAlt> ret;
78
int len = dvs->size();
79
ret.resize(len);
80
{
81
const T *r = dvs->ptr();
82
for (int i = 0; i < len; i++) {
83
ret.write[i] = r[i];
84
}
85
}
86
return ret;
87
}
88
// No EncodeT because direct pointer conversion not possible.
89
_FORCE_INLINE_ static void encode(const Vector<TAlt> &p_vec, void *p_ptr) {
90
Vector<T> *dv = reinterpret_cast<Vector<T> *>(p_ptr);
91
int len = p_vec.size();
92
dv->resize(len);
93
{
94
T *w = dv->ptrw();
95
for (int i = 0; i < len; i++) {
96
w[i] = p_vec[i];
97
}
98
}
99
}
100
};
101
102
template <typename T>
103
struct PtrToArgVectorFromArray {
104
_FORCE_INLINE_ static Vector<T> convert(const void *p_ptr) {
105
const Array *arr = reinterpret_cast<const Array *>(p_ptr);
106
Vector<T> ret;
107
int len = arr->size();
108
ret.resize(len);
109
for (int i = 0; i < len; i++) {
110
ret.write[i] = (*arr)[i];
111
}
112
return ret;
113
}
114
// No EncodeT because direct pointer conversion not possible.
115
_FORCE_INLINE_ static void encode(const Vector<T> &p_vec, void *p_ptr) {
116
Array *arr = reinterpret_cast<Array *>(p_ptr);
117
int len = p_vec.size();
118
arr->resize(len);
119
for (int i = 0; i < len; i++) {
120
(*arr)[i] = p_vec[i];
121
}
122
}
123
};
124
125
template <typename T>
126
struct PtrToArgStringConvertByReference {
127
_FORCE_INLINE_ static T convert(const void *p_ptr) {
128
T s = *reinterpret_cast<const String *>(p_ptr);
129
return s;
130
}
131
// No EncodeT because direct pointer conversion not possible.
132
_FORCE_INLINE_ static void encode(const T &p_vec, void *p_ptr) {
133
String *arr = reinterpret_cast<String *>(p_ptr);
134
*arr = String(p_vec);
135
}
136
};
137
138
} //namespace Internal
139
140
template <typename T, typename = void>
141
struct PtrToArg;
142
143
template <typename T>
144
struct PtrToArg<T, std::enable_if_t<!std::is_same_v<T, GetSimpleTypeT<T>>>> : PtrToArg<GetSimpleTypeT<T>> {};
145
146
template <>
147
struct PtrToArg<bool> : Internal::PtrToArgConvert<bool, uint8_t> {};
148
// Integer types.
149
template <>
150
struct PtrToArg<uint8_t> : Internal::PtrToArgConvert<uint8_t, int64_t> {};
151
template <>
152
struct PtrToArg<int8_t> : Internal::PtrToArgConvert<int8_t, int64_t> {};
153
template <>
154
struct PtrToArg<uint16_t> : Internal::PtrToArgConvert<uint16_t, int64_t> {};
155
template <>
156
struct PtrToArg<int16_t> : Internal::PtrToArgConvert<int16_t, int64_t> {};
157
template <>
158
struct PtrToArg<uint32_t> : Internal::PtrToArgConvert<uint32_t, int64_t> {};
159
template <>
160
struct PtrToArg<int32_t> : Internal::PtrToArgConvert<int32_t, int64_t> {};
161
template <>
162
struct PtrToArg<int64_t> : Internal::PtrToArgDirect<int64_t> {};
163
template <>
164
struct PtrToArg<uint64_t> : Internal::PtrToArgDirect<uint64_t> {};
165
// Float types
166
template <>
167
struct PtrToArg<float> : Internal::PtrToArgConvert<float, double> {};
168
template <>
169
struct PtrToArg<double> : Internal::PtrToArgDirect<double> {};
170
171
template <>
172
struct PtrToArg<String> : Internal::PtrToArgDirect<String> {};
173
template <>
174
struct PtrToArg<Vector2> : Internal::PtrToArgDirect<Vector2> {};
175
template <>
176
struct PtrToArg<Vector2i> : Internal::PtrToArgDirect<Vector2i> {};
177
template <>
178
struct PtrToArg<Rect2> : Internal::PtrToArgDirect<Rect2> {};
179
template <>
180
struct PtrToArg<Rect2i> : Internal::PtrToArgDirect<Rect2i> {};
181
template <>
182
struct PtrToArg<Vector3> : Internal::PtrToArgByReference<Vector3> {};
183
template <>
184
struct PtrToArg<Vector3i> : Internal::PtrToArgByReference<Vector3i> {};
185
template <>
186
struct PtrToArg<Vector4> : Internal::PtrToArgByReference<Vector4> {};
187
template <>
188
struct PtrToArg<Vector4i> : Internal::PtrToArgByReference<Vector4i> {};
189
template <>
190
struct PtrToArg<Transform2D> : Internal::PtrToArgDirect<Transform2D> {};
191
template <>
192
struct PtrToArg<Projection> : Internal::PtrToArgDirect<Projection> {};
193
template <>
194
struct PtrToArg<Plane> : Internal::PtrToArgByReference<Plane> {};
195
template <>
196
struct PtrToArg<Quaternion> : Internal::PtrToArgDirect<Quaternion> {};
197
template <>
198
struct PtrToArg<AABB> : Internal::PtrToArgByReference<AABB> {};
199
template <>
200
struct PtrToArg<Basis> : Internal::PtrToArgByReference<Basis> {};
201
template <>
202
struct PtrToArg<Transform3D> : Internal::PtrToArgByReference<Transform3D> {};
203
template <>
204
struct PtrToArg<Color> : Internal::PtrToArgByReference<Color> {};
205
template <>
206
struct PtrToArg<StringName> : Internal::PtrToArgDirect<StringName> {};
207
template <>
208
struct PtrToArg<NodePath> : Internal::PtrToArgDirect<NodePath> {};
209
template <>
210
struct PtrToArg<RID> : Internal::PtrToArgDirect<RID> {};
211
// Object doesn't need this.
212
template <>
213
struct PtrToArg<Callable> : Internal::PtrToArgDirect<Callable> {};
214
template <>
215
struct PtrToArg<Signal> : Internal::PtrToArgDirect<Signal> {};
216
template <>
217
struct PtrToArg<Dictionary> : Internal::PtrToArgDirect<Dictionary> {};
218
template <>
219
struct PtrToArg<Array> : Internal::PtrToArgDirect<Array> {};
220
template <>
221
struct PtrToArg<PackedByteArray> : Internal::PtrToArgDirect<PackedByteArray> {};
222
template <>
223
struct PtrToArg<PackedInt32Array> : Internal::PtrToArgDirect<PackedInt32Array> {};
224
template <>
225
struct PtrToArg<PackedInt64Array> : Internal::PtrToArgDirect<PackedInt64Array> {};
226
template <>
227
struct PtrToArg<PackedFloat32Array> : Internal::PtrToArgDirect<PackedFloat32Array> {};
228
template <>
229
struct PtrToArg<PackedFloat64Array> : Internal::PtrToArgDirect<PackedFloat64Array> {};
230
template <>
231
struct PtrToArg<PackedStringArray> : Internal::PtrToArgDirect<PackedStringArray> {};
232
template <>
233
struct PtrToArg<PackedVector2Array> : Internal::PtrToArgDirect<PackedVector2Array> {};
234
template <>
235
struct PtrToArg<PackedVector3Array> : Internal::PtrToArgDirect<PackedVector3Array> {};
236
template <>
237
struct PtrToArg<PackedColorArray> : Internal::PtrToArgDirect<PackedColorArray> {};
238
template <>
239
struct PtrToArg<PackedVector4Array> : Internal::PtrToArgDirect<PackedVector4Array> {};
240
template <>
241
struct PtrToArg<Variant> : Internal::PtrToArgByReference<Variant> {};
242
243
template <typename T>
244
struct PtrToArg<T, std::enable_if_t<std::is_enum_v<T>>> : Internal::PtrToArgConvert<T, int64_t> {};
245
template <typename T>
246
struct PtrToArg<BitField<T>, std::enable_if_t<std::is_enum_v<T>>> : Internal::PtrToArgConvert<BitField<T>, int64_t> {};
247
248
// This is for Object.
249
250
template <typename T>
251
struct PtrToArg<T *> {
252
_FORCE_INLINE_ static T *convert(const void *p_ptr) {
253
return likely(p_ptr) ? *reinterpret_cast<T *const *>(p_ptr) : nullptr;
254
}
255
typedef Object *EncodeT;
256
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
257
*((T **)p_ptr) = p_var;
258
}
259
};
260
261
template <typename T>
262
struct PtrToArg<const T *> {
263
_FORCE_INLINE_ static const T *convert(const void *p_ptr) {
264
return likely(p_ptr) ? *reinterpret_cast<T *const *>(p_ptr) : nullptr;
265
}
266
typedef const Object *EncodeT;
267
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
268
*((T **)p_ptr) = p_var;
269
}
270
};
271
272
// This is for ObjectID.
273
274
template <>
275
struct PtrToArg<ObjectID> {
276
_FORCE_INLINE_ static const ObjectID convert(const void *p_ptr) {
277
return ObjectID(*reinterpret_cast<const uint64_t *>(p_ptr));
278
}
279
typedef uint64_t EncodeT;
280
_FORCE_INLINE_ static void encode(const ObjectID &p_val, void *p_ptr) {
281
*((uint64_t *)p_ptr) = p_val;
282
}
283
};
284
285
// This is for the special cases used by Variant.
286
287
template <>
288
struct PtrToArg<Vector<StringName>> : Internal::PtrToArgVectorConvert<String, StringName> {};
289
290
// For stuff that gets converted to Array vectors.
291
292
template <>
293
struct PtrToArg<Vector<Variant>> : Internal::PtrToArgVectorFromArray<Variant> {};
294
template <>
295
struct PtrToArg<Vector<RID>> : Internal::PtrToArgVectorFromArray<RID> {};
296
template <>
297
struct PtrToArg<Vector<Plane>> : Internal::PtrToArgVectorFromArray<Plane> {};
298
299
// Special case for IPAddress.
300
301
template <>
302
struct PtrToArg<IPAddress> : Internal::PtrToArgStringConvertByReference<IPAddress> {};
303
304
template <>
305
struct PtrToArg<Vector<Face3>> {
306
_FORCE_INLINE_ static Vector<Face3> convert(const void *p_ptr) {
307
const Vector<Vector3> *dvs = reinterpret_cast<const Vector<Vector3> *>(p_ptr);
308
Vector<Face3> ret;
309
int len = dvs->size() / 3;
310
ret.resize(len);
311
{
312
const Vector3 *r = dvs->ptr();
313
Face3 *w = ret.ptrw();
314
for (int i = 0; i < len; i++) {
315
w[i].vertex[0] = r[i * 3 + 0];
316
w[i].vertex[1] = r[i * 3 + 1];
317
w[i].vertex[2] = r[i * 3 + 2];
318
}
319
}
320
return ret;
321
}
322
// No EncodeT because direct pointer conversion not possible.
323
_FORCE_INLINE_ static void encode(const Vector<Face3> &p_vec, void *p_ptr) {
324
Vector<Vector3> *arr = reinterpret_cast<Vector<Vector3> *>(p_ptr);
325
int len = p_vec.size();
326
arr->resize(len * 3);
327
{
328
const Face3 *r = p_vec.ptr();
329
Vector3 *w = arr->ptrw();
330
for (int i = 0; i < len; i++) {
331
w[i * 3 + 0] = r[i].vertex[0];
332
w[i * 3 + 1] = r[i].vertex[1];
333
w[i * 3 + 2] = r[i].vertex[2];
334
}
335
}
336
}
337
};
338
339