1 /*************************************************************************/ 2 /* method_ptrcall.h */ 3 /*************************************************************************/ 4 /* This file is part of: */ 5 /* GODOT ENGINE */ 6 /* https://godotengine.org */ 7 /*************************************************************************/ 8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ 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 #ifndef METHOD_PTRCALL_H 32 #define METHOD_PTRCALL_H 33 34 #include "core/math/transform_2d.h" 35 #include "core/typedefs.h" 36 #include "core/variant.h" 37 38 #ifdef PTRCALL_ENABLED 39 40 template <class T> 41 struct PtrToArg { 42 }; 43 44 #define MAKE_PTRARG(m_type) \ 45 template <> \ 46 struct PtrToArg<m_type> { \ 47 _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ 48 return *reinterpret_cast<const m_type *>(p_ptr); \ 49 } \ 50 _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ 51 *((m_type *)p_ptr) = p_val; \ 52 } \ 53 }; \ 54 template <> \ 55 struct PtrToArg<const m_type &> { \ 56 _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ 57 return *reinterpret_cast<const m_type *>(p_ptr); \ 58 } \ 59 _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ 60 *((m_type *)p_ptr) = p_val; \ 61 } \ 62 } 63 64 #define MAKE_PTRARGCONV(m_type, m_conv) \ 65 template <> \ 66 struct PtrToArg<m_type> { \ 67 _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ 68 return static_cast<m_type>(*reinterpret_cast<const m_conv *>(p_ptr)); \ 69 } \ 70 _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ 71 *((m_conv *)p_ptr) = static_cast<m_conv>(p_val); \ 72 } \ 73 }; \ 74 template <> \ 75 struct PtrToArg<const m_type &> { \ 76 _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ 77 return static_cast<m_type>(*reinterpret_cast<const m_conv *>(p_ptr)); \ 78 } \ 79 _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ 80 *((m_conv *)p_ptr) = static_cast<m_conv>(p_val); \ 81 } \ 82 } 83 84 #define MAKE_PTRARG_BY_REFERENCE(m_type) \ 85 template <> \ 86 struct PtrToArg<m_type> { \ 87 _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ 88 return *reinterpret_cast<const m_type *>(p_ptr); \ 89 } \ 90 _FORCE_INLINE_ static void encode(const m_type &p_val, void *p_ptr) { \ 91 *((m_type *)p_ptr) = p_val; \ 92 } \ 93 }; \ 94 template <> \ 95 struct PtrToArg<const m_type &> { \ 96 _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ 97 return *reinterpret_cast<const m_type *>(p_ptr); \ 98 } \ 99 _FORCE_INLINE_ static void encode(const m_type &p_val, void *p_ptr) { \ 100 *((m_type *)p_ptr) = p_val; \ 101 } \ 102 } 103 104 MAKE_PTRARG(bool); 105 MAKE_PTRARGCONV(uint8_t, int64_t); 106 MAKE_PTRARGCONV(int8_t, int64_t); 107 MAKE_PTRARGCONV(uint16_t, int64_t); 108 MAKE_PTRARGCONV(int16_t, int64_t); 109 MAKE_PTRARGCONV(uint32_t, int64_t); 110 MAKE_PTRARGCONV(int32_t, int64_t); 111 MAKE_PTRARG(int64_t); 112 MAKE_PTRARG(uint64_t); 113 MAKE_PTRARGCONV(float, double); 114 MAKE_PTRARG(double); 115 116 MAKE_PTRARG(String); 117 MAKE_PTRARG(Vector2); 118 MAKE_PTRARG(Rect2); 119 MAKE_PTRARG_BY_REFERENCE(Vector3); 120 MAKE_PTRARG(Transform2D); 121 MAKE_PTRARG_BY_REFERENCE(Plane); 122 MAKE_PTRARG(Quat); 123 MAKE_PTRARG_BY_REFERENCE(AABB); 124 MAKE_PTRARG_BY_REFERENCE(Basis); 125 MAKE_PTRARG_BY_REFERENCE(Transform); 126 MAKE_PTRARG_BY_REFERENCE(Color); 127 MAKE_PTRARG(NodePath); 128 MAKE_PTRARG(RID); 129 MAKE_PTRARG(Dictionary); 130 MAKE_PTRARG(Array); 131 MAKE_PTRARG(PoolByteArray); 132 MAKE_PTRARG(PoolIntArray); 133 MAKE_PTRARG(PoolRealArray); 134 MAKE_PTRARG(PoolStringArray); 135 MAKE_PTRARG(PoolVector2Array); 136 MAKE_PTRARG(PoolVector3Array); 137 MAKE_PTRARG(PoolColorArray); 138 MAKE_PTRARG_BY_REFERENCE(Variant); 139 140 //this is for Object 141 142 template <class T> 143 struct PtrToArg<T *> { 144 145 _FORCE_INLINE_ static T *convert(const void *p_ptr) { 146 147 return const_cast<T *>(reinterpret_cast<const T *>(p_ptr)); 148 } 149 150 _FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) { 151 152 *((T **)p_ptr) = p_var; 153 } 154 }; 155 156 template <class T> 157 struct PtrToArg<const T *> { 158 159 _FORCE_INLINE_ static const T *convert(const void *p_ptr) { 160 161 return reinterpret_cast<const T *>(p_ptr); 162 } 163 164 _FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) { 165 166 *((T **)p_ptr) = p_var; 167 } 168 }; 169 170 //this is for the special cases used by Variant 171 172 #define MAKE_VECARG(m_type) \ 173 template <> \ 174 struct PtrToArg<Vector<m_type> > { \ 175 _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \ 176 const PoolVector<m_type> *dvs = reinterpret_cast<const PoolVector<m_type> *>(p_ptr); \ 177 Vector<m_type> ret; \ 178 int len = dvs->size(); \ 179 ret.resize(len); \ 180 { \ 181 PoolVector<m_type>::Read r = dvs->read(); \ 182 for (int i = 0; i < len; i++) { \ 183 ret.write[i] = r[i]; \ 184 } \ 185 } \ 186 return ret; \ 187 } \ 188 _FORCE_INLINE_ static void encode(Vector<m_type> p_vec, void *p_ptr) { \ 189 PoolVector<m_type> *dv = reinterpret_cast<PoolVector<m_type> *>(p_ptr); \ 190 int len = p_vec.size(); \ 191 dv->resize(len); \ 192 { \ 193 PoolVector<m_type>::Write w = dv->write(); \ 194 for (int i = 0; i < len; i++) { \ 195 w[i] = p_vec[i]; \ 196 } \ 197 } \ 198 } \ 199 }; \ 200 template <> \ 201 struct PtrToArg<const Vector<m_type> &> { \ 202 _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \ 203 const PoolVector<m_type> *dvs = reinterpret_cast<const PoolVector<m_type> *>(p_ptr); \ 204 Vector<m_type> ret; \ 205 int len = dvs->size(); \ 206 ret.resize(len); \ 207 { \ 208 PoolVector<m_type>::Read r = dvs->read(); \ 209 for (int i = 0; i < len; i++) { \ 210 ret.write[i] = r[i]; \ 211 } \ 212 } \ 213 return ret; \ 214 } \ 215 } 216 217 #define MAKE_VECARG_ALT(m_type, m_type_alt) \ 218 template <> \ 219 struct PtrToArg<Vector<m_type_alt> > { \ 220 _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \ 221 const PoolVector<m_type> *dvs = reinterpret_cast<const PoolVector<m_type> *>(p_ptr); \ 222 Vector<m_type_alt> ret; \ 223 int len = dvs->size(); \ 224 ret.resize(len); \ 225 { \ 226 PoolVector<m_type>::Read r = dvs->read(); \ 227 for (int i = 0; i < len; i++) { \ 228 ret.write[i] = r[i]; \ 229 } \ 230 } \ 231 return ret; \ 232 } \ 233 _FORCE_INLINE_ static void encode(Vector<m_type_alt> p_vec, void *p_ptr) { \ 234 PoolVector<m_type> *dv = reinterpret_cast<PoolVector<m_type> *>(p_ptr); \ 235 int len = p_vec.size(); \ 236 dv->resize(len); \ 237 { \ 238 PoolVector<m_type>::Write w = dv->write(); \ 239 for (int i = 0; i < len; i++) { \ 240 w[i] = p_vec[i]; \ 241 } \ 242 } \ 243 } \ 244 }; \ 245 template <> \ 246 struct PtrToArg<const Vector<m_type_alt> &> { \ 247 _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \ 248 const PoolVector<m_type> *dvs = reinterpret_cast<const PoolVector<m_type> *>(p_ptr); \ 249 Vector<m_type_alt> ret; \ 250 int len = dvs->size(); \ 251 ret.resize(len); \ 252 { \ 253 PoolVector<m_type>::Read r = dvs->read(); \ 254 for (int i = 0; i < len; i++) { \ 255 ret.write[i] = r[i]; \ 256 } \ 257 } \ 258 return ret; \ 259 } \ 260 } 261 MAKE_VECARG(String); 262 MAKE_VECARG(uint8_t); 263 MAKE_VECARG(int); 264 MAKE_VECARG(float); 265 MAKE_VECARG(Vector2); 266 MAKE_VECARG(Vector3); 267 MAKE_VECARG(Color); 268 MAKE_VECARG_ALT(String, StringName); 269 270 //for stuff that gets converted to Array vectors 271 #define MAKE_VECARR(m_type) \ 272 template <> \ 273 struct PtrToArg<Vector<m_type> > { \ 274 _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \ 275 const Array *arr = reinterpret_cast<const Array *>(p_ptr); \ 276 Vector<m_type> ret; \ 277 int len = arr->size(); \ 278 ret.resize(len); \ 279 for (int i = 0; i < len; i++) { \ 280 ret.write[i] = (*arr)[i]; \ 281 } \ 282 return ret; \ 283 } \ 284 _FORCE_INLINE_ static void encode(Vector<m_type> p_vec, void *p_ptr) { \ 285 Array *arr = reinterpret_cast<Array *>(p_ptr); \ 286 int len = p_vec.size(); \ 287 arr->resize(len); \ 288 for (int i = 0; i < len; i++) { \ 289 (*arr)[i] = p_vec[i]; \ 290 } \ 291 } \ 292 }; \ 293 template <> \ 294 struct PtrToArg<const Vector<m_type> &> { \ 295 _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \ 296 const Array *arr = reinterpret_cast<const Array *>(p_ptr); \ 297 Vector<m_type> ret; \ 298 int len = arr->size(); \ 299 ret.resize(len); \ 300 for (int i = 0; i < len; i++) { \ 301 ret.write[i] = (*arr)[i]; \ 302 } \ 303 return ret; \ 304 } \ 305 } 306 307 MAKE_VECARR(Variant); 308 MAKE_VECARR(RID); 309 MAKE_VECARR(Plane); 310 311 #define MAKE_DVECARR(m_type) \ 312 template <> \ 313 struct PtrToArg<PoolVector<m_type> > { \ 314 _FORCE_INLINE_ static PoolVector<m_type> convert(const void *p_ptr) { \ 315 const Array *arr = reinterpret_cast<const Array *>(p_ptr); \ 316 PoolVector<m_type> ret; \ 317 int len = arr->size(); \ 318 ret.resize(len); \ 319 { \ 320 PoolVector<m_type>::Write w = ret.write(); \ 321 for (int i = 0; i < len; i++) { \ 322 w[i] = (*arr)[i]; \ 323 } \ 324 } \ 325 return ret; \ 326 } \ 327 _FORCE_INLINE_ static void encode(PoolVector<m_type> p_vec, void *p_ptr) { \ 328 Array *arr = reinterpret_cast<Array *>(p_ptr); \ 329 int len = p_vec.size(); \ 330 arr->resize(len); \ 331 { \ 332 PoolVector<m_type>::Read r = p_vec.read(); \ 333 for (int i = 0; i < len; i++) { \ 334 (*arr)[i] = r[i]; \ 335 } \ 336 } \ 337 } \ 338 }; \ 339 template <> \ 340 struct PtrToArg<const PoolVector<m_type> &> { \ 341 _FORCE_INLINE_ static PoolVector<m_type> convert(const void *p_ptr) { \ 342 const Array *arr = reinterpret_cast<const Array *>(p_ptr); \ 343 PoolVector<m_type> ret; \ 344 int len = arr->size(); \ 345 ret.resize(len); \ 346 { \ 347 PoolVector<m_type>::Write w = ret.write(); \ 348 for (int i = 0; i < len; i++) { \ 349 w[i] = (*arr)[i]; \ 350 } \ 351 } \ 352 return ret; \ 353 } \ 354 } 355 356 MAKE_DVECARR(Plane); 357 //for special case StringName 358 359 #define MAKE_STRINGCONV(m_type) \ 360 template <> \ 361 struct PtrToArg<m_type> { \ 362 _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ 363 m_type s = *reinterpret_cast<const String *>(p_ptr); \ 364 return s; \ 365 } \ 366 _FORCE_INLINE_ static void encode(m_type p_vec, void *p_ptr) { \ 367 String *arr = reinterpret_cast<String *>(p_ptr); \ 368 *arr = p_vec; \ 369 } \ 370 }; \ 371 \ 372 template <> \ 373 struct PtrToArg<const m_type &> { \ 374 _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ 375 m_type s = *reinterpret_cast<const String *>(p_ptr); \ 376 return s; \ 377 } \ 378 } 379 380 #define MAKE_STRINGCONV_BY_REFERENCE(m_type) \ 381 template <> \ 382 struct PtrToArg<m_type> { \ 383 _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ 384 m_type s = *reinterpret_cast<const String *>(p_ptr); \ 385 return s; \ 386 } \ 387 _FORCE_INLINE_ static void encode(const m_type &p_vec, void *p_ptr) { \ 388 String *arr = reinterpret_cast<String *>(p_ptr); \ 389 *arr = p_vec; \ 390 } \ 391 }; \ 392 \ 393 template <> \ 394 struct PtrToArg<const m_type &> { \ 395 _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ 396 m_type s = *reinterpret_cast<const String *>(p_ptr); \ 397 return s; \ 398 } \ 399 } 400 401 MAKE_STRINGCONV(StringName); 402 MAKE_STRINGCONV_BY_REFERENCE(IP_Address); 403 404 template <> 405 struct PtrToArg<PoolVector<Face3> > { 406 _FORCE_INLINE_ static PoolVector<Face3> convert(const void *p_ptr) { 407 const PoolVector<Vector3> *dvs = reinterpret_cast<const PoolVector<Vector3> *>(p_ptr); 408 PoolVector<Face3> ret; 409 int len = dvs->size() / 3; 410 ret.resize(len); 411 { 412 PoolVector<Vector3>::Read r = dvs->read(); 413 PoolVector<Face3>::Write w = ret.write(); 414 for (int i = 0; i < len; i++) { 415 w[i].vertex[0] = r[i * 3 + 0]; 416 w[i].vertex[1] = r[i * 3 + 1]; 417 w[i].vertex[2] = r[i * 3 + 2]; 418 } 419 } 420 return ret; 421 } 422 _FORCE_INLINE_ static void encode(PoolVector<Face3> p_vec, void *p_ptr) { 423 PoolVector<Vector3> *arr = reinterpret_cast<PoolVector<Vector3> *>(p_ptr); 424 int len = p_vec.size(); 425 arr->resize(len * 3); 426 { 427 PoolVector<Face3>::Read r = p_vec.read(); 428 PoolVector<Vector3>::Write w = arr->write(); 429 for (int i = 0; i < len; i++) { 430 w[i * 3 + 0] = r[i].vertex[0]; 431 w[i * 3 + 1] = r[i].vertex[1]; 432 w[i * 3 + 2] = r[i].vertex[2]; 433 } 434 } 435 } 436 }; 437 template <> 438 struct PtrToArg<const PoolVector<Face3> &> { 439 _FORCE_INLINE_ static PoolVector<Face3> convert(const void *p_ptr) { 440 const PoolVector<Vector3> *dvs = reinterpret_cast<const PoolVector<Vector3> *>(p_ptr); 441 PoolVector<Face3> ret; 442 int len = dvs->size() / 3; 443 ret.resize(len); 444 { 445 PoolVector<Vector3>::Read r = dvs->read(); 446 PoolVector<Face3>::Write w = ret.write(); 447 for (int i = 0; i < len; i++) { 448 w[i].vertex[0] = r[i * 3 + 0]; 449 w[i].vertex[1] = r[i * 3 + 1]; 450 w[i].vertex[2] = r[i * 3 + 2]; 451 } 452 } 453 return ret; 454 } 455 }; 456 457 #endif // METHOD_PTRCALL_H 458 #endif 459