example.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. /* godot-cpp integration testing project.
  2. *
  3. * This is free and unencumbered software released into the public domain.
  4. */
  5. #include "example.h"
  6. #include <godot_cpp/core/class_db.hpp>
  7. #include <godot_cpp/classes/global_constants.hpp>
  8. #include <godot_cpp/classes/label.hpp>
  9. #include <godot_cpp/classes/multiplayer_api.hpp>
  10. #include <godot_cpp/classes/multiplayer_peer.hpp>
  11. #include <godot_cpp/variant/utility_functions.hpp>
  12. using namespace godot;
  13. void ExampleRef::set_id(int p_id) {
  14. id = p_id;
  15. }
  16. int ExampleRef::get_id() const {
  17. return id;
  18. }
  19. void ExampleRef::_bind_methods() {
  20. ClassDB::bind_method(D_METHOD("set_id", "id"), &ExampleRef::set_id);
  21. ClassDB::bind_method(D_METHOD("get_id"), &ExampleRef::get_id);
  22. ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id");
  23. }
  24. ExampleRef::ExampleRef() {
  25. id = 0;
  26. }
  27. ExampleRef::~ExampleRef() {
  28. }
  29. int Example::test_static(int p_a, int p_b) {
  30. return p_a + p_b;
  31. }
  32. void Example::test_static2() {
  33. //UtilityFunctions::print(" void static");
  34. }
  35. int Example::def_args(int p_a, int p_b) {
  36. return p_a + p_b;
  37. }
  38. void Example::_notification(int p_what) {
  39. if (p_what == NOTIFICATION_READY) {
  40. Dictionary opts;
  41. opts["rpc_mode"] = MultiplayerAPI::RPC_MODE_AUTHORITY;
  42. opts["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
  43. opts["call_local"] = true;
  44. opts["channel"] = 0;
  45. rpc_config("test_rpc", opts);
  46. }
  47. //UtilityFunctions::print("Notification: ", String::num(p_what));
  48. }
  49. bool Example::_set(const StringName &p_name, const Variant &p_value) {
  50. String name = p_name;
  51. if (name.begins_with("dproperty")) {
  52. int64_t index = name.get_slicec('_', 1).to_int();
  53. dprop[index] = p_value;
  54. return true;
  55. }
  56. if (name == "property_from_list") {
  57. property_from_list = p_value;
  58. return true;
  59. }
  60. return false;
  61. }
  62. bool Example::_get(const StringName &p_name, Variant &r_ret) const {
  63. String name = p_name;
  64. if (name.begins_with("dproperty")) {
  65. int64_t index = name.get_slicec('_', 1).to_int();
  66. r_ret = dprop[index];
  67. return true;
  68. }
  69. if (name == "property_from_list") {
  70. r_ret = property_from_list;
  71. return true;
  72. }
  73. return false;
  74. }
  75. String Example::_to_string() const {
  76. return "[ GDExtension::Example <--> Instance ID:" + uitos(get_instance_id()) + " ]";
  77. }
  78. void Example::_get_property_list(List<PropertyInfo> *p_list) const {
  79. p_list->push_back(PropertyInfo(Variant::VECTOR3, "property_from_list"));
  80. for (int i = 0; i < 3; i++) {
  81. p_list->push_back(PropertyInfo(Variant::VECTOR2, "dproperty_" + itos(i)));
  82. }
  83. }
  84. bool Example::_property_can_revert(const StringName &p_name) const {
  85. if (p_name == StringName("property_from_list") && property_from_list != Vector3(42, 42, 42)) {
  86. return true;
  87. } else {
  88. return false;
  89. }
  90. };
  91. bool Example::_property_get_revert(const StringName &p_name, Variant &r_property) const {
  92. if (p_name == StringName("property_from_list")) {
  93. r_property = Vector3(42, 42, 42);
  94. return true;
  95. } else {
  96. return false;
  97. }
  98. };
  99. void Example::_validate_property(PropertyInfo &p_property) const {
  100. String name = p_property.name;
  101. // Test hiding the "mouse_filter" property from the editor.
  102. if (name == "mouse_filter") {
  103. p_property.usage = PROPERTY_USAGE_NO_EDITOR;
  104. }
  105. }
  106. void Example::_bind_methods() {
  107. // Methods.
  108. ClassDB::bind_method(D_METHOD("simple_func"), &Example::simple_func);
  109. ClassDB::bind_method(D_METHOD("simple_const_func"), &Example::simple_const_func);
  110. ClassDB::bind_method(D_METHOD("custom_ref_func", "ref"), &Example::custom_ref_func);
  111. ClassDB::bind_method(D_METHOD("custom_const_ref_func", "ref"), &Example::custom_const_ref_func);
  112. ClassDB::bind_method(D_METHOD("image_ref_func", "image"), &Example::image_ref_func);
  113. ClassDB::bind_method(D_METHOD("image_const_ref_func", "image"), &Example::image_const_ref_func);
  114. ClassDB::bind_method(D_METHOD("return_something"), &Example::return_something);
  115. ClassDB::bind_method(D_METHOD("return_something_const"), &Example::return_something_const);
  116. ClassDB::bind_method(D_METHOD("return_empty_ref"), &Example::return_empty_ref);
  117. ClassDB::bind_method(D_METHOD("return_extended_ref"), &Example::return_extended_ref);
  118. ClassDB::bind_method(D_METHOD("extended_ref_checks", "ref"), &Example::extended_ref_checks);
  119. ClassDB::bind_method(D_METHOD("test_array"), &Example::test_array);
  120. ClassDB::bind_method(D_METHOD("test_tarray_arg", "array"), &Example::test_tarray_arg);
  121. ClassDB::bind_method(D_METHOD("test_tarray"), &Example::test_tarray);
  122. ClassDB::bind_method(D_METHOD("test_dictionary"), &Example::test_dictionary);
  123. ClassDB::bind_method(D_METHOD("test_node_argument"), &Example::test_node_argument);
  124. ClassDB::bind_method(D_METHOD("test_string_ops"), &Example::test_string_ops);
  125. ClassDB::bind_method(D_METHOD("test_str_utility"), &Example::test_str_utility);
  126. ClassDB::bind_method(D_METHOD("test_string_is_fourty_two"), &Example::test_string_is_fourty_two);
  127. ClassDB::bind_method(D_METHOD("test_string_resize"), &Example::test_string_resize);
  128. ClassDB::bind_method(D_METHOD("test_vector_ops"), &Example::test_vector_ops);
  129. ClassDB::bind_method(D_METHOD("test_object_cast_to_node", "object"), &Example::test_object_cast_to_node);
  130. ClassDB::bind_method(D_METHOD("test_object_cast_to_control", "object"), &Example::test_object_cast_to_control);
  131. ClassDB::bind_method(D_METHOD("test_object_cast_to_example", "object"), &Example::test_object_cast_to_example);
  132. ClassDB::bind_method(D_METHOD("test_variant_vector2i_conversion", "variant"), &Example::test_variant_vector2i_conversion);
  133. ClassDB::bind_method(D_METHOD("test_variant_int_conversion", "variant"), &Example::test_variant_int_conversion);
  134. ClassDB::bind_method(D_METHOD("test_variant_float_conversion", "variant"), &Example::test_variant_float_conversion);
  135. ClassDB::bind_method(D_METHOD("test_add_child", "node"), &Example::test_add_child);
  136. ClassDB::bind_method(D_METHOD("test_set_tileset", "tilemap", "tileset"), &Example::test_set_tileset);
  137. ClassDB::bind_method(D_METHOD("test_bitfield", "flags"), &Example::test_bitfield);
  138. ClassDB::bind_method(D_METHOD("test_rpc", "value"), &Example::test_rpc);
  139. ClassDB::bind_method(D_METHOD("test_send_rpc", "value"), &Example::test_send_rpc);
  140. ClassDB::bind_method(D_METHOD("return_last_rpc_arg"), &Example::return_last_rpc_arg);
  141. ClassDB::bind_method(D_METHOD("def_args", "a", "b"), &Example::def_args, DEFVAL(100), DEFVAL(200));
  142. ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
  143. ClassDB::bind_static_method("Example", D_METHOD("test_static2"), &Example::test_static2);
  144. {
  145. MethodInfo mi;
  146. mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
  147. mi.name = "varargs_func";
  148. ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "varargs_func", &Example::varargs_func, mi);
  149. }
  150. {
  151. MethodInfo mi;
  152. mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
  153. mi.name = "varargs_func_nv";
  154. ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "varargs_func_nv", &Example::varargs_func_nv, mi);
  155. }
  156. {
  157. MethodInfo mi;
  158. mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
  159. mi.name = "varargs_func_void";
  160. ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "varargs_func_void", &Example::varargs_func_void, mi);
  161. }
  162. // Properties.
  163. ADD_GROUP("Test group", "group_");
  164. ADD_SUBGROUP("Test subgroup", "group_subgroup_");
  165. ClassDB::bind_method(D_METHOD("get_custom_position"), &Example::get_custom_position);
  166. ClassDB::bind_method(D_METHOD("get_v4"), &Example::get_v4);
  167. ClassDB::bind_method(D_METHOD("set_custom_position", "position"), &Example::set_custom_position);
  168. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "group_subgroup_custom_position"), "set_custom_position", "get_custom_position");
  169. // Signals.
  170. ADD_SIGNAL(MethodInfo("custom_signal", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::INT, "value")));
  171. ClassDB::bind_method(D_METHOD("emit_custom_signal", "name", "value"), &Example::emit_custom_signal);
  172. // Constants.
  173. BIND_ENUM_CONSTANT(FIRST);
  174. BIND_ENUM_CONSTANT(ANSWER_TO_EVERYTHING);
  175. BIND_BITFIELD_FLAG(FLAG_ONE);
  176. BIND_BITFIELD_FLAG(FLAG_TWO);
  177. BIND_CONSTANT(CONSTANT_WITHOUT_ENUM);
  178. BIND_ENUM_CONSTANT(OUTSIDE_OF_CLASS);
  179. }
  180. Example::Example() {
  181. //UtilityFunctions::print("Constructor.");
  182. }
  183. Example::~Example() {
  184. //UtilityFunctions::print("Destructor.");
  185. }
  186. // Methods.
  187. void Example::simple_func() {
  188. emit_custom_signal("simple_func", 3);
  189. }
  190. void Example::simple_const_func() const {
  191. ((Example *)this)->emit_custom_signal("simple_const_func", 4);
  192. }
  193. int Example::custom_ref_func(Ref<ExampleRef> p_ref) {
  194. return p_ref.is_valid() ? p_ref->get_id() : -1;
  195. }
  196. int Example::custom_const_ref_func(const Ref<ExampleRef> &p_ref) {
  197. return p_ref.is_valid() ? p_ref->get_id() : -1;
  198. }
  199. String Example::image_ref_func(Ref<Image> p_image) {
  200. return p_image.is_valid() ? String("valid") : String("invalid");
  201. }
  202. String Example::image_const_ref_func(const Ref<Image> &p_image) {
  203. return p_image.is_valid() ? String("valid") : String("invalid");
  204. }
  205. String Example::return_something(const String &base) {
  206. return base + String("42");
  207. }
  208. Viewport *Example::return_something_const() const {
  209. if (is_inside_tree()) {
  210. Viewport *result = get_viewport();
  211. return result;
  212. }
  213. return nullptr;
  214. }
  215. Ref<ExampleRef> Example::return_empty_ref() const {
  216. Ref<ExampleRef> ref;
  217. return ref;
  218. }
  219. ExampleRef *Example::return_extended_ref() const {
  220. // You can instance and return a refcounted object like this, but keep in mind that refcounting starts with the returned object
  221. // and it will be destroyed when all references are destroyed. If you store this pointer you run the risk of having a pointer
  222. // to a destroyed object.
  223. return memnew(ExampleRef());
  224. }
  225. Ref<ExampleRef> Example::extended_ref_checks(Ref<ExampleRef> p_ref) const {
  226. // This is therefor the prefered way of instancing and returning a refcounted object:
  227. Ref<ExampleRef> ref;
  228. ref.instantiate();
  229. return ref;
  230. }
  231. Variant Example::varargs_func(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
  232. return arg_count;
  233. }
  234. int Example::varargs_func_nv(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
  235. return 42 + arg_count;
  236. }
  237. void Example::varargs_func_void(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
  238. emit_custom_signal("varargs_func_void", arg_count + 1);
  239. }
  240. void Example::emit_custom_signal(const String &name, int value) {
  241. emit_signal("custom_signal", name, value);
  242. }
  243. Array Example::test_array() const {
  244. Array arr;
  245. arr.resize(2);
  246. arr[0] = Variant(1);
  247. arr[1] = Variant(2);
  248. return arr;
  249. }
  250. String Example::test_string_ops() const {
  251. String s = String("A");
  252. s += "B";
  253. s += "C";
  254. s += char32_t(0x010E);
  255. s = s + "E";
  256. return s;
  257. }
  258. String Example::test_str_utility() const {
  259. return UtilityFunctions::str("Hello, ", "World", "! The answer is ", 42);
  260. }
  261. bool Example::test_string_is_fourty_two(const String &p_string) const {
  262. return strcmp(p_string.utf8().ptr(), "fourty two") == 0;
  263. }
  264. String Example::test_string_resize(String p_string) const {
  265. int orig_len = p_string.length();
  266. p_string.resize(orig_len + 3);
  267. char32_t *data = p_string.ptrw();
  268. data[orig_len + 0] = '!';
  269. data[orig_len + 1] = '?';
  270. data[orig_len + 2] = '\0';
  271. return p_string;
  272. }
  273. int Example::test_vector_ops() const {
  274. PackedInt32Array arr;
  275. arr.push_back(10);
  276. arr.push_back(20);
  277. arr.push_back(30);
  278. arr.push_back(45);
  279. int ret = 0;
  280. for (const int32_t &E : arr) {
  281. ret += E;
  282. }
  283. return ret;
  284. }
  285. int Example::test_tarray_arg(const TypedArray<int64_t> &p_array) {
  286. int sum = 0;
  287. for (int i = 0; i < p_array.size(); i++) {
  288. sum += (int)p_array[i];
  289. }
  290. return sum;
  291. }
  292. TypedArray<Vector2> Example::test_tarray() const {
  293. TypedArray<Vector2> arr;
  294. arr.resize(2);
  295. arr[0] = Vector2(1, 2);
  296. arr[1] = Vector2(2, 3);
  297. return arr;
  298. }
  299. Dictionary Example::test_dictionary() const {
  300. Dictionary dict;
  301. dict["hello"] = "world";
  302. dict["foo"] = "bar";
  303. return dict;
  304. }
  305. Example *Example::test_node_argument(Example *p_node) const {
  306. return p_node;
  307. }
  308. bool Example::test_object_cast_to_node(Object *p_object) const {
  309. return Object::cast_to<Node>(p_object) != nullptr;
  310. }
  311. bool Example::test_object_cast_to_control(Object *p_object) const {
  312. return Object::cast_to<Control>(p_object) != nullptr;
  313. }
  314. bool Example::test_object_cast_to_example(Object *p_object) const {
  315. return Object::cast_to<Example>(p_object) != nullptr;
  316. }
  317. Vector2i Example::test_variant_vector2i_conversion(const Variant &p_variant) const {
  318. return p_variant;
  319. }
  320. int Example::test_variant_int_conversion(const Variant &p_variant) const {
  321. return p_variant;
  322. }
  323. float Example::test_variant_float_conversion(const Variant &p_variant) const {
  324. return p_variant;
  325. }
  326. void Example::test_add_child(Node *p_node) {
  327. add_child(p_node);
  328. }
  329. void Example::test_set_tileset(TileMap *p_tilemap, const Ref<TileSet> &p_tileset) const {
  330. p_tilemap->set_tileset(p_tileset);
  331. }
  332. BitField<Example::Flags> Example::test_bitfield(BitField<Flags> flags) {
  333. return flags;
  334. }
  335. void Example::test_rpc(int p_value) {
  336. last_rpc_arg = p_value;
  337. }
  338. void Example::test_send_rpc(int p_value) {
  339. rpc("test_rpc", p_value);
  340. }
  341. int Example::return_last_rpc_arg() {
  342. return last_rpc_arg;
  343. }
  344. // Properties.
  345. void Example::set_custom_position(const Vector2 &pos) {
  346. custom_position = pos;
  347. }
  348. Vector2 Example::get_custom_position() const {
  349. return custom_position;
  350. }
  351. Vector4 Example::get_v4() const {
  352. return Vector4(1.2, 3.4, 5.6, 7.8);
  353. }
  354. // Virtual function override.
  355. bool Example::_has_point(const Vector2 &point) const {
  356. Label *label = get_node<Label>("Label");
  357. label->set_text("Got point: " + Variant(point).stringify());
  358. return false;
  359. }
  360. void Example::_input(const Ref<InputEvent> &event) {
  361. const InputEventKey *key_event = Object::cast_to<const InputEventKey>(*event);
  362. if (key_event) {
  363. emit_custom_signal(String("_input: ") + key_event->get_key_label(), key_event->get_unicode());
  364. }
  365. }