diff options
author | George Marques <george@gmarqu.es> | 2021-08-18 11:03:52 -0300 |
---|---|---|
committer | Bastiaan Olij <mux213@gmail.com> | 2021-09-27 23:08:08 +1000 |
commit | e4ed48976a962b67e9585cc2d20d11f115ef7949 (patch) | |
tree | 7830ad6926b5cd14a91784b07c2eff5b77e3f533 /include | |
parent | ee708668944430a7f1d69e8faf7b3f3160432dc2 (diff) | |
download | redot-cpp-e4ed48976a962b67e9585cc2d20d11f115ef7949.tar.gz |
Replace bindgins to work with extensions
Diffstat (limited to 'include')
40 files changed, 3267 insertions, 5301 deletions
diff --git a/include/core/AABB.hpp b/include/core/AABB.hpp deleted file mode 100644 index 5c6944f..0000000 --- a/include/core/AABB.hpp +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************/ -/* AABB.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef AABB_H -#define AABB_H - -#include "Vector3.hpp" - -#include "Plane.hpp" - -#include <cstdlib> - -namespace godot { - -class AABB { -public: - Vector3 position; - Vector3 size; - - real_t get_area() const; /// get area - inline bool has_no_area() const { - return (size.x <= CMP_EPSILON || size.y <= CMP_EPSILON || size.z <= CMP_EPSILON); - } - - inline bool has_no_surface() const { - return (size.x <= CMP_EPSILON && size.y <= CMP_EPSILON && size.z <= CMP_EPSILON); - } - - inline const Vector3 &get_position() const { return position; } - inline void set_position(const Vector3 &p_position) { position = p_position; } - inline const Vector3 &get_size() const { return size; } - inline void set_size(const Vector3 &p_size) { size = p_size; } - - bool operator==(const AABB &p_rval) const; - bool operator!=(const AABB &p_rval) const; - - bool intersects(const AABB &p_aabb) const; /// Both AABBs overlap - bool intersects_inclusive(const AABB &p_aabb) const; /// Both AABBs (or their faces) overlap - bool encloses(const AABB &p_aabb) const; /// p_aabb is completely inside this - - AABB merge(const AABB &p_with) const; - void merge_with(const AABB &p_aabb); ///merge with another AABB - AABB intersection(const AABB &p_aabb) const; ///get box where two intersect, empty if no intersection occurs - bool intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip = nullptr, Vector3 *r_normal = nullptr) const; - bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip = nullptr, Vector3 *r_normal = nullptr) const; - bool smits_intersect_ray(const Vector3 &from, const Vector3 &p_dir, real_t t0, real_t t1) const; - - bool intersects_convex_shape(const Plane *p_plane, int p_plane_count) const; - bool intersects_plane(const Plane &p_plane) const; - - bool has_point(const Vector3 &p_point) const; - Vector3 get_support(const Vector3 &p_normal) const; - - Vector3 get_longest_axis() const; - int get_longest_axis_index() const; - real_t get_longest_axis_size() const; - - Vector3 get_shortest_axis() const; - int get_shortest_axis_index() const; - real_t get_shortest_axis_size() const; - - AABB grow(real_t p_by) const; - void grow_by(real_t p_amount); - - void get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const; - Vector3 get_endpoint(int p_point) const; - - AABB expand(const Vector3 &p_vector) const; - void project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r_max) const; - void expand_to(const Vector3 &p_vector); /** expand to contain a point if necesary */ - - operator String() const; - - inline AABB() {} - inline AABB(const Vector3 &p_pos, const Vector3 &p_size) { - position = p_pos; - size = p_size; - } -}; - -} // namespace godot - -#endif // RECT3_H diff --git a/include/core/Array.hpp b/include/core/Array.hpp deleted file mode 100644 index 91948a4..0000000 --- a/include/core/Array.hpp +++ /dev/null @@ -1,191 +0,0 @@ -/*************************************************************************/ -/* Array.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef ARRAY_H -#define ARRAY_H - -#include <gdnative/array.h> - -#include "String.hpp" - -namespace godot { - -namespace helpers { -template <typename T, typename ValueT> -T append_all(T appendable, ValueT value) { - appendable.append(value); - return appendable; -} - -template <typename T, typename ValueT, typename... Args> -T append_all(T appendable, ValueT value, Args... args) { - appendable.append(value); - return append_all(appendable, args...); -} - -template <typename T> -T append_all(T appendable) { - return appendable; -} - -template <typename KV, typename KeyT, typename ValueT> -KV add_all(KV kv, KeyT key, ValueT value) { - kv[key] = value; - return kv; -} - -template <typename KV, typename KeyT, typename ValueT, typename... Args> -KV add_all(KV kv, KeyT key, ValueT value, Args... args) { - kv[key] = value; - return add_all(kv, args...); -} - -template <typename KV> -KV add_all(KV kv) { - return kv; -} -} // namespace helpers - -class Variant; -class PoolByteArray; -class PoolIntArray; -class PoolRealArray; -class PoolStringArray; -class PoolVector2Array; -class PoolVector3Array; -class PoolColorArray; - -class Object; - -class Array { - godot_array _godot_array; - - friend class Variant; - friend class Dictionary; - friend class String; - inline explicit Array(const godot_array &other) { - _godot_array = other; - } - -public: - Array(); - Array(const Array &other); - Array &operator=(const Array &other); - - Array(const PoolByteArray &a); - - Array(const PoolIntArray &a); - - Array(const PoolRealArray &a); - - Array(const PoolStringArray &a); - - Array(const PoolVector2Array &a); - - Array(const PoolVector3Array &a); - - Array(const PoolColorArray &a); - - template <class... Args> - static Array make(Args... args) { - return helpers::append_all(Array(), args...); - } - - Variant &operator[](const int idx); - - const Variant &operator[](const int idx) const; - - void append(const Variant &v); - - void clear(); - - int count(const Variant &v); - - bool empty() const; - - void erase(const Variant &v); - - Variant front() const; - - Variant back() const; - - int find(const Variant &what, const int from = 0) const; - - int find_last(const Variant &what) const; - - bool has(const Variant &what) const; - - uint32_t hash() const; - - void insert(const int pos, const Variant &value); - - void invert(); - - bool is_shared() const; - - Variant pop_back(); - - Variant pop_front(); - - void push_back(const Variant &v); - - void push_front(const Variant &v); - - void remove(const int idx); - - int size() const; - - void resize(const int size); - - int rfind(const Variant &what, const int from = -1) const; - - void sort(); - - void sort_custom(Object *obj, const String &func); - - int bsearch(const Variant &value, const bool before = true); - - int bsearch_custom(const Variant &value, const Object *obj, - const String &func, const bool before = true); - - Array duplicate(const bool deep = false) const; - - Variant max() const; - - Variant min() const; - - void shuffle(); - - ~Array(); -}; - -} // namespace godot - -#endif // ARRAY_H diff --git a/include/core/Basis.hpp b/include/core/Basis.hpp deleted file mode 100644 index de956e6..0000000 --- a/include/core/Basis.hpp +++ /dev/null @@ -1,458 +0,0 @@ -/*************************************************************************/ -/* Basis.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef BASIS_H -#define BASIS_H - -#include <gdnative/basis.h> - -#include "Defs.hpp" - -#include "Vector3.hpp" - -namespace godot { - -class Quat; - -class Basis { -private: - static const Basis IDENTITY; - static const Basis FLIP_X; - static const Basis FLIP_Y; - static const Basis FLIP_Z; - - // This helper template is for mimicking the behavior difference between the engine - // and script interfaces that logically script sees matrices as column major, while - // the engine stores them in row major to efficiently take advantage of SIMD - // instructions in case of matrix-vector multiplications. - // With this helper template native scripts see the data as if it was column major - // without actually transposing the basis matrix at the script-engine boundary. - template <int column> - class ColumnVector3 { - private: - template <int column1, int component> - class ColumnVectorComponent { - private: - Vector3 elements[3]; - - protected: - inline ColumnVectorComponent<column1, component> &operator=(const ColumnVectorComponent<column1, component> &p_value) { - return *this = real_t(p_value); - } - - inline ColumnVectorComponent(const ColumnVectorComponent<column1, component> &p_value) { - *this = real_t(p_value); - } - - inline ColumnVectorComponent<column1, component> &operator=(const real_t &p_value) { - elements[component][column1] = p_value; - return *this; - } - - inline operator real_t() const { - return elements[component][column1]; - } - }; - - public: - enum Axis { - AXIS_X, - AXIS_Y, - AXIS_Z, - }; - - union { - ColumnVectorComponent<column, 0> x; - ColumnVectorComponent<column, 1> y; - ColumnVectorComponent<column, 2> z; - - Vector3 elements[3]; // Not for direct access, use [] operator instead - }; - - inline ColumnVector3<column> &operator=(const ColumnVector3<column> &p_value) { - return *this = Vector3(p_value); - } - - inline ColumnVector3(const ColumnVector3<column> &p_value) { - *this = Vector3(p_value); - } - - inline ColumnVector3<column> &operator=(const Vector3 &p_value) { - elements[0][column] = p_value.x; - elements[1][column] = p_value.y; - elements[2][column] = p_value.z; - return *this; - } - - inline operator Vector3() const { - return Vector3(elements[0][column], elements[1][column], elements[2][column]); - } - - // Unfortunately, we also need to replicate the other interfaces of Vector3 in - // order for being able to directly operate on these "meta-Vector3" objects without - // an explicit cast or an intermediate assignment to a real Vector3 object. - - inline const real_t &operator[](int p_axis) const { - return elements[p_axis][column]; - } - - inline real_t &operator[](int p_axis) { - return elements[p_axis][column]; - } - - inline ColumnVector3<column> &operator+=(const Vector3 &p_v) { - return *this = *this + p_v; - } - - inline Vector3 operator+(const Vector3 &p_v) const { - return Vector3(*this) + p_v; - } - - inline ColumnVector3<column> &operator-=(const Vector3 &p_v) { - return *this = *this - p_v; - } - - inline Vector3 operator-(const Vector3 &p_v) const { - return Vector3(*this) - p_v; - } - - inline ColumnVector3<column> &operator*=(const Vector3 &p_v) { - return *this = *this * p_v; - } - - inline Vector3 operator*(const Vector3 &p_v) const { - return Vector3(*this) * p_v; - } - - inline ColumnVector3<column> &operator/=(const Vector3 &p_v) { - return *this = *this / p_v; - } - - inline Vector3 operator/(const Vector3 &p_v) const { - return Vector3(*this) / p_v; - } - - inline ColumnVector3<column> &operator*=(real_t p_scalar) { - return *this = *this * p_scalar; - } - - inline Vector3 operator*(real_t p_scalar) const { - return Vector3(*this) * p_scalar; - } - - inline ColumnVector3<column> &operator/=(real_t p_scalar) { - return *this = *this / p_scalar; - } - - inline Vector3 operator/(real_t p_scalar) const { - return Vector3(*this) / p_scalar; - } - - inline Vector3 operator-() const { - return -Vector3(*this); - } - - inline bool operator==(const Vector3 &p_v) const { - return Vector3(*this) == p_v; - } - - inline bool operator!=(const Vector3 &p_v) const { - return Vector3(*this) != p_v; - } - - inline bool operator<(const Vector3 &p_v) const { - return Vector3(*this) < p_v; - } - - inline bool operator<=(const Vector3 &p_v) const { - return Vector3(*this) <= p_v; - } - - inline Vector3 abs() const { - return Vector3(*this).abs(); - } - - inline Vector3 ceil() const { - return Vector3(*this).ceil(); - } - - inline Vector3 cross(const Vector3 &b) const { - return Vector3(*this).cross(b); - } - - inline Vector3 linear_interpolate(const Vector3 &p_b, real_t p_t) const { - return Vector3(*this).linear_interpolate(p_b, p_t); - } - - inline Vector3 cubic_interpolate(const Vector3 &b, const Vector3 &pre_a, const Vector3 &post_b, const real_t t) const { - return Vector3(*this).cubic_interpolate(b, pre_a, post_b, t); - } - - inline Vector3 bounce(const Vector3 &p_normal) const { - return Vector3(*this).bounce(p_normal); - } - - inline real_t length() const { - return Vector3(*this).length(); - } - - inline real_t length_squared() const { - return Vector3(*this).length_squared(); - } - - inline real_t distance_squared_to(const Vector3 &b) const { - return Vector3(*this).distance_squared_to(b); - } - - inline real_t distance_to(const Vector3 &b) const { - return Vector3(*this).distance_to(b); - } - - inline real_t dot(const Vector3 &b) const { - return Vector3(*this).dot(b); - } - - inline real_t angle_to(const Vector3 &b) const { - return Vector3(*this).angle_to(b); - } - - inline Vector3 floor() const { - return Vector3(*this).floor(); - } - - inline Vector3 inverse() const { - return Vector3(*this).inverse(); - } - - inline bool is_normalized() const { - return Vector3(*this).is_normalized(); - } - - inline Basis outer(const Vector3 &b) const { - return Vector3(*this).outer(b); - } - - inline int max_axis() const { - return Vector3(*this).max_axis(); - } - - inline int min_axis() const { - return Vector3(*this).min_axis(); - } - - inline void normalize() { - Vector3 v = *this; - v.normalize(); - *this = v; - } - - inline Vector3 normalized() const { - return Vector3(*this).normalized(); - } - - inline Vector3 reflect(const Vector3 &by) const { - return Vector3(*this).reflect(by); - } - - inline Vector3 rotated(const Vector3 &axis, const real_t phi) const { - return Vector3(*this).rotated(axis, phi); - } - - inline void rotate(const Vector3 &p_axis, real_t p_phi) { - Vector3 v = *this; - v.rotate(p_axis, p_phi); - *this = v; - } - - inline Vector3 slide(const Vector3 &by) const { - return Vector3(*this).slide(by); - } - - inline void snap(real_t p_val) { - Vector3 v = *this; - v.snap(p_val); - *this = v; - } - - inline Vector3 snapped(const float by) { - return Vector3(*this).snapped(by); - } - - inline operator String() const { - return String(Vector3(*this)); - } - }; - -public: - union { - ColumnVector3<0> x; - ColumnVector3<1> y; - ColumnVector3<2> z; - - Vector3 elements[3]; // Not for direct access, use [] operator instead - }; - - inline Basis(const Basis &p_basis) { - elements[0] = p_basis.elements[0]; - elements[1] = p_basis.elements[1]; - elements[2] = p_basis.elements[2]; - } - - inline Basis &operator=(const Basis &p_basis) { - elements[0] = p_basis.elements[0]; - elements[1] = p_basis.elements[1]; - elements[2] = p_basis.elements[2]; - return *this; - } - - Basis(const Quat &p_quat); // euler - Basis(const Vector3 &p_euler); // euler - Basis(const Vector3 &p_axis, real_t p_phi); - - Basis(const Vector3 &row0, const Vector3 &row1, const Vector3 &row2); - - Basis(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz); - - Basis(); - - const Vector3 operator[](int axis) const { - return get_axis(axis); - } - - ColumnVector3<0> &operator[](int axis) { - // We need to do a little pointer magic to get this to work, because the - // ColumnVector3 template takes the axis as a template parameter. - // Don't touch this unless you're sure what you're doing! - return (reinterpret_cast<Basis *>(reinterpret_cast<real_t *>(this) + axis))->x; - } - - void invert(); - - bool isequal_approx(const Basis &a, const Basis &b) const; - - bool is_orthogonal() const; - - bool is_rotation() const; - - void transpose(); - - Basis inverse() const; - - Basis transposed() const; - - real_t determinant() const; - - Vector3 get_axis(int p_axis) const; - - void set_axis(int p_axis, const Vector3 &p_value); - - void rotate(const Vector3 &p_axis, real_t p_phi); - - Basis rotated(const Vector3 &p_axis, real_t p_phi) const; - - void scale(const Vector3 &p_scale); - - Basis scaled(const Vector3 &p_scale) const; - - Vector3 get_scale() const; - - Basis slerp(Basis b, float t) const; - - Vector3 get_euler_xyz() const; - void set_euler_xyz(const Vector3 &p_euler); - Vector3 get_euler_yxz() const; - void set_euler_yxz(const Vector3 &p_euler); - - inline Vector3 get_euler() const { return get_euler_yxz(); } - inline void set_euler(const Vector3 &p_euler) { set_euler_yxz(p_euler); } - - // transposed dot products - real_t tdotx(const Vector3 &v) const; - real_t tdoty(const Vector3 &v) const; - real_t tdotz(const Vector3 &v) const; - - bool operator==(const Basis &p_matrix) const; - - bool operator!=(const Basis &p_matrix) const; - - Vector3 xform(const Vector3 &p_vector) const; - - Vector3 xform_inv(const Vector3 &p_vector) const; - void operator*=(const Basis &p_matrix); - - Basis operator*(const Basis &p_matrix) const; - - void operator+=(const Basis &p_matrix); - - Basis operator+(const Basis &p_matrix) const; - - void operator-=(const Basis &p_matrix); - - Basis operator-(const Basis &p_matrix) const; - - void operator*=(real_t p_val); - - Basis operator*(real_t p_val) const; - - int get_orthogonal_index() const; // down below - - void set_orthogonal_index(int p_index); // down below - - operator String() const; - - void get_axis_and_angle(Vector3 &r_axis, real_t &r_angle) const; - - /* create / set */ - - void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz); - - Vector3 get_column(int i) const; - - Vector3 get_row(int i) const; - Vector3 get_main_diagonal() const; - - void set_row(int i, const Vector3 &p_row); - - Basis transpose_xform(const Basis &m) const; - - void orthonormalize(); - - Basis orthonormalized() const; - - bool is_symmetric() const; - - Basis diagonalize(); - - operator Quat() const; -}; - -} // namespace godot - -#endif // BASIS_H diff --git a/include/core/CameraMatrix.hpp b/include/core/CameraMatrix.hpp deleted file mode 100644 index 27b6f73..0000000 --- a/include/core/CameraMatrix.hpp +++ /dev/null @@ -1,124 +0,0 @@ -/*************************************************************************/ -/* CameraMatrix.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef CAMERA_MATRIX_H -#define CAMERA_MATRIX_H - -#include "Defs.hpp" -#include "Math.hpp" -#include "Plane.hpp" -#include "Rect2.hpp" -#include "Transform.hpp" - -#include <vector> - -namespace { -using namespace godot; -} // namespace - -struct CameraMatrix { - enum Planes { - PLANE_NEAR, - PLANE_FAR, - PLANE_LEFT, - PLANE_TOP, - PLANE_RIGHT, - PLANE_BOTTOM - }; - - real_t matrix[4][4]; - - void set_identity(); - void set_zero(); - void set_light_bias(); - void set_light_atlas_rect(const Rect2 &p_rect); - void set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov = false); - void set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist); - void set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far); - void set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar); - void set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov = false); - void set_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far); - void set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov = false); - - static real_t get_fovy(real_t p_fovx, real_t p_aspect) { - return Math::rad2deg(atan(p_aspect * tan(Math::deg2rad(p_fovx) * 0.5)) * 2.0); - } - - static inline double absd(double g) { - union { - double d; - uint64_t i; - } u; - u.d = g; - u.i &= (uint64_t)9223372036854775807ll; - return u.d; - } - - real_t get_z_far() const; - real_t get_z_near() const; - real_t get_aspect() const; - real_t get_fov() const; - bool is_orthogonal() const; - - std::vector<Plane> get_projection_planes(const Transform &p_transform) const; - - bool get_endpoints(const Transform &p_transform, Vector3 *p_8points) const; - Vector2 get_viewport_half_extents() const; - - void invert(); - CameraMatrix inverse() const; - - CameraMatrix operator*(const CameraMatrix &p_matrix) const; - - Plane xform4(const Plane &p_vec4) const; - inline Vector3 xform(const Vector3 &p_vec3) const; - - operator String() const; - - void scale_translate_to_fit(const AABB &p_aabb); - void make_scale(const Vector3 &p_scale); - int get_pixels_per_meter(int p_for_pixel_width) const; - operator Transform() const; - - CameraMatrix(); - CameraMatrix(const Transform &p_transform); - ~CameraMatrix(); -}; - -Vector3 CameraMatrix::xform(const Vector3 &p_vec3) const { - Vector3 ret; - ret.x = matrix[0][0] * p_vec3.x + matrix[1][0] * p_vec3.y + matrix[2][0] * p_vec3.z + matrix[3][0]; - ret.y = matrix[0][1] * p_vec3.x + matrix[1][1] * p_vec3.y + matrix[2][1] * p_vec3.z + matrix[3][1]; - ret.z = matrix[0][2] * p_vec3.x + matrix[1][2] * p_vec3.y + matrix[2][2] * p_vec3.z + matrix[3][2]; - real_t w = matrix[0][3] * p_vec3.x + matrix[1][3] * p_vec3.y + matrix[2][3] * p_vec3.z + matrix[3][3]; - return ret / w; -} - -#endif diff --git a/include/core/Color.hpp b/include/core/Color.hpp deleted file mode 100644 index 36d3254..0000000 --- a/include/core/Color.hpp +++ /dev/null @@ -1,171 +0,0 @@ -/*************************************************************************/ -/* Color.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef COLOR_H -#define COLOR_H - -#include <gdnative/color.h> - -#include <cmath> - -#include "Defs.hpp" -#include "String.hpp" - -namespace godot { - -struct Color { -private: - // static float _parse_col(const String& p_str, int p_ofs); -public: - union { - struct { - float r; - float g; - float b; - float a; - }; - float components[4]; - }; - - inline bool operator==(const Color &p_color) const { return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a); } - inline bool operator!=(const Color &p_color) const { return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a); } - - uint32_t to_32() const; - - uint32_t to_ARGB32() const; - - uint32_t to_ABGR32() const; - - uint64_t to_ABGR64() const; - - uint64_t to_ARGB64() const; - - uint32_t to_RGBA32() const; - - uint64_t to_RGBA64() const; - - float gray() const; - - uint8_t get_r8() const; - - uint8_t get_g8() const; - - uint8_t get_b8() const; - - uint8_t get_a8() const; - - float get_h() const; - - float get_s() const; - - float get_v() const; - - void set_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0); - - Color darkened(const float amount) const; - - Color lightened(const float amount) const; - - Color from_hsv(float p_h, float p_s, float p_v, float p_a = 1.0) const; - - inline float &operator[](int idx) { - return components[idx]; - } - inline const float &operator[](int idx) const { - return components[idx]; - } - - Color operator+(const Color &p_color) const; - void operator+=(const Color &p_color); - - Color operator-() const; - Color operator-(const Color &p_color) const; - void operator-=(const Color &p_color); - - Color operator*(const Color &p_color) const; - Color operator*(const real_t &rvalue) const; - void operator*=(const Color &p_color); - void operator*=(const real_t &rvalue); - - Color operator/(const Color &p_color) const; - Color operator/(const real_t &rvalue) const; - void operator/=(const Color &p_color); - void operator/=(const real_t &rvalue); - - void invert(); - - void contrast(); - - Color inverted() const; - - Color contrasted() const; - - Color linear_interpolate(const Color &p_b, float p_t) const; - - Color blend(const Color &p_over) const; - - Color to_linear() const; - - static Color hex(uint32_t p_hex); - - static Color html(const String &p_color); - - static bool html_is_valid(const String &p_color); - - String to_html(bool p_alpha = true) const; - - bool operator<(const Color &p_color) const; //used in set keys - - operator String() const; - - /** - * No construct parameters, r=0, g=0, b=0. a=255 - */ - inline Color() { - r = 0; - g = 0; - b = 0; - a = 1.0; - } - - /** - * RGB / RGBA construct parameters. Alpha is optional, but defaults to 1.0 - */ - inline Color(float p_r, float p_g, float p_b, float p_a = 1.0) { - r = p_r; - g = p_g; - b = p_b; - a = p_a; - } -}; - -} // namespace godot - -#endif // COLOR_H diff --git a/include/core/CoreTypes.hpp b/include/core/CoreTypes.hpp deleted file mode 100644 index 95ba2a7..0000000 --- a/include/core/CoreTypes.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************/ -/* CoreTypes.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef CORETYPES_H -#define CORETYPES_H - -#include "Defs.hpp" - -#include "AABB.hpp" -#include "Array.hpp" -#include "Basis.hpp" -#include "Color.hpp" -#include "Dictionary.hpp" -#include "NodePath.hpp" -#include "Plane.hpp" -#include "PoolArrays.hpp" -#include "Quat.hpp" -#include "RID.hpp" -#include "Rect2.hpp" -#include "String.hpp" -#include "Transform.hpp" -#include "Transform2D.hpp" -#include "Variant.hpp" -#include "Vector2.hpp" -#include "Vector3.hpp" - -#include "Wrapped.hpp" - -#endif // CORETYPES_H diff --git a/include/core/Defs.hpp b/include/core/Defs.hpp deleted file mode 100644 index 369240e..0000000 --- a/include/core/Defs.hpp +++ /dev/null @@ -1,298 +0,0 @@ -/*************************************************************************/ -/* Defs.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef DEFS_H -#define DEFS_H - -namespace godot { - -enum class Error { - OK, - FAILED, ///< Generic fail error - ERR_UNAVAILABLE, ///< What is requested is unsupported/unavailable - ERR_UNCONFIGURED, ///< The object being used hasnt been properly set up yet - ERR_UNAUTHORIZED, ///< Missing credentials for requested resource - ERR_PARAMETER_RANGE_ERROR, ///< Parameter given out of range (5) - ERR_OUT_OF_MEMORY, ///< Out of memory - ERR_FILE_NOT_FOUND, - ERR_FILE_BAD_DRIVE, - ERR_FILE_BAD_PATH, - ERR_FILE_NO_PERMISSION, // (10) - ERR_FILE_ALREADY_IN_USE, - ERR_FILE_CANT_OPEN, - ERR_FILE_CANT_WRITE, - ERR_FILE_CANT_READ, - ERR_FILE_UNRECOGNIZED, // (15) - ERR_FILE_CORRUPT, - ERR_FILE_MISSING_DEPENDENCIES, - ERR_FILE_EOF, - ERR_CANT_OPEN, ///< Can't open a resource/socket/file - ERR_CANT_CREATE, // (20) - ERR_QUERY_FAILED, - ERR_ALREADY_IN_USE, - ERR_LOCKED, ///< resource is locked - ERR_TIMEOUT, - ERR_CANT_CONNECT, // (25) - ERR_CANT_RESOLVE, - ERR_CONNECTION_ERROR, - ERR_CANT_AQUIRE_RESOURCE, - ERR_CANT_FORK, - ERR_INVALID_DATA, ///< Data passed is invalid (30) - ERR_INVALID_PARAMETER, ///< Parameter passed is invalid - ERR_ALREADY_EXISTS, ///< When adding, item already exists - ERR_DOES_NOT_EXIST, ///< When retrieving/erasing, it item does not exist - ERR_DATABASE_CANT_READ, ///< database is full - ERR_DATABASE_CANT_WRITE, ///< database is full (35) - ERR_COMPILATION_FAILED, - ERR_METHOD_NOT_FOUND, - ERR_LINK_FAILED, - ERR_SCRIPT_FAILED, - ERR_CYCLIC_LINK, // (40) - ERR_INVALID_DECLARATION, - ERR_DUPLICATE_SYMBOL, - ERR_PARSE_ERROR, - ERR_BUSY, - ERR_SKIP, // (45) - ERR_HELP, ///< user requested help!! - ERR_BUG, ///< a bug in the software certainly happened, due to a double check failing or unexpected behavior. - ERR_PRINTER_ON_FIRE, /// the parallel port printer is engulfed in flames -}; - -} // namespace godot - -#include <GodotGlobal.hpp> - -// alloca() is non-standard. When using MSVC, it's in malloc.h. -#if defined(__linux__) || defined(__APPLE__) -#include <alloca.h> -#else -#include <malloc.h> -#endif - -typedef float real_t; - -// This epsilon should match the one used by Godot for consistency. -// Using `f` when `real_t` is float. -#define CMP_EPSILON 0.00001f -#define CMP_EPSILON2 (CMP_EPSILON * CMP_EPSILON) - -#define Math_PI 3.1415926535897932384626433833 -#define Math_TAU 6.2831853071795864769252867666 - -#define _PLANE_EQ_DOT_EPSILON 0.999 -#define _PLANE_EQ_D_EPSILON 0.0001 - -#ifdef __GNUC__ -#define likely(x) __builtin_expect(!!(x), 1) -#define unlikely(x) __builtin_expect(!!(x), 0) -#else -#define likely(x) x -#define unlikely(x) x -#endif - -// Don't use this directly; instead, use any of the CRASH_* macros -#ifdef _MSC_VER -#define GENERATE_TRAP \ - __debugbreak(); \ - /* Avoid warning about control paths */ \ - for (;;) { \ - } -#else -#define GENERATE_TRAP __builtin_trap(); -#endif - -// ERR/WARN macros -#ifndef WARN_PRINT -#define WARN_PRINT(msg) godot::Godot::print_warning(msg, __func__, __FILE__, __LINE__) -#endif - -#ifndef WARN_PRINTS -#define WARN_PRINTS(msg) WARN_PRINT((msg).utf8().get_data()) -#endif - -#ifndef ERR_PRINT -#define ERR_PRINT(msg) godot::Godot::print_error(msg, __func__, __FILE__, __LINE__) -#endif - -#ifndef ERR_PRINTS -#define ERR_PRINTS(msg) ERR_PRINT((msg).utf8().get_data()) -#endif - -#ifndef FATAL_PRINT -#define FATAL_PRINT(msg) ERR_PRINT(godot::String("FATAL: ") + (msg)) -#endif - -#ifndef ERR_MSG_INDEX -#define ERR_MSG_INDEX(index, size) (godot::String("Index ") + #index + "=" + godot::String::num_int64(index) + " out of size (" + #size + "=" + godot::String::num_int64(size) + ")") -#endif - -#ifndef ERR_MSG_NULL -#define ERR_MSG_NULL(param) (godot::String("Parameter '") + #param + "' is null.") -#endif - -#ifndef ERR_MSG_COND -#define ERR_MSG_COND(cond) (godot::String("Condition '") + #cond + "' is true.") -#endif - -#ifndef ERR_FAIL_INDEX -#define ERR_FAIL_INDEX(index, size) \ - do { \ - if (unlikely((index) < 0 || (index) >= (size))) { \ - ERR_PRINT(ERR_MSG_INDEX(index, size)); \ - return; \ - } \ - } while (0) -#endif - -#ifndef ERR_FAIL_INDEX_V -#define ERR_FAIL_INDEX_V(index, size, ret) \ - do { \ - if (unlikely((index) < 0 || (index) >= (size))) { \ - ERR_PRINT(ERR_MSG_INDEX(index, size)); \ - return ret; \ - } \ - } while (0) -#endif - -#ifndef ERR_FAIL_UNSIGNED_INDEX_V -#define ERR_FAIL_UNSIGNED_INDEX_V(index, size, ret) \ - do { \ - if (unlikely((index) >= (size))) { \ - ERR_PRINT(ERR_MSG_INDEX(index, size)); \ - return ret; \ - } \ - } while (0) -#endif - -#ifndef CRASH_BAD_INDEX -#define CRASH_BAD_INDEX(index, size) \ - do { \ - if (unlikely((index) < 0 || (index) >= (size))) { \ - FATAL_PRINT(ERR_MSG_INDEX(index, size)); \ - GENERATE_TRAP; \ - } \ - } while (0) -#endif - -#ifndef ERR_FAIL_NULL -#define ERR_FAIL_NULL(param) \ - do { \ - if (unlikely(!param)) { \ - ERR_PRINT(ERR_MSG_NULL(param)); \ - return; \ - } \ - } while (0) -#endif - -#ifndef ERR_FAIL_NULL_V -#define ERR_FAIL_NULL_V(param, ret) \ - do { \ - if (unlikely(!param)) { \ - ERR_PRINT(ERR_MSG_NULL(param)); \ - return ret; \ - } \ - } while (0) -#endif - -#ifndef ERR_FAIL_COND -#define ERR_FAIL_COND(cond) \ - do { \ - if (unlikely(cond)) { \ - ERR_PRINT(ERR_MSG_COND(cond)); \ - return; \ - } \ - } while (0) -#endif - -#ifndef CRASH_COND -#define CRASH_COND(cond) \ - do { \ - if (unlikely(cond)) { \ - FATAL_PRINT(ERR_MSG_COND(cond)); \ - GENERATE_TRAP; \ - } \ - } while (0) -#endif - -#ifndef ERR_FAIL_COND_V -#define ERR_FAIL_COND_V(cond, ret) \ - do { \ - if (unlikely(cond)) { \ - ERR_PRINT(ERR_MSG_COND(cond)); \ - return ret; \ - } \ - } while (0) -#endif - -#ifndef ERR_CONTINUE -#define ERR_CONTINUE(cond) \ - { \ - if (unlikely(cond)) { \ - ERR_PRINT(ERR_MSG_COND(cond)); \ - continue; \ - } \ - } -#endif - -#ifndef ERR_BREAK -#define ERR_BREAK(cond) \ - { \ - if (unlikely(cond)) { \ - ERR_PRINT(ERR_MSG_COND(cond)); \ - break; \ - } \ - } -#endif - -#ifndef ERR_FAIL -#define ERR_FAIL() \ - do { \ - ERR_PRINT("Method/Function Failed."); \ - return; \ - } while (0) -#endif - -#ifndef ERR_FAIL_V -#define ERR_FAIL_V(ret) \ - do { \ - ERR_PRINT("Method/Function Failed."); \ - return ret; \ - } while (0) -#endif - -#ifndef CRASH_NOW -#define CRASH_NOW() \ - do { \ - FATAL_PRINT("Method/Function Failed."); \ - GENERATE_TRAP; \ - } while (0) -#endif - -#endif // DEFS_H diff --git a/include/core/Godot.hpp b/include/core/Godot.hpp deleted file mode 100644 index 265bc71..0000000 --- a/include/core/Godot.hpp +++ /dev/null @@ -1,619 +0,0 @@ -/*************************************************************************/ -/* Godot.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef GODOT_HPP -#define GODOT_HPP - -#include <cstdlib> -#include <cstring> - -#include <gdnative_api_struct.gen.h> -#include <nativescript/godot_nativescript.h> -#include <typeinfo> - -#include "CoreTypes.hpp" -#include "Ref.hpp" -#include "TagDB.hpp" -#include "Variant.hpp" - -#include "Object.hpp" - -#include "GodotGlobal.hpp" - -#include <type_traits> - -namespace godot { -namespace detail { - -// Godot classes are wrapped by heap-allocated instances mimicking them through the C API. -// They all inherit `_Wrapped`. -template <class T> -T *get_wrapper(godot_object *obj) { - return (T *)godot::nativescript_1_1_api->godot_nativescript_get_instance_binding_data(godot::_RegisterState::language_index, obj); -} - -// Custom class instances are not obtainable by just casting the pointer to the base class they inherit, -// partly because in Godot, scripts are not instances of the classes themselves, they are only attached to them. -// Yet we want to "fake" it as if they were the same entity. -template <class T> -T *get_custom_class_instance(const Object *obj) { - return (obj) ? (T *)godot::nativescript_api->godot_nativescript_get_userdata(obj->_owner) : nullptr; -} - -template <class T> -inline T *create_custom_class_instance() { - // Usually, script instances hold a reference to their NativeScript resource. - // that resource is obtained from a `.gdns` file, which in turn exists because - // of the resource system of Godot. We can't cleanly hardcode that here, - // so the easiest for now (though not really clean) is to create new resource instances, - // individually attached to the script instances. - - // We cannot use wrappers because of https://github.com/godotengine/godot/issues/39181 - // godot::NativeScript *script = godot::NativeScript::_new(); - // script->set_library(get_wrapper<godot::GDNativeLibrary>((godot_object *)godot::gdnlib)); - // script->set_class_name(T::___get_class_name()); - - static_assert(T::___CLASS_IS_SCRIPT, "This function must only be used on custom classes"); - - // So we use the C API directly. - static godot_class_constructor script_constructor = godot::api->godot_get_class_constructor("NativeScript"); - static godot_method_bind *mb_set_library = godot::api->godot_method_bind_get_method("NativeScript", "set_library"); - static godot_method_bind *mb_set_class_name = godot::api->godot_method_bind_get_method("NativeScript", "set_class_name"); - godot_object *script = script_constructor(); - { - const void *args[] = { godot::gdnlib }; - godot::api->godot_method_bind_ptrcall(mb_set_library, script, args, nullptr); - } - { - const String class_name = T::___get_class_name(); - const void *args[] = { &class_name }; - godot::api->godot_method_bind_ptrcall(mb_set_class_name, script, args, nullptr); - } - - // Now to instanciate T, we initially did this, however in case of Reference it returns a variant with refcount - // already initialized, which woud cause inconsistent behavior compared to other classes (we still have to return a pointer). - //Variant instance_variant = script->new_(); - //T *instance = godot::get_custom_class_instance<T>(instance_variant); - - // So we should do this instead, however while convenient, it uses unnecessary wrapper objects. - // Object *base_obj = T::___new_godot_base(); - // base_obj->set_script(script); - // return get_custom_class_instance<T>(base_obj); - - // Again using the C API to do exactly what we have to do. - static godot_class_constructor base_constructor = godot::api->godot_get_class_constructor(T::___get_godot_class_name()); - static godot_method_bind *mb_set_script = godot::api->godot_method_bind_get_method("Object", "set_script"); - godot_object *base_obj = base_constructor(); - { - const void *args[] = { script }; - godot::api->godot_method_bind_ptrcall(mb_set_script, base_obj, args, nullptr); - } - - return (T *)godot::nativescript_api->godot_nativescript_get_userdata(base_obj); -} - -} // namespace detail - -// Used in the definition of a custom class. -// -// Name: Name of your class, without namespace -// Base: Name of the direct base class, with namespace if necessary -// -// ___get_class_name: Name of the class -// ___get_godot_class_name: Name of the Godot base class this class inherits from (i.e not direct) -// _new: Creates a new instance of the class -// ___get_id: Gets the unique ID of the class. Godot and custom classes are both within that set. -// ___get_base_id: Gets the ID of the direct base class, as returned by ___get_id -// ___get_base_class_name: Name of the direct base class -// ___get_from_variant: Converts a Variant into an Object*. Will be non-null if the class matches. -#define GODOT_CLASS(Name, Base) \ - \ -public: \ - inline static const char *___get_class_name() { return #Name; } \ - enum { ___CLASS_IS_SCRIPT = 1 }; \ - inline static const char *___get_godot_class_name() { \ - return Base::___get_godot_class_name(); \ - } \ - inline static Name *_new() { \ - return godot::detail::create_custom_class_instance<Name>(); \ - } \ - inline static size_t ___get_id() { return typeid(Name).hash_code(); } \ - inline static size_t ___get_base_id() { return Base::___get_id(); } \ - inline static const char *___get_base_class_name() { return Base::___get_class_name(); } \ - inline static godot::Object *___get_from_variant(godot::Variant a) { \ - return (godot::Object *)godot::detail::get_custom_class_instance<Name>( \ - godot::Object::___get_from_variant(a)); \ - } \ - \ -private: - -// Legacy compatibility -#define GODOT_SUBCLASS(Name, Base) GODOT_CLASS(Name, Base) - -template <class T> -struct _ArgCast { - static T _arg_cast(Variant a) { - return a; - } -}; - -template <class T> -struct _ArgCast<T *> { - static T *_arg_cast(Variant a) { - return (T *)T::___get_from_variant(a); - } -}; - -template <> -struct _ArgCast<Variant> { - static Variant _arg_cast(Variant a) { - return a; - } -}; - -// instance and destroy funcs - -template <class T> -void *_godot_class_instance_func(godot_object *p, void * /*method_data*/) { - T *d = new T(); - d->_owner = p; - d->_type_tag = typeid(T).hash_code(); - d->_init(); - return d; -} - -template <class T> -void _godot_class_destroy_func(godot_object * /*p*/, void * /*method_data*/, void *data) { - T *d = (T *)data; - delete d; -} - -template <class T> -void register_class() { - static_assert(T::___CLASS_IS_SCRIPT, "This function must only be used on custom classes"); - - godot_instance_create_func create = {}; - create.create_func = _godot_class_instance_func<T>; - - godot_instance_destroy_func destroy = {}; - destroy.destroy_func = _godot_class_destroy_func<T>; - - _TagDB::register_type(T::___get_id(), T::___get_base_id()); - - godot::nativescript_api->godot_nativescript_register_class(godot::_RegisterState::nativescript_handle, - T::___get_class_name(), T::___get_base_class_name(), create, destroy); - - godot::nativescript_1_1_api->godot_nativescript_set_type_tag(godot::_RegisterState::nativescript_handle, - T::___get_class_name(), (const void *)T::___get_id()); - - T::_register_methods(); -} - -template <class T> -void register_tool_class() { - static_assert(T::___CLASS_IS_SCRIPT, "This function must only be used on custom classes"); - - godot_instance_create_func create = {}; - create.create_func = _godot_class_instance_func<T>; - - godot_instance_destroy_func destroy = {}; - destroy.destroy_func = _godot_class_destroy_func<T>; - - _TagDB::register_type(T::___get_id(), T::___get_base_id()); - - godot::nativescript_api->godot_nativescript_register_tool_class(godot::_RegisterState::nativescript_handle, - T::___get_class_name(), T::___get_base_class_name(), create, destroy); - - godot::nativescript_1_1_api->godot_nativescript_set_type_tag(godot::_RegisterState::nativescript_handle, - T::___get_class_name(), (const void *)T::___get_id()); - - T::_register_methods(); -} - -// method registering - -typedef godot_variant (*__godot_wrapper_method)(godot_object *, void *, void *, int, godot_variant **); - -template <class T, class R, class... args> -const char *___get_method_class_name(R (T::*p)(args... a)) { - static_assert(T::___CLASS_IS_SCRIPT, "This function must only be used on custom classes"); - (void)p; // To avoid "unused parameter" warnings. `p` is required for template matching. - return T::___get_class_name(); -} - -// This second version is also required to match constant functions -template <class T, class R, class... args> -const char *___get_method_class_name(R (T::*p)(args... a) const) { - static_assert(T::___CLASS_IS_SCRIPT, "This function must only be used on custom classes"); - (void)p; // To avoid "unused parameter" warnings. `p` is required for template matching. - return T::___get_class_name(); -} - -// Okay, time for some template magic. -// Many thanks to manpat from the GDL Discord Server. - -// This is stuff that's available in C++14 I think, but whatever. - -template <int... I> -struct __Sequence {}; - -template <int N, int... I> -struct __construct_sequence { - using type = typename __construct_sequence<N - 1, N - 1, I...>::type; -}; - -template <int... I> -struct __construct_sequence<0, I...> { - using type = __Sequence<I...>; -}; - -// Now the wrapping part. -template <class T, class R, class... As> -struct _WrappedMethod { - R(T::*f) - (As...); - - template <int... I> - void apply(Variant *ret, T *obj, Variant **args, __Sequence<I...>) { - *ret = (obj->*f)(_ArgCast<As>::_arg_cast(*args[I])...); - } -}; - -template <class T, class... As> -struct _WrappedMethod<T, void, As...> { - void (T::*f)(As...); - - template <int... I> - void apply(Variant * /*ret*/, T *obj, Variant **args, __Sequence<I...>) { - (obj->*f)(_ArgCast<As>::_arg_cast(*args[I])...); - } -}; - -template <class T, class R, class... As> -godot_variant __wrapped_method(godot_object *, void *method_data, void *user_data, int /*num_args*/, godot_variant **args) { - godot_variant v; - godot::api->godot_variant_new_nil(&v); - - T *obj = (T *)user_data; - _WrappedMethod<T, R, As...> *method = (_WrappedMethod<T, R, As...> *)method_data; - - Variant *var = (Variant *)&v; - Variant **arg = (Variant **)args; - - method->apply(var, obj, arg, typename __construct_sequence<sizeof...(As)>::type{}); - - return v; -} - -template <class T, class R, class... As> -void *___make_wrapper_function(R (T::*f)(As...)) { - using MethodType = _WrappedMethod<T, R, As...>; - MethodType *p = (MethodType *)godot::api->godot_alloc(sizeof(MethodType)); - p->f = f; - return (void *)p; -} - -template <class T, class R, class... As> -__godot_wrapper_method ___get_wrapper_function(R (T::* /*f*/)(As...)) { - return (__godot_wrapper_method)&__wrapped_method<T, R, As...>; -} - -template <class T, class R, class... A> -void *___make_wrapper_function(R (T::*f)(A...) const) { - return ___make_wrapper_function((R(T::*)(A...))f); -} - -template <class T, class R, class... A> -__godot_wrapper_method ___get_wrapper_function(R (T::*f)(A...) const) { - return ___get_wrapper_function((R(T::*)(A...))f); -} - -template <class M> -void register_method(const char *name, M method_ptr, godot_method_rpc_mode rpc_type = GODOT_METHOD_RPC_MODE_DISABLED) { - godot_instance_method method = {}; - method.method_data = ___make_wrapper_function(method_ptr); - method.free_func = godot::api->godot_free; - method.method = (__godot_wrapper_method)___get_wrapper_function(method_ptr); - - godot_method_attributes attr = {}; - attr.rpc_type = rpc_type; - - godot::nativescript_api->godot_nativescript_register_method(godot::_RegisterState::nativescript_handle, - ___get_method_class_name(method_ptr), name, attr, method); -} - -// User can specify a derived class D to register the method for, instead of it being inferred. -template <class D, class B, class R, class... As> -void register_method_explicit(const char *name, R (B::*method_ptr)(As...), - godot_method_rpc_mode rpc_type = GODOT_METHOD_RPC_MODE_DISABLED) { - static_assert(std::is_base_of<B, D>::value, "Explicit class must derive from method class"); - register_method(name, static_cast<R (D::*)(As...)>(method_ptr), rpc_type); -} - -template <class T, class P> -struct _PropertySetFunc { - void (T::*f)(P); - static void _wrapped_setter(godot_object * /*object*/, void *method_data, void *user_data, godot_variant *value) { - _PropertySetFunc<T, P> *set_func = (_PropertySetFunc<T, P> *)method_data; - T *obj = (T *)user_data; - - Variant *v = (Variant *)value; - - (obj->*(set_func->f))(_ArgCast<P>::_arg_cast(*v)); - } -}; - -template <class T, class P> -struct _PropertyGetFunc { - P(T::*f) - (); - static godot_variant _wrapped_getter(godot_object * /*object*/, void *method_data, void *user_data) { - _PropertyGetFunc<T, P> *get_func = (_PropertyGetFunc<T, P> *)method_data; - T *obj = (T *)user_data; - - godot_variant var; - godot::api->godot_variant_new_nil(&var); - - Variant *v = (Variant *)&var; - - *v = (obj->*(get_func->f))(); - - return var; - } -}; - -template <class T, class P> -struct _PropertyDefaultSetFunc { - P(T::*f); - static void _wrapped_setter(godot_object * /*object*/, void *method_data, void *user_data, godot_variant *value) { - _PropertyDefaultSetFunc<T, P> *set_func = (_PropertyDefaultSetFunc<T, P> *)method_data; - T *obj = (T *)user_data; - - Variant *v = (Variant *)value; - - (obj->*(set_func->f)) = _ArgCast<P>::_arg_cast(*v); - } -}; - -template <class T, class P> -struct _PropertyDefaultGetFunc { - P(T::*f); - static godot_variant _wrapped_getter(godot_object * /*object*/, void *method_data, void *user_data) { - _PropertyDefaultGetFunc<T, P> *get_func = (_PropertyDefaultGetFunc<T, P> *)method_data; - T *obj = (T *)user_data; - - godot_variant var; - godot::api->godot_variant_new_nil(&var); - - Variant *v = (Variant *)&var; - - *v = (obj->*(get_func->f)); - - return var; - } -}; - -template <class T, class P> -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 = "") { - static_assert(T::___CLASS_IS_SCRIPT, "This function must only be used on custom classes"); - - Variant def_val = default_value; - - usage = (godot_property_usage_flags)((int)usage | GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE); - - if (def_val.get_type() == Variant::OBJECT) { - Object *o = detail::get_wrapper<Object>(def_val.operator godot_object *()); - if (o && o->is_class("Resource")) { - hint = (godot_property_hint)((int)hint | GODOT_PROPERTY_HINT_RESOURCE_TYPE); - hint_string = o->get_class(); - } - } - - godot_string *_hint_string = (godot_string *)&hint_string; - - godot_property_attributes attr = {}; - if (def_val.get_type() == Variant::NIL) { - attr.type = Variant::OBJECT; - } else { - attr.type = def_val.get_type(); - attr.default_value = *(godot_variant *)&def_val; - } - - attr.hint = hint; - attr.rset_type = rpc_mode; - attr.usage = usage; - attr.hint_string = *_hint_string; - - _PropertyDefaultSetFunc<T, P> *wrapped_set = - (_PropertyDefaultSetFunc<T, P> *)godot::api->godot_alloc(sizeof(_PropertyDefaultSetFunc<T, P>)); - wrapped_set->f = var; - - _PropertyDefaultGetFunc<T, P> *wrapped_get = - (_PropertyDefaultGetFunc<T, P> *)godot::api->godot_alloc(sizeof(_PropertyDefaultGetFunc<T, P>)); - wrapped_get->f = var; - - godot_property_set_func set_func = {}; - set_func.method_data = (void *)wrapped_set; - set_func.free_func = godot::api->godot_free; - set_func.set_func = &_PropertyDefaultSetFunc<T, P>::_wrapped_setter; - - godot_property_get_func get_func = {}; - get_func.method_data = (void *)wrapped_get; - get_func.free_func = godot::api->godot_free; - get_func.get_func = &_PropertyDefaultGetFunc<T, P>::_wrapped_getter; - - godot::nativescript_api->godot_nativescript_register_property(godot::_RegisterState::nativescript_handle, - T::___get_class_name(), name, &attr, set_func, get_func); -} - -template <class T, class P> -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 = "") { - static_assert(T::___CLASS_IS_SCRIPT, "This function must only be used on custom classes"); - - Variant def_val = default_value; - - godot_string *_hint_string = (godot_string *)&hint_string; - - godot_property_attributes attr = {}; - if (def_val.get_type() == Variant::NIL) { - attr.type = Variant::OBJECT; - } else { - attr.type = def_val.get_type(); - attr.default_value = *(godot_variant *)&def_val; - } - attr.hint = hint; - attr.rset_type = rpc_mode; - attr.usage = usage; - attr.hint_string = *_hint_string; - - _PropertySetFunc<T, P> *wrapped_set = (_PropertySetFunc<T, P> *)godot::api->godot_alloc(sizeof(_PropertySetFunc<T, P>)); - wrapped_set->f = setter; - - _PropertyGetFunc<T, P> *wrapped_get = (_PropertyGetFunc<T, P> *)godot::api->godot_alloc(sizeof(_PropertyGetFunc<T, P>)); - wrapped_get->f = getter; - - godot_property_set_func set_func = {}; - set_func.method_data = (void *)wrapped_set; - set_func.free_func = godot::api->godot_free; - set_func.set_func = &_PropertySetFunc<T, P>::_wrapped_setter; - - godot_property_get_func get_func = {}; - get_func.method_data = (void *)wrapped_get; - get_func.free_func = godot::api->godot_free; - get_func.get_func = &_PropertyGetFunc<T, P>::_wrapped_getter; - - godot::nativescript_api->godot_nativescript_register_property(godot::_RegisterState::nativescript_handle, - T::___get_class_name(), name, &attr, set_func, get_func); -} - -template <class T, class P> -void register_property(const char *name, void (T::*setter)(P), P (T::*getter)() const, 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 = "") { - register_property(name, setter, (P(T::*)())getter, default_value, rpc_mode, usage, hint, hint_string); -} - -template <class T> -void register_signal(String name, Dictionary args) { - static_assert(T::___CLASS_IS_SCRIPT, "This function must only be used on custom classes"); - - godot_signal signal = {}; - signal.name = *(godot_string *)&name; - signal.num_args = args.size(); - signal.num_default_args = 0; - - // Need to check because malloc(0) is platform-dependent. Zero arguments will leave args to nullptr. - if (signal.num_args != 0) { - signal.args = (godot_signal_argument *)godot::api->godot_alloc(sizeof(godot_signal_argument) * signal.num_args); - memset((void *)signal.args, 0, sizeof(godot_signal_argument) * signal.num_args); - } - - for (int i = 0; i < signal.num_args; i++) { - // Array entry = args[i]; - // String name = entry[0]; - String name = args.keys()[i]; - godot_string *_key = (godot_string *)&name; - godot::api->godot_string_new_copy(&signal.args[i].name, _key); - - // if (entry.size() > 1) { - // signal.args[i].type = entry[1]; - // } - signal.args[i].type = args.values()[i]; - } - - godot::nativescript_api->godot_nativescript_register_signal(godot::_RegisterState::nativescript_handle, - T::___get_class_name(), &signal); - - for (int i = 0; i < signal.num_args; i++) { - godot::api->godot_string_destroy(&signal.args[i].name); - } - - if (signal.args) { - godot::api->godot_free(signal.args); - } -} - -template <class T, class... Args> -void register_signal(String name, Args... varargs) { - register_signal<T>(name, Dictionary::make(varargs...)); -} - -template <class T> -void register_signal(String name) { - static_assert(T::___CLASS_IS_SCRIPT, "This function must only be used on custom classes"); - - godot_signal signal = {}; - signal.name = *(godot_string *)&name; - - godot::nativescript_api->godot_nativescript_register_signal(godot::_RegisterState::nativescript_handle, - T::___get_class_name(), &signal); -} - -#ifndef GODOT_CPP_NO_OBJECT_CAST -template <class T> -T *Object::cast_to(const Object *obj) { - if (!obj) - return nullptr; - - if (T::___CLASS_IS_SCRIPT) { - size_t have_tag = (size_t)godot::nativescript_1_1_api->godot_nativescript_get_type_tag(obj->_owner); - if (have_tag) { - if (!godot::_TagDB::is_type_known((size_t)have_tag)) { - have_tag = 0; - } - } - - if (!have_tag) { - have_tag = obj->_type_tag; - } - - if (godot::_TagDB::is_type_compatible(T::___get_id(), have_tag)) { - return detail::get_custom_class_instance<T>(obj); - } - } else { - if (godot::core_1_2_api->godot_object_cast_to(obj->_owner, (void *)T::___get_id())) { - return (T *)obj; - } - } - - return nullptr; -} -#endif - -} // namespace godot - -#endif // GODOT_HPP diff --git a/include/core/GodotGlobal.hpp b/include/core/GodotGlobal.hpp deleted file mode 100644 index 6312d19..0000000 --- a/include/core/GodotGlobal.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/*************************************************************************/ -/* GodotGlobal.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef GODOT_GLOBAL_HPP -#define GODOT_GLOBAL_HPP - -#include "Array.hpp" -#include "String.hpp" -#include <gdnative_api_struct.gen.h> - -namespace godot { - -extern "C" const godot_gdnative_core_api_struct *api; -extern "C" const godot_gdnative_core_1_1_api_struct *core_1_1_api; -extern "C" const godot_gdnative_core_1_2_api_struct *core_1_2_api; - -extern "C" const godot_gdnative_ext_nativescript_api_struct *nativescript_api; -extern "C" const godot_gdnative_ext_nativescript_1_1_api_struct *nativescript_1_1_api; -extern "C" const godot_gdnative_ext_pluginscript_api_struct *pluginscript_api; -extern "C" const godot_gdnative_ext_android_api_struct *android_api; -extern "C" const godot_gdnative_ext_arvr_api_struct *arvr_api; -extern "C" const godot_gdnative_ext_videodecoder_api_struct *videodecoder_api; -extern "C" const godot_gdnative_ext_net_api_struct *net_api; -extern "C" const godot_gdnative_ext_net_3_2_api_struct *net_3_2_api; - -extern "C" const void *gdnlib; - -class Godot { -public: - static void print(const String &message); - static void print_warning(const String &description, const String &function, const String &file, int line); - static void print_error(const String &description, const String &function, const String &file, int line); - - static void gdnative_init(godot_gdnative_init_options *o); - static void gdnative_terminate(godot_gdnative_terminate_options *o); - static void nativescript_init(void *handle); - static void nativescript_terminate(void *handle); - - static void gdnative_profiling_add_data(const char *p_signature, uint64_t p_time); - - template <class... Args> - static void print(const String &fmt, Args... values) { - print(fmt.format(Array::make(values...))); - } -}; - -struct _RegisterState { - static void *nativescript_handle; - static int language_index; -}; - -} // namespace godot - -#endif diff --git a/include/core/GodotProfiling.hpp b/include/core/GodotProfiling.hpp deleted file mode 100644 index fc34343..0000000 --- a/include/core/GodotProfiling.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************/ -/* GodotProfiling.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef GODOT_PROFILING_HPP -#define GODOT_PROFILING_HPP - -#include "OS.hpp" - -namespace godot { - -class FunctionProfiling { - char signature[1024]; - uint64_t ticks; - -public: - FunctionProfiling(const char *p_function, const int p_line) { - snprintf(signature, 1024, "::%d::%s", p_line, p_function); - ticks = OS::get_singleton()->get_ticks_usec(); - } - ~FunctionProfiling() { - uint64_t t = OS::get_singleton()->get_ticks_usec() - ticks; - if (t > 0) { - Godot::gdnative_profiling_add_data(signature, t); - } - } -}; - -} // namespace godot - -#ifdef DEBUG_ENABLED -#define GODOT_PROFILING_FUNCTION FunctionProfiling __function_profiling(__FUNCTION__, __LINE__); -#else -#define GODOT_PROFILING_FUNCTION -#endif - -#endif diff --git a/include/core/Math.hpp b/include/core/Math.hpp deleted file mode 100644 index 1f54f98..0000000 --- a/include/core/Math.hpp +++ /dev/null @@ -1,302 +0,0 @@ -/*************************************************************************/
-/* Math.hpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef GODOT_MATH_H
-#define GODOT_MATH_H
-
-#include "Defs.hpp"
-#include <cmath>
-
-namespace godot {
-namespace Math {
-
-// Functions reproduced as in Godot's source code `math_funcs.h`.
-// Some are overloads to automatically support changing real_t into either double or float in the way Godot does.
-
-inline double fmod(double p_x, double p_y) {
- return ::fmod(p_x, p_y);
-}
-inline float fmod(float p_x, float p_y) {
- return ::fmodf(p_x, p_y);
-}
-
-inline double floor(double p_x) {
- return ::floor(p_x);
-}
-inline float floor(float p_x) {
- return ::floorf(p_x);
-}
-
-inline double exp(double p_x) {
- return ::exp(p_x);
-}
-inline float exp(float p_x) {
- return ::expf(p_x);
-}
-
-inline double sin(double p_x) {
- return ::sin(p_x);
-}
-inline float sin(float p_x) {
- return ::sinf(p_x);
-}
-
-inline double cos(double p_x) {
- return ::cos(p_x);
-}
-inline float cos(float p_x) {
- return ::cosf(p_x);
-}
-
-inline double tan(double p_x) {
- return ::tan(p_x);
-}
-inline float tan(float p_x) {
- return ::tanf(p_x);
-}
-
-inline double asin(double p_x) {
- return ::asin(p_x);
-}
-inline float asin(float p_x) {
- return ::asinf(p_x);
-}
-
-inline double acos(double p_x) {
- return ::acos(p_x);
-}
-inline float acos(float p_x) {
- return ::acosf(p_x);
-}
-
-inline double atan(double p_x) {
- return ::atan(p_x);
-}
-inline float atan(float p_x) {
- return ::atanf(p_x);
-}
-
-inline double atan2(double p_y, double p_x) {
- return ::atan2(p_y, p_x);
-}
-inline float atan2(float p_y, float p_x) {
- return ::atan2f(p_y, p_x);
-}
-
-inline double sqrt(double p_x) {
- return ::sqrt(p_x);
-}
-inline float sqrt(float p_x) {
- return ::sqrtf(p_x);
-}
-
-inline float lerp(float minv, float maxv, float t) {
- return minv + t * (maxv - minv);
-}
-inline double lerp(double minv, double maxv, double t) {
- return minv + t * (maxv - minv);
-}
-
-inline double lerp_angle(double p_from, double p_to, double p_weight) {
- double difference = fmod(p_to - p_from, Math_TAU);
- double distance = fmod(2.0 * difference, Math_TAU) - difference;
- return p_from + distance * p_weight;
-}
-inline float lerp_angle(float p_from, float p_to, float p_weight) {
- float difference = fmod(p_to - p_from, (float)Math_TAU);
- float distance = fmod(2.0f * difference, (float)Math_TAU) - difference;
- return p_from + distance * p_weight;
-}
-
-template <typename T>
-inline T clamp(T x, T minv, T maxv) {
- if (x < minv) {
- return minv;
- }
- if (x > maxv) {
- return maxv;
- }
- return x;
-}
-
-template <typename T>
-inline T min(T a, T b) {
- return a < b ? a : b;
-}
-
-template <typename T>
-inline T max(T a, T b) {
- return a > b ? a : b;
-}
-
-template <typename T>
-inline T sign(T x) {
- return static_cast<T>(x < 0 ? -1 : 1);
-}
-
-inline double deg2rad(double p_y) {
- return p_y * Math_PI / 180.0;
-}
-inline float deg2rad(float p_y) {
- return p_y * static_cast<float>(Math_PI) / 180.f;
-}
-
-inline double rad2deg(double p_y) {
- return p_y * 180.0 / Math_PI;
-}
-inline float rad2deg(float p_y) {
- return p_y * 180.f / static_cast<float>(Math_PI);
-}
-
-inline double inverse_lerp(double p_from, double p_to, double p_value) {
- return (p_value - p_from) / (p_to - p_from);
-}
-inline float inverse_lerp(float p_from, float p_to, float p_value) {
- return (p_value - p_from) / (p_to - p_from);
-}
-
-inline double range_lerp(double p_value, double p_istart, double p_istop, double p_ostart, double p_ostop) {
- return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value));
-}
-inline float range_lerp(float p_value, float p_istart, float p_istop, float p_ostart, float p_ostop) {
- return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value));
-}
-
-inline bool is_equal_approx(real_t a, real_t b) {
- // Check for exact equality first, required to handle "infinity" values.
- if (a == b) {
- return true;
- }
- // Then check for approximate equality.
- real_t tolerance = CMP_EPSILON * std::abs(a);
- if (tolerance < CMP_EPSILON) {
- tolerance = CMP_EPSILON;
- }
- return std::abs(a - b) < tolerance;
-}
-
-inline bool is_equal_approx(real_t a, real_t b, real_t tolerance) {
- // Check for exact equality first, required to handle "infinity" values.
- if (a == b) {
- return true;
- }
- // Then check for approximate equality.
- return std::abs(a - b) < tolerance;
-}
-
-inline bool is_zero_approx(real_t s) {
- return std::abs(s) < CMP_EPSILON;
-}
-
-inline double smoothstep(double p_from, double p_to, double p_weight) {
- if (is_equal_approx(static_cast<real_t>(p_from), static_cast<real_t>(p_to))) {
- return p_from;
- }
- double x = clamp((p_weight - p_from) / (p_to - p_from), 0.0, 1.0);
- return x * x * (3.0 - 2.0 * x);
-}
-inline float smoothstep(float p_from, float p_to, float p_weight) {
- if (is_equal_approx(p_from, p_to)) {
- return p_from;
- }
- float x = clamp((p_weight - p_from) / (p_to - p_from), 0.0f, 1.0f);
- return x * x * (3.0f - 2.0f * x);
-}
-
-inline double move_toward(double p_from, double p_to, double p_delta) {
- return std::abs(p_to - p_from) <= p_delta ? p_to : p_from + sign(p_to - p_from) * p_delta;
-}
-
-inline float move_toward(float p_from, float p_to, float p_delta) {
- return std::abs(p_to - p_from) <= p_delta ? p_to : p_from + sign(p_to - p_from) * p_delta;
-}
-
-inline double linear2db(double p_linear) {
- return log(p_linear) * 8.6858896380650365530225783783321;
-}
-inline float linear2db(float p_linear) {
- return log(p_linear) * 8.6858896380650365530225783783321f;
-}
-
-inline double db2linear(double p_db) {
- return exp(p_db * 0.11512925464970228420089957273422);
-}
-inline float db2linear(float p_db) {
- return exp(p_db * 0.11512925464970228420089957273422f);
-}
-
-inline double round(double p_val) {
- return (p_val >= 0) ? floor(p_val + 0.5) : -floor(-p_val + 0.5);
-}
-inline float round(float p_val) {
- return (p_val >= 0) ? floor(p_val + 0.5f) : -floor(-p_val + 0.5f);
-}
-
-inline int64_t wrapi(int64_t value, int64_t min, int64_t max) {
- int64_t range = max - min;
- return range == 0 ? min : min + ((((value - min) % range) + range) % range);
-}
-
-inline float wrapf(real_t value, real_t min, real_t max) {
- const real_t range = max - min;
- return is_zero_approx(range) ? min : value - (range * floor((value - min) / range));
-}
-
-inline float stepify(float p_value, float p_step) {
- if (p_step != 0) {
- p_value = floor(p_value / p_step + 0.5f) * p_step;
- }
- return p_value;
-}
-inline double stepify(double p_value, double p_step) {
- if (p_step != 0) {
- p_value = floor(p_value / p_step + 0.5) * p_step;
- }
- return p_value;
-}
-
-inline unsigned int next_power_of_2(unsigned int x) {
- if (x == 0)
- return 0;
-
- --x;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
-
- return ++x;
-}
-
-} // namespace Math
-} // namespace godot
-
-#endif // GODOT_MATH_H
diff --git a/include/core/Plane.hpp b/include/core/Plane.hpp deleted file mode 100644 index be01591..0000000 --- a/include/core/Plane.hpp +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************/ -/* Plane.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef PLANE_H -#define PLANE_H - -#include "Vector3.hpp" - -#include <cmath> - -namespace godot { - -enum ClockDirection { - - CLOCKWISE, - COUNTERCLOCKWISE -}; - -class Plane { -public: - Vector3 normal; - real_t d; - - void set_normal(const Vector3 &p_normal); - - inline Vector3 get_normal() const { return normal; } ///Point is coplanar, CMP_EPSILON for precision - - void normalize(); - - Plane normalized() const; - - /* Plane-Point operations */ - - inline Vector3 center() const { return normal * d; } - Vector3 get_any_point() const; - Vector3 get_any_perpendicular_normal() const; - - bool is_point_over(const Vector3 &p_point) const; ///< Point is over plane - real_t distance_to(const Vector3 &p_point) const; - bool has_point(const Vector3 &p_point, real_t _epsilon = CMP_EPSILON) const; - - /* intersections */ - - bool intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r_result = 0) const; - bool intersects_ray(Vector3 p_from, Vector3 p_dir, Vector3 *p_intersection) const; - bool intersects_segment(Vector3 p_begin, Vector3 p_end, Vector3 *p_intersection) const; - - Vector3 project(const Vector3 &p_point) const; - - /* misc */ - - inline Plane operator-() const { return Plane(-normal, -d); } - bool is_almost_like(const Plane &p_plane) const; - - bool operator==(const Plane &p_plane) const; - bool operator!=(const Plane &p_plane) const; - operator String() const; - - inline Plane() { d = 0; } - inline Plane(real_t p_a, real_t p_b, real_t p_c, real_t p_d) : - normal(p_a, p_b, p_c), - d(p_d) {} - - Plane(const Vector3 &p_normal, real_t p_d); - Plane(const Vector3 &p_point, const Vector3 &p_normal); - Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_point3, ClockDirection p_dir = CLOCKWISE); -}; - -} // namespace godot - -#endif // PLANE_H diff --git a/include/core/PoolArrays.hpp b/include/core/PoolArrays.hpp deleted file mode 100644 index 233b146..0000000 --- a/include/core/PoolArrays.hpp +++ /dev/null @@ -1,766 +0,0 @@ -/*************************************************************************/ -/* PoolArrays.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef POOLARRAYS_H -#define POOLARRAYS_H - -#include "Defs.hpp" - -#include "Color.hpp" -#include "GodotGlobal.hpp" -#include "String.hpp" -#include "Vector2.hpp" -#include "Vector3.hpp" - -#include <gdnative/pool_arrays.h> - -namespace godot { - -class Array; - -class PoolByteArray { - godot_pool_byte_array _godot_array; - - friend class String; - friend class Variant; - inline explicit PoolByteArray(godot_pool_byte_array a) { - _godot_array = a; - } - -public: - class Read { - friend class PoolByteArray; - godot_pool_byte_array_read_access *_read_access; - - public: - inline Read() { - _read_access = nullptr; - } - - inline Read(const Read &p_other) { - _read_access = godot::api->godot_pool_byte_array_read_access_copy(p_other._read_access); - } - - inline ~Read() { - godot::api->godot_pool_byte_array_read_access_destroy(_read_access); - } - - inline const uint8_t *ptr() const { - return godot::api->godot_pool_byte_array_read_access_ptr(_read_access); - } - - inline const uint8_t &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Read &p_other) { - godot::api->godot_pool_byte_array_read_access_operator_assign(_read_access, p_other._read_access); - } - }; - - class Write { - friend class PoolByteArray; - godot_pool_byte_array_write_access *_write_access; - - public: - inline Write() { - _write_access = nullptr; - } - - inline Write(const Write &p_other) { - _write_access = godot::api->godot_pool_byte_array_write_access_copy(p_other._write_access); - } - - inline ~Write() { - godot::api->godot_pool_byte_array_write_access_destroy(_write_access); - } - - inline uint8_t *ptr() const { - return godot::api->godot_pool_byte_array_write_access_ptr(_write_access); - } - - inline uint8_t &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Write &p_other) { - godot::api->godot_pool_byte_array_write_access_operator_assign(_write_access, p_other._write_access); - } - }; - - PoolByteArray(); - PoolByteArray(const PoolByteArray &p_other); - PoolByteArray &operator=(const PoolByteArray &p_other); - - PoolByteArray(const Array &array); - - Read read() const; - - Write write(); - - void append(const uint8_t data); - - void append_array(const PoolByteArray &array); - - int insert(const int idx, const uint8_t data); - - void invert(); - - void push_back(const uint8_t data); - - void remove(const int idx); - - void resize(const int size); - - void set(const int idx, const uint8_t data); - - uint8_t operator[](const int idx); - - int size() const; - - ~PoolByteArray(); -}; - -class PoolIntArray { - godot_pool_int_array _godot_array; - - friend class Variant; - explicit inline PoolIntArray(godot_pool_int_array a) { - _godot_array = a; - } - -public: - class Read { - friend class PoolIntArray; - godot_pool_int_array_read_access *_read_access; - - public: - inline Read() { - _read_access = nullptr; - } - - inline Read(const Read &p_other) { - _read_access = godot::api->godot_pool_int_array_read_access_copy(p_other._read_access); - } - - inline ~Read() { - godot::api->godot_pool_int_array_read_access_destroy(_read_access); - } - - inline const int *ptr() const { - return godot::api->godot_pool_int_array_read_access_ptr(_read_access); - } - - inline const int &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Read &p_other) { - godot::api->godot_pool_int_array_read_access_operator_assign(_read_access, p_other._read_access); - } - }; - - class Write { - friend class PoolIntArray; - godot_pool_int_array_write_access *_write_access; - - public: - inline Write() { - _write_access = nullptr; - } - - inline Write(const Write &p_other) { - _write_access = godot::api->godot_pool_int_array_write_access_copy(p_other._write_access); - } - - inline ~Write() { - godot::api->godot_pool_int_array_write_access_destroy(_write_access); - } - - inline int *ptr() const { - return godot::api->godot_pool_int_array_write_access_ptr(_write_access); - } - - inline int &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Write &p_other) { - godot::api->godot_pool_int_array_write_access_operator_assign(_write_access, p_other._write_access); - } - }; - - PoolIntArray(); - PoolIntArray(const PoolIntArray &p_other); - PoolIntArray &operator=(const PoolIntArray &p_other); - - PoolIntArray(const Array &array); - - Read read() const; - - Write write(); - - void append(const int data); - - void append_array(const PoolIntArray &array); - - int insert(const int idx, const int data); - - void invert(); - - void push_back(const int data); - - void remove(const int idx); - - void resize(const int size); - - void set(const int idx, const int data); - - int operator[](const int idx); - - int size() const; - - ~PoolIntArray(); -}; - -class PoolRealArray { - godot_pool_real_array _godot_array; - - friend class Variant; - explicit inline PoolRealArray(godot_pool_real_array a) { - _godot_array = a; - } - -public: - class Read { - friend class PoolRealArray; - godot_pool_real_array_read_access *_read_access; - - public: - inline Read() { - _read_access = nullptr; - } - - inline Read(const Read &p_other) { - _read_access = godot::api->godot_pool_real_array_read_access_copy(p_other._read_access); - } - - inline ~Read() { - godot::api->godot_pool_real_array_read_access_destroy(_read_access); - } - - inline const real_t *ptr() const { - return godot::api->godot_pool_real_array_read_access_ptr(_read_access); - } - - inline const real_t &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Read &p_other) { - godot::api->godot_pool_real_array_read_access_operator_assign(_read_access, p_other._read_access); - } - }; - - class Write { - friend class PoolRealArray; - godot_pool_real_array_write_access *_write_access; - - public: - inline Write() { - _write_access = nullptr; - } - - inline Write(const Write &p_other) { - _write_access = godot::api->godot_pool_real_array_write_access_copy(p_other._write_access); - } - - inline ~Write() { - godot::api->godot_pool_real_array_write_access_destroy(_write_access); - } - - inline real_t *ptr() const { - return godot::api->godot_pool_real_array_write_access_ptr(_write_access); - } - - inline real_t &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Write &p_other) { - godot::api->godot_pool_real_array_write_access_operator_assign(_write_access, p_other._write_access); - } - }; - - PoolRealArray(); - PoolRealArray(const PoolRealArray &p_other); - PoolRealArray &operator=(const PoolRealArray &p_other); - - PoolRealArray(const Array &array); - - Read read() const; - - Write write(); - - void append(const real_t data); - - void append_array(const PoolRealArray &array); - - int insert(const int idx, const real_t data); - - void invert(); - - void push_back(const real_t data); - - void remove(const int idx); - - void resize(const int size); - - void set(const int idx, const real_t data); - - real_t operator[](const int idx); - - int size() const; - - ~PoolRealArray(); -}; - -class PoolStringArray { - godot_pool_string_array _godot_array; - - friend class String; - friend class Variant; - explicit inline PoolStringArray(godot_pool_string_array a) { - _godot_array = a; - } - -public: - class Read { - friend class PoolStringArray; - godot_pool_string_array_read_access *_read_access; - - public: - inline Read() { - _read_access = nullptr; - } - - inline Read(const Read &p_other) { - _read_access = godot::api->godot_pool_string_array_read_access_copy(p_other._read_access); - } - - inline ~Read() { - godot::api->godot_pool_string_array_read_access_destroy(_read_access); - } - - inline const String *ptr() const { - return (const String *)godot::api->godot_pool_string_array_read_access_ptr(_read_access); - } - - inline const String &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Read &p_other) { - godot::api->godot_pool_string_array_read_access_operator_assign(_read_access, p_other._read_access); - } - }; - - class Write { - friend class PoolStringArray; - godot_pool_string_array_write_access *_write_access; - - public: - inline Write() { - _write_access = nullptr; - } - - inline Write(const Write &p_other) { - _write_access = godot::api->godot_pool_string_array_write_access_copy(p_other._write_access); - } - - inline ~Write() { - godot::api->godot_pool_string_array_write_access_destroy(_write_access); - } - - inline String *ptr() const { - return (String *)godot::api->godot_pool_string_array_write_access_ptr(_write_access); - } - - inline String &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Write &p_other) { - godot::api->godot_pool_string_array_write_access_operator_assign(_write_access, p_other._write_access); - } - }; - - PoolStringArray(); - PoolStringArray(const PoolStringArray &p_other); - PoolStringArray &operator=(const PoolStringArray &p_other); - - PoolStringArray(const Array &array); - - Read read() const; - - Write write(); - - void append(const String &data); - - void append_array(const PoolStringArray &array); - - int insert(const int idx, const String &data); - - void invert(); - - void push_back(const String &data); - - void remove(const int idx); - - void resize(const int size); - - void set(const int idx, const String &data); - - const String operator[](const int idx); - - int size() const; - - ~PoolStringArray(); -}; - -class PoolVector2Array { - godot_pool_vector2_array _godot_array; - - friend class Variant; - explicit inline PoolVector2Array(godot_pool_vector2_array a) { - _godot_array = a; - } - -public: - class Read { - friend class PoolVector2Array; - godot_pool_vector2_array_read_access *_read_access; - - public: - inline Read() { - _read_access = nullptr; - } - - inline Read(const Read &p_other) { - _read_access = godot::api->godot_pool_vector2_array_read_access_copy(p_other._read_access); - } - - inline ~Read() { - godot::api->godot_pool_vector2_array_read_access_destroy(_read_access); - } - - inline const Vector2 *ptr() const { - return (const Vector2 *)godot::api->godot_pool_vector2_array_read_access_ptr(_read_access); - } - - inline const Vector2 &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Read &p_other) { - godot::api->godot_pool_vector2_array_read_access_operator_assign(_read_access, p_other._read_access); - } - }; - - class Write { - friend class PoolVector2Array; - godot_pool_vector2_array_write_access *_write_access; - - public: - inline Write() { - _write_access = nullptr; - } - - inline Write(const Write &p_other) { - _write_access = godot::api->godot_pool_vector2_array_write_access_copy(p_other._write_access); - } - - inline ~Write() { - godot::api->godot_pool_vector2_array_write_access_destroy(_write_access); - } - - inline Vector2 *ptr() const { - return (Vector2 *)godot::api->godot_pool_vector2_array_write_access_ptr(_write_access); - } - - inline Vector2 &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Write &p_other) { - godot::api->godot_pool_vector2_array_write_access_operator_assign(_write_access, p_other._write_access); - } - }; - - PoolVector2Array(); - PoolVector2Array(const PoolVector2Array &p_other); - PoolVector2Array &operator=(const PoolVector2Array &p_other); - - PoolVector2Array(const Array &array); - - Read read() const; - - Write write(); - - void append(const Vector2 &data); - - void append_array(const PoolVector2Array &array); - - int insert(const int idx, const Vector2 &data); - - void invert(); - - void push_back(const Vector2 &data); - - void remove(const int idx); - - void resize(const int size); - - void set(const int idx, const Vector2 &data); - - const Vector2 operator[](const int idx); - - int size() const; - - ~PoolVector2Array(); -}; - -class PoolVector3Array { - godot_pool_vector3_array _godot_array; - - friend class Variant; - explicit inline PoolVector3Array(godot_pool_vector3_array a) { - _godot_array = a; - } - -public: - class Read { - friend class PoolVector3Array; - godot_pool_vector3_array_read_access *_read_access; - - public: - inline Read() { - _read_access = nullptr; - } - - inline Read(const Read &p_other) { - _read_access = godot::api->godot_pool_vector3_array_read_access_copy(p_other._read_access); - } - - inline ~Read() { - godot::api->godot_pool_vector3_array_read_access_destroy(_read_access); - } - - inline const Vector3 *ptr() const { - return (const Vector3 *)godot::api->godot_pool_vector3_array_read_access_ptr(_read_access); - } - - inline const Vector3 &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Read &p_other) { - godot::api->godot_pool_vector3_array_read_access_operator_assign(_read_access, p_other._read_access); - } - }; - - class Write { - friend class PoolVector3Array; - godot_pool_vector3_array_write_access *_write_access; - - public: - inline Write() { - _write_access = nullptr; - } - - inline Write(const Write &p_other) { - _write_access = godot::api->godot_pool_vector3_array_write_access_copy(p_other._write_access); - } - - inline ~Write() { - godot::api->godot_pool_vector3_array_write_access_destroy(_write_access); - } - - inline Vector3 *ptr() const { - return (Vector3 *)godot::api->godot_pool_vector3_array_write_access_ptr(_write_access); - } - - inline Vector3 &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Write &p_other) { - godot::api->godot_pool_vector3_array_write_access_operator_assign(_write_access, p_other._write_access); - } - }; - - PoolVector3Array(); - PoolVector3Array(const PoolVector3Array &p_other); - PoolVector3Array &operator=(const PoolVector3Array &p_other); - - PoolVector3Array(const Array &array); - - Read read() const; - - Write write(); - - void append(const Vector3 &data); - - void append_array(const PoolVector3Array &array); - - int insert(const int idx, const Vector3 &data); - - void invert(); - - void push_back(const Vector3 &data); - - void remove(const int idx); - - void resize(const int size); - - void set(const int idx, const Vector3 &data); - - const Vector3 operator[](const int idx); - - int size() const; - - ~PoolVector3Array(); -}; - -class PoolColorArray { - godot_pool_color_array _godot_array; - - friend class Variant; - explicit inline PoolColorArray(godot_pool_color_array a) { - _godot_array = a; - } - -public: - class Read { - friend class PoolColorArray; - godot_pool_color_array_read_access *_read_access; - - public: - inline Read() { - _read_access = nullptr; - } - - inline Read(const Read &p_other) { - _read_access = godot::api->godot_pool_color_array_read_access_copy(p_other._read_access); - } - - inline ~Read() { - godot::api->godot_pool_color_array_read_access_destroy(_read_access); - } - - inline const Color *ptr() const { - return (const Color *)godot::api->godot_pool_color_array_read_access_ptr(_read_access); - } - - inline const Color &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Read &p_other) { - godot::api->godot_pool_color_array_read_access_operator_assign(_read_access, p_other._read_access); - } - }; - - class Write { - friend class PoolColorArray; - godot_pool_color_array_write_access *_write_access; - - public: - inline Write() { - _write_access = nullptr; - } - - inline Write(const Write &p_other) { - _write_access = godot::api->godot_pool_color_array_write_access_copy(p_other._write_access); - } - - inline ~Write() { - godot::api->godot_pool_color_array_write_access_destroy(_write_access); - } - - inline Color *ptr() const { - return (Color *)godot::api->godot_pool_color_array_write_access_ptr(_write_access); - } - - inline Color &operator[](int p_idx) const { - return ptr()[p_idx]; - } - - inline void operator=(const Write &p_other) { - godot::api->godot_pool_color_array_write_access_operator_assign(_write_access, p_other._write_access); - } - }; - - PoolColorArray(); - PoolColorArray(const PoolColorArray &p_other); - PoolColorArray &operator=(const PoolColorArray &p_other); - - PoolColorArray(const Array &array); - - Read read() const; - - Write write(); - - void append(const Color &data); - - void append_array(const PoolColorArray &array); - - int insert(const int idx, const Color &data); - - void invert(); - - void push_back(const Color &data); - - void remove(const int idx); - - void resize(const int size); - - void set(const int idx, const Color &data); - - const Color operator[](const int idx); - - int size() const; - - ~PoolColorArray(); -}; - -} // namespace godot - -#endif // POOLARRAYS_H diff --git a/include/core/Quat.hpp b/include/core/Quat.hpp deleted file mode 100644 index fba5ec6..0000000 --- a/include/core/Quat.hpp +++ /dev/null @@ -1,125 +0,0 @@ -/*************************************************************************/ -/* Quat.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef QUAT_H -#define QUAT_H - -#include <cmath> - -#include "Vector3.hpp" - -// #include "Basis.h" - -namespace godot { - -class Quat { -public: - static const Quat IDENTITY; - - real_t x, y, z, w; - - real_t length_squared() const; - real_t length() const; - - void normalize(); - - Quat normalized() const; - - bool is_normalized() const; - - Quat inverse() const; - - void set_euler_xyz(const Vector3 &p_euler); - Vector3 get_euler_xyz() const; - void set_euler_yxz(const Vector3 &p_euler); - Vector3 get_euler_yxz() const; - - inline void set_euler(const Vector3 &p_euler) { set_euler_yxz(p_euler); } - inline Vector3 get_euler() const { return get_euler_yxz(); } - - real_t dot(const Quat &q) const; - - Quat slerp(const Quat &q, const real_t &t) const; - - Quat slerpni(const Quat &q, const real_t &t) const; - - Quat cubic_slerp(const Quat &q, const Quat &prep, const Quat &postq, const real_t &t) const; - - void get_axis_and_angle(Vector3 &r_axis, real_t &r_angle) const; - - void set_axis_angle(const Vector3 &axis, const float angle); - - void operator*=(const Quat &q); - Quat operator*(const Quat &q) const; - - Quat operator*(const Vector3 &v) const; - - Vector3 xform(const Vector3 &v) const; - - void operator+=(const Quat &q); - void operator-=(const Quat &q); - void operator*=(const real_t &s); - void operator/=(const real_t &s); - Quat operator+(const Quat &q2) const; - Quat operator-(const Quat &q2) const; - Quat operator-() const; - Quat operator*(const real_t &s) const; - Quat operator/(const real_t &s) const; - - bool operator==(const Quat &p_quat) const; - bool operator!=(const Quat &p_quat) const; - - operator String() const; - - inline void set(real_t p_x, real_t p_y, real_t p_z, real_t p_w) { - x = p_x; - y = p_y; - z = p_z; - w = p_w; - } - inline Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) { - x = p_x; - y = p_y; - z = p_z; - w = p_w; - } - Quat(const Vector3 &axis, const real_t &angle); - - Quat(const Vector3 &v0, const Vector3 &v1); - - inline Quat() { - x = y = z = 0; - w = 1; - } -}; - -} // namespace godot - -#endif // QUAT_H diff --git a/include/core/Rect2.hpp b/include/core/Rect2.hpp deleted file mode 100644 index 9cd7d10..0000000 --- a/include/core/Rect2.hpp +++ /dev/null @@ -1,160 +0,0 @@ -/*************************************************************************/ -/* Rect2.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef RECT2_H -#define RECT2_H - -#include "Vector2.hpp" - -#include <cmath> - -#include <cstdlib> - -namespace godot { - -class String; - -typedef Vector2 Size2; -typedef Vector2 Point2; - -struct Transform2D; - -struct Rect2 { - Point2 position; - Size2 size; - - inline const Vector2 &get_position() const { return position; } - inline void set_position(const Vector2 &p_position) { position = p_position; } - inline const Vector2 &get_size() const { return size; } - inline void set_size(const Vector2 &p_size) { size = p_size; } - - inline real_t get_area() const { return size.width * size.height; } - - inline bool intersects(const Rect2 &p_rect) const { - if (position.x >= (p_rect.position.x + p_rect.size.width)) - return false; - if ((position.x + size.width) <= p_rect.position.x) - return false; - if (position.y >= (p_rect.position.y + p_rect.size.height)) - return false; - if ((position.y + size.height) <= p_rect.position.y) - return false; - - return true; - } - - real_t distance_to(const Vector2 &p_point) const; - - bool intersects_transformed(const Transform2D &p_xform, const Rect2 &p_rect) const; - - bool intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_position = nullptr, Point2 *r_normal = nullptr) const; - - inline bool encloses(const Rect2 &p_rect) const { - return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) && - ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) && - ((p_rect.position.y + p_rect.size.y) < (position.y + size.y)); - } - - inline bool has_no_area() const { - return (size.x <= 0 || size.y <= 0); - } - Rect2 clip(const Rect2 &p_rect) const; - - Rect2 merge(const Rect2 &p_rect) const; - - inline bool has_point(const Point2 &p_point) const { - if (p_point.x < position.x) - return false; - if (p_point.y < position.y) - return false; - - if (p_point.x >= (position.x + size.x)) - return false; - if (p_point.y >= (position.y + size.y)) - return false; - - return true; - } - - inline bool no_area() const { return (size.width <= 0 || size.height <= 0); } - - inline bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; } - inline bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; } - - inline Rect2 grow(real_t p_by) const { - Rect2 g = *this; - g.position.x -= p_by; - g.position.y -= p_by; - g.size.width += p_by * 2; - g.size.height += p_by * 2; - return g; - } - - inline Rect2 expand(const Vector2 &p_vector) const { - Rect2 r = *this; - r.expand_to(p_vector); - return r; - } - - inline void expand_to(const Vector2 &p_vector) { //in place function for speed - - Vector2 begin = position; - Vector2 end = position + size; - - if (p_vector.x < begin.x) - begin.x = p_vector.x; - if (p_vector.y < begin.y) - begin.y = p_vector.y; - - if (p_vector.x > end.x) - end.x = p_vector.x; - if (p_vector.y > end.y) - end.y = p_vector.y; - - position = begin; - size = end - begin; - } - - operator String() const; - - inline Rect2() {} - inline Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) { - position = Point2(p_x, p_y); - size = Size2(p_width, p_height); - } - inline Rect2(const Point2 &p_position, const Size2 &p_size) { - position = p_position; - size = p_size; - } -}; - -} // namespace godot - -#endif // RECT2_H diff --git a/include/core/String.hpp b/include/core/String.hpp deleted file mode 100644 index 91400c7..0000000 --- a/include/core/String.hpp +++ /dev/null @@ -1,184 +0,0 @@ -/*************************************************************************/ -/* String.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef STRING_H -#define STRING_H - -#include <gdnative/string.h> - -namespace godot { - -class NodePath; -class Variant; -class PoolByteArray; -class PoolIntArray; -class PoolRealArray; -class PoolStringArray; -class String; - -class CharString { - friend class String; - - godot_char_string _char_string; - -public: - ~CharString(); - - int length() const; - const char *get_data() const; -}; - -class String { - godot_string _godot_string; - - friend class Dictionary; - friend class NodePath; - friend class Variant; - explicit inline String(godot_string contents) : - _godot_string(contents) {} - -public: - String(); - String(const char *contents); - String(const wchar_t *contents); - String(const wchar_t c); - String(const String &other); - String(String &&other); - - ~String(); - - static String num(double p_num, int p_decimals = -1); - static String num_scientific(double p_num); - static String num_real(double p_num); - static String num_int64(int64_t p_num, int base = 10, bool capitalize_hex = false); - static String chr(godot_char_type p_char); - static String md5(const uint8_t *p_md5); - static String hex_encode_buffer(const uint8_t *p_buffer, int p_len); - - wchar_t &operator[](const int idx); - wchar_t operator[](const int idx) const; - - void operator=(const String &s); - void operator=(String &&s); - bool operator==(const String &s) const; - bool operator!=(const String &s) const; - String operator+(const String &s) const; - void operator+=(const String &s); - void operator+=(const wchar_t c); - bool operator<(const String &s) const; - bool operator<=(const String &s) const; - bool operator>(const String &s) const; - bool operator>=(const String &s) const; - - operator NodePath() const; - - int length() const; - const wchar_t *unicode_str() const; - char *alloc_c_string() const; - CharString utf8() const; - CharString ascii(bool p_extended = false) const; - - bool begins_with(const String &s) const; - bool begins_with_char_array(const char *p_char_array) const; - PoolStringArray bigrams() const; - String c_escape() const; - String c_unescape() const; - String capitalize() const; - bool empty() const; - bool ends_with(const String &text) const; - void erase(int position, int chars); - int find(String what, int from = 0) const; - int find_last(String what) const; - int findn(String what, int from = 0) const; - String format(Variant values) const; - String format(Variant values, String placeholder) const; - String get_base_dir() const; - String get_basename() const; - String get_extension() const; - String get_file() const; - int hash() const; - int hex_to_int() const; - String insert(int position, String what) const; - bool is_abs_path() const; - bool is_rel_path() const; - bool is_subsequence_of(String text) const; - bool is_subsequence_ofi(String text) const; - bool is_valid_float() const; - bool is_valid_html_color() const; - bool is_valid_identifier() const; - bool is_valid_integer() const; - bool is_valid_ip_address() const; - String json_escape() const; - String left(int position) const; - bool match(String expr) const; - bool matchn(String expr) const; - PoolByteArray md5_buffer() const; - String md5_text() const; - int ord_at(int at) const; - String pad_decimals(int digits) const; - String pad_zeros(int digits) const; - String percent_decode() const; - String percent_encode() const; - String plus_file(String file) const; - String replace(String what, String forwhat) const; - String replacen(String what, String forwhat) const; - int rfind(String what, int from = -1) const; - int rfindn(String what, int from = -1) const; - String right(int position) const; - PoolByteArray sha256_buffer() const; - String sha256_text() const; - float similarity(String text) const; - PoolStringArray split(String divisor, bool allow_empty = true) const; - PoolIntArray split_ints(String divisor, bool allow_empty = true) const; - PoolRealArray split_floats(String divisor, bool allow_empty = true) const; - String strip_edges(bool left = true, bool right = true) const; - String substr(int from, int len) const; - float to_float() const; - int64_t to_int() const; - String to_lower() const; - String to_upper() const; - String xml_escape() const; - String xml_unescape() const; - signed char casecmp_to(String p_str) const; - signed char nocasecmp_to(String p_str) const; - signed char naturalnocasecmp_to(String p_str) const; - String dedent() const; - PoolStringArray rsplit(const String &divisor, const bool allow_empty = true, const int maxsplit = 0) const; - String rstrip(const String &chars) const; - String trim_prefix(const String &prefix) const; - String trim_suffix(const String &suffix) const; -}; - -String operator+(const char *a, const String &b); -String operator+(const wchar_t *a, const String &b); - -} // namespace godot - -#endif // STRING_H diff --git a/include/core/TagDB.hpp b/include/core/TagDB.hpp deleted file mode 100644 index 71f5e5c..0000000 --- a/include/core/TagDB.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************/ -/* TagDB.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef TAGDB_HPP -#define TAGDB_HPP - -#include <stddef.h> - -namespace godot { - -namespace _TagDB { - -void register_type(size_t type_tag, size_t base_type_tag); -bool is_type_known(size_t type_tag); -void register_global_type(const char *name, size_t type_tag, size_t base_type_tag); -bool is_type_compatible(size_t type_tag, size_t base_type_tag); - -} // namespace _TagDB - -} // namespace godot - -#endif // TAGDB_HPP diff --git a/include/core/Transform.hpp b/include/core/Transform.hpp deleted file mode 100644 index 9dea7f2..0000000 --- a/include/core/Transform.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************/ -/* Transform.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef TRANSFORM_H -#define TRANSFORM_H - -#include "Basis.hpp" - -#include "AABB.hpp" -#include "Plane.hpp" - -namespace godot { - -class Transform { -public: - static const Transform IDENTITY; - static const Transform FLIP_X; - static const Transform FLIP_Y; - static const Transform FLIP_Z; - - Basis basis; - Vector3 origin; - - void invert(); - Transform inverse() const; - - void affine_invert(); - Transform affine_inverse() const; - - Transform rotated(const Vector3 &p_axis, real_t p_phi) const; - - void rotate(const Vector3 &p_axis, real_t p_phi); - void rotate_basis(const Vector3 &p_axis, real_t p_phi); - - void set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up); - Transform looking_at(const Vector3 &p_target, const Vector3 &p_up) const; - - void scale(const Vector3 &p_scale); - Transform scaled(const Vector3 &p_scale) const; - void scale_basis(const Vector3 &p_scale); - void translate(real_t p_tx, real_t p_ty, real_t p_tz); - void translate(const Vector3 &p_translation); - Transform translated(const Vector3 &p_translation) const; - - inline const Basis &get_basis() const { return basis; } - inline void set_basis(const Basis &p_basis) { basis = p_basis; } - - inline const Vector3 &get_origin() const { return origin; } - inline void set_origin(const Vector3 &p_origin) { origin = p_origin; } - - void orthonormalize(); - Transform orthonormalized() const; - - bool operator==(const Transform &p_transform) const; - bool operator!=(const Transform &p_transform) const; - - Vector3 xform(const Vector3 &p_vector) const; - Vector3 xform_inv(const Vector3 &p_vector) const; - - Plane xform(const Plane &p_plane) const; - Plane xform_inv(const Plane &p_plane) const; - - AABB xform(const AABB &p_aabb) const; - AABB xform_inv(const AABB &p_aabb) const; - - void operator*=(const Transform &p_transform); - Transform operator*(const Transform &p_transform) const; - - inline Vector3 operator*(const Vector3 &p_vector) const { - return Vector3( - basis.elements[0].dot(p_vector) + origin.x, - basis.elements[1].dot(p_vector) + origin.y, - basis.elements[2].dot(p_vector) + origin.z); - } - - Transform interpolate_with(const Transform &p_transform, real_t p_c) const; - - Transform inverse_xform(const Transform &t) const; - - void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t tx, real_t ty, real_t tz); - - operator String() const; - - inline Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t tx, real_t ty, real_t tz) { - set(xx, xy, xz, yx, yy, yz, zx, zy, zz, tx, ty, tz); - } - - Transform(const Basis &p_basis, const Vector3 &p_origin = Vector3()); - inline Transform() {} -}; - -} // namespace godot - -#endif // TRANSFORM_H diff --git a/include/core/Transform2D.hpp b/include/core/Transform2D.hpp deleted file mode 100644 index 659ac1a..0000000 --- a/include/core/Transform2D.hpp +++ /dev/null @@ -1,136 +0,0 @@ -/*************************************************************************/ -/* Transform2D.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef TRANSFORM2D_H -#define TRANSFORM2D_H - -#include "Vector2.hpp" - -namespace godot { - -typedef Vector2 Size2; - -struct Rect2; - -struct Transform2D { - static const Transform2D IDENTITY; - static const Transform2D FLIP_X; - static const Transform2D FLIP_Y; - - // Warning #1: basis of Transform2D is stored differently from Basis. In terms of elements array, the basis matrix looks like "on paper": - // M = (elements[0][0] elements[1][0]) - // (elements[0][1] elements[1][1]) - // This is such that the columns, which can be interpreted as basis vectors of the coordinate system "painted" on the object, can be accessed as elements[i]. - // Note that this is the opposite of the indices in mathematical texts, meaning: $M_{12}$ in a math book corresponds to elements[1][0] here. - // This requires additional care when working with explicit indices. - // See https://en.wikipedia.org/wiki/Row-_and_column-major_order for further reading. - - // Warning #2: 2D be aware that unlike 3D code, 2D code uses a left-handed coordinate system: Y-axis points down, - // and angle is measure from +X to +Y in a clockwise-fashion. - - Vector2 elements[3]; - - inline real_t tdotx(const Vector2 &v) const { return elements[0][0] * v.x + elements[1][0] * v.y; } - inline real_t tdoty(const Vector2 &v) const { return elements[0][1] * v.x + elements[1][1] * v.y; } - - inline const Vector2 &operator[](int p_idx) const { return elements[p_idx]; } - inline Vector2 &operator[](int p_idx) { return elements[p_idx]; } - - inline Vector2 get_axis(int p_axis) const { - ERR_FAIL_INDEX_V(p_axis, 3, Vector2()); - return elements[p_axis]; - } - inline void set_axis(int p_axis, const Vector2 &p_vec) { - ERR_FAIL_INDEX(p_axis, 3); - elements[p_axis] = p_vec; - } - - void invert(); - Transform2D inverse() const; - - void affine_invert(); - Transform2D affine_inverse() const; - - void set_rotation(real_t p_phi); - real_t get_rotation() const; - void set_rotation_and_scale(real_t p_phi, const Size2 &p_scale); - void rotate(real_t p_phi); - - void scale(const Size2 &p_scale); - void scale_basis(const Size2 &p_scale); - void translate(real_t p_tx, real_t p_ty); - void translate(const Vector2 &p_translation); - - real_t basis_determinant() const; - - Size2 get_scale() const; - - inline const Vector2 &get_origin() const { return elements[2]; } - inline void set_origin(const Vector2 &p_origin) { elements[2] = p_origin; } - - Transform2D scaled(const Size2 &p_scale) const; - Transform2D basis_scaled(const Size2 &p_scale) const; - Transform2D translated(const Vector2 &p_offset) const; - Transform2D rotated(real_t p_phi) const; - - Transform2D untranslated() const; - - void orthonormalize(); - Transform2D orthonormalized() const; - - bool operator==(const Transform2D &p_transform) const; - bool operator!=(const Transform2D &p_transform) const; - - void operator*=(const Transform2D &p_transform); - Transform2D operator*(const Transform2D &p_transform) const; - - Transform2D interpolate_with(const Transform2D &p_transform, real_t p_c) const; - - Vector2 basis_xform(const Vector2 &p_vec) const; - Vector2 basis_xform_inv(const Vector2 &p_vec) const; - Vector2 xform(const Vector2 &p_vec) const; - Vector2 xform_inv(const Vector2 &p_vec) const; - Rect2 xform(const Rect2 &p_vec) const; - Rect2 xform_inv(const Rect2 &p_vec) const; - - operator String() const; - - Transform2D(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy); - - Transform2D(real_t p_rot, const Vector2 &p_pos); - inline Transform2D() { - elements[0][0] = 1.0; - elements[1][1] = 1.0; - } -}; - -} // namespace godot - -#endif // TRANSFORM2D_H diff --git a/include/core/Variant.hpp b/include/core/Variant.hpp deleted file mode 100644 index 7f388d3..0000000 --- a/include/core/Variant.hpp +++ /dev/null @@ -1,304 +0,0 @@ -/*************************************************************************/ -/* Variant.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VARIANT_H -#define VARIANT_H - -#include <gdnative/variant.h> - -#include "Defs.hpp" - -#include "AABB.hpp" -#include "Basis.hpp" -#include "Color.hpp" -#include "NodePath.hpp" -#include "Plane.hpp" -#include "PoolArrays.hpp" -#include "Quat.hpp" -#include "RID.hpp" -#include "Rect2.hpp" -#include "String.hpp" -#include "Transform.hpp" -#include "Transform2D.hpp" -#include "Vector2.hpp" -#include "Vector3.hpp" - -namespace godot { - -class Dictionary; - -class Array; - -class Variant { - godot_variant _godot_variant; - - friend class Array; - inline explicit Variant(godot_variant v) { - _godot_variant = v; - } - -public: - enum Type { - - NIL, - - // atomic types - BOOL, - INT, - REAL, - STRING, - - // math types - - VECTOR2, // 5 - RECT2, - VECTOR3, - TRANSFORM2D, - PLANE, - QUAT, // 10 - RECT3, //sorry naming convention fail :( not like it's used often - BASIS, - TRANSFORM, - - // misc types - COLOR, - NODE_PATH, // 15 - _RID, - OBJECT, - DICTIONARY, - ARRAY, - - // arrays - POOL_BYTE_ARRAY, // 20 - POOL_INT_ARRAY, - POOL_REAL_ARRAY, - POOL_STRING_ARRAY, - POOL_VECTOR2_ARRAY, - POOL_VECTOR3_ARRAY, // 25 - POOL_COLOR_ARRAY, - - VARIANT_MAX - - }; - - enum Operator { - - //comparation - OP_EQUAL, - OP_NOT_EQUAL, - OP_LESS, - OP_LESS_EQUAL, - OP_GREATER, - OP_GREATER_EQUAL, - - //mathematic - OP_ADD, - OP_SUBSTRACT, - OP_MULTIPLY, - OP_DIVIDE, - OP_NEGATE, - OP_POSITIVE, - OP_MODULE, - OP_STRING_CONCAT, - - //bitwise - OP_SHIFT_LEFT, - OP_SHIFT_RIGHT, - OP_BIT_AND, - OP_BIT_OR, - OP_BIT_XOR, - OP_BIT_NEGATE, - - //logic - OP_AND, - OP_OR, - OP_XOR, - OP_NOT, - - //containment - OP_IN, - OP_MAX - - }; - - Variant(); - - Variant(const Variant &v); - - Variant(bool p_bool); - - Variant(signed int p_int); - - Variant(unsigned int p_int); - - Variant(signed short p_short); - - inline Variant(unsigned short p_short) : - Variant((unsigned int)p_short) {} - - inline Variant(signed char p_char) : - Variant((signed int)p_char) {} - - inline Variant(unsigned char p_char) : - Variant((unsigned int)p_char) {} - Variant(int64_t p_char); - - Variant(uint64_t p_char); - - Variant(float p_float); - - Variant(double p_double); - - Variant(const String &p_string); - - Variant(const char *const p_cstring); - - Variant(const wchar_t *p_wstring); - - Variant(const Vector2 &p_vector2); - - Variant(const Rect2 &p_rect2); - - Variant(const Vector3 &p_vector3); - - Variant(const Plane &p_plane); - - Variant(const AABB &p_aabb); - - Variant(const Quat &p_quat); - - Variant(const Basis &p_transform); - - Variant(const Transform2D &p_transform); - - Variant(const Transform &p_transform); - - Variant(const Color &p_color); - - Variant(const NodePath &p_path); - - Variant(const RID &p_rid); - - Variant(const Object *p_object); - - Variant(const Dictionary &p_dictionary); - - Variant(const Array &p_array); - - Variant(const PoolByteArray &p_raw_array); - - Variant(const PoolIntArray &p_int_array); - - Variant(const PoolRealArray &p_real_array); - - Variant(const PoolStringArray &p_string_array); - - Variant(const PoolVector2Array &p_vector2_array); - - Variant(const PoolVector3Array &p_vector3_array); - - Variant(const PoolColorArray &p_color_array); - - Variant &operator=(const Variant &v); - - operator bool() const; - operator signed int() const; - operator unsigned int() const; - operator signed short() const; - operator unsigned short() const; - operator signed char() const; - operator unsigned char() const; - operator int64_t() const; - operator uint64_t() const; - - operator wchar_t() const; - - operator float() const; - - operator double() const; - operator String() const; - operator Vector2() const; - operator Rect2() const; - operator Vector3() const; - operator Plane() const; - operator AABB() const; - operator Quat() const; - operator Basis() const; - operator Transform() const; - operator Transform2D() const; - - operator Color() const; - - operator NodePath() const; - operator RID() const; - operator godot_object *() const; - - template <typename T> - operator T *() const { return static_cast<T *>(T::___get_from_variant(*this)); } - - operator Dictionary() const; - operator Array() const; - - operator PoolByteArray() const; - operator PoolIntArray() const; - operator PoolRealArray() const; - operator PoolStringArray() const; - operator PoolVector2Array() const; - operator PoolVector3Array() const; - operator PoolColorArray() const; - - Type get_type() const; - - Variant call(const String &method, const Variant **args, const int arg_count); - - bool has_method(const String &method); - - bool operator==(const Variant &b) const; - - bool operator!=(const Variant &b) const; - - bool operator<(const Variant &b) const; - - bool operator<=(const Variant &b) const; - - bool operator>(const Variant &b) const; - - bool operator>=(const Variant &b) const; - - bool hash_compare(const Variant &b) const; - - bool booleanize() const; - - ~Variant(); -}; - -} // namespace godot - -#endif // VARIANT_H diff --git a/include/core/Vector2.hpp b/include/core/Vector2.hpp deleted file mode 100644 index a3a8897..0000000 --- a/include/core/Vector2.hpp +++ /dev/null @@ -1,306 +0,0 @@ -/*************************************************************************/ -/* Vector2.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VECTOR2_H -#define VECTOR2_H - -#include <gdnative/vector2.h> - -#include "Defs.hpp" - -#include <Math.hpp> - -namespace godot { - -class String; - -struct Vector2 { - enum Axis { - AXIS_X = 0, - AXIS_Y, - AXIS_COUNT - }; - - static const Vector2 ZERO; - static const Vector2 ONE; - static const Vector2 INF; - - // Coordinate system of the 2D engine - static const Vector2 LEFT; - static const Vector2 RIGHT; - static const Vector2 UP; - static const Vector2 DOWN; - - union { - real_t x; - real_t width; - }; - union { - real_t y; - real_t height; - }; - - inline Vector2(real_t p_x, real_t p_y) { - x = p_x; - y = p_y; - } - - inline Vector2() { - x = 0; - y = 0; - } - - inline real_t &operator[](int p_idx) { - return p_idx ? y : x; - } - - inline const real_t &operator[](int p_idx) const { - return p_idx ? y : x; - } - - inline Vector2 operator+(const Vector2 &p_v) const { - return Vector2(x + p_v.x, y + p_v.y); - } - - inline void operator+=(const Vector2 &p_v) { - x += p_v.x; - y += p_v.y; - } - - inline Vector2 operator-(const Vector2 &p_v) const { - return Vector2(x - p_v.x, y - p_v.y); - } - - inline void operator-=(const Vector2 &p_v) { - x -= p_v.x; - y -= p_v.y; - } - - inline Vector2 operator*(const Vector2 &p_v1) const { - return Vector2(x * p_v1.x, y * p_v1.y); - } - - inline Vector2 operator*(const real_t &rvalue) const { - return Vector2(x * rvalue, y * rvalue); - } - - inline void operator*=(const real_t &rvalue) { - x *= rvalue; - y *= rvalue; - } - - inline void operator*=(const Vector2 &rvalue) { - *this = *this * rvalue; - } - - inline Vector2 operator/(const Vector2 &p_v1) const { - return Vector2(x / p_v1.x, y / p_v1.y); - } - - inline Vector2 operator/(const real_t &rvalue) const { - return Vector2(x / rvalue, y / rvalue); - } - - inline void operator/=(const real_t &rvalue) { - x /= rvalue; - y /= rvalue; - } - - inline Vector2 operator-() const { - return Vector2(-x, -y); - } - - bool operator==(const Vector2 &p_vec2) const; - - bool operator!=(const Vector2 &p_vec2) const; - - inline bool operator<(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); } - inline bool operator<=(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y <= p_vec2.y) : (x <= p_vec2.x); } - - inline void normalize() { - real_t l = x * x + y * y; - if (l != 0) { - l = sqrt(l); - x /= l; - y /= l; - } - } - - inline Vector2 normalized() const { - Vector2 v = *this; - v.normalize(); - return v; - } - - inline real_t length() const { - return sqrt(x * x + y * y); - } - - inline real_t length_squared() const { - return x * x + y * y; - } - - inline real_t distance_to(const Vector2 &p_vector2) const { - return sqrt((x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y)); - } - - inline real_t distance_squared_to(const Vector2 &p_vector2) const { - return (x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y); - } - - inline real_t angle_to(const Vector2 &p_vector2) const { - return atan2(cross(p_vector2), dot(p_vector2)); - } - - inline real_t angle_to_point(const Vector2 &p_vector2) const { - return atan2(y - p_vector2.y, x - p_vector2.x); - } - - inline Vector2 direction_to(const Vector2 &p_b) const { - Vector2 ret(p_b.x - x, p_b.y - y); - ret.normalize(); - return ret; - } - - inline real_t dot(const Vector2 &p_other) const { - return x * p_other.x + y * p_other.y; - } - - inline real_t cross(const Vector2 &p_other) const { - return x * p_other.y - y * p_other.x; - } - - inline Vector2 cross(real_t p_other) const { - return Vector2(p_other * y, -p_other * x); - } - - Vector2 project(const Vector2 &p_vec) const; - - Vector2 plane_project(real_t p_d, const Vector2 &p_vec) const; - - Vector2 clamped(real_t p_len) const; - - static inline Vector2 linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_t) { - Vector2 res = p_a; - res.x += (p_t * (p_b.x - p_a.x)); - res.y += (p_t * (p_b.y - p_a.y)); - return res; - } - - inline Vector2 linear_interpolate(const Vector2 &p_b, real_t p_t) const { - Vector2 res = *this; - res.x += (p_t * (p_b.x - x)); - res.y += (p_t * (p_b.y - y)); - return res; - } - - Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const; - - Vector2 move_toward(const Vector2 &p_to, const real_t p_delta) const { - Vector2 v = *this; - Vector2 vd = p_to - v; - real_t len = vd.length(); - return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta; - } - - inline Vector2 slide(const Vector2 &p_vec) const { - return p_vec - *this * this->dot(p_vec); - } - - inline Vector2 bounce(const Vector2 &p_normal) const { - return -reflect(p_normal); - } - - inline Vector2 reflect(const Vector2 &p_normal) const { - return -(*this - p_normal * this->dot(p_normal) * 2.0); - } - - inline real_t angle() const { - return atan2(y, x); - } - - inline void set_rotation(real_t p_radians) { - x = cosf(p_radians); - y = sinf(p_radians); - } - - inline Vector2 abs() const { - return Vector2(fabs(x), fabs(y)); - } - - inline Vector2 rotated(real_t p_by) const { - Vector2 v; - v.set_rotation(angle() + p_by); - v *= length(); - return v; - } - - inline Vector2 tangent() const { - return Vector2(y, -x); - } - - inline Vector2 floor() const { - return Vector2(Math::floor(x), Math::floor(y)); - } - - inline Vector2 snapped(const Vector2 &p_by) const { - return Vector2( - Math::stepify(x, p_by.x), - Math::stepify(y, p_by.y)); - } - - inline real_t aspect() const { return width / height; } - - operator String() const; -}; - -inline Vector2 operator*(real_t p_scalar, const Vector2 &p_vec) { - return p_vec * p_scalar; -} - -namespace Math { - -// Convenience, since they exist in GDScript - -inline Vector2 cartesian2polar(Vector2 v) { - return Vector2(Math::sqrt(v.x * v.x + v.y * v.y), Math::atan2(v.y, v.x)); -} - -inline Vector2 polar2cartesian(Vector2 v) { - // x == radius - // y == angle - return Vector2(v.x * Math::cos(v.y), v.x * Math::sin(v.y)); -} - -} // namespace Math - -} // namespace godot - -#endif // VECTOR2_H diff --git a/include/core/Vector3.hpp b/include/core/Vector3.hpp deleted file mode 100644 index aa28c61..0000000 --- a/include/core/Vector3.hpp +++ /dev/null @@ -1,342 +0,0 @@ -/*************************************************************************/ -/* Vector3.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VECTOR3_H -#define VECTOR3_H - -#include <gdnative/vector3.h> - -#include "Defs.hpp" - -#include "String.hpp" - -#include <Math.hpp> - -namespace godot { - -class Basis; - -struct Vector3 { - enum Axis { - AXIS_X, - AXIS_Y, - AXIS_Z, - AXIS_COUNT - }; - - static const Vector3 ZERO; - static const Vector3 ONE; - static const Vector3 INF; - - // Coordinate system of the 3D engine - static const Vector3 LEFT; - static const Vector3 RIGHT; - static const Vector3 UP; - static const Vector3 DOWN; - static const Vector3 FORWARD; - static const Vector3 BACK; - - union { - struct { - real_t x; - real_t y; - real_t z; - }; - - real_t coord[3]; // Not for direct access, use [] operator instead - }; - - inline Vector3(real_t x, real_t y, real_t z) { - this->x = x; - this->y = y; - this->z = z; - } - - inline Vector3() { - this->x = 0; - this->y = 0; - this->z = 0; - } - - inline const real_t &operator[](int p_axis) const { - return coord[p_axis]; - } - - inline real_t &operator[](int p_axis) { - return coord[p_axis]; - } - - inline Vector3 &operator+=(const Vector3 &p_v) { - x += p_v.x; - y += p_v.y; - z += p_v.z; - return *this; - } - - inline Vector3 operator+(const Vector3 &p_v) const { - Vector3 v = *this; - v += p_v; - return v; - } - - inline Vector3 &operator-=(const Vector3 &p_v) { - x -= p_v.x; - y -= p_v.y; - z -= p_v.z; - return *this; - } - - inline Vector3 operator-(const Vector3 &p_v) const { - Vector3 v = *this; - v -= p_v; - return v; - } - - inline Vector3 &operator*=(const Vector3 &p_v) { - x *= p_v.x; - y *= p_v.y; - z *= p_v.z; - return *this; - } - - inline Vector3 operator*(const Vector3 &p_v) const { - Vector3 v = *this; - v *= p_v; - return v; - } - - inline Vector3 &operator/=(const Vector3 &p_v) { - x /= p_v.x; - y /= p_v.y; - z /= p_v.z; - return *this; - } - - inline Vector3 operator/(const Vector3 &p_v) const { - Vector3 v = *this; - v /= p_v; - return v; - } - - inline Vector3 &operator*=(real_t p_scalar) { - *this *= Vector3(p_scalar, p_scalar, p_scalar); - return *this; - } - - inline Vector3 operator*(real_t p_scalar) const { - Vector3 v = *this; - v *= p_scalar; - return v; - } - - inline Vector3 &operator/=(real_t p_scalar) { - *this /= Vector3(p_scalar, p_scalar, p_scalar); - return *this; - } - - inline Vector3 operator/(real_t p_scalar) const { - Vector3 v = *this; - v /= p_scalar; - return v; - } - - inline Vector3 operator-() const { - return Vector3(-x, -y, -z); - } - - inline bool operator==(const Vector3 &p_v) const { - return (x == p_v.x && y == p_v.y && z == p_v.z); - } - - inline bool operator!=(const Vector3 &p_v) const { - return (x != p_v.x || y != p_v.y || z != p_v.z); - } - - bool operator<(const Vector3 &p_v) const; - - bool operator<=(const Vector3 &p_v) const; - - inline Vector3 abs() const { - return Vector3(::fabs(x), ::fabs(y), ::fabs(z)); - } - - inline Vector3 ceil() const { - return Vector3(::ceil(x), ::ceil(y), ::ceil(z)); - } - - inline Vector3 cross(const Vector3 &b) const { - Vector3 ret( - (y * b.z) - (z * b.y), - (z * b.x) - (x * b.z), - (x * b.y) - (y * b.x)); - - return ret; - } - - inline Vector3 linear_interpolate(const Vector3 &p_b, real_t p_t) const { - return Vector3( - x + (p_t * (p_b.x - x)), - y + (p_t * (p_b.y - y)), - z + (p_t * (p_b.z - z))); - } - - inline Vector3 slerp(const Vector3 &p_b, real_t p_t) const { - real_t theta = angle_to(p_b); - return rotated(cross(p_b).normalized(), theta * p_t); - } - - Vector3 cubic_interpolate(const Vector3 &b, const Vector3 &pre_a, const Vector3 &post_b, const real_t t) const; - - Vector3 move_toward(const Vector3 &p_to, const real_t p_delta) const { - Vector3 v = *this; - Vector3 vd = p_to - v; - real_t len = vd.length(); - return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta; - } - - Vector3 bounce(const Vector3 &p_normal) const { - return -reflect(p_normal); - } - - inline real_t length() const { - real_t x2 = x * x; - real_t y2 = y * y; - real_t z2 = z * z; - - return ::sqrt(x2 + y2 + z2); - } - - inline real_t length_squared() const { - real_t x2 = x * x; - real_t y2 = y * y; - real_t z2 = z * z; - - return x2 + y2 + z2; - } - - inline real_t distance_squared_to(const Vector3 &b) const { - return (b - *this).length_squared(); - } - - inline real_t distance_to(const Vector3 &b) const { - return (b - *this).length(); - } - - inline real_t dot(const Vector3 &b) const { - return x * b.x + y * b.y + z * b.z; - } - - inline Vector3 project(const Vector3 &p_b) const { - return p_b * (dot(p_b) / p_b.length_squared()); - } - - inline real_t angle_to(const Vector3 &b) const { - return std::atan2(cross(b).length(), dot(b)); - } - - inline Vector3 direction_to(const Vector3 &p_b) const { - Vector3 ret(p_b.x - x, p_b.y - y, p_b.z - z); - ret.normalize(); - return ret; - } - - inline Vector3 floor() const { - return Vector3(::floor(x), ::floor(y), ::floor(z)); - } - - inline Vector3 inverse() const { - return Vector3(1.f / x, 1.f / y, 1.f / z); - } - - inline bool is_normalized() const { - return std::abs(length_squared() - 1.f) < 0.00001f; - } - - Basis outer(const Vector3 &b) const; - - int max_axis() const; - - int min_axis() const; - - inline void normalize() { - real_t l = length(); - if (l == 0) { - x = y = z = 0; - } else { - x /= l; - y /= l; - z /= l; - } - } - - inline Vector3 normalized() const { - Vector3 v = *this; - v.normalize(); - return v; - } - - inline Vector3 reflect(const Vector3 &p_normal) const { - return -(*this - p_normal * this->dot(p_normal) * 2.0); - } - - inline Vector3 rotated(const Vector3 &axis, const real_t phi) const { - Vector3 v = *this; - v.rotate(axis, phi); - return v; - } - - void rotate(const Vector3 &p_axis, real_t p_phi); - - inline Vector3 slide(const Vector3 &by) const { - return *this - by * this->dot(by); - } - - void snap(real_t p_val); - - inline Vector3 snapped(const float by) { - Vector3 v = *this; - v.snap(by); - return v; - } - - operator String() const; -}; - -inline Vector3 operator*(real_t p_scalar, const Vector3 &p_vec) { - return p_vec * p_scalar; -} - -inline Vector3 vec3_cross(const Vector3 &p_a, const Vector3 &p_b) { - return p_a.cross(p_b); -} - -} // namespace godot - -#endif // VECTOR3_H diff --git a/include/core/Wrapped.hpp b/include/core/Wrapped.hpp deleted file mode 100644 index 26f2f0c..0000000 --- a/include/core/Wrapped.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************/ -/* Wrapped.hpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef WRAPPED_HPP -#define WRAPPED_HPP - -#include <gdnative/gdnative.h> - -namespace godot { - -// This is an internal base class used by the bindings. You should not need to access its members. -class _Wrapped { -public: - godot_object *_owner; - size_t _type_tag; -}; - -} // namespace godot - -#endif // WRAPPED_HPP diff --git a/include/gen/.gitignore b/include/gen/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/include/gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/include/core/Ref.hpp b/include/godot_cpp/classes/ref.hpp index 77a0aa4..2140ef3 100644 --- a/include/core/Ref.hpp +++ b/include/godot_cpp/classes/ref.hpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* Ref.hpp */ +/* ref.hpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,82 +28,90 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef REF_H -#define REF_H +#ifndef GODOT_CPP_REF_HPP +#define GODOT_CPP_REF_HPP -#include "GodotGlobal.hpp" -#include "Reference.hpp" -#include "Variant.hpp" +#include <godot_cpp/core/defs.hpp> + +#include <godot_cpp/classes/object.hpp> +#include <godot_cpp/classes/ref_counted.hpp> +#include <godot_cpp/core/memory.hpp> +#include <godot_cpp/variant/variant.hpp> namespace godot { -// Replicates Godot's Ref<T> behavior -// Rewritten from f5234e70be7dec4930c2d5a0e829ff480d044b1d. +// Helper class for RefCounted objects, same as Godot one. + +class RefCounted; + template <class T> class Ref { - // TODO For this nice check to work, each class must actually #include Reference classes mentionned in its methods, - // which might be annoying for coders who prefer to forward-declare to reduce compile times - // static_assert(std::is_base_of<Reference, T>::value, - // "Ref<T> can only be used with classes deriving from Reference"); - T *reference = nullptr; void ref(const Ref &p_from) { - if (p_from.reference == reference) + if (p_from.reference == reference) { return; + } unref(); reference = p_from.reference; - if (reference) + if (reference) { reference->reference(); + } } void ref_pointer(T *p_ref) { - ERR_FAIL_COND(p_ref == nullptr); + ERR_FAIL_COND(!p_ref); - if (p_ref->init_ref()) + if (p_ref->init_ref()) { reference = p_ref; + } } public: - inline bool operator<(const Ref<T> &p_r) const { + _FORCE_INLINE_ bool operator==(const T *p_ptr) const { + return reference == p_ptr; + } + _FORCE_INLINE_ bool operator!=(const T *p_ptr) const { + return reference != p_ptr; + } + + _FORCE_INLINE_ bool operator<(const Ref<T> &p_r) const { return reference < p_r.reference; } - inline bool operator==(const Ref<T> &p_r) const { + _FORCE_INLINE_ bool operator==(const Ref<T> &p_r) const { return reference == p_r.reference; } - inline bool operator!=(const Ref<T> &p_r) const { + _FORCE_INLINE_ bool operator!=(const Ref<T> &p_r) const { return reference != p_r.reference; } - inline T *operator->() { + _FORCE_INLINE_ T *operator->() { return reference; } - inline T *operator*() { + _FORCE_INLINE_ T *operator*() { return reference; } - inline const T *operator->() const { + _FORCE_INLINE_ const T *operator->() const { return reference; } - inline const T *ptr() const { + _FORCE_INLINE_ const T *ptr() const { return reference; } - inline T *ptr() { + _FORCE_INLINE_ T *ptr() { return reference; } - inline const T *operator*() const { + _FORCE_INLINE_ const T *operator*() const { return reference; } operator Variant() const { - // Note: the C API handles the cases where the object is a Reference, - // so the Variant will be correctly constructed with a RefPtr engine-side - return Variant((Object *)reference); + return Variant(reference); } void operator=(const Ref &p_from) { @@ -112,8 +120,8 @@ public: template <class T_Other> void operator=(const Ref<T_Other> &p_from) { - Reference *refb = const_cast<Reference *>(static_cast<const Reference *>(p_from.ptr())); - if (refb == nullptr) { + RefCounted *refb = const_cast<RefCounted *>(static_cast<const RefCounted *>(p_from.ptr())); + if (!refb) { unref(); return; } @@ -124,79 +132,77 @@ public: } void operator=(const Variant &p_variant) { - Object *refb = T::___get_from_variant(p_variant); - if (refb == nullptr) { - unref(); - return; - } - Ref r; - r.reference = Object::cast_to<T>(refb); - ref(r); - r.reference = nullptr; - } + // FIXME + // Object *object = p_variant.get_validated_object(); - Ref(const Ref &p_from) { - reference = nullptr; - ref(p_from); + // if (object == reference) { + // return; + // } + + // unref(); + + // if (!object) { + // return; + // } + + // T *r = Object::cast_to<T>(object); + // if (r && r->reference()) { + // reference = r; + // } } template <class T_Other> - Ref(const Ref<T_Other> &p_from) { - reference = nullptr; - Reference *refb = const_cast<Reference *>(static_cast<const Reference *>(p_from.ptr())); - if (refb == nullptr) { - unref(); + void reference_ptr(T_Other *p_ptr) { + if (reference == p_ptr) { return; } - Ref r; - r.reference = Object::cast_to<T>(refb); - ref(r); - r.reference = nullptr; + unref(); + + T *r = Object::cast_to<T>(p_ptr); + if (r) { + ref_pointer(r); + } + } + + Ref(const Ref &p_from) { + ref(p_from); } Ref(T *p_reference) { - if (p_reference) + if (p_reference) { ref_pointer(p_reference); - else - reference = nullptr; + } } Ref(const Variant &p_variant) { - reference = nullptr; - Object *refb = T::___get_from_variant(p_variant); - if (refb == nullptr) { - unref(); - return; - } - Ref r; - r.reference = Object::cast_to<T>(refb); - ref(r); - r.reference = nullptr; + // FIXME + // Object *object = p_variant.get_validated_object(); + + // if (!object) { + // return; + // } + + // T *r = Object::cast_to<T>(object); + // if (r && r->reference()) { + // reference = r; + // } } inline bool is_valid() const { return reference != nullptr; } inline bool is_null() const { return reference == nullptr; } void unref() { - //TODO this should be moved to mutexes, since this engine does not really - // do a lot of referencing on references and stuff - // mutexes will avoid more crashes? - if (reference && reference->unreference()) { - //memdelete(reference); - reference->free(); + memdelete(reference); } reference = nullptr; } - void instance() { - //ref(memnew(T)); - ref(T::_new()); + void instantiate() { + ref(memnew(T)); } - Ref() { - reference = nullptr; - } + Ref() {} ~Ref() { unref(); @@ -204,7 +210,7 @@ public: // Used exclusively in the bindings to recreate the Ref Godot encapsulates in return values, // without adding to the refcount. - inline static Ref<T> __internal_constructor(Object *obj) { + inline static Ref<T> ___internal_constructor(Object *obj) { Ref<T> r; r.reference = (T *)obj; return r; @@ -213,4 +219,4 @@ public: } // namespace godot -#endif +#endif // ! GODOT_CPP_REF_HPP diff --git a/include/godot_cpp/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp new file mode 100644 index 0000000..770224a --- /dev/null +++ b/include/godot_cpp/classes/wrapped.hpp @@ -0,0 +1,167 @@ +/*************************************************************************/ +/* wrapped.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_CPP_WRAPPED_HPP +#define GODOT_CPP_WRAPPED_HPP + +#include <godot_cpp/core/memory.hpp> + +namespace godot { +namespace internal { +struct empty_constructor {}; +} // namespace internal + +typedef void GodotObject; + +// Base for all engine classes, to contain the pointer to the engine instance. +class Wrapped { + friend class GDExtensionBinding; + + // Private constructor, this should not be created directly by users. + Wrapped(GodotObject *p_owner) : + _owner(p_owner) {} + +protected: + Wrapped() = default; + Wrapped(internal::empty_constructor empty) {} + +public: + // Must be public but you should not touch this. + GodotObject *_owner = nullptr; +}; + +} // namespace godot + +#define GDCLASS(m_class, m_inherits) \ +private: \ + friend class ClassDB; \ + \ + using SelfType = m_class; \ + \ +protected: \ + static void (*_get_bind_methods())() { \ + return &m_class::_bind_methods; \ + } \ + \ + m_class(godot::GodotObject *owner) : m_inherits(godot::internal::empty_constructor()) { \ + _owner = owner; \ + } \ + \ + m_class(godot::internal::empty_constructor empty) : m_inherits(empty) {} \ + \ +public: \ + static void initialize_class() { \ + static bool initialized = false; \ + if (initialized) { \ + return; \ + } \ + m_inherits::initialize_class(); \ + if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \ + _bind_methods(); \ + } \ + initialized = true; \ + } \ + \ + static const char *get_class_static() { \ + return #m_class; \ + } \ + \ + static const char *get_parent_class_static() { \ + return #m_inherits; \ + } \ + \ + static GDExtensionClassInstancePtr create(void *data) { \ + return (GDExtensionClassInstancePtr)godot::Memory::alloc_static(sizeof(m_class)); \ + } \ + \ + static void free(void *data, GDExtensionClassInstancePtr ptr) { \ + godot::memdelete(reinterpret_cast<m_class *>(ptr)); \ + } \ + \ + static void set_object_instance(GDExtensionClassInstancePtr p_instance, GDNativeObjectPtr p_object_instance) { \ + memnew_placement((void *)p_instance, m_class((godot::GodotObject *)p_object_instance)); \ + } \ + \ + static void *___binding_create_callback(void *p_token, void *p_instance) { \ + return memnew(m_class((godot::GodotObject *)p_instance)); \ + } \ + static void ___binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \ + memdelete((m_class *)p_binding); \ + } \ + static GDNativeBool ___binding_reference_callback(void *p_token, void *p_instance, GDNativeBool p_reference) { \ + return true; \ + } \ + static constexpr GDNativeInstanceBindingCallbacks ___binding_callbacks = { \ + ___binding_create_callback, \ + ___binding_free_callback, \ + ___binding_reference_callback, \ + }; \ + \ +private: + +// Don't use this for your classes, use GDCLASS() instead. +#define GDNATIVE_CLASS(m_class, m_inherits) \ +protected: \ + static void (*_get_bind_methods())() { \ + return nullptr; \ + } \ + m_class(godot::internal::empty_constructor empty) : m_inherits(empty) {} \ + \ +public: \ + static void initialize_class() {} \ + \ + static const char *get_class_static() { \ + return #m_class; \ + } \ + \ + static const char *get_parent_class_static() { \ + return #m_inherits; \ + } \ + \ + static void *___binding_create_callback(void *p_token, void *p_instance) { \ + m_class *obj = memnew(m_class(godot::internal::empty_constructor())); \ + obj->_owner = (godot::GodotObject *)p_instance; \ + return obj; \ + } \ + static void ___binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \ + memdelete((m_class *)p_binding); \ + } \ + static GDNativeBool ___binding_reference_callback(void *p_token, void *p_instance, GDNativeBool p_reference) { \ + return true; \ + } \ + static constexpr GDNativeInstanceBindingCallbacks ___binding_callbacks = { \ + ___binding_create_callback, \ + ___binding_free_callback, \ + ___binding_reference_callback, \ + }; \ + \ +private: + +#endif // ! GODOT_CPP_WRAPPED_HPP diff --git a/include/godot_cpp/core/binder_common.hpp b/include/godot_cpp/core/binder_common.hpp new file mode 100644 index 0000000..c1827fa --- /dev/null +++ b/include/godot_cpp/core/binder_common.hpp @@ -0,0 +1,449 @@ +/*************************************************************************/ +/* binder_common.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_CPP_BINDER_COMMON_HPP +#define GODOT_CPP_BINDER_COMMON_HPP + +#include <godot/gdnative_interface.h> + +#include <godot_cpp/core/method_ptrcall.hpp> +#include <godot_cpp/core/type_info.hpp> + +#include <array> +#include <vector> + +namespace godot { + +#define VARIANT_ENUM_CAST(m_class, m_enum) \ + namespace godot { \ + MAKE_ENUM_TYPE_INFO(m_class, m_enum) \ + template <> \ + struct VariantCaster<m_class::m_enum> { \ + static _FORCE_INLINE_ m_class::m_enum cast(const Variant &p_variant) { \ + return (m_class::m_enum)p_variant.operator int64_t(); \ + } \ + }; \ + template <> \ + struct PtrToArg<m_class::m_enum> { \ + _FORCE_INLINE_ static m_class::m_enum convert(const void *p_ptr) { \ + return m_class::m_enum(*reinterpret_cast<const int64_t *>(p_ptr)); \ + } \ + typedef int64_t EncodeT; \ + _FORCE_INLINE_ static void encode(m_class::m_enum p_val, const void *p_ptr) { \ + *(int64_t *)p_ptr = p_val; \ + } \ + }; \ + } + +template <class T> +struct VariantCaster { + static _FORCE_INLINE_ T cast(const Variant &p_variant) { + return p_variant; + } +}; + +template <class T> +struct VariantCaster<T &> { + static _FORCE_INLINE_ T cast(const Variant &p_variant) { + return p_variant; + } +}; + +template <class T> +struct VariantCaster<const T &> { + static _FORCE_INLINE_ T cast(const Variant &p_variant) { + return p_variant; + } +}; + +template <typename T> +struct VariantObjectClassChecker { + static _FORCE_INLINE_ bool check(const Variant &p_variant) { + return true; + } +}; + +template <typename T> +class Ref; + +template <typename T> +struct VariantObjectClassChecker<const Ref<T> &> { + static _FORCE_INLINE_ bool check(const Variant &p_variant) { + Object *obj = p_variant; + const Ref<T> node = p_variant; + return node.ptr() || !obj; + } +}; + +template <class T> +struct VariantCasterAndValidate { + static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, GDNativeCallError &r_error) { + GDNativeVariantType argtype = GetTypeInfo<T>::VARIANT_TYPE; + if (!internal::interface->variant_can_convert_strict(static_cast<GDNativeVariantType>(p_args[p_arg_idx]->get_type()), argtype) || + !VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) { + r_error.error = GDNATIVE_CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = p_arg_idx; + r_error.expected = argtype; + } + + return VariantCaster<T>::cast(*p_args[p_arg_idx]); + } +}; + +template <class T> +struct VariantCasterAndValidate<T &> { + static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, GDNativeCallError &r_error) { + GDNativeVariantType argtype = GetTypeInfo<T>::VARIANT_TYPE; + if (!internal::interface->variant_can_convert_strict(static_cast<GDNativeVariantType>(p_args[p_arg_idx]->get_type()), argtype) || + !VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) { + r_error.error = GDNATIVE_CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = p_arg_idx; + r_error.expected = argtype; + } + + return VariantCaster<T>::cast(*p_args[p_arg_idx]); + } +}; + +template <class T> +struct VariantCasterAndValidate<const T &> { + static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, GDNativeCallError &r_error) { + GDNativeVariantType argtype = GetTypeInfo<T>::VARIANT_TYPE; + if (!internal::interface->variant_can_convert_strict(static_cast<GDNativeVariantType>(p_args[p_arg_idx]->get_type()), argtype) || + !VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) { + r_error.error = GDNATIVE_CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = p_arg_idx; + r_error.expected = argtype; + } + + return VariantCaster<T>::cast(*p_args[p_arg_idx]); + } +}; + +template <class T, class... P, size_t... Is> +void call_with_ptr_args_helper(T *p_instance, void (T::*p_method)(P...), const GDNativeTypePtr *p_args, IndexSequence<Is...>) { + (p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...); +} + +template <class T, class... P, size_t... Is> +void call_with_ptr_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const GDNativeTypePtr *p_args, IndexSequence<Is...>) { + (p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...); +} + +template <class T, class R, class... P, size_t... Is> +void call_with_ptr_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const GDNativeTypePtr *p_args, void *r_ret, IndexSequence<Is...>) { + PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret); +} + +template <class T, class R, class... P, size_t... Is> +void call_with_ptr_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const GDNativeTypePtr *p_args, void *r_ret, IndexSequence<Is...>) { + PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret); +} + +template <class T, class... P> +void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...), const GDNativeTypePtr *p_args) { + call_with_ptr_args_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class T, class... P> +void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...) const, const GDNativeTypePtr *p_args) { + call_with_ptr_argsc_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class T, class R, class... P> +void call_with_ptr_args(T *p_instance, R (T::*p_method)(P...), const GDNativeTypePtr *p_args, void *r_ret) { + call_with_ptr_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class T, class R, class... P> +void call_with_ptr_args(T *p_instance, R (T::*p_method)(P...) const, const GDNativeTypePtr *p_args, void *r_ret) { + call_with_ptr_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class T, class... P, size_t... Is> +void call_with_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, GDNativeCallError &r_error, IndexSequence<Is...>) { + r_error.error = GDNATIVE_CALL_OK; + +#ifdef DEBUG_METHODS_ENABLED + (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); +#else + (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...); +#endif + (void)(p_args); // Avoid warning. +} + +template <class T, class... P, size_t... Is> +void call_with_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, GDNativeCallError &r_error, IndexSequence<Is...>) { + r_error.error = GDNATIVE_CALL_OK; + +#ifdef DEBUG_METHODS_ENABLED + (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); +#else + (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...); +#endif + (void)(p_args); // Avoid warning. +} + +template <class T, class R, class... P, size_t... Is> +void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant &r_ret, GDNativeCallError &r_error, IndexSequence<Is...>) { + r_error.error = GDNATIVE_CALL_OK; + +#ifdef DEBUG_METHODS_ENABLED + r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); +#else + r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...); +#endif +} + +template <class T, class R, class... P, size_t... Is> +void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant &r_ret, GDNativeCallError &r_error, IndexSequence<Is...>) { + r_error.error = GDNATIVE_CALL_OK; + +#ifdef DEBUG_METHODS_ENABLED + r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); +#else + r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...); +#endif + (void)p_args; +} + +template <class T, class... P> +void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const GDNativeVariantPtr *p_args, int p_argcount, GDNativeCallError &r_error, const std::vector<Variant> &default_values) { +#ifdef DEBUG_ENABLED + if ((size_t)p_argcount > sizeof...(P)) { + r_error.error = GDNATIVE_CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount; + + int32_t dvs = default_values.size(); +#ifdef DEBUG_ENABLED + if (missing > dvs) { + r_error.error = GDNATIVE_CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + Variant args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; // Avoid zero sized array. + std::array<const Variant *, sizeof...(P)> argsp; + for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) { + if (i < p_argcount) { + args[i] = p_args[i]; + } else { + args[i] = default_values[i - p_argcount + (dvs - missing)]; + } + argsp[i] = &args[i]; + } + + call_with_variant_args_helper(p_instance, p_method, argsp.data(), r_error, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class T, class... P> +void call_with_variant_argsc_dv(T *p_instance, void (T::*p_method)(P...) const, const GDNativeVariantPtr *p_args, int p_argcount, GDNativeCallError &r_error, const std::vector<Variant> &default_values) { +#ifdef DEBUG_ENABLED + if ((size_t)p_argcount > sizeof...(P)) { + r_error.error = GDNATIVE_CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount; + + int32_t dvs = default_values.size(); +#ifdef DEBUG_ENABLED + if (missing > dvs) { + r_error.error = GDNATIVE_CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + Variant args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; // Avoid zero sized array. + std::array<const Variant *, sizeof...(P)> argsp; + for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) { + if (i < p_argcount) { + args[i] = p_args[i]; + } else { + args[i] = default_values[i - p_argcount + (dvs - missing)]; + } + argsp[i] = &args[i]; + } + + call_with_variant_argsc_helper(p_instance, p_method, argsp.data(), r_error, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class T, class R, class... P> +void call_with_variant_args_ret_dv(T *p_instance, R (T::*p_method)(P...), const GDNativeVariantPtr *p_args, int p_argcount, Variant &r_ret, GDNativeCallError &r_error, const std::vector<Variant> &default_values) { +#ifdef DEBUG_ENABLED + if ((size_t)p_argcount > sizeof...(P)) { + r_error.error = GDNATIVE_CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount; + + int32_t dvs = default_values.size(); +#ifdef DEBUG_ENABLED + if (missing > dvs) { + r_error.error = GDNATIVE_CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + Variant args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; // Avoid zero sized array. + std::array<const Variant *, sizeof...(P)> argsp; + for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) { + if (i < p_argcount) { + args[i] = p_args[i]; + } else { + args[i] = default_values[i - p_argcount + (dvs - missing)]; + } + argsp[i] = &args[i]; + } + + call_with_variant_args_ret_helper(p_instance, p_method, argsp.data(), r_ret, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + +template <class T, class R, class... P> +void call_with_variant_args_retc_dv(T *p_instance, R (T::*p_method)(P...) const, const GDNativeVariantPtr *p_args, int p_argcount, Variant &r_ret, GDNativeCallError &r_error, const std::vector<Variant> &default_values) { +#ifdef DEBUG_ENABLED + if ((size_t)p_argcount > sizeof...(P)) { + r_error.error = GDNATIVE_CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount; + + int32_t dvs = default_values.size(); +#ifdef DEBUG_ENABLED + if (missing > dvs) { + r_error.error = GDNATIVE_CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument = sizeof...(P); + return; + } +#endif + + Variant args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; // Avoid zero sized array. + std::array<const Variant *, sizeof...(P)> argsp; + for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) { + if (i < p_argcount) { + args[i] = p_args[i]; + } else { + args[i] = default_values[i - p_argcount + (dvs - missing)]; + } + argsp[i] = &args[i]; + } + + call_with_variant_args_retc_helper(p_instance, p_method, argsp.data(), r_ret, r_error, BuildIndexSequence<sizeof...(P)>{}); +} + +// GCC raises "parameter 'p_args' set but not used" when P = {}, +// it's not clever enough to treat other P values as making this branch valid. +#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-but-set-parameter" +#endif + +template <class Q> +void call_get_argument_type_helper(int p_arg, int &index, GDNativeVariantType &type) { + if (p_arg == index) { + type = GetTypeInfo<Q>::VARIANT_TYPE; + } + index++; +} + +template <class... P> +GDNativeVariantType call_get_argument_type(int p_arg) { + GDNativeVariantType type = GDNATIVE_VARIANT_TYPE_NIL; + int index = 0; + // I think rocket science is simpler than modern C++. + using expand_type = int[]; + expand_type a{ 0, (call_get_argument_type_helper<P>(p_arg, index, type), 0)... }; + (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning. + (void)index; // Suppress GCC warning. + return type; +} + +template <class Q> +void call_get_argument_type_info_helper(int p_arg, int &index, GDNativePropertyInfo &info) { + if (p_arg == index) { + info = GetTypeInfo<Q>::get_class_info(); + } + index++; +} + +template <class... P> +void call_get_argument_type_info(int p_arg, GDNativePropertyInfo &info) { + int index = 0; + // I think rocket science is simpler than modern C++. + using expand_type = int[]; + expand_type a{ 0, (call_get_argument_type_info_helper<P>(p_arg, index, info), 0)... }; + (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning. + (void)index; // Suppress GCC warning. +} + +template <class Q> +void call_get_argument_metadata_helper(int p_arg, int &index, GDNativeExtensionClassMethodArgumentMetadata &md) { + if (p_arg == index) { + md = GetTypeInfo<Q>::METADATA; + } + index++; +} + +template <class... P> +GDNativeExtensionClassMethodArgumentMetadata call_get_argument_metadata(int p_arg) { + GDNativeExtensionClassMethodArgumentMetadata md = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; + + int index = 0; + // I think rocket science is simpler than modern C++. + using expand_type = int[]; + expand_type a{ 0, (call_get_argument_metadata_helper<P>(p_arg, index, md), 0)... }; + (void)a; // Suppress (valid, but unavoidable) -Wunused-variable warning. + (void)index; + return md; +} + +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + +} // namespace godot + +#endif // ! GODOT_CPP_BINDER_COMMON_HPP diff --git a/include/core/NodePath.hpp b/include/godot_cpp/core/builtin_ptrcall.hpp index f76537b..961769f 100644 --- a/include/core/NodePath.hpp +++ b/include/godot_cpp/core/builtin_ptrcall.hpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* NodePath.hpp */ +/* builtin_ptrcall.hpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,57 +28,53 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef NODEPATH_H -#define NODEPATH_H +#ifndef GODOT_CPP_BUILTIN_PTRCALL_HPP +#define GODOT_CPP_BUILTIN_PTRCALL_HPP -#include "String.hpp" +#include <godot/gdnative_interface.h> -#include <gdnative/node_path.h> +#include <array> namespace godot { -class NodePath { - godot_node_path _node_path; - - friend class Variant; - inline explicit NodePath(godot_node_path node_path) { - _node_path = node_path; - } - -public: - NodePath(); - - NodePath(const NodePath &other); - - NodePath(const String &from); - - NodePath(const char *contents); - - String get_name(const int idx) const; - - int get_name_count() const; - - String get_subname(const int idx) const; - - int get_subname_count() const; - - bool is_absolute() const; - - bool is_empty() const; - - NodePath get_as_property_path() const; - - String get_concatenated_subnames() const; - - operator String() const; - - void operator=(const NodePath &other); - - bool operator==(const NodePath &other); - - ~NodePath(); -}; +namespace internal { + +template <class... Args> +void _call_builtin_constructor(const GDNativePtrConstructor constructor, GDNativeTypePtr base, Args... args) { + std::array<const GDNativeTypePtr, sizeof...(Args)> call_args = { { (const GDNativeTypePtr)args... } }; + constructor(base, call_args.data()); +} + +template <class T, class... Args> +T _call_builtin_method_ptr_ret(const GDNativePtrBuiltInMethod method, GDNativeTypePtr base, Args... args) { + T ret; + std::array<const GDNativeTypePtr, sizeof...(Args)> call_args = { { (const GDNativeTypePtr)args... } }; + method(base, call_args.data(), &ret, sizeof...(Args)); + return ret; +} + +template <class... Args> +void _call_builtin_method_ptr_no_ret(const GDNativePtrBuiltInMethod method, GDNativeTypePtr base, Args... args) { + std::array<const GDNativeTypePtr, sizeof...(Args)> call_args = { { (const GDNativeTypePtr)args... } }; + method(base, call_args.data(), nullptr, sizeof...(Args)); +} + +template <class T> +T _call_builtin_operator_ptr(const GDNativePtrOperatorEvaluator op, const GDNativeTypePtr left, const GDNativeTypePtr right) { + T ret; + op(left, right, &ret); + return ret; +} + +template <class T> +T _call_builtin_ptr_getter(const GDNativePtrGetter getter, const GDNativeTypePtr base) { + T ret; + getter(base, &ret); + return ret; +} + +} // namespace internal } // namespace godot -#endif // NODEPATH_H +#endif // ! GODOT_CPP_BUILTIN_PTRCALL_HPP diff --git a/include/godot_cpp/core/class_db.hpp b/include/godot_cpp/core/class_db.hpp new file mode 100644 index 0000000..ed16971 --- /dev/null +++ b/include/godot_cpp/core/class_db.hpp @@ -0,0 +1,187 @@ +/*************************************************************************/ +/* class_db.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef CLASS_DB_HPP +#define CLASS_DB_HPP + +#include <godot/gdnative_interface.h> + +#include <godot_cpp/core/defs.hpp> +#include <godot_cpp/core/error_macros.hpp> +#include <godot_cpp/core/method_bind.hpp> +#include <godot_cpp/core/object.hpp> + +#include <list> +#include <string> +#include <unordered_map> +#include <vector> + +namespace godot { + +struct MethodDefinition { + const char *name = nullptr; + std::list<std::string> args; + MethodDefinition() {} + MethodDefinition(const char *p_name) : + name(p_name) {} +}; + +MethodDefinition D_METHOD(const char *p_name); +MethodDefinition D_METHOD(const char *p_name, const char *p_arg1); +template <typename... Args> +MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, Args... args) { + MethodDefinition md = D_METHOD(p_name, args...); + md.args.push_front(p_arg1); + return md; +} + +class ClassDB { +public: + struct PropertySetGet { + int index; + const char *setter; + const char *getter; + MethodBind *_setptr; + MethodBind *_getptr; + Variant::Type type; + }; + + struct ClassInfo { + const char *name = nullptr; + const char *parent_name = nullptr; + GDNativeInitializationLevel level = GDNATIVE_INITIALIZATION_SCENE; + std::unordered_map<std::string, MethodBind *> method_map; + std::unordered_map<std::string, MethodInfo> signal_map; + std::list<MethodBind *> method_order; + GDExtensionClassInstancePtr (*constructor)(void *data); + std::unordered_map<std::string, GDNativeExtensionClassCallVirtual> virtual_methods; + void (*destructor)(void *data, GDExtensionClassInstancePtr ptr); + void (*object_instance)(GDExtensionClassInstancePtr p_instance, GDNativeObjectPtr p_object_instance); + std::unordered_map<std::string, PropertySetGet> property_setget; + std::list<PropertyInfo> property_list; + std::unordered_map<std::string, std::pair<std::string, GDNativeInt>> constant_map; // String in pair is enum name. + std::list<std::string> constant_order; + ClassInfo *parent_ptr = nullptr; + }; + +private: + static std::unordered_map<std::string, ClassInfo> classes; + + static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const void **p_defs, int p_defcount); + +public: + template <class T> + static void register_class(GDNativeInitializationLevel p_level = GDNATIVE_INITIALIZATION_SCENE); + + template <class N, class M> + static MethodBind *bind_method(N p_method_name, M p_method); + template <class M> + static MethodBind *bind_vararg_method(uint32_t p_flags, const char *p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const std::vector<Variant> &p_default_args = std::vector<Variant>{}, bool p_return_nil_is_variant = true); + static void add_property(const char *p_class, const PropertyInfo &p_pinfo, const char *p_setter, const char *p_getter, int p_index = -1); + static void add_signal(const char *p_class, const MethodInfo &p_signal); + static void bind_integer_constant(const char *p_class, const char *p_enum, const char *p_name, GDNativeInt p_constant); + static void bind_virtual_method(const char *p_class, const char *p_method, GDNativeExtensionClassCallVirtual p_call); + + static MethodBind *get_method(const char *p_class, const char *p_method); + + static GDNativeExtensionClassCallVirtual get_virtual_func(void *p_userdata, const char *p_name); + + static void initialize(GDNativeInitializationLevel p_level); + static void deinitialize(GDNativeInitializationLevel p_level); +}; + +#define BIND_CONSTANT(m_constant) \ + ClassDB::bind_integer_constant(get_class_static(), "", #m_constant, m_constant); + +#define BIND_ENUM_CONSTANT(m_constant) \ + ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant); + +#define BIND_VIRTUAL_METHOD(m_method) \ + { \ + auto ___call##m_method = [](GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr p_ret) -> void { \ + call_with_ptr_args(reinterpret_cast<SelfType *>(p_instance), &SelfType::m_method, p_args, p_ret); \ + }; \ + ClassDB::bind_virtual_method(get_class_static(), #m_method, ___call##m_method); \ + } + +template <class T> +void ClassDB::register_class(GDNativeInitializationLevel p_level) { + ClassInfo cl; + cl.name = T::get_class_static(); + cl.parent_name = T::get_parent_class_static(); + cl.level = p_level; + cl.constructor = T::create; + cl.destructor = T::free; + cl.object_instance = T::set_object_instance; + classes[cl.name] = cl; + if (classes.find(cl.parent_name) != classes.end()) { + cl.parent_ptr = &classes[cl.parent_name]; + } + T::initialize_class(); +} + +template <class N, class M> +MethodBind *ClassDB::bind_method(N p_method_name, M p_method) { + MethodBind *bind = create_method_bind(p_method); + + return bind_methodfi(0, bind, p_method_name, nullptr, 0); +} + +template <class M> +MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, const char *p_name, M p_method, const MethodInfo &p_info, const std::vector<Variant> &p_default_args, bool p_return_nil_is_variant) { + MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant); + ERR_FAIL_COND_V(!bind, nullptr); + + bind->set_name(p_name); + bind->set_default_arguments(p_default_args); + + const char *instance_type = bind->get_instance_class(); + + std::unordered_map<std::string, ClassInfo>::iterator type_it = classes.find(instance_type); + if (type_it == classes.end()) { + memdelete(bind); + ERR_FAIL_V_MSG(nullptr, "Class doesn't exist."); + } + + ClassInfo &type = type_it->second; + + if (type.method_map.find(p_name) != type.method_map.end()) { + memdelete(bind); + ERR_FAIL_V_MSG(nullptr, "Binding duplicate method."); + } + + type.method_map[p_name] = bind; + type.method_order.push_back(bind); + + return bind; +} +} // namespace godot + +#endif // ! CLASS_DB_HPP diff --git a/include/godot_cpp/core/defs.hpp b/include/godot_cpp/core/defs.hpp new file mode 100644 index 0000000..a103985 --- /dev/null +++ b/include/godot_cpp/core/defs.hpp @@ -0,0 +1,106 @@ +/*************************************************************************/ +/* defs.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef DEFS_H +#define DEFS_H + +#include <cstddef> +#include <cstdint> + +#ifdef __GNUC__ +#define GDN_EXPORT __attribute__((visibility("default"))) +#elif defined(_WIN32) +#define GDN_EXPORT __declspec(dllexport) +#else +#define GDN_EXPORT +#endif + +// Turn argument to string constant: +// https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html#Stringizing +#ifndef _STR +#define _STR(m_x) #m_x +#define _MKSTR(m_x) _STR(m_x) +#endif + +// Should always inline no matter what. +#ifndef _ALWAYS_INLINE_ +#if defined(__GNUC__) +#define _ALWAYS_INLINE_ __attribute__((always_inline)) inline +#elif defined(_MSC_VER) +#define _ALWAYS_INLINE_ __forceinline +#else +#define _ALWAYS_INLINE_ inline +#endif +#endif + +// Should always inline, except in debug builds because it makes debugging harder. +#ifndef _FORCE_INLINE_ +#ifdef DISABLE_FORCED_INLINE +#define _FORCE_INLINE_ inline +#else +#define _FORCE_INLINE_ _ALWAYS_INLINE_ +#endif +#endif + +// Windows badly defines a lot of stuff we'll never use. Undefine it. +#ifdef _WIN32 +#undef min // override standard definition +#undef max // override standard definition +#undef ERROR // override (really stupid) wingdi.h standard definition +#undef DELETE // override (another really stupid) winnt.h standard definition +#undef MessageBox // override winuser.h standard definition +#undef MIN // override standard definition +#undef MAX // override standard definition +#undef CLAMP // override standard definition +#undef Error +#undef OK +#undef CONNECT_DEFERRED // override from Windows SDK, clashes with Object enum +#endif + +#if defined(__GNUC__) +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#else +#define likely(x) x +#define unlikely(x) x +#endif + +// Home-made index sequence trick, so it can be used everywhere without the costly include of std::tuple. +// https://stackoverflow.com/questions/15014096/c-index-of-type-during-variadic-template-expansion +template <size_t... Is> +struct IndexSequence {}; + +template <size_t N, size_t... Is> +struct BuildIndexSequence : BuildIndexSequence<N - 1, N - 1, Is...> {}; + +template <size_t... Is> +struct BuildIndexSequence<0, Is...> : IndexSequence<Is...> {}; + +#endif // ! DEFS_H diff --git a/include/godot_cpp/core/engine_ptrcall.hpp b/include/godot_cpp/core/engine_ptrcall.hpp new file mode 100644 index 0000000..636a0c2 --- /dev/null +++ b/include/godot_cpp/core/engine_ptrcall.hpp @@ -0,0 +1,94 @@ +/*************************************************************************/ +/* engine_ptrcall.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_CPP_ENGINE_PTRCALL_HPP +#define GODOT_CPP_ENGINE_PTRCALL_HPP + +#include <godot/gdnative_interface.h> + +#include <godot_cpp/core/binder_common.hpp> +#include <godot_cpp/core/object.hpp> +#include <godot_cpp/godot.hpp> + +#include <array> + +namespace godot { + +namespace internal { + +template <class O, class... Args> +Object *_call_native_mb_ret_obj(const GDNativeMethodBindPtr mb, void *instance, const Args &...args) { + GodotObject *ret = nullptr; + std::array<const GDNativeTypePtr, sizeof...(Args)> mb_args = { { (const GDNativeTypePtr)args... } }; + internal::interface->object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret); + return (Object *)internal::interface->object_get_instance_binding(ret, internal::token, &O::___binding_callbacks); +} + +template <class R, class... Args> +R _call_native_mb_ret(const GDNativeMethodBindPtr mb, void *instance, const Args &...args) { + R ret; + std::array<const GDNativeTypePtr, sizeof...(Args)> mb_args = { { (const GDNativeTypePtr)args... } }; + internal::interface->object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret); + return ret; +} + +template <class... Args> +void _call_native_mb_no_ret(const GDNativeMethodBindPtr mb, void *instance, const Args &...args) { + std::array<const GDNativeTypePtr, sizeof...(Args)> mb_args = { { (const GDNativeTypePtr)args... } }; + internal::interface->object_method_bind_ptrcall(mb, instance, mb_args.data(), nullptr); +} + +template <class R, class... Args> +R _call_utility_ret(GDNativePtrUtilityFunction func, const Args &...args) { + R ret; + std::array<const GDNativeTypePtr, sizeof...(Args)> mb_args = { { (const GDNativeTypePtr)args... } }; + func(&ret, mb_args.data(), mb_args.size()); + return ret; +} + +template <class... Args> +Object *_call_utility_ret_obj(const GDNativePtrUtilityFunction func, void *instance, const Args &...args) { + GodotObject *ret = nullptr; + std::array<const GDNativeTypePtr, sizeof...(Args)> mb_args = { { (const GDNativeTypePtr)args... } }; + func(&ret, mb_args.data(), mb_args.size()); + return (Object *)internal::interface->object_get_instance_binding(ret, internal::token, &Object::___binding_callbacks); +} + +template <class... Args> +void _call_utility_no_ret(const GDNativePtrUtilityFunction func, const Args &...args) { + std::array<const GDNativeTypePtr, sizeof...(Args)> mb_args = { { (const GDNativeTypePtr)args... } }; + func(nullptr, mb_args.data(), mb_args.size()); +} + +} // namespace internal + +} // namespace godot + +#endif // ! GODOT_CPP_ENGINE_PTRCALL_HPP diff --git a/include/godot_cpp/core/error_macros.hpp b/include/godot_cpp/core/error_macros.hpp new file mode 100644 index 0000000..5a7f4e9 --- /dev/null +++ b/include/godot_cpp/core/error_macros.hpp @@ -0,0 +1,596 @@ +/*************************************************************************/ +/* error_macros.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_CPP_ERROR_MACROS_HPP +#define GODOT_CPP_ERROR_MACROS_HPP + +#include <godot_cpp/core/defs.hpp> + +#include <cstdint> + +namespace godot { + +void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_is_warning = false); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_is_warning = false); +void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool fatal = false); + +// Used to strip debug messages in release mode +#ifdef DEBUG_ENABLED +#define DEBUG_STR(m_msg) m_msg +#else +#define DEBUG_STR(m_msg) "" +#endif + +#ifdef __GNUC__ +//#define FUNCTION_STR __PRETTY_FUNCTION__ - too annoying +#define FUNCTION_STR __FUNCTION__ +#else +#define FUNCTION_STR __FUNCTION__ +#endif + +#ifdef _MSC_VER +/** + * Don't use GENERATE_TRAP() directly, should only be used be the macros below. + */ +#define GENERATE_TRAP() __debugbreak() +#else +/** + * Don't use GENERATE_TRAP() directly, should only be used be the macros below. + */ +#define GENERATE_TRAP() __builtin_trap() +#endif + +#define ERR_FAIL_INDEX(m_index, m_size) \ + if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \ + return; \ + } else \ + ((void)0) + +/** + * Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0. + * If not, prints `m_msg` and the current function returns. + */ +#define ERR_FAIL_INDEX_MSG(m_index, m_size, m_msg) \ + if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \ + return; \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_INDEX_V_MSG`. + * Only use this macro if there is no sensible error message. + * + * Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0. + * If not, the current function returns `m_retval`. + */ +#define ERR_FAIL_INDEX_V(m_index, m_size, m_retval) \ + if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \ + return m_retval; \ + } else \ + ((void)0) + +/** + * Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0. + * If not, prints `m_msg` and the current function returns `m_retval`. + */ +#define ERR_FAIL_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \ + if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \ + return m_retval; \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_INDEX_MSG` or `ERR_FAIL_INDEX_V_MSG`. + * Only use this macro if there is no sensible fallback i.e. the error is unrecoverable, and + * there is no sensible error message. + * + * Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0. + * If not, the application crashes. + */ +#define CRASH_BAD_INDEX(m_index, m_size) \ + if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), "", true); \ + GENERATE_TRAP(); \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_INDEX_MSG` or `ERR_FAIL_INDEX_V_MSG`. + * Only use this macro if there is no sensible fallback i.e. the error is unrecoverable. + * + * Ensures an integer index `m_index` is less than `m_size` and greater than or equal to 0. + * If not, prints `m_msg` and the application crashes. + */ +#define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg) \ + if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg), true); \ + GENERATE_TRAP(); \ + } else \ + ((void)0) + +// Unsigned integer index out of bounds error macros. + +/** + * Try using `ERR_FAIL_UNSIGNED_INDEX_MSG`. + * Only use this macro if there is no sensible error message. + * + * Ensures an unsigned integer index `m_index` is less than `m_size`. + * If not, the current function returns. + */ +#define ERR_FAIL_UNSIGNED_INDEX(m_index, m_size) \ + if (unlikely((m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \ + return; \ + } else \ + ((void)0) + +/** + * Ensures an unsigned integer index `m_index` is less than `m_size`. + * If not, prints `m_msg` and the current function returns. + */ +#define ERR_FAIL_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg) \ + if (unlikely((m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \ + return; \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_UNSIGNED_INDEX_V_MSG`. + * Only use this macro if there is no sensible error message. + * + * Ensures an unsigned integer index `m_index` is less than `m_size`. + * If not, the current function returns `m_retval`. + */ +#define ERR_FAIL_UNSIGNED_INDEX_V(m_index, m_size, m_retval) \ + if (unlikely((m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \ + return m_retval; \ + } else \ + ((void)0) + +/** + * Ensures an unsigned integer index `m_index` is less than `m_size`. + * If not, prints `m_msg` and the current function returns `m_retval`. + */ +#define ERR_FAIL_UNSIGNED_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \ + if (unlikely((m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \ + return m_retval; \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_UNSIGNED_INDEX_MSG` or `ERR_FAIL_UNSIGNED_INDEX_V_MSG`. + * Only use this macro if there is no sensible fallback i.e. the error is unrecoverable, and + * there is no sensible error message. + * + * Ensures an unsigned integer index `m_index` is less than `m_size`. + * If not, the application crashes. + */ +#define CRASH_BAD_UNSIGNED_INDEX(m_index, m_size) \ + if (unlikely((m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), "", true); \ + GENERATE_TRAP(); \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_UNSIGNED_INDEX_MSG` or `ERR_FAIL_UNSIGNED_INDEX_V_MSG`. + * Only use this macro if there is no sensible fallback i.e. the error is unrecoverable. + * + * Ensures an unsigned integer index `m_index` is less than `m_size`. + * If not, prints `m_msg` and the application crashes. + */ +#define CRASH_BAD_UNSIGNED_INDEX_MSG(m_index, m_size, m_msg) \ + if (unlikely((m_index) >= (m_size))) { \ + _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg), true); \ + GENERATE_TRAP(); \ + } else \ + ((void)0) + +// Null reference error macros. + +/** + * Try using `ERR_FAIL_NULL_MSG`. + * Only use this macro if there is no sensible error message. + * + * Ensures a pointer `m_param` is not null. + * If it is null, the current function returns. + */ +#define ERR_FAIL_NULL(m_param) \ + if (unlikely(m_param == nullptr)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null."); \ + return; \ + } else \ + ((void)0) + +/** + * Ensures a pointer `m_param` is not null. + * If it is null, prints `m_msg` and the current function returns. + */ +#define ERR_FAIL_NULL_MSG(m_param, m_msg) \ + if (unlikely(m_param == nullptr)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", DEBUG_STR(m_msg)); \ + return; \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_NULL_V_MSG`. + * Only use this macro if there is no sensible error message. + * + * Ensures a pointer `m_param` is not null. + * If it is null, the current function returns `m_retval`. + */ +#define ERR_FAIL_NULL_V(m_param, m_retval) \ + if (unlikely(m_param == nullptr)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null."); \ + return m_retval; \ + } else \ + ((void)0) + +/** + * Ensures a pointer `m_param` is not null. + * If it is null, prints `m_msg` and the current function returns `m_retval`. + */ +#define ERR_FAIL_NULL_V_MSG(m_param, m_retval, m_msg) \ + if (unlikely(m_param == nullptr)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", DEBUG_STR(m_msg)); \ + return m_retval; \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_COND_MSG`. + * Only use this macro if there is no sensible error message. + * If checking for null use ERR_FAIL_NULL_MSG instead. + * If checking index bounds use ERR_FAIL_INDEX_MSG instead. + * + * Ensures `m_cond` is false. + * If `m_cond` is true, the current function returns. + */ +#define ERR_FAIL_COND(m_cond) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true."); \ + return; \ + } else \ + ((void)0) + +/** + * Ensures `m_cond` is false. + * If `m_cond` is true, prints `m_msg` and the current function returns. + * + * If checking for null use ERR_FAIL_NULL_MSG instead. + * If checking index bounds use ERR_FAIL_INDEX_MSG instead. + */ +#define ERR_FAIL_COND_MSG(m_cond, m_msg) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true.", DEBUG_STR(m_msg)); \ + return; \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_COND_V_MSG`. + * Only use this macro if there is no sensible error message. + * If checking for null use ERR_FAIL_NULL_V_MSG instead. + * If checking index bounds use ERR_FAIL_INDEX_V_MSG instead. + * + * Ensures `m_cond` is false. + * If `m_cond` is true, the current function returns `m_retval`. + */ +#define ERR_FAIL_COND_V(m_cond, m_retval) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returning: " _STR(m_retval)); \ + return m_retval; \ + } else \ + ((void)0) + +/** + * Ensures `m_cond` is false. + * If `m_cond` is true, prints `m_msg` and the current function returns `m_retval`. + * + * If checking for null use ERR_FAIL_NULL_V_MSG instead. + * If checking index bounds use ERR_FAIL_INDEX_V_MSG instead. + */ +#define ERR_FAIL_COND_V_MSG(m_cond, m_retval, m_msg) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returning: " _STR(m_retval), DEBUG_STR(m_msg)); \ + return m_retval; \ + } else \ + ((void)0) + +/** + * Try using `ERR_CONTINUE_MSG`. + * Only use this macro if there is no sensible error message. + * + * Ensures `m_cond` is false. + * If `m_cond` is true, the current loop continues. + */ +#define ERR_CONTINUE(m_cond) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Continuing."); \ + continue; \ + } else \ + ((void)0) + +/** + * Ensures `m_cond` is false. + * If `m_cond` is true, prints `m_msg` and the current loop continues. + */ +#define ERR_CONTINUE_MSG(m_cond, m_msg) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Continuing.", DEBUG_STR(m_msg)); \ + continue; \ + } else \ + ((void)0) + +/** + * Try using `ERR_BREAK_MSG`. + * Only use this macro if there is no sensible error message. + * + * Ensures `m_cond` is false. + * If `m_cond` is true, the current loop breaks. + */ +#define ERR_BREAK(m_cond) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Breaking."); \ + break; \ + } else \ + ((void)0) + +/** + * Ensures `m_cond` is false. + * If `m_cond` is true, prints `m_msg` and the current loop breaks. + */ +#define ERR_BREAK_MSG(m_cond, m_msg) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Breaking.", DEBUG_STR(m_msg)); \ + break; \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_COND_MSG` or `ERR_FAIL_COND_V_MSG`. + * Only use this macro if there is no sensible fallback i.e. the error is unrecoverable, and + * there is no sensible error message. + * + * Ensures `m_cond` is false. + * If `m_cond` is true, the application crashes. + */ +#define CRASH_COND(m_cond) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true."); \ + GENERATE_TRAP(); \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_COND_MSG` or `ERR_FAIL_COND_V_MSG`. + * Only use this macro if there is no sensible fallback i.e. the error is unrecoverable. + * + * Ensures `m_cond` is false. + * If `m_cond` is true, prints `m_msg` and the application crashes. + */ +#define CRASH_COND_MSG(m_cond, m_msg) \ + if (unlikely(m_cond)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true.", DEBUG_STR(m_msg)); \ + GENERATE_TRAP(); \ + } else \ + ((void)0) + +// Generic error macros. + +/** + * Try using `ERR_FAIL_COND_MSG` or `ERR_FAIL_MSG`. + * Only use this macro if more complex error detection or recovery is required, and + * there is no sensible error message. + * + * The current function returns. + */ +#define ERR_FAIL() \ + if (true) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed."); \ + return; \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_COND_MSG`. + * Only use this macro if more complex error detection or recovery is required. + * + * Prints `m_msg`, and the current function returns. + */ +#define ERR_FAIL_MSG(m_msg) \ + if (true) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed.", DEBUG_STR(m_msg)); \ + return; \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_COND_V_MSG` or `ERR_FAIL_V_MSG`. + * Only use this macro if more complex error detection or recovery is required, and + * there is no sensible error message. + * + * The current function returns `m_retval`. + */ +#define ERR_FAIL_V(m_retval) \ + if (true) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed. Returning: " _STR(m_retval)); \ + return m_retval; \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_COND_V_MSG`. + * Only use this macro if more complex error detection or recovery is required. + * + * Prints `m_msg`, and the current function returns `m_retval`. + */ +#define ERR_FAIL_V_MSG(m_retval, m_msg) \ + if (true) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed. Returning: " _STR(m_retval), DEBUG_STR(m_msg)); \ + return m_retval; \ + } else \ + ((void)0) + +/** + * Try using `ERR_FAIL_COND_MSG`, `ERR_FAIL_COND_V_MSG`, `ERR_CONTINUE_MSG` or ERR_BREAK_MSG. + * Only use this macro at the start of a function that has not been implemented yet, or + * if more complex error detection or recovery is required. + * + * Prints `m_msg`. + */ +#define ERR_PRINT(m_msg) \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg) + +/** + * Prints `m_msg` once during the application lifetime. + */ +#define ERR_PRINT_ONCE(m_msg) \ + if (true) { \ + static bool first_print = true; \ + if (first_print) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg); \ + first_print = false; \ + } \ + } else \ + ((void)0) + +// Print warning message macros. + +/** + * Prints `m_msg`. + * + * If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead. + */ +#define WARN_PRINT(m_msg) \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, true) + +/** + * Prints `m_msg` once during the application lifetime. + * + * If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead. + */ +#define WARN_PRINT_ONCE(m_msg) \ + if (true) { \ + static bool first_print = true; \ + if (first_print) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, true); \ + first_print = false; \ + } \ + } else \ + ((void)0) + +// Print deprecated warning message macros. + +/** + * Warns that the current function is deprecated. + */ +#define WARN_DEPRECATED \ + if (true) { \ + static SafeFlag warning_shown; \ + if (!warning_shown.is_set()) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", true); \ + warning_shown.set(); \ + } \ + } else \ + ((void)0) + +/** + * Warns that the current function is deprecated and prints `m_msg`. + */ +#define WARN_DEPRECATED_MSG(m_msg) \ + if (true) { \ + static SafeFlag warning_shown; \ + if (!warning_shown.is_set()) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", DEBUG_STR(m_msg), true); \ + warning_shown.set(); \ + } \ + } else \ + ((void)0) + +/** + * Do not use. + * If the application should never reach this point use CRASH_NOW_MSG(m_msg) to explain why. + * + * The application crashes. + */ +#define CRASH_NOW() \ + if (true) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/function failed."); \ + GENERATE_TRAP(); \ + } else \ + ((void)0) + +/** + * Only use if the application should never reach this point. + * + * Prints `m_msg`, and then the application crashes. + */ +#define CRASH_NOW_MSG(m_msg) \ + if (true) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/function failed.", DEBUG_STR(m_msg)); \ + GENERATE_TRAP(); \ + } else \ + ((void)0) + +} // namespace godot + +/** + * Gives an error message when a method bind is invalid (likely the hash changed). + * Avoids crashing the application in this case. It's not free, so it's debug only. + */ +#ifdef DEBUG_ENABLED +#define CHECK_METHOD_BIND_RET(m_mb, m_ret) \ + if (unlikely(!m_mb)) { \ + ERR_PRINT_ONCE("Method bind was not found. Likely the engine method changed to an incompatible version."); \ + return m_ret; \ + } else \ + ((void)0) + +#define CHECK_METHOD_BIND(m_mb) \ + if (unlikely(!m_mb)) { \ + ERR_PRINT_ONCE("Method bind was not found. Likely the engine method changed to an incompatible version."); \ + return; \ + } else \ + ((void)0) +#else +#define CHECK_METHOD_BIND_RET(m_mb, m_ret) +#define CHECK_METHOD_BIND(m_mb) +#endif + +#endif // ! GODOT_CPP_ERROR_MACROS_HPP diff --git a/include/godot_cpp/core/memory.hpp b/include/godot_cpp/core/memory.hpp new file mode 100644 index 0000000..34d9079 --- /dev/null +++ b/include/godot_cpp/core/memory.hpp @@ -0,0 +1,115 @@ +/*************************************************************************/ +/* memory.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_CPP_MEMORY_HPP +#define GODOT_CPP_MEMORY_HPP + +#include <cstddef> +#include <cstdint> + +#include <godot_cpp/core/defs.hpp> +#include <godot_cpp/core/error_macros.hpp> + +void *operator new(size_t p_size, const char *p_description); ///< operator new that takes a description and uses MemoryStaticPool +void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description); ///< operator new that takes a description and uses a pointer to the preallocated memory + +_ALWAYS_INLINE_ void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description) { + return p_pointer; +} + +namespace godot { + +class Memory { + Memory(); + +public: + static void *alloc_static(size_t p_bytes); + static void *realloc_static(void *p_memory, size_t p_bytes); + static void free_static(void *p_ptr); +}; + +#define memnew(m_v) (new ("") m_v) +#define memnew_placement(m_placement, m_class) (new (m_placement, sizeof(m_class), "") m_class) + +template <class T> +void memdelete(T *p_class) { + if (!__has_trivial_destructor(T)) { + p_class->~T(); + } + + Memory::free_static(p_class); +} + +#define memnew_arr(m_class, m_count) memnew_arr_template<m_class>(m_count) + +template <typename T> +T *memnew_arr_template(size_t p_elements, const char *p_descr = "") { + if (p_elements == 0) { + return nullptr; + } + /** overloading operator new[] cannot be done , because it may not return the real allocated address (it may pad the 'element count' before the actual array). Because of that, it must be done by hand. This is the + same strategy used by std::vector, and the Vector class, so it should be safe.*/ + + size_t len = sizeof(T) * p_elements; + uint64_t *mem = (uint64_t *)Memory::alloc_static(len); + T *failptr = nullptr; // Get rid of a warning. + ERR_FAIL_COND_V(!mem, failptr); + *(mem - 1) = p_elements; + + if (!__has_trivial_constructor(T)) { + T *elems = (T *)mem; + + /* call operator new */ + for (size_t i = 0; i < p_elements; i++) { + new (&elems[i], sizeof(T), p_descr) T; + } + } + + return (T *)mem; +} + +template <typename T> +void memdelete_arr(T *p_class) { + uint64_t *ptr = (uint64_t *)p_class; + + if (!__has_trivial_destructor(T)) { + uint64_t elem_count = *(ptr - 1); + + for (uint64_t i = 0; i < elem_count; i++) { + p_class[i].~T(); + } + } + + Memory::free_static(ptr); +} + +} // namespace godot + +#endif // ! GODOT_CPP_MEMORY_HPP diff --git a/include/godot_cpp/core/method_bind.hpp b/include/godot_cpp/core/method_bind.hpp new file mode 100644 index 0000000..6caaf4d --- /dev/null +++ b/include/godot_cpp/core/method_bind.hpp @@ -0,0 +1,539 @@ +/*************************************************************************/ +/* method_bind.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_CPP_METHOD_BIND_HPP +#define GODOT_CPP_METHOD_BIND_HPP + +#include <godot_cpp/core/binder_common.hpp> +#include <godot_cpp/core/type_info.hpp> + +#include <godot_cpp/core/memory.hpp> + +#include <godot/gdnative_interface.h> + +#include <godot_cpp/classes/global_constants.hpp> + +#include <string> +#include <vector> + +#include <iostream> + +namespace godot { + +class MethodBind { + const char *name = nullptr; + const char *instance_class = nullptr; + int argument_count = 0; + uint32_t hint_flags = METHOD_FLAGS_DEFAULT; + + bool _is_const = false; + bool _has_return = false; + + std::vector<std::string> argument_names; + GDNativeVariantType *argument_types = nullptr; + std::vector<Variant> default_arguments; + +protected: + virtual GDNativeVariantType gen_argument_type(int p_arg) const = 0; + virtual GDNativePropertyInfo gen_argument_type_info(int p_arg) const = 0; + void generate_argument_types(int p_count); + void set_const(bool p_const); + void set_return(bool p_return); + void set_argument_count(int p_count); + +public: + const char *get_name() const; + void set_name(const char *p_name); + _FORCE_INLINE_ int get_default_argument_count() const { return default_arguments.size(); } + _FORCE_INLINE_ const std::vector<Variant> &get_default_arguments() const { return default_arguments; } + _FORCE_INLINE_ Variant has_default_argument(int p_arg) const { + int idx = p_arg - (argument_count - default_arguments.size()); + + if (idx < 0 || idx >= default_arguments.size()) { + return false; + } else { + return true; + } + } + _FORCE_INLINE_ Variant get_default_argument(int p_arg) const { + int idx = p_arg - (argument_count - default_arguments.size()); + + if (idx < 0 || idx >= default_arguments.size()) { + return Variant(); + } else { + return default_arguments[idx]; + } + } + _FORCE_INLINE_ const char *get_instance_class() const { return instance_class; } + _FORCE_INLINE_ void set_instance_class(const char *p_class) { instance_class = p_class; } + + _FORCE_INLINE_ int get_argument_count() const { return argument_count; }; + _FORCE_INLINE_ bool is_const() const { return _is_const; } + _FORCE_INLINE_ bool has_return() const { return _has_return; } + _FORCE_INLINE_ uint32_t get_hint_flags() const { return hint_flags; } + _FORCE_INLINE_ void set_hint_flags(uint32_t p_hint_flags) { hint_flags = p_hint_flags; } + void set_argument_names(const std::vector<std::string> &p_names); + std::vector<std::string> get_argument_names() const; + void set_default_arguments(const std::vector<Variant> &p_default_arguments) { default_arguments = p_default_arguments; } + + _FORCE_INLINE_ GDNativeVariantType get_argument_type(int p_argument) const { + ERR_FAIL_COND_V(p_argument < -1 || p_argument > argument_count, GDNATIVE_VARIANT_TYPE_NIL); + return argument_types[p_argument + 1]; + } + + GDNativePropertyInfo get_argument_info(int p_argument) const; + virtual GDNativeExtensionClassMethodArgumentMetadata get_argument_metadata(int p_argument) const = 0; + + virtual Variant call(GDExtensionClassInstancePtr p_instance, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeCallError &r_error) const = 0; + virtual void ptrcall(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_return) const = 0; + + // Extension info. + static GDNativeVariantType bind_get_argument_type(void *p_method_userdata, int32_t p_argument); + static void bind_get_argument_info(void *p_method_userdata, int32_t p_argument, GDNativePropertyInfo *r_info); + static GDNativeExtensionClassMethodArgumentMetadata bind_get_argument_metadata(void *p_method_userdata, int32_t p_argument); + + static void bind_call(void *p_method_userdata, GDExtensionClassInstancePtr p_instance, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeVariantPtr r_return, GDNativeCallError *r_error); + static void bind_ptrcall(void *p_method_userdata, GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_return); + + virtual ~MethodBind(); +}; + +template <class T> +class MethodBindVarArg : public MethodBind { +public: + typedef Variant (T::*NativeCall)(const Variant **, GDNativeInt, GDNativeCallError &); + +protected: + NativeCall call_method = nullptr; + MethodInfo arguments; + +public: + virtual GDNativePropertyInfo gen_argument_type_info(int p_arg) const { + if (p_arg < 0) { + return arguments.return_val; + } else if (p_arg < arguments.arguments.size()) { + return arguments.arguments[p_arg]; + } else { + return PropertyInfo(Variant::NIL, "vararg", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); + } + } + + virtual GDNativeVariantType gen_argument_type(int p_arg) const { + return static_cast<GDNativeVariantType>(gen_argument_type_info(p_arg).type); + } + + virtual GDNativeExtensionClassMethodArgumentMetadata get_argument_metadata(int) const { + return GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; + } + + virtual Variant call(GDExtensionClassInstancePtr p_instance, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeCallError &r_error) const { + T *instance = static_cast<T *>(p_instance); + return (instance->*call_method)((const Variant **)p_args, p_argument_count, r_error); + } + + void set_method_info(const MethodInfo &p_info, bool p_return_nil_is_variant) { + set_argument_count(p_info.arguments.size()); + if (p_info.arguments.size()) { + std::vector<std::string> names; + names.reserve(p_info.arguments.size()); + for (int i = 0; i < p_info.arguments.size(); i++) { + names.push_back(p_info.arguments[i].name); + } + + set_argument_names(names); + } + + arguments = p_info; + + if (p_return_nil_is_variant) { + arguments.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + } + generate_argument_types(p_info.arguments.size()); + } + + virtual void ptrcall(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_return) const { + ERR_FAIL(); // Can't call. + } + + void set_method(NativeCall p_method) { call_method = p_method; } + virtual bool is_const() const { return false; } + + virtual bool is_vararg() const { return true; } + + MethodBindVarArg() { + set_return(true); + } +}; + +template <class T> +MethodBind *create_vararg_method_bind(Variant (T::*p_method)(const Variant **, GDNativeInt, GDNativeCallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) { + MethodBindVarArg<T> *a = memnew((MethodBindVarArg<T>)); + a->set_method(p_method); + a->set_method_info(p_info, p_return_nil_is_variant); + a->set_instance_class(T::get_class_static()); + return a; +} + +#ifndef TYPED_METHOD_BIND +class ___UnexistingClass; +#define MB_T ___UnexistingClass +#else +#define MB_T T +#endif + +// No return, not const. + +#ifdef TYPED_METHOD_BIND +template <class T, class... P> +#else +template <class... P> +#endif // TYPED_METHOD_BIND +class MethodBindT : public MethodBind { + void (MB_T::*method)(P...); + +protected: +// GCC raises warnings in the case P = {} as the comparison is always false... +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlogical-op" +#endif + virtual GDNativeVariantType gen_argument_type(int p_arg) const { + if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { + return call_get_argument_type<P...>(p_arg); + } else { + return GDNATIVE_VARIANT_TYPE_NIL; + } + } + + virtual GDNativePropertyInfo gen_argument_type_info(int p_arg) const { + GDNativePropertyInfo pi; + if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { + call_get_argument_type_info<P...>(p_arg, pi); + } else { + pi = PropertyInfo(); + } + return pi; + } +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + +public: + virtual GDNativeExtensionClassMethodArgumentMetadata get_argument_metadata(int p_argument) const { + return call_get_argument_metadata<P...>(p_argument); + } + + virtual Variant call(GDExtensionClassInstancePtr p_instance, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeCallError &r_error) const { +#ifdef TYPED_METHOD_BIND + call_with_variant_args_dv(static_cast<T *>(p_instance), method, p_args, p_argument_count, r_error, get_default_arguments()); +#else + call_with_variant_args_dv(reinterpret_cast<MB_T *>(p_instance), method, p_args, p_argument_count, r_error, get_default_arguments()); +#endif + return Variant(); + } + virtual void ptrcall(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret) const { +#ifdef TYPED_METHOD_BIND + call_with_ptr_args<T, P...>(static_cast<T *>(p_instance), method, p_args); +#else + call_with_ptr_args<MB_T, P...>(reinterpret_cast<MB_T *>(p_instance), method, p_args); +#endif // TYPED_METHOD_BIND + } + + MethodBindT(void (MB_T::*p_method)(P...)) { + method = p_method; +#ifdef DEBUG_METHODS_ENABLED + generate_argument_types(sizeof...(P)); +#endif // DEBUG_METHODS_ENABLED + set_argument_count(sizeof...(P)); + } +}; + +template <class T, class... P> +MethodBind *create_method_bind(void (T::*p_method)(P...)) { +#ifdef TYPED_METHOD_BIND + MethodBind *a = memnew((MethodBindT<T, P...>)(p_method)); +#else + MethodBind *a = memnew((MethodBindT<P...>)(reinterpret_cast<void (MB_T::*)(P...)>(p_method))); +#endif // TYPED_METHOD_BIND + a->set_instance_class(T::get_class_static()); + return a; +} + +// No return, const. + +#ifdef TYPED_METHOD_BIND +template <class T, class... P> +#else +template <class... P> +#endif // TYPED_METHOD_BIND +class MethodBindTC : public MethodBind { + void (MB_T::*method)(P...) const; + +protected: +// GCC raises warnings in the case P = {} as the comparison is always false... +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlogical-op" +#endif + virtual GDNativeVariantType gen_argument_type(int p_arg) const { + if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { + return call_get_argument_type<P...>(p_arg); + } else { + return GDNATIVE_VARIANT_TYPE_NIL; + } + } + + virtual GDNativePropertyInfo gen_argument_type_info(int p_arg) const { + GDNativePropertyInfo pi; + if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { + call_get_argument_type_info<P...>(p_arg, pi); + } else { + pi = PropertyInfo(); + } + return pi; + } +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + +public: + virtual GDNativeExtensionClassMethodArgumentMetadata get_argument_metadata(int p_argument) const { + return call_get_argument_metadata<P...>(p_argument); + } + + virtual Variant call(GDExtensionClassInstancePtr p_instance, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeCallError &r_error) const { +#ifdef TYPED_METHOD_BIND + call_with_variant_argsc_dv(static_cast<T *>(p_instance), method, p_args, p_argument_count, r_error, get_default_arguments()); +#else + call_with_variant_argsc_dv(reinterpret_cast<MB_T *>(p_instance), method, p_args, p_argument_count, r_error, get_default_arguments()); +#endif + return Variant(); + } + virtual void ptrcall(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret) const { +#ifdef TYPED_METHOD_BIND + call_with_ptr_args<T, P...>(static_cast<T *>(p_instance), method, p_args); +#else + call_with_ptr_args<MB_T, P...>(reinterpret_cast<MB_T *>(p_instance), method, p_args); +#endif // TYPED_METHOD_BIND + } + + MethodBindTC(void (MB_T::*p_method)(P...) const) { + method = p_method; +#ifdef DEBUG_METHODS_ENABLED + generate_argument_types(sizeof...(P)); +#endif // DEBUG_METHODS_ENABLED + set_argument_count(sizeof...(P)); + } +}; + +template <class T, class... P> +MethodBind *create_method_bind(void (T::*p_method)(P...) const) { +#ifdef TYPED_METHOD_BIND + MethodBind *a = memnew((MethodBindTC<T, P...>)(p_method)); +#else + MethodBind *a = memnew((MethodBindTC<P...>)(reinterpret_cast<void (MB_T::*)(P...) const>(p_method))); +#endif // TYPED_METHOD_BIND + a->set_instance_class(T::get_class_static()); + return a; +} + +// Return, not const. + +#ifdef TYPED_METHOD_BIND +template <class T, class R, class... P> +#else +template <class R, class... P> +#endif // TYPED_METHOD_BIND +class MethodBindTR : public MethodBind { + R(MB_T::*method) + (P...); + +protected: +// GCC raises warnings in the case P = {} as the comparison is always false... +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlogical-op" +#endif + virtual GDNativeVariantType gen_argument_type(int p_arg) const { + if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { + return call_get_argument_type<P...>(p_arg); + } else { + return GetTypeInfo<R>::VARIANT_TYPE; + } + } + + virtual GDNativePropertyInfo gen_argument_type_info(int p_arg) const { + if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { + GDNativePropertyInfo pi; + call_get_argument_type_info<P...>(p_arg, pi); + return pi; + } else { + return GetTypeInfo<R>::get_class_info(); + } + } +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + +public: + virtual GDNativeExtensionClassMethodArgumentMetadata get_argument_metadata(int p_argument) const { + if (p_argument >= 0) { + return call_get_argument_metadata<P...>(p_argument); + } else { + return GetTypeInfo<R>::METADATA; + } + } + + virtual Variant call(GDExtensionClassInstancePtr p_instance, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeCallError &r_error) const { + Variant ret; +#ifdef TYPED_METHOD_BIND + call_with_variant_args_ret_dv(static_cast<T *>(p_instance), method, p_args, p_argument_count, ret, r_error, get_default_arguments()); +#else + call_with_variant_args_ret_dv((MB_T *)p_instance, method, p_args, p_argument_count, ret, r_error, get_default_arguments()); +#endif + return ret; + } + virtual void ptrcall(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret) const { +#ifdef TYPED_METHOD_BIND + call_with_ptr_args<T, R, P...>(static_cast<T *>(p_instance), method, p_args, r_ret); +#else + call_with_ptr_args<MB_T, R, P...>(reinterpret_cast<MB_T *>(p_instance), method, p_args, r_ret); +#endif // TYPED_METHOD_BIND + } + + MethodBindTR(R (MB_T::*p_method)(P...)) { + method = p_method; +#ifdef DEBUG_METHODS_ENABLED + generate_argument_types(sizeof...(P)); +#endif // DEBUG_METHODS_ENABLED + set_argument_count(sizeof...(P)); + set_return(true); + } +}; + +template <class T, class R, class... P> +MethodBind *create_method_bind(R (T::*p_method)(P...)) { +#ifdef TYPED_METHOD_BIND + MethodBind *a = memnew((MethodBindTR<T, R, P...>)(p_method)); +#else + MethodBind *a = memnew((MethodBindTR<R, P...>)(reinterpret_cast<R (MB_T::*)(P...)>(p_method))); +#endif // TYPED_METHOD_BIND + a->set_instance_class(T::get_class_static()); + return a; +} + +// Return, const. + +#ifdef TYPED_METHOD_BIND +template <class T, class R, class... P> +#else +template <class R, class... P> +#endif // TYPED_METHOD_BIND +class MethodBindTRC : public MethodBind { + R(MB_T::*method) + (P...) const; + +protected: +// GCC raises warnings in the case P = {} as the comparison is always false... +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlogical-op" +#endif + virtual GDNativeVariantType gen_argument_type(int p_arg) const { + if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { + return call_get_argument_type<P...>(p_arg); + } else { + return GetTypeInfo<R>::VARIANT_TYPE; + } + } + + virtual GDNativePropertyInfo gen_argument_type_info(int p_arg) const { + if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { + GDNativePropertyInfo pi; + call_get_argument_type_info<P...>(p_arg, pi); + return pi; + } else { + return GetTypeInfo<R>::get_class_info(); + } + } +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + +public: + virtual GDNativeExtensionClassMethodArgumentMetadata get_argument_metadata(int p_argument) const { + if (p_argument >= 0) { + return call_get_argument_metadata<P...>(p_argument); + } else { + return GetTypeInfo<R>::METADATA; + } + } + + virtual Variant call(GDExtensionClassInstancePtr p_instance, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeCallError &r_error) const { + Variant ret; +#ifdef TYPED_METHOD_BIND + call_with_variant_args_retc_dv(static_cast<T *>(p_instance), method, p_args, p_argument_count, ret, r_error, get_default_arguments()); +#else + call_with_variant_args_retc_dv((MB_T *)p_instance, method, p_args, p_argument_count, ret, r_error, get_default_arguments()); +#endif + return ret; + } + virtual void ptrcall(GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret) const { +#ifdef TYPED_METHOD_BIND + call_with_ptr_args<T, R, P...>(static_cast<T *>(p_instance), method, p_args, r_ret); +#else + call_with_ptr_args<MB_T, R, P...>(reinterpret_cast<MB_T *>(p_instance), method, p_args, r_ret); +#endif // TYPED_METHOD_BIND + } + + MethodBindTRC(R (MB_T::*p_method)(P...) const) { + method = p_method; +#ifdef DEBUG_METHODS_ENABLED + generate_argument_types(sizeof...(P)); +#endif // DEBUG_METHODS_ENABLED + set_argument_count(sizeof...(P)); + set_return(true); + } +}; + +template <class T, class R, class... P> +MethodBind *create_method_bind(R (T::*p_method)(P...) const) { +#ifdef TYPED_METHOD_BIND + MethodBind *a = memnew((MethodBindTRC<T, R, P...>)(p_method)); +#else + MethodBind *a = memnew((MethodBindTRC<R, P...>)(reinterpret_cast<R (MB_T::*)(P...) const>(p_method))); +#endif // TYPED_METHOD_BIND + a->set_instance_class(T::get_class_static()); + return a; +} + +} // namespace godot + +#endif // ! GODOT_CPP_METHOD_BIND_HPP diff --git a/include/godot_cpp/core/method_ptrcall.hpp b/include/godot_cpp/core/method_ptrcall.hpp new file mode 100644 index 0000000..b0b9874 --- /dev/null +++ b/include/godot_cpp/core/method_ptrcall.hpp @@ -0,0 +1,189 @@ +/*************************************************************************/ +/* method_ptrcall.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_CPP_METHOD_PTRCALL_HPP +#define GODOT_CPP_METHOD_PTRCALL_HPP + +#include <godot_cpp/core/defs.hpp> + +#include <godot_cpp/godot.hpp> +#include <godot_cpp/variant/variant.hpp> + +namespace godot { + +template <class T> +struct PtrToArg {}; + +#define MAKE_PTRARG(m_type) \ + template <> \ + struct PtrToArg<m_type> { \ + _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ + return *reinterpret_cast<const m_type *>(p_ptr); \ + } \ + typedef m_type EncodeT; \ + _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ + *((m_type *)p_ptr) = p_val; \ + } \ + }; \ + template <> \ + struct PtrToArg<const m_type &> { \ + _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ + return *reinterpret_cast<const m_type *>(p_ptr); \ + } \ + typedef m_type EncodeT; \ + _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ + *((m_type *)p_ptr) = p_val; \ + } \ + } + +#define MAKE_PTRARGCONV(m_type, m_conv) \ + template <> \ + struct PtrToArg<m_type> { \ + _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ + return static_cast<m_type>(*reinterpret_cast<const m_conv *>(p_ptr)); \ + } \ + typedef m_conv EncodeT; \ + _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ + *((m_conv *)p_ptr) = static_cast<m_conv>(p_val); \ + } \ + _FORCE_INLINE_ static m_conv encode_arg(m_type p_val) { \ + return static_cast<m_conv>(p_val); \ + } \ + }; \ + template <> \ + struct PtrToArg<const m_type &> { \ + _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ + return static_cast<m_type>(*reinterpret_cast<const m_conv *>(p_ptr)); \ + } \ + typedef m_conv EncodeT; \ + _FORCE_INLINE_ static void encode(m_type p_val, void *p_ptr) { \ + *((m_conv *)p_ptr) = static_cast<m_conv>(p_val); \ + } \ + _FORCE_INLINE_ static m_conv encode_arg(m_type p_val) { \ + return static_cast<m_conv>(p_val); \ + } \ + } + +#define MAKE_PTRARG_BY_REFERENCE(m_type) \ + template <> \ + struct PtrToArg<m_type> { \ + _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ + return *reinterpret_cast<const m_type *>(p_ptr); \ + } \ + typedef m_type EncodeT; \ + _FORCE_INLINE_ static void encode(const m_type &p_val, void *p_ptr) { \ + *((m_type *)p_ptr) = p_val; \ + } \ + }; \ + template <> \ + struct PtrToArg<const m_type &> { \ + _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \ + return *reinterpret_cast<const m_type *>(p_ptr); \ + } \ + typedef m_type EncodeT; \ + _FORCE_INLINE_ static void encode(const m_type &p_val, void *p_ptr) { \ + *((m_type *)p_ptr) = p_val; \ + } \ + } + +MAKE_PTRARGCONV(bool, uint8_t); +// Integer types. +MAKE_PTRARGCONV(uint8_t, int64_t); +MAKE_PTRARGCONV(int8_t, int64_t); +MAKE_PTRARGCONV(uint16_t, int64_t); +MAKE_PTRARGCONV(int16_t, int64_t); +MAKE_PTRARGCONV(uint32_t, int64_t); +MAKE_PTRARGCONV(int32_t, int64_t); +MAKE_PTRARG(int64_t); +MAKE_PTRARG(uint64_t); +// Float types +MAKE_PTRARGCONV(float, double); +MAKE_PTRARG(double); + +MAKE_PTRARG(String); +MAKE_PTRARG(Vector2); +MAKE_PTRARG(Vector2i); +MAKE_PTRARG(Rect2); +MAKE_PTRARG(Rect2i); +MAKE_PTRARG_BY_REFERENCE(Vector3); +MAKE_PTRARG_BY_REFERENCE(Vector3i); +MAKE_PTRARG(Transform2D); +MAKE_PTRARG_BY_REFERENCE(Plane); +MAKE_PTRARG(Quaternion); +MAKE_PTRARG_BY_REFERENCE(AABB); +MAKE_PTRARG_BY_REFERENCE(Basis); +MAKE_PTRARG_BY_REFERENCE(Transform3D); +MAKE_PTRARG_BY_REFERENCE(Color); +MAKE_PTRARG(StringName); +MAKE_PTRARG(NodePath); +MAKE_PTRARG(RID); +// Object doesn't need this. +MAKE_PTRARG(Callable); +MAKE_PTRARG(Signal); +MAKE_PTRARG(Dictionary); +MAKE_PTRARG(Array); +MAKE_PTRARG(PackedByteArray); +MAKE_PTRARG(PackedInt32Array); +MAKE_PTRARG(PackedInt64Array); +MAKE_PTRARG(PackedFloat32Array); +MAKE_PTRARG(PackedFloat64Array); +MAKE_PTRARG(PackedStringArray); +MAKE_PTRARG(PackedVector2Array); +MAKE_PTRARG(PackedVector3Array); +MAKE_PTRARG(PackedColorArray); +MAKE_PTRARG_BY_REFERENCE(Variant); + +// This is for Object. + +template <class T> +struct PtrToArg<T *> { + _FORCE_INLINE_ static T *convert(const void *p_ptr) { + return reinterpret_cast<T *>(godot::internal::interface->object_get_instance_binding(p_ptr, godot::internal::token, T::___binding_callbacks)); + } + typedef Object *EncodeT; + _FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) { + p_ptr = p_var->_owner; + } +}; + +template <class T> +struct PtrToArg<const T *> { + _FORCE_INLINE_ static const T *convert(const void *p_ptr) { + return reinterpret_cast<const T *>(godot::internal::interface->object_get_instance_binding(p_ptr, godot::internal::token, T::___binding_callbacks)); + } + typedef const Object *EncodeT; + _FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) { + p_ptr = p_var->_owner; + } +}; + +} // namespace godot + +#endif // ! GODOT_CPP_METHOD_PTRCALL_HPP diff --git a/include/godot_cpp/core/object.hpp b/include/godot_cpp/core/object.hpp new file mode 100644 index 0000000..61cedcb --- /dev/null +++ b/include/godot_cpp/core/object.hpp @@ -0,0 +1,146 @@ +/*************************************************************************/ +/* object.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_OBJECT_HPP +#define GODOT_OBJECT_HPP + +#include <godot_cpp/core/defs.hpp> +#include <godot_cpp/variant/variant.hpp> + +#include <godot_cpp/classes/object.hpp> + +#include <godot_cpp/godot.hpp> + +#include <godot/gdnative_interface.h> + +#include <vector> + +#define ADD_SIGNAL(m_signal) ClassDB::add_signal(get_class_static(), m_signal) +#define ADD_PROPERTY(m_property, m_setter, m_getter) ClassDB::add_property(get_class_static(), m_property, m_setter, m_getter) + +namespace godot { + +struct PropertyInfo { + Variant::Type type = Variant::NIL; + const char *name = nullptr; + const char *class_name = nullptr; + uint32_t hint = 0; + const char *hint_string = nullptr; + uint32_t usage = 7; + + operator GDNativePropertyInfo() const { + GDNativePropertyInfo info; + info.type = type; + info.name = name; + info.hint = hint; + info.hint_string = hint_string; + info.class_name = class_name; + info.usage = usage; + return info; + } + + PropertyInfo() = default; + + PropertyInfo(Variant::Type p_type, const char *p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const char *p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const char *p_class_name = "") : + type(p_type), + name(p_name), + hint(p_hint), + hint_string(p_hint_string), + usage(p_usage) { + if (hint == PROPERTY_HINT_RESOURCE_TYPE) { + class_name = hint_string; + } else { + class_name = p_class_name; + } + } + + PropertyInfo(GDNativeVariantType p_type, const char *p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const char *p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const char *p_class_name = "") : + PropertyInfo((Variant::Type)p_type, p_name, p_hint, p_hint_string, p_usage, p_class_name) {} +}; + +struct MethodInfo { + const char *name; + PropertyInfo return_val; + uint32_t flags; + int id = 0; + std::vector<PropertyInfo> arguments; + std::vector<Variant> default_arguments; + + inline bool operator==(const MethodInfo &p_method) const { return id == p_method.id; } + inline bool operator<(const MethodInfo &p_method) const { return id == p_method.id ? (name < p_method.name) : (id < p_method.id); } + + operator Dictionary() const; + + static MethodInfo from_dict(const Dictionary &p_dict); + + MethodInfo(); + MethodInfo(const char *p_name); + template <class... Args> + MethodInfo(const char *p_name, const Args &...args); + MethodInfo(Variant::Type ret); + MethodInfo(Variant::Type ret, const char *p_name); + template <class... Args> + MethodInfo(Variant::Type ret, const char *p_name, const Args &...args); + MethodInfo(const PropertyInfo &p_ret, const char *p_name); + template <class... Args> + MethodInfo(const PropertyInfo &p_ret, const char *p_name, const Args &...); +}; + +template <class... Args> +MethodInfo::MethodInfo(const char *p_name, const Args &...args) : + name(p_name), flags(METHOD_FLAG_NORMAL) { + arguments = { args... }; +} + +template <class... Args> +MethodInfo::MethodInfo(Variant::Type ret, const char *p_name, const Args &...args) : + name(p_name), flags(METHOD_FLAG_NORMAL) { + return_val.type = ret; + arguments = { args... }; +} + +template <class... Args> +MethodInfo::MethodInfo(const PropertyInfo &p_ret, const char *p_name, const Args &...args) : + name(p_name), return_val(p_ret), flags(METHOD_FLAG_NORMAL) { + arguments = { args... }; +} + +template <class T> +T *Object::cast_to(Object *p_object) { + GDNativeObjectPtr casted = internal::interface->object_cast_to(p_object->_owner, internal::interface->classdb_get_class_tag(T::get_class_static())); + if (casted == nullptr) { + return nullptr; + } + return reinterpret_cast<T *>(internal::interface->object_get_instance_binding(casted, internal::token, &T::___binding_callbacks)); +} + +} // namespace godot + +#endif // ! GODOT_OBJECT_HPP diff --git a/include/godot_cpp/core/type_info.hpp b/include/godot_cpp/core/type_info.hpp new file mode 100644 index 0000000..d7a7473 --- /dev/null +++ b/include/godot_cpp/core/type_info.hpp @@ -0,0 +1,178 @@ +/*************************************************************************/ +/* type_info.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_TYPE_INFO_HPP +#define GODOT_TYPE_INFO_HPP + +#include <godot_cpp/core/object.hpp> +#include <godot_cpp/variant/variant.hpp> + +#include <godot/gdnative_interface.h> + +namespace godot { + +// If the compiler fails because it's trying to instantiate the primary 'GetTypeInfo' template +// instead of one of the specializations, it's most likely because the type 'T' is not supported. +// If 'T' is a class that inherits 'Object', make sure it can see the actual class declaration +// instead of a forward declaration. You can always forward declare 'T' in a header file, and then +// include the actual declaration of 'T' in the source file where 'GetTypeInfo<T>' is instantiated. + +template <class T, typename = void> +struct GetTypeInfo; + +#define MAKE_TYPE_INFO(m_type, m_var_type) \ + template <> \ + struct GetTypeInfo<m_type> { \ + static constexpr GDNativeVariantType VARIANT_TYPE = m_var_type; \ + static constexpr GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \ + static inline GDNativePropertyInfo get_class_info() { \ + return PropertyInfo(VARIANT_TYPE, ""); \ + } \ + }; \ + template <> \ + struct GetTypeInfo<const m_type &> { \ + static constexpr GDNativeVariantType VARIANT_TYPE = m_var_type; \ + static constexpr GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \ + static inline GDNativePropertyInfo get_class_info() { \ + return PropertyInfo(VARIANT_TYPE, ""); \ + } \ + }; + +#define MAKE_TYPE_INFO_WITH_META(m_type, m_var_type, m_metadata) \ + template <> \ + struct GetTypeInfo<m_type> { \ + static constexpr GDNativeVariantType VARIANT_TYPE = m_var_type; \ + static constexpr GDNativeExtensionClassMethodArgumentMetadata METADATA = m_metadata; \ + static inline GDNativePropertyInfo get_class_info() { \ + return PropertyInfo(VARIANT_TYPE, ""); \ + } \ + }; \ + template <> \ + struct GetTypeInfo<const m_type &> { \ + static constexpr GDNativeVariantType VARIANT_TYPE = m_var_type; \ + static constexpr GDNativeExtensionClassMethodArgumentMetadata METADATA = m_metadata; \ + static inline GDNativePropertyInfo get_class_info() { \ + return PropertyInfo(VARIANT_TYPE, ""); \ + } \ + }; + +MAKE_TYPE_INFO(bool, GDNATIVE_VARIANT_TYPE_BOOL) +MAKE_TYPE_INFO_WITH_META(uint8_t, GDNATIVE_VARIANT_TYPE_INT, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT8) +MAKE_TYPE_INFO_WITH_META(int8_t, GDNATIVE_VARIANT_TYPE_INT, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT8) +MAKE_TYPE_INFO_WITH_META(uint16_t, GDNATIVE_VARIANT_TYPE_INT, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT16) +MAKE_TYPE_INFO_WITH_META(int16_t, GDNATIVE_VARIANT_TYPE_INT, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT16) +MAKE_TYPE_INFO_WITH_META(uint32_t, GDNATIVE_VARIANT_TYPE_INT, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT32) +MAKE_TYPE_INFO_WITH_META(int32_t, GDNATIVE_VARIANT_TYPE_INT, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT32) +MAKE_TYPE_INFO_WITH_META(uint64_t, GDNATIVE_VARIANT_TYPE_INT, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT64) +MAKE_TYPE_INFO_WITH_META(int64_t, GDNATIVE_VARIANT_TYPE_INT, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT64) +MAKE_TYPE_INFO(char16_t, GDNATIVE_VARIANT_TYPE_INT) +MAKE_TYPE_INFO(char32_t, GDNATIVE_VARIANT_TYPE_INT) +MAKE_TYPE_INFO_WITH_META(float, GDNATIVE_VARIANT_TYPE_FLOAT, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_FLOAT) +MAKE_TYPE_INFO_WITH_META(double, GDNATIVE_VARIANT_TYPE_FLOAT, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_DOUBLE) + +MAKE_TYPE_INFO(String, GDNATIVE_VARIANT_TYPE_STRING) +MAKE_TYPE_INFO(Vector2, GDNATIVE_VARIANT_TYPE_VECTOR2) +MAKE_TYPE_INFO(Vector2i, GDNATIVE_VARIANT_TYPE_VECTOR2I) +MAKE_TYPE_INFO(Rect2, GDNATIVE_VARIANT_TYPE_RECT2) +MAKE_TYPE_INFO(Rect2i, GDNATIVE_VARIANT_TYPE_RECT2I) +MAKE_TYPE_INFO(Vector3, GDNATIVE_VARIANT_TYPE_VECTOR3) +MAKE_TYPE_INFO(Vector3i, GDNATIVE_VARIANT_TYPE_VECTOR3I) +MAKE_TYPE_INFO(Transform2D, GDNATIVE_VARIANT_TYPE_TRANSFORM2D) +MAKE_TYPE_INFO(Plane, GDNATIVE_VARIANT_TYPE_PLANE) +MAKE_TYPE_INFO(Quaternion, GDNATIVE_VARIANT_TYPE_QUATERNION) +MAKE_TYPE_INFO(AABB, GDNATIVE_VARIANT_TYPE_AABB) +MAKE_TYPE_INFO(Basis, GDNATIVE_VARIANT_TYPE_BASIS) +MAKE_TYPE_INFO(Transform3D, GDNATIVE_VARIANT_TYPE_TRANSFORM3D) +MAKE_TYPE_INFO(Color, GDNATIVE_VARIANT_TYPE_COLOR) +MAKE_TYPE_INFO(StringName, GDNATIVE_VARIANT_TYPE_STRING_NAME) +MAKE_TYPE_INFO(NodePath, GDNATIVE_VARIANT_TYPE_NODE_PATH) +MAKE_TYPE_INFO(RID, GDNATIVE_VARIANT_TYPE_RID) +MAKE_TYPE_INFO(Callable, GDNATIVE_VARIANT_TYPE_CALLABLE) +MAKE_TYPE_INFO(Signal, GDNATIVE_VARIANT_TYPE_SIGNAL) +MAKE_TYPE_INFO(Dictionary, GDNATIVE_VARIANT_TYPE_DICTIONARY) +MAKE_TYPE_INFO(Array, GDNATIVE_VARIANT_TYPE_ARRAY) +MAKE_TYPE_INFO(PackedByteArray, GDNATIVE_VARIANT_TYPE_PACKED_BYTE_ARRAY) +MAKE_TYPE_INFO(PackedInt32Array, GDNATIVE_VARIANT_TYPE_PACKED_INT32_ARRAY) +MAKE_TYPE_INFO(PackedInt64Array, GDNATIVE_VARIANT_TYPE_PACKED_INT64_ARRAY) +MAKE_TYPE_INFO(PackedFloat32Array, GDNATIVE_VARIANT_TYPE_PACKED_FLOAT32_ARRAY) +MAKE_TYPE_INFO(PackedFloat64Array, GDNATIVE_VARIANT_TYPE_PACKED_FLOAT64_ARRAY) +MAKE_TYPE_INFO(PackedStringArray, GDNATIVE_VARIANT_TYPE_PACKED_STRING_ARRAY) +MAKE_TYPE_INFO(PackedVector2Array, GDNATIVE_VARIANT_TYPE_PACKED_VECTOR2_ARRAY) +MAKE_TYPE_INFO(PackedVector3Array, GDNATIVE_VARIANT_TYPE_PACKED_VECTOR3_ARRAY) +MAKE_TYPE_INFO(PackedColorArray, GDNATIVE_VARIANT_TYPE_PACKED_COLOR_ARRAY) + +// For variant. +template <> +struct GetTypeInfo<Variant> { + static constexpr GDNativeVariantType VARIANT_TYPE = GDNATIVE_VARIANT_TYPE_NIL; + static constexpr GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; + static inline GDNativePropertyInfo get_class_info() { + return PropertyInfo(GDNATIVE_VARIANT_TYPE_NIL, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); + } +}; + +template <> +struct GetTypeInfo<const Variant &> { + static constexpr GDNativeVariantType VARIANT_TYPE = GDNATIVE_VARIANT_TYPE_NIL; + static constexpr GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; + static inline GDNativePropertyInfo get_class_info() { + return PropertyInfo(GDNATIVE_VARIANT_TYPE_NIL, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); + } +}; + +#define TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, m_impl) \ + template <> \ + struct GetTypeInfo<m_impl> { \ + static const Variant::Type VARIANT_TYPE = Variant::INT; \ + static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \ + static inline GDNativePropertyInfo get_class_info() { \ + return PropertyInfo(GDNATIVE_VARIANT_TYPE_INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, #m_class "." #m_enum); \ + } \ + }; + +#define MAKE_ENUM_TYPE_INFO(m_class, m_enum) \ + TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, m_class::m_enum) \ + TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, m_class::m_enum const) \ + TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, m_class::m_enum &) \ + TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, const m_class::m_enum &) + +template <typename T> +inline const char *__constant_get_enum_name(T param, const char *p_constant) { + if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL) { + ERR_PRINT(("Missing VARIANT_ENUM_CAST for constant's enum: " + String(p_constant)).utf8().get_data()); + } + return GetTypeInfo<T>::get_class_info().class_name; +} + +#define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info()) + +} // namespace godot + +#endif // ! GODOT_TYPE_INFO_HPP diff --git a/include/core/RID.hpp b/include/godot_cpp/godot.hpp index e36e1c3..f2bdf73 100644 --- a/include/core/RID.hpp +++ b/include/godot_cpp/godot.hpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* RID.hpp */ +/* godot.hpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,40 +28,31 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef RID_H -#define RID_H +#ifndef GODOT_HPP +#define GODOT_HPP -#include <gdnative/rid.h> +#include <godot/gdnative_interface.h> namespace godot { -class Object; +namespace internal { -class RID { - godot_rid _godot_rid; +extern "C" const GDNativeInterface *interface; +extern "C" GDNativeExtensionClassLibraryPtr library; +extern "C" void *token; -public: - RID(); - - RID(Object *p); - - godot_rid _get_godot_rid() const; +} // namespace internal - int32_t get_id() const; - - inline bool is_valid() const { - // is_valid() is not available in the C API... - return *this != RID(); - } +class GDExtensionBinding { +public: + static GDNativeBool init(const GDNativeInterface *p_interface, const GDNativeExtensionClassLibraryPtr p_library, GDNativeInitialization *r_initialization); + static void initialize_level(void *userdata, GDNativeInitializationLevel p_level); + static void deinitialize_level(void *userdata, GDNativeInitializationLevel p_level); - bool operator==(const RID &p_other) const; - bool operator!=(const RID &p_other) const; - bool operator<(const RID &p_other) const; - bool operator>(const RID &p_other) const; - bool operator<=(const RID &p_other) const; - bool operator>=(const RID &p_other) const; + static void *create_instance_callback(void *p_token, void *p_instance); + static void free_instance_callback(void *p_token, void *p_instance, void *p_binding); }; } // namespace godot -#endif // RID_H +#endif // ! GODOT_HPP diff --git a/include/core/Dictionary.hpp b/include/godot_cpp/variant/char_string.hpp index 9f01c52..3ba8948 100644 --- a/include/core/Dictionary.hpp +++ b/include/godot_cpp/variant/char_string.hpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* Dictionary.hpp */ +/* char_string.hpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,62 +28,74 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef DICTIONARY_H -#define DICTIONARY_H +#ifndef GODOT_CPP_CHAR_STRING_HPP +#define GODOT_CPP_CHAR_STRING_HPP -#include "Variant.hpp" - -#include "Array.hpp" - -#include <gdnative/dictionary.h> +#include <cstddef> +#include <cstdint> namespace godot { -class Dictionary { - godot_dictionary _godot_dictionary; +class CharString { + friend class String; + + const char *_data = nullptr; + int _length = 0; - friend Variant::operator Dictionary() const; - inline explicit Dictionary(const godot_dictionary &other) { - _godot_dictionary = other; - } + CharString(const char *str, int length); public: - Dictionary(); - Dictionary(const Dictionary &other); - Dictionary &operator=(const Dictionary &other); + int length() const; + const char *get_data() const; - template <class... Args> - static Dictionary make(Args... args) { - return helpers::add_all(Dictionary(), args...); - } + ~CharString(); +}; - void clear(); +class Char16String { + friend class String; - bool empty() const; + const char16_t *_data = nullptr; + int _length = 0; - void erase(const Variant &key); + Char16String(const char16_t *str, int length); - bool has(const Variant &key) const; +public: + int length() const; + const char16_t *get_data() const; - bool has_all(const Array &keys) const; + ~Char16String(); +}; - uint32_t hash() const; +class Char32String { + friend class String; - Array keys() const; + const char32_t *_data = nullptr; + int _length = 0; - Variant &operator[](const Variant &key); + Char32String(const char32_t *str, int length); - const Variant &operator[](const Variant &key) const; +public: + int length() const; + const char32_t *get_data() const; + + ~Char32String(); +}; - int size() const; +class CharWideString { + friend class String; - String to_json() const; + const wchar_t *_data = nullptr; + int _length = 0; - Array values() const; + CharWideString(const wchar_t *str, int length); + +public: + int length() const; + const wchar_t *get_data() const; - ~Dictionary(); + ~CharWideString(); }; } // namespace godot -#endif // DICTIONARY_H +#endif // ! GODOT_CPP_CHAR_STRING_HPP diff --git a/include/godot_cpp/variant/variant.hpp b/include/godot_cpp/variant/variant.hpp new file mode 100644 index 0000000..f94f907 --- /dev/null +++ b/include/godot_cpp/variant/variant.hpp @@ -0,0 +1,308 @@ +/*************************************************************************/ +/* variant.hpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GODOT_CPP_VARIANT_HPP +#define GODOT_CPP_VARIANT_HPP + +#include <godot_cpp/core/defs.hpp> + +#include <godot_cpp/variant/builtin_types.hpp> +#include <godot_cpp/variant/variant_size.hpp> + +#include <godot/gdnative_interface.h> + +#include <array> + +namespace godot { + +class Variant { + uint8_t opaque[GODOT_CPP_VARIANT_SIZE]{ 0 }; + GDNativeVariantPtr ptr = const_cast<uint8_t (*)[GODOT_CPP_VARIANT_SIZE]>(&opaque); + + friend class GDExtensionBinding; + friend class MethodBind; + + static void init_bindings(); + +public: + enum Type { + NIL, + + // atomic types + BOOL, + INT, + FLOAT, + STRING, + + // math types + VECTOR2, + VECTOR2I, + RECT2, + RECT2I, + VECTOR3, + VECTOR3I, + TRANSFORM2D, + PLANE, + QUATERNION, + AABB, + BASIS, + TRANSFORM3D, + + // misc types + COLOR, + STRING_NAME, + NODE_PATH, + RID, + OBJECT, + CALLABLE, + SIGNAL, + DICTIONARY, + ARRAY, + + // typed arrays + PACKED_BYTE_ARRAY, + PACKED_INT32_ARRAY, + PACKED_INT64_ARRAY, + PACKED_FLOAT32_ARRAY, + PACKED_FLOAT64_ARRAY, + PACKED_STRING_ARRAY, + PACKED_VECTOR2_ARRAY, + PACKED_VECTOR3_ARRAY, + PACKED_COLOR_ARRAY, + + VARIANT_MAX + }; + + enum Operator { + //comparison + OP_EQUAL, + OP_NOT_EQUAL, + OP_LESS, + OP_LESS_EQUAL, + OP_GREATER, + OP_GREATER_EQUAL, + //mathematic + OP_ADD, + OP_SUBTRACT, + OP_MULTIPLY, + OP_DIVIDE, + OP_NEGATE, + OP_POSITIVE, + OP_MODULE, + //bitwise + OP_SHIFT_LEFT, + OP_SHIFT_RIGHT, + OP_BIT_AND, + OP_BIT_OR, + OP_BIT_XOR, + OP_BIT_NEGATE, + //logic + OP_AND, + OP_OR, + OP_XOR, + OP_NOT, + //containment + OP_IN, + OP_MAX + }; + +private: + static GDNativeVariantFromTypeConstructorFunc from_type_constructor[VARIANT_MAX]; + static GDNativeTypeFromVariantConstructorFunc to_type_constructor[VARIANT_MAX]; + +public: + Variant(); + Variant(std::nullptr_t n) : + Variant() {} + Variant(const GDNativeVariantPtr native_ptr); + Variant(const Variant &other); + Variant(Variant &&other); + Variant(bool v); + Variant(int64_t v); + Variant(int32_t v) : + Variant(static_cast<int64_t>(v)) {} + Variant(uint32_t v) : + Variant(static_cast<int64_t>(v)) {} + Variant(uint64_t v) : + Variant(static_cast<int64_t>(v)) {} + Variant(double v); + Variant(float v) : + Variant((double)v) {} + Variant(const String &v); + Variant(const char *v) : + Variant(String(v)) {} + Variant(const char16_t *v) : + Variant(String(v)) {} + Variant(const char32_t *v) : + Variant(String(v)) {} + Variant(const wchar_t *v) : + Variant(String(v)) {} + Variant(const Vector2 &v); + Variant(const Vector2i &v); + Variant(const Rect2 &v); + Variant(const Rect2i &v); + Variant(const Vector3 &v); + Variant(const Vector3i &v); + Variant(const Transform2D &v); + Variant(const Plane &v); + Variant(const Quaternion &v); + Variant(const godot::AABB &v); + Variant(const Basis &v); + Variant(const Transform3D &v); + Variant(const Color &v); + Variant(const StringName &v); + Variant(const NodePath &v); + Variant(const godot::RID &v); + Variant(const Object *v); + Variant(const Callable &v); + Variant(const Signal &v); + Variant(const Dictionary &v); + Variant(const Array &v); + Variant(const PackedByteArray &v); + Variant(const PackedInt32Array &v); + Variant(const PackedInt64Array &v); + Variant(const PackedFloat32Array &v); + Variant(const PackedFloat64Array &v); + Variant(const PackedStringArray &v); + Variant(const PackedVector2Array &v); + Variant(const PackedVector3Array &v); + Variant(const PackedColorArray &v); + ~Variant(); + + operator bool() const; + operator int64_t() const; + operator int32_t() const; + operator uint64_t() const; + operator uint32_t() const; + operator double() const; + operator float() const; + operator String() const; + operator Vector2() const; + operator Vector2i() const; + operator Rect2() const; + operator Rect2i() const; + operator Vector3() const; + operator Vector3i() const; + operator Transform2D() const; + operator Plane() const; + operator Quaternion() const; + operator godot::AABB() const; + operator Basis() const; + operator Transform3D() const; + operator Color() const; + operator StringName() const; + operator NodePath() const; + operator godot::RID() const; + operator Object *() const; + operator Callable() const; + operator Signal() const; + operator Dictionary() const; + operator Array() const; + operator PackedByteArray() const; + operator PackedInt32Array() const; + operator PackedInt64Array() const; + operator PackedFloat32Array() const; + operator PackedFloat64Array() const; + operator PackedStringArray() const; + operator PackedVector2Array() const; + operator PackedVector3Array() const; + operator PackedColorArray() const; + + operator const GDNativeVariantPtr() const; + operator GDNativeVariantPtr(); + + Variant &operator=(const Variant &other); + Variant &operator=(Variant &&other); + bool operator==(const Variant &other) const; + bool operator!=(const Variant &other) const; + bool operator<(const Variant &other) const; + + void operator=(const GDNativeVariantPtr other_ptr); + + void call(const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDNativeCallError &r_error); + + template <class... Args> + Variant call(const StringName &method, Args... args) { + Variant result; + GDNativeCallError error; + std::array<const GDNativeVariantPtr, sizeof...(Args)> call_args = { Variant(args)... }; + call(method, call_args.data(), call_args.size(), result, error); + return result; + } + + static void call_static(Variant::Type type, const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDNativeCallError &r_error); + + template <class... Args> + static Variant call_static(Variant::Type type, const StringName &method, Args... args) { + Variant result; + GDNativeCallError error; + std::array<const GDNativeVariantPtr, sizeof...(Args)> call_args = { Variant(args)... }; + call_static(type, method, call_args.data(), call_args.size(), result, error); + return result; + } + + static void evaluate(const Operator &op, const Variant &a, const Variant &b, Variant &r_ret, bool &r_valid); + + void set(const Variant &key, const Variant &value, bool *r_valid = nullptr); + void set_named(const StringName &name, const Variant &value, bool &r_valid); + void set_indexed(int64_t index, const Variant &value, bool &r_valid, bool &r_oob); + void set_keyed(const Variant &key, const Variant &value, bool &r_valid); + Variant get(const Variant &key, bool *r_valid = nullptr) const; + Variant get_named(const StringName &name, bool &r_valid) const; + Variant get_indexed(int64_t index, bool &r_valid, bool &r_oob) const; + Variant get_keyed(const Variant &key, bool &r_valid) const; + bool in(const Variant &index, bool *r_valid = nullptr) const; + + bool iter_init(Variant &r_iter, bool &r_valid) const; + bool iter_next(Variant &r_iter, bool &r_valid) const; + Variant iter_get(const Variant &r_iter, bool &r_valid) const; + + Variant::Type get_type() const; + bool has_method(const StringName &method) const; + bool has_key(const Variant &key, bool *r_valid = nullptr) const; + static bool has_member(Variant::Type type, const StringName &member); + + bool hash_compare(const Variant &variant) const; + bool booleanize() const; + String stringify() const; + Variant duplicate(bool deep = false) const; + static void blend(const Variant &a, const Variant &b, float c, Variant &r_dst); + static void interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst); + + static String get_type_name(Variant::Type type); + static bool can_convert(Variant::Type from, Variant::Type to); + static bool can_convert_strict(Variant::Type from, Variant::Type to); + + void clear(); +}; + +} // namespace godot + +#endif // ! GODOT_CPP_VARIANT_HPP |