Godot.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. #ifndef GODOT_HPP
  2. #define GODOT_HPP
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <godot/gdnative.h>
  6. #include <godot_nativescript.h>
  7. #include <CoreTypes.hpp>
  8. #include <Variant.hpp>
  9. #include <Ref.hpp>
  10. #include <Object.hpp>
  11. #include <GodotGlobal.hpp>
  12. namespace godot {
  13. template<class T>
  14. class GodotScript {
  15. public:
  16. T *owner;
  17. // GodotScript() {}
  18. void _init() {}
  19. static const char *___get_base_type_name()
  20. {
  21. return T::___get_class_name();
  22. }
  23. static void _register_methods() {}
  24. };
  25. #define GDNATIVE_INIT(arg) void gdnative_init(arg)
  26. #define GDNATIVE_TERMINATE(arg) void gdnative_terminate(arg)
  27. #define NATIVESCRIPT_INIT() void nativescript_init()
  28. #define GODOT_CLASS(Name) \
  29. public: inline static const char *___get_type_name() { return static_cast<const char *>(#Name); } \
  30. private:
  31. #define GODOT_SUBCLASS(Name, Base) \
  32. public: inline static const char *___get_type_name() { return static_cast<const char *>(#Name); } \
  33. inline static const char *___get_base_type_name() { return static_cast<const char *>(#Base); } \
  34. private:
  35. template<class T>
  36. struct _ArgCast {
  37. static T _arg_cast(Variant a)
  38. {
  39. return a;
  40. }
  41. };
  42. template<class T>
  43. struct _ArgCast<T*> {
  44. static T *_arg_cast(Variant a)
  45. {
  46. return (T *) ((Object *) a);
  47. }
  48. };
  49. template<>
  50. struct _ArgCast<Variant> {
  51. static Variant _arg_cast(Variant a)
  52. {
  53. return a;
  54. }
  55. };
  56. template<class T>
  57. T *as(Object *obj)
  58. {
  59. return (T *) godot_nativescript_get_userdata(obj);
  60. }
  61. // instance and destroy funcs
  62. template<class T>
  63. void *_godot_class_instance_func(godot_object *p, void *method_data)
  64. {
  65. T *d = new T();
  66. *(godot_object **) &d->owner = p;
  67. d->_init();
  68. return d;
  69. }
  70. template<class T>
  71. void _godot_class_destroy_func(godot_object *p, void *method_data, void *data)
  72. {
  73. T *d = (T *) data;
  74. delete d;
  75. }
  76. template<class T>
  77. void register_class()
  78. {
  79. godot_instance_create_func create = {};
  80. create.create_func = _godot_class_instance_func<T>;
  81. godot_instance_destroy_func destroy = {};
  82. destroy.destroy_func = _godot_class_destroy_func<T>;
  83. godot_nativescript_register_class(godot::_RegisterState::nativescript_handle, T::___get_type_name(), T::___get_base_type_name(), create, destroy);
  84. T::_register_methods();
  85. }
  86. template<class T>
  87. void register_tool_class()
  88. {
  89. godot_instance_create_func create = {};
  90. create.create_func = _godot_class_instance_func<T>;
  91. godot_instance_destroy_func destroy = {};
  92. destroy.destroy_func = _godot_class_destroy_func<T>;
  93. godot_nativescript_register_tool_class(godot::_RegisterState::nativescript_handle, T::___get_type_name(), T::___get_base_type_name(), create, destroy);
  94. T::_register_methods();
  95. }
  96. // method registering
  97. typedef godot_variant (*__godot_wrapper_method)(godot_object *, void *, void *, int, godot_variant **);
  98. template<class T, class R, class ...args>
  99. const char *___get_method_class_name(R (T::*p)(args... a))
  100. {
  101. return T::___get_type_name();
  102. }
  103. template<class T, class R, class ...args>
  104. const char *___get_method_class_name(R (T::*p)(args... a) const)
  105. {
  106. return T::___get_type_name();
  107. }
  108. // Okay, time for some template magic.
  109. // Many thanks to manpat from the GDL Discord Server.
  110. // This is stuff that's available in C++14 I think, but whatever.
  111. template<int... I>
  112. struct __Sequence{};
  113. template<int N, int... I>
  114. struct __construct_sequence {
  115. using type = typename __construct_sequence<N-1, N-1, I...>::type;
  116. };
  117. template<int... I>
  118. struct __construct_sequence<0, I...> {
  119. using type = __Sequence<I...>;
  120. };
  121. // Now the wrapping part.
  122. template<class T, class R, class... As>
  123. struct _WrappedMethod {
  124. R (T::*f)(As...);
  125. template<int... I>
  126. void apply(Variant* ret, T* obj, Variant** args, __Sequence<I...>) {
  127. *ret = (obj->*f)( _ArgCast<As>::_arg_cast(*args[I])... );
  128. }
  129. };
  130. template<class T, class... As>
  131. struct _WrappedMethod<T, void, As...> {
  132. void (T::*f)(As...);
  133. template<int... I>
  134. void apply(Variant* ret, T* obj, Variant** args, __Sequence<I...>) {
  135. (obj->*f)( _ArgCast<As>::_arg_cast(*args[I])... );
  136. }
  137. };
  138. template<class T, class R, class... As>
  139. godot_variant __wrapped_method(godot_object *, void *method_data, void *user_data, int num_args, godot_variant **args)
  140. {
  141. godot_variant v;
  142. godot_variant_new_nil(&v);
  143. T *obj = (T *) user_data;
  144. _WrappedMethod<T, R, As...> *method = (_WrappedMethod<T, R, As...>*) method_data;
  145. Variant *var = (Variant *) &v;
  146. Variant **arg = (Variant **) args;
  147. method->apply(var, obj, arg, typename __construct_sequence<sizeof...(As)>::type {});
  148. return v;
  149. }
  150. template<class T, class R, class... As>
  151. void *___make_wrapper_function(R (T::*f)(As...))
  152. {
  153. using MethodType = _WrappedMethod<T, R, As...>;
  154. MethodType *p = (MethodType *) godot_alloc(sizeof(MethodType));
  155. p->f = f;
  156. return (void *) p;
  157. }
  158. template<class T, class R, class... As>
  159. __godot_wrapper_method ___get_wrapper_function(R (T::*f)(As...))
  160. {
  161. return (__godot_wrapper_method) &__wrapped_method<T, R, As...>;
  162. }
  163. template<class T, class R, class ...A>
  164. void *___make_wrapper_function(R (T::*f)(A...) const)
  165. {
  166. return ___make_wrapper_function((R (T::*)(A...)) f);
  167. }
  168. template<class T, class R, class ...A>
  169. __godot_wrapper_method ___get_wrapper_function(R (T::*f)(A...) const)
  170. {
  171. return ___get_wrapper_function((R (T::*)(A...)) f);
  172. }
  173. template<class M>
  174. void register_method(const char *name, M method_ptr, godot_method_rpc_mode rpc_type = GODOT_METHOD_RPC_MODE_DISABLED)
  175. {
  176. godot_instance_method method = {};
  177. method.method_data = ___make_wrapper_function(method_ptr);
  178. method.free_func = godot_free;
  179. method.method = (__godot_wrapper_method) ___get_wrapper_function(method_ptr);
  180. godot_method_attributes attr = {};
  181. attr.rpc_type = rpc_type;
  182. godot_nativescript_register_method(godot::_RegisterState::nativescript_handle, ___get_method_class_name(method_ptr), name, attr, method);
  183. }
  184. template<class T, class P>
  185. struct _PropertySetFunc {
  186. void (T::*f)(P);
  187. static void _wrapped_setter(godot_object *object, void *method_data, void *user_data, godot_variant *value)
  188. {
  189. _PropertySetFunc<T, P> *set_func = (_PropertySetFunc<T, P> *) method_data;
  190. T *obj = (T *) user_data;
  191. Variant *v = (Variant *) value;
  192. (obj->*(set_func->f))(_ArgCast<P>::_arg_cast(*v));
  193. }
  194. };
  195. template<class T, class P>
  196. struct _PropertyGetFunc {
  197. P (T::*f)();
  198. static godot_variant _wrapped_getter(godot_object *object, void *method_data, void *user_data)
  199. {
  200. _PropertyGetFunc<T, P> *get_func = (_PropertyGetFunc<T, P> *) method_data;
  201. T *obj = (T *) user_data;
  202. godot_variant var;
  203. godot_variant_new_nil(&var);
  204. Variant *v = (Variant *) &var;
  205. *v = (obj->*(get_func->f))();
  206. return var;
  207. }
  208. };
  209. template<class T, class P>
  210. struct _PropertyDefaultSetFunc {
  211. P (T::*f);
  212. static void _wrapped_setter(godot_object *object, void *method_data, void *user_data, godot_variant *value)
  213. {
  214. _PropertyDefaultSetFunc<T, P> *set_func = (_PropertyDefaultSetFunc<T, P> *) method_data;
  215. T *obj = (T *) user_data;
  216. Variant *v = (Variant *) value;
  217. (obj->*(set_func->f)) = _ArgCast<P>::_arg_cast(*v);
  218. }
  219. };
  220. template<class T, class P>
  221. struct _PropertyDefaultGetFunc {
  222. P (T::*f);
  223. static godot_variant _wrapped_getter(godot_object *object, void *method_data, void *user_data)
  224. {
  225. _PropertyDefaultGetFunc<T, P> *get_func = (_PropertyDefaultGetFunc<T, P> *) method_data;
  226. T *obj = (T *) user_data;
  227. godot_variant var;
  228. godot_variant_new_nil(&var);
  229. Variant *v = (Variant *) &var;
  230. *v = (obj->*(get_func->f));
  231. return var;
  232. }
  233. };
  234. template<class T, class P>
  235. void register_property(const char *name, P (T::*var), P default_value, godot_method_rpc_mode rpc_mode = GODOT_METHOD_RPC_MODE_DISABLED, godot_property_usage_flags usage = GODOT_PROPERTY_USAGE_DEFAULT, godot_property_hint hint = GODOT_PROPERTY_HINT_NONE, String hint_string = "")
  236. {
  237. Variant def_val = default_value;
  238. usage = (godot_property_usage_flags) ((int) usage | GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE);
  239. if (def_val.get_type() == Variant::OBJECT) {
  240. Object *o = def_val;
  241. if (o && o->is_class("Resource")) {
  242. hint = (godot_property_hint) ((int) hint | GODOT_PROPERTY_HINT_RESOURCE_TYPE);
  243. hint_string = o->get_class();
  244. }
  245. }
  246. godot_string *_hint_string = (godot_string*) &hint_string;
  247. godot_property_attributes attr = {};
  248. attr.type = def_val.get_type();
  249. attr.default_value = *(godot_variant *) &def_val;
  250. attr.hint = hint;
  251. attr.rset_type = rpc_mode;
  252. attr.usage = usage;
  253. attr.hint_string = *_hint_string;
  254. _PropertyDefaultSetFunc<T, P> *wrapped_set = (_PropertyDefaultSetFunc<T, P> *) godot_alloc(sizeof(_PropertyDefaultSetFunc<T, P>));
  255. wrapped_set->f = var;
  256. _PropertyDefaultGetFunc<T, P> *wrapped_get = (_PropertyDefaultGetFunc<T, P> *) godot_alloc(sizeof(_PropertyDefaultGetFunc<T, P>));
  257. wrapped_get->f = var;
  258. godot_property_set_func set_func = {};
  259. set_func.method_data = (void *) wrapped_set;
  260. set_func.free_func = godot_free;
  261. set_func.set_func = &_PropertyDefaultSetFunc<T, P>::_wrapped_setter;
  262. godot_property_get_func get_func = {};
  263. get_func.method_data = (void *) wrapped_get;
  264. get_func.free_func = godot_free;
  265. get_func.get_func = &_PropertyDefaultGetFunc<T, P>::_wrapped_getter;
  266. godot_nativescript_register_property(godot::_RegisterState::nativescript_handle, T::___get_type_name(), name, &attr, set_func, get_func);
  267. }
  268. template<class T, class P>
  269. void register_property(const char *name, void (T::*setter)(P), P (T::*getter)(), P default_value, godot_method_rpc_mode rpc_mode = GODOT_METHOD_RPC_MODE_DISABLED, godot_property_usage_flags usage = GODOT_PROPERTY_USAGE_DEFAULT, godot_property_hint hint = GODOT_PROPERTY_HINT_NONE, String hint_string = "")
  270. {
  271. Variant def_val = default_value;
  272. godot_property_attributes attr = {};
  273. attr.type = def_val.get_type();
  274. attr.default_value = *(godot_variant *) &def_val;
  275. attr.hint = hint;
  276. attr.rset_type = rpc_mode;
  277. attr.usage = usage;
  278. _PropertySetFunc<T, P> *wrapped_set = (_PropertySetFunc<T, P> *) godot_alloc(sizeof(_PropertySetFunc<T, P>));
  279. wrapped_set->f = setter;
  280. _PropertyGetFunc<T, P> *wrapped_get = (_PropertyGetFunc<T, P> *) godot_alloc(sizeof(_PropertyGetFunc<T, P>));
  281. wrapped_get->f = getter;
  282. godot_property_set_func set_func = {};
  283. set_func.method_data = (void *) wrapped_set;
  284. set_func.free_func = godot_free;
  285. set_func.set_func = &_PropertySetFunc<T, P>::_wrapped_setter;
  286. godot_property_get_func get_func = {};
  287. get_func.method_data = (void *) wrapped_get;
  288. get_func.free_func = godot_free;
  289. get_func.get_func = &_PropertyGetFunc<T, P>::_wrapped_getter;
  290. godot_nativescript_register_property(godot::_RegisterState::nativescript_handle, T::___get_type_name(), name, &attr, set_func, get_func);
  291. }
  292. template<class T>
  293. void register_signal(String name, Dictionary args = Dictionary())
  294. {
  295. godot_signal signal = {};
  296. signal.name = *(godot_string *)&name;
  297. signal.num_args = args.size();
  298. signal.num_default_args = 0;
  299. signal.args = (godot_signal_argument*) godot_alloc(sizeof(godot_signal_argument) * signal.num_args);
  300. memset((void *) signal.args, 0, sizeof(godot_signal_argument) * signal.num_args);
  301. for (int i = 0; i < signal.num_args; i++) {
  302. // Array entry = args[i];
  303. // String name = entry[0];
  304. String name = args.keys()[i];
  305. godot_string *_key = (godot_string *)&name;
  306. godot_string_new_copy(&signal.args[i].name, _key);
  307. // if (entry.size() > 1) {
  308. // signal.args[i].type = entry[1];
  309. // }
  310. signal.args[i].type = args.values()[i];
  311. }
  312. godot_nativescript_register_signal(godot::_RegisterState::nativescript_handle, T::___get_type_name(), &signal);
  313. for (int i = 0; i < signal.num_args; i++) {
  314. godot_string_destroy(&signal.args[i].name);
  315. }
  316. godot_free(signal.args);
  317. }
  318. }
  319. #endif // GODOT_H