example.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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/variant/utility_functions.hpp>
  10. using namespace godot;
  11. int ExampleRef::instance_count = 0;
  12. int ExampleRef::last_id = 0;
  13. int ExampleRef::get_id() {
  14. return id;
  15. }
  16. void ExampleRef::_bind_methods() {
  17. ClassDB::bind_method(D_METHOD("get_id"), &ExampleRef::get_id);
  18. }
  19. ExampleRef::ExampleRef() {
  20. id = ++last_id;
  21. instance_count++;
  22. UtilityFunctions::print("ExampleRef ", itos(id), " created, current instance count: ", itos(instance_count));
  23. }
  24. ExampleRef::~ExampleRef() {
  25. instance_count--;
  26. UtilityFunctions::print("ExampleRef ", itos(id), " destroyed, current instance count: ", itos(instance_count));
  27. }
  28. int Example::test_static(int p_a, int p_b) {
  29. return p_a + p_b;
  30. }
  31. void Example::test_static2() {
  32. UtilityFunctions::print(" void static");
  33. }
  34. int Example::def_args(int p_a, int p_b) {
  35. return p_a + p_b;
  36. }
  37. void Example::_notification(int p_what) {
  38. UtilityFunctions::print("Notification: ", String::num(p_what));
  39. }
  40. bool Example::_set(const StringName &p_name, const Variant &p_value) {
  41. String name = p_name;
  42. if (name.begins_with("dproperty")) {
  43. int64_t index = name.get_slicec('_', 1).to_int();
  44. dprop[index] = p_value;
  45. return true;
  46. }
  47. if (name == "property_from_list") {
  48. property_from_list = p_value;
  49. return true;
  50. }
  51. return false;
  52. }
  53. bool Example::_get(const StringName &p_name, Variant &r_ret) const {
  54. String name = p_name;
  55. if (name.begins_with("dproperty")) {
  56. int64_t index = name.get_slicec('_', 1).to_int();
  57. r_ret = dprop[index];
  58. return true;
  59. }
  60. if (name == "property_from_list") {
  61. r_ret = property_from_list;
  62. return true;
  63. }
  64. return false;
  65. }
  66. String Example::_to_string() const {
  67. return "[ GDExtension::Example <--> Instance ID:" + uitos(get_instance_id()) + " ]";
  68. }
  69. void Example::_get_property_list(List<PropertyInfo> *p_list) const {
  70. p_list->push_back(PropertyInfo(Variant::VECTOR3, "property_from_list"));
  71. for (int i = 0; i < 3; i++) {
  72. p_list->push_back(PropertyInfo(Variant::VECTOR2, "dproperty_" + itos(i)));
  73. }
  74. }
  75. bool Example::_property_can_revert(const StringName &p_name) const {
  76. if (p_name == StringName("property_from_list") && property_from_list != Vector3(42, 42, 42)) {
  77. return true;
  78. } else {
  79. return false;
  80. }
  81. };
  82. bool Example::_property_get_revert(const StringName &p_name, Variant &r_property) const {
  83. if (p_name == StringName("property_from_list")) {
  84. r_property = Vector3(42, 42, 42);
  85. return true;
  86. } else {
  87. return false;
  88. }
  89. };
  90. void Example::_bind_methods() {
  91. // Methods.
  92. ClassDB::bind_method(D_METHOD("simple_func"), &Example::simple_func);
  93. ClassDB::bind_method(D_METHOD("simple_const_func"), &Example::simple_const_func);
  94. ClassDB::bind_method(D_METHOD("return_something"), &Example::return_something);
  95. ClassDB::bind_method(D_METHOD("return_something_const"), &Example::return_something_const);
  96. ClassDB::bind_method(D_METHOD("return_empty_ref"), &Example::return_empty_ref);
  97. ClassDB::bind_method(D_METHOD("return_extended_ref"), &Example::return_extended_ref);
  98. ClassDB::bind_method(D_METHOD("extended_ref_checks", "ref"), &Example::extended_ref_checks);
  99. ClassDB::bind_method(D_METHOD("test_array"), &Example::test_array);
  100. ClassDB::bind_method(D_METHOD("test_tarray_arg", "array"), &Example::test_tarray_arg);
  101. ClassDB::bind_method(D_METHOD("test_tarray"), &Example::test_tarray);
  102. ClassDB::bind_method(D_METHOD("test_dictionary"), &Example::test_dictionary);
  103. ClassDB::bind_method(D_METHOD("test_node_argument"), &Example::test_node_argument);
  104. ClassDB::bind_method(D_METHOD("test_string_ops"), &Example::test_string_ops);
  105. ClassDB::bind_method(D_METHOD("test_vector_ops"), &Example::test_vector_ops);
  106. ClassDB::bind_method(D_METHOD("test_bitfield", "flags"), &Example::test_bitfield);
  107. ClassDB::bind_method(D_METHOD("def_args", "a", "b"), &Example::def_args, DEFVAL(100), DEFVAL(200));
  108. ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
  109. ClassDB::bind_static_method("Example", D_METHOD("test_static2"), &Example::test_static2);
  110. {
  111. MethodInfo mi;
  112. mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
  113. mi.name = "varargs_func";
  114. ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "varargs_func", &Example::varargs_func, mi);
  115. }
  116. {
  117. MethodInfo mi;
  118. mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
  119. mi.name = "varargs_func_nv";
  120. ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "varargs_func_nv", &Example::varargs_func_nv, mi);
  121. }
  122. {
  123. MethodInfo mi;
  124. mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
  125. mi.name = "varargs_func_void";
  126. ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "varargs_func_void", &Example::varargs_func_void, mi);
  127. }
  128. // Properties.
  129. ADD_GROUP("Test group", "group_");
  130. ADD_SUBGROUP("Test subgroup", "group_subgroup_");
  131. ClassDB::bind_method(D_METHOD("get_custom_position"), &Example::get_custom_position);
  132. ClassDB::bind_method(D_METHOD("get_v4"), &Example::get_v4);
  133. ClassDB::bind_method(D_METHOD("set_custom_position", "position"), &Example::set_custom_position);
  134. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "group_subgroup_custom_position"), "set_custom_position", "get_custom_position");
  135. // Signals.
  136. ADD_SIGNAL(MethodInfo("custom_signal", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::INT, "value")));
  137. ClassDB::bind_method(D_METHOD("emit_custom_signal", "name", "value"), &Example::emit_custom_signal);
  138. // Constants.
  139. BIND_ENUM_CONSTANT(FIRST);
  140. BIND_ENUM_CONSTANT(ANSWER_TO_EVERYTHING);
  141. BIND_BITFIELD_FLAG(FLAG_ONE);
  142. BIND_BITFIELD_FLAG(FLAG_TWO);
  143. BIND_CONSTANT(CONSTANT_WITHOUT_ENUM);
  144. BIND_ENUM_CONSTANT(OUTSIDE_OF_CLASS);
  145. }
  146. Example::Example() {
  147. UtilityFunctions::print("Constructor.");
  148. }
  149. Example::~Example() {
  150. UtilityFunctions::print("Destructor.");
  151. }
  152. // Methods.
  153. void Example::simple_func() {
  154. UtilityFunctions::print(" Simple func called.");
  155. }
  156. void Example::simple_const_func() const {
  157. UtilityFunctions::print(" Simple const func called.");
  158. }
  159. String Example::return_something(const String &base) {
  160. UtilityFunctions::print(" Return something called.");
  161. return base;
  162. }
  163. Viewport *Example::return_something_const() const {
  164. UtilityFunctions::print(" Return something const called.");
  165. if (is_inside_tree()) {
  166. Viewport *result = get_viewport();
  167. return result;
  168. }
  169. return nullptr;
  170. }
  171. Ref<ExampleRef> Example::return_empty_ref() const {
  172. Ref<ExampleRef> ref;
  173. return ref;
  174. }
  175. ExampleRef *Example::return_extended_ref() const {
  176. // You can instance and return a refcounted object like this, but keep in mind that refcounting starts with the returned object
  177. // and it will be destroyed when all references are destroyed. If you store this pointer you run the risk of having a pointer
  178. // to a destroyed object.
  179. return memnew(ExampleRef());
  180. }
  181. Example *Example::test_node_argument(Example *p_node) const {
  182. UtilityFunctions::print(" Test node argument called with ", p_node ? String::num(p_node->get_instance_id()) : "null");
  183. return p_node;
  184. }
  185. Ref<ExampleRef> Example::extended_ref_checks(Ref<ExampleRef> p_ref) const {
  186. // This is therefor the prefered way of instancing and returning a refcounted object:
  187. Ref<ExampleRef> ref;
  188. ref.instantiate();
  189. UtilityFunctions::print(" Example ref checks called with value: ", p_ref->get_instance_id(), ", returning value: ", ref->get_instance_id());
  190. return ref;
  191. }
  192. Variant Example::varargs_func(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
  193. UtilityFunctions::print(" Varargs (Variant return) called with ", String::num((double)arg_count), " arguments");
  194. return arg_count;
  195. }
  196. int Example::varargs_func_nv(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
  197. UtilityFunctions::print(" Varargs (int return) called with ", String::num((double)arg_count), " arguments");
  198. return 42;
  199. }
  200. void Example::varargs_func_void(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
  201. UtilityFunctions::print(" Varargs (no return) called with ", String::num((double)arg_count), " arguments");
  202. }
  203. void Example::emit_custom_signal(const String &name, int value) {
  204. emit_signal("custom_signal", name, value);
  205. }
  206. Array Example::test_array() const {
  207. Array arr;
  208. arr.resize(2);
  209. arr[0] = Variant(1);
  210. arr[1] = Variant(2);
  211. return arr;
  212. }
  213. String Example::test_string_ops() const {
  214. String s = String("A");
  215. s += "B";
  216. s += "C";
  217. s += char32_t(0x010E);
  218. s = s + "E";
  219. return s;
  220. }
  221. int Example::test_vector_ops() const {
  222. PackedInt32Array arr;
  223. arr.push_back(10);
  224. arr.push_back(20);
  225. arr.push_back(30);
  226. arr.push_back(45);
  227. int ret = 0;
  228. for (const int32_t &E : arr) {
  229. ret += E;
  230. }
  231. return ret;
  232. }
  233. void Example::test_tarray_arg(const TypedArray<int64_t> &p_array) {
  234. for (int i = 0; i < p_array.size(); i++) {
  235. UtilityFunctions::print(p_array[i]);
  236. }
  237. }
  238. TypedArray<Vector2> Example::test_tarray() const {
  239. TypedArray<Vector2> arr;
  240. arr.resize(2);
  241. arr[0] = Vector2(1, 2);
  242. arr[1] = Vector2(2, 3);
  243. return arr;
  244. }
  245. Dictionary Example::test_dictionary() const {
  246. Dictionary dict;
  247. dict["hello"] = "world";
  248. dict["foo"] = "bar";
  249. return dict;
  250. }
  251. BitField<Example::Flags> Example::test_bitfield(BitField<Flags> flags) {
  252. UtilityFunctions::print(" Got BitField: ", String::num_int64(flags));
  253. return flags;
  254. }
  255. // Properties.
  256. void Example::set_custom_position(const Vector2 &pos) {
  257. custom_position = pos;
  258. }
  259. Vector2 Example::get_custom_position() const {
  260. return custom_position;
  261. }
  262. Vector4 Example::get_v4() const {
  263. return Vector4(1.2, 3.4, 5.6, 7.8);
  264. }
  265. // Virtual function override.
  266. bool Example::_has_point(const Vector2 &point) const {
  267. Label *label = get_node<Label>("Label");
  268. label->set_text("Got point: " + Variant(point).stringify());
  269. return false;
  270. }