gd_mono_marshal.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988
  1. /*************************************************************************/
  2. /* gd_mono_marshal.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2019 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. #include "gd_mono_marshal.h"
  31. #include "gd_mono.h"
  32. #include "gd_mono_class.h"
  33. namespace GDMonoMarshal {
  34. Variant::Type managed_to_variant_type(const ManagedType &p_type) {
  35. switch (p_type.type_encoding) {
  36. case MONO_TYPE_BOOLEAN:
  37. return Variant::BOOL;
  38. case MONO_TYPE_I1:
  39. return Variant::INT;
  40. case MONO_TYPE_I2:
  41. return Variant::INT;
  42. case MONO_TYPE_I4:
  43. return Variant::INT;
  44. case MONO_TYPE_I8:
  45. return Variant::INT;
  46. case MONO_TYPE_U1:
  47. return Variant::INT;
  48. case MONO_TYPE_U2:
  49. return Variant::INT;
  50. case MONO_TYPE_U4:
  51. return Variant::INT;
  52. case MONO_TYPE_U8:
  53. return Variant::INT;
  54. case MONO_TYPE_R4:
  55. return Variant::REAL;
  56. case MONO_TYPE_R8:
  57. return Variant::REAL;
  58. case MONO_TYPE_STRING: {
  59. return Variant::STRING;
  60. } break;
  61. case MONO_TYPE_VALUETYPE: {
  62. GDMonoClass *vtclass = p_type.type_class;
  63. if (vtclass == CACHED_CLASS(Vector2))
  64. return Variant::VECTOR2;
  65. if (vtclass == CACHED_CLASS(Rect2))
  66. return Variant::RECT2;
  67. if (vtclass == CACHED_CLASS(Transform2D))
  68. return Variant::TRANSFORM2D;
  69. if (vtclass == CACHED_CLASS(Vector3))
  70. return Variant::VECTOR3;
  71. if (vtclass == CACHED_CLASS(Basis))
  72. return Variant::BASIS;
  73. if (vtclass == CACHED_CLASS(Quat))
  74. return Variant::QUAT;
  75. if (vtclass == CACHED_CLASS(Transform))
  76. return Variant::TRANSFORM;
  77. if (vtclass == CACHED_CLASS(AABB))
  78. return Variant::AABB;
  79. if (vtclass == CACHED_CLASS(Color))
  80. return Variant::COLOR;
  81. if (vtclass == CACHED_CLASS(Plane))
  82. return Variant::PLANE;
  83. if (mono_class_is_enum(vtclass->get_mono_ptr()))
  84. return Variant::INT;
  85. } break;
  86. case MONO_TYPE_ARRAY:
  87. case MONO_TYPE_SZARRAY: {
  88. MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type());
  89. if (array_type->eklass == CACHED_CLASS_RAW(MonoObject))
  90. return Variant::ARRAY;
  91. if (array_type->eklass == CACHED_CLASS_RAW(uint8_t))
  92. return Variant::POOL_BYTE_ARRAY;
  93. if (array_type->eklass == CACHED_CLASS_RAW(int32_t))
  94. return Variant::POOL_INT_ARRAY;
  95. if (array_type->eklass == REAL_T_MONOCLASS)
  96. return Variant::POOL_REAL_ARRAY;
  97. if (array_type->eklass == CACHED_CLASS_RAW(String))
  98. return Variant::POOL_STRING_ARRAY;
  99. if (array_type->eklass == CACHED_CLASS_RAW(Vector2))
  100. return Variant::POOL_VECTOR2_ARRAY;
  101. if (array_type->eklass == CACHED_CLASS_RAW(Vector3))
  102. return Variant::POOL_VECTOR3_ARRAY;
  103. if (array_type->eklass == CACHED_CLASS_RAW(Color))
  104. return Variant::POOL_COLOR_ARRAY;
  105. } break;
  106. case MONO_TYPE_CLASS: {
  107. GDMonoClass *type_class = p_type.type_class;
  108. // GodotObject
  109. if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) {
  110. return Variant::OBJECT;
  111. }
  112. if (CACHED_CLASS(NodePath) == type_class) {
  113. return Variant::NODE_PATH;
  114. }
  115. if (CACHED_CLASS(RID) == type_class) {
  116. return Variant::_RID;
  117. }
  118. if (CACHED_CLASS(Dictionary) == type_class) {
  119. return Variant::DICTIONARY;
  120. }
  121. if (CACHED_CLASS(Array) == type_class) {
  122. return Variant::ARRAY;
  123. }
  124. } break;
  125. case MONO_TYPE_GENERICINST: {
  126. MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, p_type.type_class->get_mono_type());
  127. MonoException *exc = NULL;
  128. GDMonoUtils::IsDictionaryGenericType type_is_dict = CACHED_METHOD_THUNK(MarshalUtils, IsDictionaryGenericType);
  129. MonoBoolean is_dict = invoke_method_thunk(type_is_dict, (MonoObject *)reftype, (MonoObject **)&exc);
  130. UNLIKELY_UNHANDLED_EXCEPTION(exc);
  131. if (is_dict) {
  132. return Variant::DICTIONARY;
  133. }
  134. exc = NULL;
  135. GDMonoUtils::IsArrayGenericType type_is_array = CACHED_METHOD_THUNK(MarshalUtils, IsArrayGenericType);
  136. MonoBoolean is_array = invoke_method_thunk(type_is_array, (MonoObject *)reftype, (MonoObject **)&exc);
  137. UNLIKELY_UNHANDLED_EXCEPTION(exc);
  138. if (is_array) {
  139. return Variant::ARRAY;
  140. }
  141. } break;
  142. default: {
  143. } break;
  144. }
  145. // Unknown
  146. return Variant::NIL;
  147. }
  148. String mono_to_utf8_string(MonoString *p_mono_string) {
  149. MonoError error;
  150. char *utf8 = mono_string_to_utf8_checked(p_mono_string, &error);
  151. if (!mono_error_ok(&error)) {
  152. ERR_PRINTS(String("Failed to convert MonoString* to UTF-8: ") + mono_error_get_message(&error));
  153. mono_error_cleanup(&error);
  154. return String();
  155. }
  156. String ret = String::utf8(utf8);
  157. mono_free(utf8);
  158. return ret;
  159. }
  160. String mono_to_utf16_string(MonoString *p_mono_string) {
  161. int len = mono_string_length(p_mono_string);
  162. String ret;
  163. if (len == 0)
  164. return ret;
  165. ret.resize(len + 1);
  166. ret.set(len, 0);
  167. CharType *src = (CharType *)mono_string_chars(p_mono_string);
  168. CharType *dst = ret.ptrw();
  169. for (int i = 0; i < len; i++) {
  170. dst[i] = src[i];
  171. }
  172. return ret;
  173. }
  174. MonoObject *variant_to_mono_object(const Variant *p_var) {
  175. ManagedType type;
  176. type.type_encoding = MONO_TYPE_OBJECT;
  177. // type.type_class is not needed when we specify the MONO_TYPE_OBJECT encoding
  178. return variant_to_mono_object(p_var, type);
  179. }
  180. MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_type) {
  181. switch (p_type.type_encoding) {
  182. case MONO_TYPE_BOOLEAN: {
  183. MonoBoolean val = p_var->operator bool();
  184. return BOX_BOOLEAN(val);
  185. }
  186. case MONO_TYPE_CHAR: {
  187. uint16_t val = p_var->operator unsigned short();
  188. return BOX_UINT16(val);
  189. }
  190. case MONO_TYPE_I1: {
  191. int8_t val = p_var->operator signed char();
  192. return BOX_INT8(val);
  193. }
  194. case MONO_TYPE_I2: {
  195. int16_t val = p_var->operator signed short();
  196. return BOX_INT16(val);
  197. }
  198. case MONO_TYPE_I4: {
  199. int32_t val = p_var->operator signed int();
  200. return BOX_INT32(val);
  201. }
  202. case MONO_TYPE_I8: {
  203. int64_t val = p_var->operator int64_t();
  204. return BOX_INT64(val);
  205. }
  206. case MONO_TYPE_U1: {
  207. uint8_t val = p_var->operator unsigned char();
  208. return BOX_UINT8(val);
  209. }
  210. case MONO_TYPE_U2: {
  211. uint16_t val = p_var->operator unsigned short();
  212. return BOX_UINT16(val);
  213. }
  214. case MONO_TYPE_U4: {
  215. uint32_t val = p_var->operator unsigned int();
  216. return BOX_UINT32(val);
  217. }
  218. case MONO_TYPE_U8: {
  219. uint64_t val = p_var->operator uint64_t();
  220. return BOX_UINT64(val);
  221. }
  222. case MONO_TYPE_R4: {
  223. float val = p_var->operator float();
  224. return BOX_FLOAT(val);
  225. }
  226. case MONO_TYPE_R8: {
  227. double val = p_var->operator double();
  228. return BOX_DOUBLE(val);
  229. }
  230. case MONO_TYPE_STRING: {
  231. return (MonoObject *)mono_string_from_godot(p_var->operator String());
  232. } break;
  233. case MONO_TYPE_VALUETYPE: {
  234. GDMonoClass *vtclass = p_type.type_class;
  235. if (vtclass == CACHED_CLASS(Vector2)) {
  236. GDMonoMarshal::M_Vector2 from = MARSHALLED_OUT(Vector2, p_var->operator ::Vector2());
  237. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2), &from);
  238. }
  239. if (vtclass == CACHED_CLASS(Rect2)) {
  240. GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_var->operator ::Rect2());
  241. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2), &from);
  242. }
  243. if (vtclass == CACHED_CLASS(Transform2D)) {
  244. GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_var->operator ::Transform2D());
  245. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform2D), &from);
  246. }
  247. if (vtclass == CACHED_CLASS(Vector3)) {
  248. GDMonoMarshal::M_Vector3 from = MARSHALLED_OUT(Vector3, p_var->operator ::Vector3());
  249. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3), &from);
  250. }
  251. if (vtclass == CACHED_CLASS(Basis)) {
  252. GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_var->operator ::Basis());
  253. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Basis), &from);
  254. }
  255. if (vtclass == CACHED_CLASS(Quat)) {
  256. GDMonoMarshal::M_Quat from = MARSHALLED_OUT(Quat, p_var->operator ::Quat());
  257. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Quat), &from);
  258. }
  259. if (vtclass == CACHED_CLASS(Transform)) {
  260. GDMonoMarshal::M_Transform from = MARSHALLED_OUT(Transform, p_var->operator ::Transform());
  261. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform), &from);
  262. }
  263. if (vtclass == CACHED_CLASS(AABB)) {
  264. GDMonoMarshal::M_AABB from = MARSHALLED_OUT(AABB, p_var->operator ::AABB());
  265. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(AABB), &from);
  266. }
  267. if (vtclass == CACHED_CLASS(Color)) {
  268. GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_var->operator ::Color());
  269. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Color), &from);
  270. }
  271. if (vtclass == CACHED_CLASS(Plane)) {
  272. GDMonoMarshal::M_Plane from = MARSHALLED_OUT(Plane, p_var->operator ::Plane());
  273. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Plane), &from);
  274. }
  275. if (mono_class_is_enum(vtclass->get_mono_ptr())) {
  276. MonoType *enum_basetype = mono_class_enum_basetype(vtclass->get_mono_ptr());
  277. MonoClass *enum_baseclass = mono_class_from_mono_type(enum_basetype);
  278. switch (mono_type_get_type(enum_basetype)) {
  279. case MONO_TYPE_BOOLEAN: {
  280. MonoBoolean val = p_var->operator bool();
  281. return BOX_ENUM(enum_baseclass, val);
  282. }
  283. case MONO_TYPE_CHAR: {
  284. uint16_t val = p_var->operator unsigned short();
  285. return BOX_ENUM(enum_baseclass, val);
  286. }
  287. case MONO_TYPE_I1: {
  288. int8_t val = p_var->operator signed char();
  289. return BOX_ENUM(enum_baseclass, val);
  290. }
  291. case MONO_TYPE_I2: {
  292. int16_t val = p_var->operator signed short();
  293. return BOX_ENUM(enum_baseclass, val);
  294. }
  295. case MONO_TYPE_I4: {
  296. int32_t val = p_var->operator signed int();
  297. return BOX_ENUM(enum_baseclass, val);
  298. }
  299. case MONO_TYPE_I8: {
  300. int64_t val = p_var->operator int64_t();
  301. return BOX_ENUM(enum_baseclass, val);
  302. }
  303. case MONO_TYPE_U1: {
  304. uint8_t val = p_var->operator unsigned char();
  305. return BOX_ENUM(enum_baseclass, val);
  306. }
  307. case MONO_TYPE_U2: {
  308. uint16_t val = p_var->operator unsigned short();
  309. return BOX_ENUM(enum_baseclass, val);
  310. }
  311. case MONO_TYPE_U4: {
  312. uint32_t val = p_var->operator unsigned int();
  313. return BOX_ENUM(enum_baseclass, val);
  314. }
  315. case MONO_TYPE_U8: {
  316. uint64_t val = p_var->operator uint64_t();
  317. return BOX_ENUM(enum_baseclass, val);
  318. }
  319. default: {
  320. ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed enum value of unmarshallable base type.");
  321. ERR_FAIL_V(NULL);
  322. }
  323. }
  324. }
  325. } break;
  326. case MONO_TYPE_ARRAY:
  327. case MONO_TYPE_SZARRAY: {
  328. MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type());
  329. if (array_type->eklass == CACHED_CLASS_RAW(MonoObject))
  330. return (MonoObject *)Array_to_mono_array(p_var->operator Array());
  331. if (array_type->eklass == CACHED_CLASS_RAW(uint8_t))
  332. return (MonoObject *)PoolByteArray_to_mono_array(p_var->operator PoolByteArray());
  333. if (array_type->eklass == CACHED_CLASS_RAW(int32_t))
  334. return (MonoObject *)PoolIntArray_to_mono_array(p_var->operator PoolIntArray());
  335. if (array_type->eklass == REAL_T_MONOCLASS)
  336. return (MonoObject *)PoolRealArray_to_mono_array(p_var->operator PoolRealArray());
  337. if (array_type->eklass == CACHED_CLASS_RAW(String))
  338. return (MonoObject *)PoolStringArray_to_mono_array(p_var->operator PoolStringArray());
  339. if (array_type->eklass == CACHED_CLASS_RAW(Vector2))
  340. return (MonoObject *)PoolVector2Array_to_mono_array(p_var->operator PoolVector2Array());
  341. if (array_type->eklass == CACHED_CLASS_RAW(Vector3))
  342. return (MonoObject *)PoolVector3Array_to_mono_array(p_var->operator PoolVector3Array());
  343. if (array_type->eklass == CACHED_CLASS_RAW(Color))
  344. return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray());
  345. ERR_EXPLAIN(String() + "Attempted to convert Variant to a managed array of unmarshallable element type.");
  346. ERR_FAIL_V(NULL);
  347. } break;
  348. case MONO_TYPE_CLASS: {
  349. GDMonoClass *type_class = p_type.type_class;
  350. // GodotObject
  351. if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) {
  352. return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *());
  353. }
  354. if (CACHED_CLASS(NodePath) == type_class) {
  355. return GDMonoUtils::create_managed_from(p_var->operator NodePath());
  356. }
  357. if (CACHED_CLASS(RID) == type_class) {
  358. return GDMonoUtils::create_managed_from(p_var->operator RID());
  359. }
  360. if (CACHED_CLASS(Dictionary) == type_class) {
  361. return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
  362. }
  363. if (CACHED_CLASS(Array) == type_class) {
  364. return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
  365. }
  366. } break;
  367. case MONO_TYPE_OBJECT: {
  368. // Variant
  369. switch (p_var->get_type()) {
  370. case Variant::BOOL: {
  371. MonoBoolean val = p_var->operator bool();
  372. return BOX_BOOLEAN(val);
  373. }
  374. case Variant::INT: {
  375. int32_t val = p_var->operator signed int();
  376. return BOX_INT32(val);
  377. }
  378. case Variant::REAL: {
  379. #ifdef REAL_T_IS_DOUBLE
  380. double val = p_var->operator double();
  381. return BOX_DOUBLE(val);
  382. #else
  383. float val = p_var->operator float();
  384. return BOX_FLOAT(val);
  385. #endif
  386. }
  387. case Variant::STRING:
  388. return (MonoObject *)mono_string_from_godot(p_var->operator String());
  389. case Variant::VECTOR2: {
  390. GDMonoMarshal::M_Vector2 from = MARSHALLED_OUT(Vector2, p_var->operator ::Vector2());
  391. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2), &from);
  392. }
  393. case Variant::RECT2: {
  394. GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_var->operator ::Rect2());
  395. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2), &from);
  396. }
  397. case Variant::VECTOR3: {
  398. GDMonoMarshal::M_Vector3 from = MARSHALLED_OUT(Vector3, p_var->operator ::Vector3());
  399. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3), &from);
  400. }
  401. case Variant::TRANSFORM2D: {
  402. GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_var->operator ::Transform2D());
  403. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform2D), &from);
  404. }
  405. case Variant::PLANE: {
  406. GDMonoMarshal::M_Plane from = MARSHALLED_OUT(Plane, p_var->operator ::Plane());
  407. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Plane), &from);
  408. }
  409. case Variant::QUAT: {
  410. GDMonoMarshal::M_Quat from = MARSHALLED_OUT(Quat, p_var->operator ::Quat());
  411. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Quat), &from);
  412. }
  413. case Variant::AABB: {
  414. GDMonoMarshal::M_AABB from = MARSHALLED_OUT(AABB, p_var->operator ::AABB());
  415. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(AABB), &from);
  416. }
  417. case Variant::BASIS: {
  418. GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_var->operator ::Basis());
  419. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Basis), &from);
  420. }
  421. case Variant::TRANSFORM: {
  422. GDMonoMarshal::M_Transform from = MARSHALLED_OUT(Transform, p_var->operator ::Transform());
  423. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform), &from);
  424. }
  425. case Variant::COLOR: {
  426. GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_var->operator ::Color());
  427. return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Color), &from);
  428. }
  429. case Variant::NODE_PATH:
  430. return GDMonoUtils::create_managed_from(p_var->operator NodePath());
  431. case Variant::_RID:
  432. return GDMonoUtils::create_managed_from(p_var->operator RID());
  433. case Variant::OBJECT:
  434. return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *());
  435. case Variant::DICTIONARY:
  436. return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
  437. case Variant::ARRAY:
  438. return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
  439. case Variant::POOL_BYTE_ARRAY:
  440. return (MonoObject *)PoolByteArray_to_mono_array(p_var->operator PoolByteArray());
  441. case Variant::POOL_INT_ARRAY:
  442. return (MonoObject *)PoolIntArray_to_mono_array(p_var->operator PoolIntArray());
  443. case Variant::POOL_REAL_ARRAY:
  444. return (MonoObject *)PoolRealArray_to_mono_array(p_var->operator PoolRealArray());
  445. case Variant::POOL_STRING_ARRAY:
  446. return (MonoObject *)PoolStringArray_to_mono_array(p_var->operator PoolStringArray());
  447. case Variant::POOL_VECTOR2_ARRAY:
  448. return (MonoObject *)PoolVector2Array_to_mono_array(p_var->operator PoolVector2Array());
  449. case Variant::POOL_VECTOR3_ARRAY:
  450. return (MonoObject *)PoolVector3Array_to_mono_array(p_var->operator PoolVector3Array());
  451. case Variant::POOL_COLOR_ARRAY:
  452. return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray());
  453. default:
  454. return NULL;
  455. }
  456. break;
  457. case MONO_TYPE_GENERICINST: {
  458. MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, p_type.type_class->get_mono_type());
  459. MonoException *exc = NULL;
  460. GDMonoUtils::IsDictionaryGenericType type_is_dict = CACHED_METHOD_THUNK(MarshalUtils, IsDictionaryGenericType);
  461. MonoBoolean is_dict = invoke_method_thunk(type_is_dict, (MonoObject *)reftype, (MonoObject **)&exc);
  462. UNLIKELY_UNHANDLED_EXCEPTION(exc);
  463. if (is_dict) {
  464. return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), p_type.type_class);
  465. }
  466. exc = NULL;
  467. GDMonoUtils::IsArrayGenericType type_is_array = CACHED_METHOD_THUNK(MarshalUtils, IsArrayGenericType);
  468. MonoBoolean is_array = invoke_method_thunk(type_is_array, (MonoObject *)reftype, (MonoObject **)&exc);
  469. UNLIKELY_UNHANDLED_EXCEPTION(exc);
  470. if (is_array) {
  471. return GDMonoUtils::create_managed_from(p_var->operator Array(), p_type.type_class);
  472. }
  473. } break;
  474. } break;
  475. }
  476. ERR_EXPLAIN(String() + "Attempted to convert Variant to an unmarshallable managed type. Name: \'" +
  477. p_type.type_class->get_name() + "\' Encoding: " + itos(p_type.type_encoding));
  478. ERR_FAIL_V(NULL);
  479. }
  480. Variant mono_object_to_variant(MonoObject *p_obj) {
  481. if (!p_obj)
  482. return Variant();
  483. GDMonoClass *tclass = GDMono::get_singleton()->get_class(mono_object_get_class(p_obj));
  484. ERR_FAIL_COND_V(!tclass, Variant());
  485. MonoType *raw_type = tclass->get_mono_type();
  486. ManagedType type;
  487. type.type_encoding = mono_type_get_type(raw_type);
  488. type.type_class = tclass;
  489. switch (type.type_encoding) {
  490. case MONO_TYPE_BOOLEAN:
  491. return (bool)unbox<MonoBoolean>(p_obj);
  492. case MONO_TYPE_CHAR:
  493. return unbox<uint16_t>(p_obj);
  494. case MONO_TYPE_I1:
  495. return unbox<int8_t>(p_obj);
  496. case MONO_TYPE_I2:
  497. return unbox<int16_t>(p_obj);
  498. case MONO_TYPE_I4:
  499. return unbox<int32_t>(p_obj);
  500. case MONO_TYPE_I8:
  501. return unbox<int64_t>(p_obj);
  502. case MONO_TYPE_U1:
  503. return unbox<uint8_t>(p_obj);
  504. case MONO_TYPE_U2:
  505. return unbox<uint16_t>(p_obj);
  506. case MONO_TYPE_U4:
  507. return unbox<uint32_t>(p_obj);
  508. case MONO_TYPE_U8:
  509. return unbox<uint64_t>(p_obj);
  510. case MONO_TYPE_R4:
  511. return unbox<float>(p_obj);
  512. case MONO_TYPE_R8:
  513. return unbox<double>(p_obj);
  514. case MONO_TYPE_STRING: {
  515. if (p_obj == NULL)
  516. return Variant(); // NIL
  517. return mono_string_to_godot_not_null((MonoString *)p_obj);
  518. } break;
  519. case MONO_TYPE_VALUETYPE: {
  520. GDMonoClass *vtclass = type.type_class;
  521. if (vtclass == CACHED_CLASS(Vector2))
  522. return MARSHALLED_IN(Vector2, (GDMonoMarshal::M_Vector2 *)mono_object_unbox(p_obj));
  523. if (vtclass == CACHED_CLASS(Rect2))
  524. return MARSHALLED_IN(Rect2, (GDMonoMarshal::M_Rect2 *)mono_object_unbox(p_obj));
  525. if (vtclass == CACHED_CLASS(Transform2D))
  526. return MARSHALLED_IN(Transform2D, (GDMonoMarshal::M_Transform2D *)mono_object_unbox(p_obj));
  527. if (vtclass == CACHED_CLASS(Vector3))
  528. return MARSHALLED_IN(Vector3, (GDMonoMarshal::M_Vector3 *)mono_object_unbox(p_obj));
  529. if (vtclass == CACHED_CLASS(Basis))
  530. return MARSHALLED_IN(Basis, (GDMonoMarshal::M_Basis *)mono_object_unbox(p_obj));
  531. if (vtclass == CACHED_CLASS(Quat))
  532. return MARSHALLED_IN(Quat, (GDMonoMarshal::M_Quat *)mono_object_unbox(p_obj));
  533. if (vtclass == CACHED_CLASS(Transform))
  534. return MARSHALLED_IN(Transform, (GDMonoMarshal::M_Transform *)mono_object_unbox(p_obj));
  535. if (vtclass == CACHED_CLASS(AABB))
  536. return MARSHALLED_IN(AABB, (GDMonoMarshal::M_AABB *)mono_object_unbox(p_obj));
  537. if (vtclass == CACHED_CLASS(Color))
  538. return MARSHALLED_IN(Color, (GDMonoMarshal::M_Color *)mono_object_unbox(p_obj));
  539. if (vtclass == CACHED_CLASS(Plane))
  540. return MARSHALLED_IN(Plane, (GDMonoMarshal::M_Plane *)mono_object_unbox(p_obj));
  541. if (mono_class_is_enum(vtclass->get_mono_ptr()))
  542. return unbox<int32_t>(p_obj);
  543. } break;
  544. case MONO_TYPE_ARRAY:
  545. case MONO_TYPE_SZARRAY: {
  546. MonoArrayType *array_type = mono_type_get_array_type(type.type_class->get_mono_type());
  547. if (array_type->eklass == CACHED_CLASS_RAW(MonoObject))
  548. return mono_array_to_Array((MonoArray *)p_obj);
  549. if (array_type->eklass == CACHED_CLASS_RAW(uint8_t))
  550. return mono_array_to_PoolByteArray((MonoArray *)p_obj);
  551. if (array_type->eklass == CACHED_CLASS_RAW(int32_t))
  552. return mono_array_to_PoolIntArray((MonoArray *)p_obj);
  553. if (array_type->eklass == REAL_T_MONOCLASS)
  554. return mono_array_to_PoolRealArray((MonoArray *)p_obj);
  555. if (array_type->eklass == CACHED_CLASS_RAW(String))
  556. return mono_array_to_PoolStringArray((MonoArray *)p_obj);
  557. if (array_type->eklass == CACHED_CLASS_RAW(Vector2))
  558. return mono_array_to_PoolVector2Array((MonoArray *)p_obj);
  559. if (array_type->eklass == CACHED_CLASS_RAW(Vector3))
  560. return mono_array_to_PoolVector3Array((MonoArray *)p_obj);
  561. if (array_type->eklass == CACHED_CLASS_RAW(Color))
  562. return mono_array_to_PoolColorArray((MonoArray *)p_obj);
  563. ERR_EXPLAIN(String() + "Attempted to convert a managed array of unmarshallable element type to Variant.");
  564. ERR_FAIL_V(Variant());
  565. } break;
  566. case MONO_TYPE_CLASS: {
  567. GDMonoClass *type_class = type.type_class;
  568. // GodotObject
  569. if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) {
  570. Object *ptr = unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_obj));
  571. if (ptr != NULL) {
  572. Reference *ref = Object::cast_to<Reference>(ptr);
  573. return ref ? Variant(Ref<Reference>(ref)) : Variant(ptr);
  574. }
  575. return Variant();
  576. }
  577. if (CACHED_CLASS(NodePath) == type_class) {
  578. NodePath *ptr = unbox<NodePath *>(CACHED_FIELD(NodePath, ptr)->get_value(p_obj));
  579. return ptr ? Variant(*ptr) : Variant();
  580. }
  581. if (CACHED_CLASS(RID) == type_class) {
  582. RID *ptr = unbox<RID *>(CACHED_FIELD(RID, ptr)->get_value(p_obj));
  583. return ptr ? Variant(*ptr) : Variant();
  584. }
  585. if (CACHED_CLASS(Array) == type_class) {
  586. MonoException *exc = NULL;
  587. Array *ptr = invoke_method_thunk(CACHED_METHOD_THUNK(Array, GetPtr), p_obj, (MonoObject **)&exc);
  588. UNLIKELY_UNHANDLED_EXCEPTION(exc);
  589. return ptr ? Variant(*ptr) : Variant();
  590. }
  591. if (CACHED_CLASS(Dictionary) == type_class) {
  592. MonoException *exc = NULL;
  593. Dictionary *ptr = invoke_method_thunk(CACHED_METHOD_THUNK(Dictionary, GetPtr), p_obj, (MonoObject **)&exc);
  594. UNLIKELY_UNHANDLED_EXCEPTION(exc);
  595. return ptr ? Variant(*ptr) : Variant();
  596. }
  597. } break;
  598. case MONO_TYPE_GENERICINST: {
  599. MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, type.type_class->get_mono_type());
  600. MonoException *exc = NULL;
  601. GDMonoUtils::IsDictionaryGenericType type_is_dict = CACHED_METHOD_THUNK(MarshalUtils, IsDictionaryGenericType);
  602. MonoBoolean is_dict = invoke_method_thunk(type_is_dict, (MonoObject *)reftype, (MonoObject **)&exc);
  603. UNLIKELY_UNHANDLED_EXCEPTION(exc);
  604. if (is_dict) {
  605. exc = NULL;
  606. MonoObject *ret = type.type_class->get_method("GetPtr")->invoke(p_obj, &exc);
  607. UNLIKELY_UNHANDLED_EXCEPTION(exc);
  608. return *unbox<Dictionary *>(ret);
  609. }
  610. exc = NULL;
  611. GDMonoUtils::IsArrayGenericType type_is_array = CACHED_METHOD_THUNK(MarshalUtils, IsArrayGenericType);
  612. MonoBoolean is_array = invoke_method_thunk(type_is_array, (MonoObject *)reftype, (MonoObject **)&exc);
  613. UNLIKELY_UNHANDLED_EXCEPTION(exc);
  614. if (is_array) {
  615. exc = NULL;
  616. MonoObject *ret = type.type_class->get_method("GetPtr")->invoke(p_obj, &exc);
  617. UNLIKELY_UNHANDLED_EXCEPTION(exc);
  618. return *unbox<Array *>(ret);
  619. }
  620. } break;
  621. }
  622. ERR_EXPLAIN(String() + "Attempted to convert an unmarshallable managed type to Variant. Name: \'" +
  623. type.type_class->get_name() + "\' Encoding: " + itos(type.type_encoding));
  624. ERR_FAIL_V(Variant());
  625. }
  626. MonoArray *Array_to_mono_array(const Array &p_array) {
  627. MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), p_array.size());
  628. for (int i = 0; i < p_array.size(); i++) {
  629. MonoObject *boxed = variant_to_mono_object(p_array[i]);
  630. mono_array_setref(ret, i, boxed);
  631. }
  632. return ret;
  633. }
  634. Array mono_array_to_Array(MonoArray *p_array) {
  635. Array ret;
  636. if (!p_array)
  637. return ret;
  638. int length = mono_array_length(p_array);
  639. ret.resize(length);
  640. for (int i = 0; i < length; i++) {
  641. MonoObject *elem = mono_array_get(p_array, MonoObject *, i);
  642. ret[i] = mono_object_to_variant(elem);
  643. }
  644. return ret;
  645. }
  646. MonoArray *PoolIntArray_to_mono_array(const PoolIntArray &p_array) {
  647. PoolIntArray::Read r = p_array.read();
  648. MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int32_t), p_array.size());
  649. for (int i = 0; i < p_array.size(); i++) {
  650. mono_array_set(ret, int32_t, i, r[i]);
  651. }
  652. return ret;
  653. }
  654. PoolIntArray mono_array_to_PoolIntArray(MonoArray *p_array) {
  655. PoolIntArray ret;
  656. if (!p_array)
  657. return ret;
  658. int length = mono_array_length(p_array);
  659. ret.resize(length);
  660. PoolIntArray::Write w = ret.write();
  661. for (int i = 0; i < length; i++) {
  662. w[i] = mono_array_get(p_array, int32_t, i);
  663. }
  664. return ret;
  665. }
  666. MonoArray *PoolByteArray_to_mono_array(const PoolByteArray &p_array) {
  667. PoolByteArray::Read r = p_array.read();
  668. MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), p_array.size());
  669. for (int i = 0; i < p_array.size(); i++) {
  670. mono_array_set(ret, uint8_t, i, r[i]);
  671. }
  672. return ret;
  673. }
  674. PoolByteArray mono_array_to_PoolByteArray(MonoArray *p_array) {
  675. PoolByteArray ret;
  676. if (!p_array)
  677. return ret;
  678. int length = mono_array_length(p_array);
  679. ret.resize(length);
  680. PoolByteArray::Write w = ret.write();
  681. for (int i = 0; i < length; i++) {
  682. w[i] = mono_array_get(p_array, uint8_t, i);
  683. }
  684. return ret;
  685. }
  686. MonoArray *PoolRealArray_to_mono_array(const PoolRealArray &p_array) {
  687. PoolRealArray::Read r = p_array.read();
  688. MonoArray *ret = mono_array_new(mono_domain_get(), REAL_T_MONOCLASS, p_array.size());
  689. for (int i = 0; i < p_array.size(); i++) {
  690. mono_array_set(ret, real_t, i, r[i]);
  691. }
  692. return ret;
  693. }
  694. PoolRealArray mono_array_to_PoolRealArray(MonoArray *p_array) {
  695. PoolRealArray ret;
  696. if (!p_array)
  697. return ret;
  698. int length = mono_array_length(p_array);
  699. ret.resize(length);
  700. PoolRealArray::Write w = ret.write();
  701. for (int i = 0; i < length; i++) {
  702. w[i] = mono_array_get(p_array, real_t, i);
  703. }
  704. return ret;
  705. }
  706. MonoArray *PoolStringArray_to_mono_array(const PoolStringArray &p_array) {
  707. PoolStringArray::Read r = p_array.read();
  708. MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), p_array.size());
  709. for (int i = 0; i < p_array.size(); i++) {
  710. MonoString *boxed = mono_string_from_godot(r[i]);
  711. mono_array_set(ret, MonoString *, i, boxed);
  712. }
  713. return ret;
  714. }
  715. PoolStringArray mono_array_to_PoolStringArray(MonoArray *p_array) {
  716. PoolStringArray ret;
  717. if (!p_array)
  718. return ret;
  719. int length = mono_array_length(p_array);
  720. ret.resize(length);
  721. PoolStringArray::Write w = ret.write();
  722. for (int i = 0; i < length; i++) {
  723. MonoString *elem = mono_array_get(p_array, MonoString *, i);
  724. w[i] = mono_string_to_godot(elem);
  725. }
  726. return ret;
  727. }
  728. MonoArray *PoolColorArray_to_mono_array(const PoolColorArray &p_array) {
  729. PoolColorArray::Read r = p_array.read();
  730. MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Color), p_array.size());
  731. for (int i = 0; i < p_array.size(); i++) {
  732. M_Color *raw = (M_Color *)mono_array_addr_with_size(ret, sizeof(M_Color), i);
  733. *raw = MARSHALLED_OUT(Color, r[i]);
  734. }
  735. return ret;
  736. }
  737. PoolColorArray mono_array_to_PoolColorArray(MonoArray *p_array) {
  738. PoolColorArray ret;
  739. if (!p_array)
  740. return ret;
  741. int length = mono_array_length(p_array);
  742. ret.resize(length);
  743. PoolColorArray::Write w = ret.write();
  744. for (int i = 0; i < length; i++) {
  745. w[i] = MARSHALLED_IN(Color, (M_Color *)mono_array_addr_with_size(p_array, sizeof(M_Color), i));
  746. }
  747. return ret;
  748. }
  749. MonoArray *PoolVector2Array_to_mono_array(const PoolVector2Array &p_array) {
  750. PoolVector2Array::Read r = p_array.read();
  751. MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector2), p_array.size());
  752. for (int i = 0; i < p_array.size(); i++) {
  753. M_Vector2 *raw = (M_Vector2 *)mono_array_addr_with_size(ret, sizeof(M_Vector2), i);
  754. *raw = MARSHALLED_OUT(Vector2, r[i]);
  755. }
  756. return ret;
  757. }
  758. PoolVector2Array mono_array_to_PoolVector2Array(MonoArray *p_array) {
  759. PoolVector2Array ret;
  760. if (!p_array)
  761. return ret;
  762. int length = mono_array_length(p_array);
  763. ret.resize(length);
  764. PoolVector2Array::Write w = ret.write();
  765. for (int i = 0; i < length; i++) {
  766. w[i] = MARSHALLED_IN(Vector2, (M_Vector2 *)mono_array_addr_with_size(p_array, sizeof(M_Vector2), i));
  767. }
  768. return ret;
  769. }
  770. MonoArray *PoolVector3Array_to_mono_array(const PoolVector3Array &p_array) {
  771. PoolVector3Array::Read r = p_array.read();
  772. MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector3), p_array.size());
  773. for (int i = 0; i < p_array.size(); i++) {
  774. M_Vector3 *raw = (M_Vector3 *)mono_array_addr_with_size(ret, sizeof(M_Vector3), i);
  775. *raw = MARSHALLED_OUT(Vector3, r[i]);
  776. }
  777. return ret;
  778. }
  779. PoolVector3Array mono_array_to_PoolVector3Array(MonoArray *p_array) {
  780. PoolVector3Array ret;
  781. if (!p_array)
  782. return ret;
  783. int length = mono_array_length(p_array);
  784. ret.resize(length);
  785. PoolVector3Array::Write w = ret.write();
  786. for (int i = 0; i < length; i++) {
  787. w[i] = MARSHALLED_IN(Vector3, (M_Vector3 *)mono_array_addr_with_size(p_array, sizeof(M_Vector3), i));
  788. }
  789. return ret;
  790. }
  791. } // namespace GDMonoMarshal