summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/SCsub4
-rw-r--r--core/error_macros.h6
-rw-r--r--core/io/file_access_buffered_fa.h8
-rw-r--r--core/io/file_access_compressed.cpp13
-rw-r--r--core/io/file_access_compressed.h2
-rw-r--r--core/io/file_access_encrypted.cpp10
-rw-r--r--core/io/file_access_encrypted.h2
-rw-r--r--core/io/file_access_memory.h2
-rw-r--r--core/io/file_access_network.cpp10
-rw-r--r--core/io/file_access_network.h2
-rw-r--r--core/io/file_access_pack.h2
-rw-r--r--core/io/file_access_zip.h2
-rw-r--r--core/make_binders.py12
-rw-r--r--core/math/camera_matrix.cpp8
-rw-r--r--core/math/camera_matrix.h1
-rw-r--r--core/math/delaunay.h4
-rw-r--r--core/math/geometry.cpp2
-rw-r--r--core/math/geometry.h10
-rw-r--r--core/math/math_funcs.h19
-rw-r--r--core/math/plane.cpp4
-rw-r--r--core/math/plane.h4
-rw-r--r--core/math/vector2.h8
-rw-r--r--core/math/vector3.h23
-rw-r--r--core/method_bind.h6
-rw-r--r--core/object.cpp5
-rw-r--r--core/object.h1
-rw-r--r--core/os/dir_access.cpp2
-rw-r--r--core/os/file_access.cpp23
-rw-r--r--core/os/file_access.h7
-rw-r--r--core/os/os.h4
-rw-r--r--core/reference.h6
-rw-r--r--core/string_builder.h4
-rw-r--r--core/translation.cpp15
-rw-r--r--core/translation.h2
-rw-r--r--core/type_info.h122
-rw-r--r--core/ustring.cpp25
-rw-r--r--core/ustring.h5
-rw-r--r--core/variant_call.cpp15
-rw-r--r--core/variant_parser.cpp3
39 files changed, 321 insertions, 82 deletions
diff --git a/core/SCsub b/core/SCsub
index 00d0bcac24..d5be74a64f 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -129,10 +129,10 @@ if env['builtin_zstd']:
thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources]
env_thirdparty.Append(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"])
- env_thirdparty.Append(CCFLAGS="-DZSTD_STATIC_LINKING_ONLY")
+ env_thirdparty.Append(CPPFLAGS="-DZSTD_STATIC_LINKING_ONLY")
env.Append(CPPPATH=thirdparty_zstd_dir)
# Also needed in main env includes will trigger warnings
- env.Append(CCFLAGS="-DZSTD_STATIC_LINKING_ONLY")
+ env.Append(CPPFLAGS="-DZSTD_STATIC_LINKING_ONLY")
env_thirdparty.add_source_files(env.core_sources, thirdparty_zstd_sources)
diff --git a/core/error_macros.h b/core/error_macros.h
index ca5ccd24cf..78e29551d4 100644
--- a/core/error_macros.h
+++ b/core/error_macros.h
@@ -86,7 +86,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
#define _FNL __FILE__ ":"
-/** An index has failed if m_index<0 or m_index >=m_size, the function exists */
+/** An index has failed if m_index<0 or m_index >=m_size, the function exits */
extern bool _err_error_exists;
@@ -140,7 +140,7 @@ extern bool _err_error_exists;
_err_error_exists = false; \
} while (0); // (*)
-/** An index has failed if m_index<0 or m_index >=m_size, the function exists.
+/** An index has failed if m_index<0 or m_index >=m_size, the function exits.
* This function returns an error value, if returning Error, please select the most
* appropriate error condition from error_macros.h
*/
@@ -154,7 +154,7 @@ extern bool _err_error_exists;
_err_error_exists = false; \
} while (0); // (*)
-/** An index has failed if m_index >=m_size, the function exists.
+/** An index has failed if m_index >=m_size, the function exits.
* This function returns an error value, if returning Error, please select the most
* appropriate error condition from error_macros.h
*/
diff --git a/core/io/file_access_buffered_fa.h b/core/io/file_access_buffered_fa.h
index be960fbc25..24b40cbce8 100644
--- a/core/io/file_access_buffered_fa.h
+++ b/core/io/file_access_buffered_fa.h
@@ -143,6 +143,14 @@ public:
return f._get_modified_time(p_file);
}
+ virtual uint32_t _get_unix_permissions(const String &p_file) {
+ return f._get_unix_permissions(p_file);
+ }
+
+ virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) {
+ return f._set_unix_permissions(p_file, p_permissions);
+ }
+
FileAccessBufferedFA(){
};
diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp
index b268d5c710..6c4310a572 100644
--- a/core/io/file_access_compressed.cpp
+++ b/core/io/file_access_compressed.cpp
@@ -373,6 +373,19 @@ uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
return 0;
}
+uint32_t FileAccessCompressed::_get_unix_permissions(const String &p_file) {
+ if (f)
+ return f->_get_unix_permissions(p_file);
+ return 0;
+}
+
+Error FileAccessCompressed::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
+ if (f) {
+ return f->_set_unix_permissions(p_file, p_permissions);
+ }
+ return FAILED;
+}
+
FileAccessCompressed::FileAccessCompressed() :
cmode(Compression::MODE_ZSTD),
writing(false),
diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h
index f408b1bc29..773fed6a3a 100644
--- a/core/io/file_access_compressed.h
+++ b/core/io/file_access_compressed.h
@@ -91,6 +91,8 @@ public:
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file);
+ virtual uint32_t _get_unix_permissions(const String &p_file);
+ virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);
FileAccessCompressed();
virtual ~FileAccessCompressed();
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index 6ad68dd74d..3cf6908961 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -301,6 +301,16 @@ uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) {
return 0;
}
+uint32_t FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
+
+ return 0;
+}
+
+Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
+
+ return FAILED;
+}
+
FileAccessEncrypted::FileAccessEncrypted() {
file = NULL;
diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h
index e77d62a9f4..d779a150ac 100644
--- a/core/io/file_access_encrypted.h
+++ b/core/io/file_access_encrypted.h
@@ -79,6 +79,8 @@ public:
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file);
+ virtual uint32_t _get_unix_permissions(const String &p_file);
+ virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);
FileAccessEncrypted();
~FileAccessEncrypted();
diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h
index 73952133c1..4db7811aaa 100644
--- a/core/io/file_access_memory.h
+++ b/core/io/file_access_memory.h
@@ -70,6 +70,8 @@ public:
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) { return 0; }
+ virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; }
+ virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; }
FileAccessMemory();
};
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index 501a21a50d..722e62c54e 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -497,6 +497,16 @@ uint64_t FileAccessNetwork::_get_modified_time(const String &p_file) {
return exists_modtime;
}
+uint32_t FileAccessNetwork::_get_unix_permissions(const String &p_file) {
+ //could be implemented, not sure if worth it
+ return 0;
+}
+
+Error FileAccessNetwork::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
+
+ return FAILED;
+}
+
void FileAccessNetwork::configure() {
GLOBAL_DEF("network/remote_fs/page_size", 65536);
diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h
index 5bbf7588c7..073b75a37b 100644
--- a/core/io/file_access_network.h
+++ b/core/io/file_access_network.h
@@ -159,6 +159,8 @@ public:
virtual bool file_exists(const String &p_path); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file);
+ virtual uint32_t _get_unix_permissions(const String &p_file);
+ virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);
static void configure();
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index a90672ce26..a21dd7d22d 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -142,6 +142,8 @@ class FileAccessPack : public FileAccess {
FileAccess *f;
virtual Error _open(const String &p_path, int p_mode_flags);
virtual uint64_t _get_modified_time(const String &p_file) { return 0; }
+ virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; }
+ virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; }
public:
virtual void close();
diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h
index fc8f85c07b..217176c0af 100644
--- a/core/io/file_access_zip.h
+++ b/core/io/file_access_zip.h
@@ -112,6 +112,8 @@ public:
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) { return 0; } // todo
+ virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; }
+ virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; }
FileAccessZip(const String &p_path, const PackedData::PackedFile &p_file);
~FileAccessZip();
diff --git a/core/make_binders.py b/core/make_binders.py
index 4c61b90d99..5c1c66cab6 100644
--- a/core/make_binders.py
+++ b/core/make_binders.py
@@ -9,6 +9,12 @@ public:
$ifret R$ $ifnoret void$ (T::*method)($arg, P@$) $ifconst const$;
#ifdef DEBUG_METHODS_ENABLED
virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
+ virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
+ $ifret if (p_arg==-1) return GetTypeInfo<R>::METADATA;$
+ $arg if (p_arg==(@-1)) return GetTypeInfo<P@>::METADATA;
+ $
+ return GodotTypeInfo::METADATA_NONE;
+ }
Variant::Type _get_argument_type(int p_argument) const {
$ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo<R>::VARIANT_TYPE;$
$arg if (p_argument==(@-1)) return (Variant::Type)GetTypeInfo<P@>::VARIANT_TYPE;
@@ -94,6 +100,12 @@ public:
#ifdef DEBUG_METHODS_ENABLED
virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); }
+ virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const {
+ $ifret if (p_arg==-1) return GetTypeInfo<R>::METADATA;$
+ $arg if (p_arg==(@-1)) return GetTypeInfo<P@>::METADATA;
+ $
+ return GodotTypeInfo::METADATA_NONE;
+ }
Variant::Type _get_argument_type(int p_argument) const {
$ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo<R>::VARIANT_TYPE;$
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index caf08c7379..f615cc8c65 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -210,6 +210,14 @@ void CameraMatrix::set_frustum(real_t p_left, real_t p_right, real_t p_bottom, r
te[15] = 0;
}
+void CameraMatrix::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) {
+ if (!p_flip_fov) {
+ p_size *= p_aspect;
+ }
+
+ set_frustum(-p_size / 2 + p_offset.x, +p_size / 2 + p_offset.x, -p_size / p_aspect / 2 + p_offset.y, +p_size / p_aspect / 2 + p_offset.y, p_near, p_far);
+}
+
real_t CameraMatrix::get_z_far() const {
const real_t *matrix = (const real_t *)this->matrix;
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index 015588a8cb..3bcf48f5da 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -61,6 +61,7 @@ struct CameraMatrix {
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) {
diff --git a/core/math/delaunay.h b/core/math/delaunay.h
index bd0cf97937..ed52c506db 100644
--- a/core/math/delaunay.h
+++ b/core/math/delaunay.h
@@ -80,11 +80,11 @@ public:
}
static bool edge_compare(const Vector<Vector2> &p_vertices, const Edge &p_a, const Edge &p_b) {
- if (p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[0]]) < CMP_EPSILON && p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[1]]) < CMP_EPSILON) {
+ if (Math::is_zero_approx(p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[0]])) && Math::is_zero_approx(p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[1]]))) {
return true;
}
- if (p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[1]]) < CMP_EPSILON && p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[0]]) < CMP_EPSILON) {
+ if (Math::is_zero_approx(p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[1]])) && Math::is_zero_approx(p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[0]]))) {
return true;
}
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index a84b5a16c7..0ab8707d3a 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -836,7 +836,7 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<Plane> &p_planes
Vector3 rel = edge1_A - edge0_A;
real_t den = clip.normal.dot(rel);
- if (Math::abs(den) < CMP_EPSILON)
+ if (Math::is_zero_approx(den))
continue; // point too short
real_t dist = -(clip.normal.dot(edge0_A) - clip.d) / den;
diff --git a/core/math/geometry.h b/core/math/geometry.h
index 7347cb742a..f3a671aa9a 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -181,8 +181,8 @@ public:
}
}
// finally do the division to get sc and tc
- sc = (Math::abs(sN) < CMP_EPSILON ? 0.0 : sN / sD);
- tc = (Math::abs(tN) < CMP_EPSILON ? 0.0 : tN / tD);
+ sc = (Math::is_zero_approx(sN) ? 0.0 : sN / sD);
+ tc = (Math::is_zero_approx(tN) ? 0.0 : tN / tD);
// get the difference of the two closest points
Vector3 dP = w + (sc * u) - (tc * v); // = S1(sc) - S2(tc)
@@ -195,7 +195,7 @@ public:
Vector3 e2 = p_v2 - p_v0;
Vector3 h = p_dir.cross(e2);
real_t a = e1.dot(h);
- if (a > -CMP_EPSILON && a < CMP_EPSILON) // parallel test
+ if (Math::is_zero_approx(a)) // parallel test
return false;
real_t f = 1.0 / a;
@@ -233,7 +233,7 @@ public:
Vector3 e2 = p_v2 - p_v0;
Vector3 h = rel.cross(e2);
real_t a = e1.dot(h);
- if (a > -CMP_EPSILON && a < CMP_EPSILON) // parallel test
+ if (Math::is_zero_approx(a)) // parallel test
return false;
real_t f = 1.0 / a;
@@ -535,7 +535,7 @@ public:
// see http://paulbourke.net/geometry/pointlineplane/
const real_t denom = p_dir_b.y * p_dir_a.x - p_dir_b.x * p_dir_a.y;
- if (Math::abs(denom) < CMP_EPSILON) { // parallel?
+ if (Math::is_zero_approx(denom)) { // parallel?
return false;
}
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 0d209402dd..a75f2fb4ab 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -272,13 +272,20 @@ public:
return diff < epsilon;
}
- static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b, real_t epsilon = CMP_EPSILON) {
- // TODO: Comparing floats for approximate-equality is non-trivial.
- // Using epsilon should cover the typical cases in Godot (where a == b is used to compare two reals), such as matrix and vector comparison operators.
- // A proper implementation in terms of ULPs should eventually replace the contents of this function.
- // See https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ for details.
+ static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b) {
+ real_t tolerance = CMP_EPSILON * abs(a);
+ if (tolerance < CMP_EPSILON) {
+ tolerance = CMP_EPSILON;
+ }
+ return abs(a - b) < tolerance;
+ }
+
+ static _ALWAYS_INLINE_ bool is_equal_approx(real_t a, real_t b, real_t tolerance) {
+ return abs(a - b) < tolerance;
+ }
- return abs(a - b) < epsilon;
+ static _ALWAYS_INLINE_ bool is_zero_approx(real_t s) {
+ return abs(s) < CMP_EPSILON;
}
static _ALWAYS_INLINE_ float absf(float g) {
diff --git a/core/math/plane.cpp b/core/math/plane.cpp
index cd3cbce300..b01853c4ac 100644
--- a/core/math/plane.cpp
+++ b/core/math/plane.cpp
@@ -110,7 +110,7 @@ bool Plane::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3
real_t den = normal.dot(segment);
//printf("den is %i\n",den);
- if (Math::abs(den) <= CMP_EPSILON) {
+ if (Math::is_zero_approx(den)) {
return false;
}
@@ -135,7 +135,7 @@ bool Plane::intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vec
real_t den = normal.dot(segment);
//printf("den is %i\n",den);
- if (Math::abs(den) <= CMP_EPSILON) {
+ if (Math::is_zero_approx(den)) {
return false;
}
diff --git a/core/math/plane.h b/core/math/plane.h
index 1c6e4b816b..ec817edd2c 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -125,12 +125,12 @@ Plane::Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_
bool Plane::operator==(const Plane &p_plane) const {
- return normal == p_plane.normal && d == p_plane.d;
+ return normal == p_plane.normal && Math::is_equal_approx(d, p_plane.d);
}
bool Plane::operator!=(const Plane &p_plane) const {
- return normal != p_plane.normal || d != p_plane.d;
+ return normal != p_plane.normal || !Math::is_equal_approx(d, p_plane.d);
}
#endif // PLANE_H
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 9a214ef9b5..a0c6024c9f 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -106,8 +106,8 @@ struct Vector2 {
bool operator==(const Vector2 &p_vec2) const;
bool operator!=(const Vector2 &p_vec2) const;
- bool operator<(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
- bool operator<=(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y <= p_vec2.y) : (x <= p_vec2.x); }
+ bool operator<(const Vector2 &p_vec2) const { return (Math::is_equal_approx(x, p_vec2.x)) ? (y < p_vec2.y) : (x < p_vec2.x); }
+ bool operator<=(const Vector2 &p_vec2) const { return (Math::is_equal_approx(x, p_vec2.x)) ? (y <= p_vec2.y) : (x < p_vec2.x); }
real_t angle() const;
@@ -213,11 +213,11 @@ _FORCE_INLINE_ Vector2 Vector2::operator-() const {
_FORCE_INLINE_ bool Vector2::operator==(const Vector2 &p_vec2) const {
- return x == p_vec2.x && y == p_vec2.y;
+ return Math::is_equal_approx(x, p_vec2.x) && Math::is_equal_approx(y, p_vec2.y);
}
_FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const {
- return x != p_vec2.x || y != p_vec2.y;
+ return !Math::is_equal_approx(x, p_vec2.x) || !Math::is_equal_approx(y, p_vec2.y);
}
Vector2 Vector2::linear_interpolate(const Vector2 &p_b, real_t p_t) const {
diff --git a/core/math/vector3.h b/core/math/vector3.h
index e9074c5bd4..21fc09653f 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -341,17 +341,17 @@ Vector3 Vector3::operator-() const {
bool Vector3::operator==(const Vector3 &p_v) const {
- return (x == p_v.x && y == p_v.y && z == p_v.z);
+ return (Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y) && Math::is_equal_approx(z, p_v.z));
}
bool Vector3::operator!=(const Vector3 &p_v) const {
- return (x != p_v.x || y != p_v.y || z != p_v.z);
+ return (!Math::is_equal_approx(x, p_v.x) || !Math::is_equal_approx(y, p_v.y) || !Math::is_equal_approx(z, p_v.z));
}
bool Vector3::operator<(const Vector3 &p_v) const {
- if (x == p_v.x) {
- if (y == p_v.y)
+ if (Math::is_equal_approx(x, p_v.x)) {
+ if (Math::is_equal_approx(y, p_v.y))
return z < p_v.z;
else
return y < p_v.y;
@@ -362,8 +362,8 @@ bool Vector3::operator<(const Vector3 &p_v) const {
bool Vector3::operator<=(const Vector3 &p_v) const {
- if (x == p_v.x) {
- if (y == p_v.y)
+ if (Math::is_equal_approx(x, p_v.x)) {
+ if (Math::is_equal_approx(y, p_v.y))
return z <= p_v.z;
else
return y < p_v.y;
@@ -402,13 +402,14 @@ real_t Vector3::length_squared() const {
void Vector3::normalize() {
- real_t l = length();
- if (l == 0) {
+ real_t lengthsq = length_squared();
+ if (lengthsq == 0) {
x = y = z = 0;
} else {
- x /= l;
- y /= l;
- z /= l;
+ real_t length = Math::sqrt(lengthsq);
+ x /= length;
+ y /= length;
+ z /= length;
}
}
diff --git a/core/method_bind.h b/core/method_bind.h
index 5ea8adb7e0..1b0c3b27c0 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -273,6 +273,8 @@ public:
void set_argument_names(const Vector<StringName> &p_names); //set by class, db, can't be inferred otherwise
Vector<StringName> get_argument_names() const;
+ virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const = 0;
+
#endif
void set_hint_flags(uint32_t p_hint) { hint_flags = p_hint; }
uint32_t get_hint_flags() const { return hint_flags | (is_const() ? METHOD_FLAG_CONST : 0) | (is_vararg() ? METHOD_FLAG_VARARG : 0); }
@@ -329,6 +331,10 @@ public:
return _gen_argument_type_info(p_arg).type;
}
+ virtual GodotTypeInfo::Metadata get_argument_meta(int) const {
+ return GodotTypeInfo::METADATA_NONE;
+ }
+
#else
virtual Variant::Type _gen_argument_type(int p_arg) const {
diff --git a/core/object.cpp b/core/object.cpp
index 039f556c87..f860423a27 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -1059,6 +1059,10 @@ Variant Object::get_meta(const String &p_name) const {
return metadata[p_name];
}
+void Object::remove_meta(const String &p_name) {
+ metadata.erase(p_name);
+}
+
Array Object::_get_property_list_bind() const {
List<PropertyInfo> lpi;
@@ -1691,6 +1695,7 @@ void Object::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_script"), &Object::get_script);
ClassDB::bind_method(D_METHOD("set_meta", "name", "value"), &Object::set_meta);
+ ClassDB::bind_method(D_METHOD("remove_meta", "name"), &Object::remove_meta);
ClassDB::bind_method(D_METHOD("get_meta", "name"), &Object::get_meta);
ClassDB::bind_method(D_METHOD("has_meta", "name"), &Object::has_meta);
ClassDB::bind_method(D_METHOD("get_meta_list"), &Object::_get_meta_list_bind);
diff --git a/core/object.h b/core/object.h
index 3730af1ad4..94abaacdcc 100644
--- a/core/object.h
+++ b/core/object.h
@@ -673,6 +673,7 @@ public:
bool has_meta(const String &p_name) const;
void set_meta(const String &p_name, const Variant &p_value);
+ void remove_meta(const String &p_name);
Variant get_meta(const String &p_name) const;
void get_meta_list(List<String> *p_list) const;
diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp
index 2c1c655175..d81c30f33a 100644
--- a/core/os/dir_access.cpp
+++ b/core/os/dir_access.cpp
@@ -330,7 +330,7 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) {
if (err == OK && p_chmod_flags != -1) {
fdst->close();
- err = fdst->_chmod(p_to, p_chmod_flags);
+ err = FileAccess::set_unix_permissions(p_to, p_chmod_flags);
// If running on a platform with no chmod support (i.e., Windows), don't fail
if (err == ERR_UNAVAILABLE)
err = OK;
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 4be1364278..079f51bada 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -507,6 +507,29 @@ uint64_t FileAccess::get_modified_time(const String &p_file) {
return mt;
}
+uint32_t FileAccess::get_unix_permissions(const String &p_file) {
+
+ if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file))
+ return 0;
+
+ FileAccess *fa = create_for_path(p_file);
+ ERR_FAIL_COND_V(!fa, 0);
+
+ uint32_t mt = fa->_get_unix_permissions(p_file);
+ memdelete(fa);
+ return mt;
+}
+
+Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissions) {
+
+ FileAccess *fa = create_for_path(p_file);
+ ERR_FAIL_COND_V(!fa, ERR_CANT_CREATE);
+
+ Error err = fa->_set_unix_permissions(p_file, p_permissions);
+ memdelete(fa);
+ return err;
+}
+
void FileAccess::store_string(const String &p_string) {
if (p_string.length() == 0)
diff --git a/core/os/file_access.h b/core/os/file_access.h
index 9df2a5cade..4930eae35a 100644
--- a/core/os/file_access.h
+++ b/core/os/file_access.h
@@ -56,6 +56,9 @@ public:
bool endian_swap;
bool real_is_double;
+ virtual uint32_t _get_unix_permissions(const String &p_file) = 0;
+ virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) = 0;
+
protected:
String fix_path(const String &p_path) const;
virtual Error _open(const String &p_path, int p_mode_flags) = 0; ///< open a file
@@ -148,14 +151,14 @@ public:
virtual Error reopen(const String &p_path, int p_mode_flags); ///< does not change the AccessType
- virtual Error _chmod(const String &p_path, int p_mod) { return ERR_UNAVAILABLE; }
-
static FileAccess *create(AccessType p_access); /// Create a file access (for the current platform) this is the only portable way of accessing files.
static FileAccess *create_for_path(const String &p_path);
static FileAccess *open(const String &p_path, int p_mode_flags, Error *r_error = NULL); /// Create a file access (for the current platform) this is the only portable way of accessing files.
static CreateFunc get_create_func(AccessType p_access);
static bool exists(const String &p_name); ///< return true if a file exists
static uint64_t get_modified_time(const String &p_file);
+ static uint32_t get_unix_permissions(const String &p_file);
+ static Error set_unix_permissions(const String &p_file, uint32_t p_permissions);
static void set_backup_save(bool p_enable) { backup_save = p_enable; };
static bool is_backup_save_enabled() { return backup_save; };
diff --git a/core/os/os.h b/core/os/os.h
index 12012fba80..4ae8a354e5 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -45,6 +45,8 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
+class Mutex;
+
class OS {
static OS *singleton;
@@ -260,7 +262,7 @@ public:
virtual int get_low_processor_usage_mode_sleep_usec() const;
virtual String get_executable_path() const;
- virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false) = 0;
+ virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL) = 0;
virtual Error kill(const ProcessID &p_pid) = 0;
virtual int get_process_id() const;
diff --git a/core/reference.h b/core/reference.h
index 9105dbbd58..8a19f846c7 100644
--- a/core/reference.h
+++ b/core/reference.h
@@ -375,7 +375,8 @@ struct PtrToArg<const RefPtr &> {
template <class T>
struct GetTypeInfo<Ref<T> > {
- enum { VARIANT_TYPE = Variant::OBJECT };
+ static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
static inline PropertyInfo get_class_info() {
return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
@@ -384,7 +385,8 @@ struct GetTypeInfo<Ref<T> > {
template <class T>
struct GetTypeInfo<const Ref<T> &> {
- enum { VARIANT_TYPE = Variant::OBJECT };
+ static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
static inline PropertyInfo get_class_info() {
return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
diff --git a/core/string_builder.h b/core/string_builder.h
index 40d70e8f45..0c4985d230 100644
--- a/core/string_builder.h
+++ b/core/string_builder.h
@@ -70,6 +70,10 @@ public:
return appended_strings.size();
}
+ _FORCE_INLINE_ uint32_t get_string_length() const {
+ return string_length;
+ }
+
String as_string() const;
_FORCE_INLINE_ operator String() const {
diff --git a/core/translation.cpp b/core/translation.cpp
index 6921f1d9f1..afbc639eaa 100644
--- a/core/translation.cpp
+++ b/core/translation.cpp
@@ -968,6 +968,19 @@ String TranslationServer::get_locale_name(const String &p_locale) const {
return locale_name_map[p_locale];
}
+Array TranslationServer::get_loaded_locales() const {
+ Array locales;
+ for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) {
+
+ const Ref<Translation> &t = E->get();
+ String l = t->get_locale();
+
+ locales.push_back(l);
+ }
+
+ return locales;
+}
+
Vector<String> TranslationServer::get_all_locales() {
Vector<String> locales;
@@ -1168,6 +1181,8 @@ void TranslationServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_translation", "translation"), &TranslationServer::remove_translation);
ClassDB::bind_method(D_METHOD("clear"), &TranslationServer::clear);
+
+ ClassDB::bind_method(D_METHOD("get_loaded_locales"), &TranslationServer::get_loaded_locales);
}
void TranslationServer::load_translations() {
diff --git a/core/translation.h b/core/translation.h
index b12bad0d72..d172b9ecf2 100644
--- a/core/translation.h
+++ b/core/translation.h
@@ -94,6 +94,8 @@ public:
String get_locale_name(const String &p_locale) const;
+ Array get_loaded_locales() const;
+
void add_translation(const Ref<Translation> &p_translation);
void remove_translation(const Ref<Translation> &p_translation);
diff --git a/core/type_info.h b/core/type_info.h
index c38688fea1..d85a63ee42 100644
--- a/core/type_info.h
+++ b/core/type_info.h
@@ -67,43 +67,80 @@ struct TypeInherits {
!TypesAreSame<B volatile const, void volatile const>::value;
};
+namespace GodotTypeInfo {
+enum Metadata {
+ METADATA_NONE,
+ METADATA_INT_IS_INT8,
+ METADATA_INT_IS_INT16,
+ METADATA_INT_IS_INT32,
+ METADATA_INT_IS_INT64,
+ METADATA_INT_IS_UINT8,
+ METADATA_INT_IS_UINT16,
+ METADATA_INT_IS_UINT32,
+ METADATA_INT_IS_UINT64,
+ METADATA_REAL_IS_FLOAT,
+ METADATA_REAL_IS_DOUBLE
+};
+}
+
template <class T, typename = void>
struct GetTypeInfo {
static const Variant::Type VARIANT_TYPE = Variant::NIL;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
static inline PropertyInfo get_class_info() {
ERR_PRINT("GetTypeInfo fallback. Bug!");
return PropertyInfo(); // Not "Nil", this is an error
}
};
-#define MAKE_TYPE_INFO(m_type, m_var_type) \
- template <> \
- struct GetTypeInfo<m_type> { \
- static const Variant::Type VARIANT_TYPE = m_var_type; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo(VARIANT_TYPE, String()); \
- } \
- }; \
- template <> \
- struct GetTypeInfo<const m_type &> { \
- static const Variant::Type VARIANT_TYPE = m_var_type; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo(VARIANT_TYPE, String()); \
- } \
+#define MAKE_TYPE_INFO(m_type, m_var_type) \
+ template <> \
+ struct GetTypeInfo<m_type> { \
+ static const Variant::Type VARIANT_TYPE = m_var_type; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(VARIANT_TYPE, String()); \
+ } \
+ }; \
+ template <> \
+ struct GetTypeInfo<const m_type &> { \
+ static const Variant::Type VARIANT_TYPE = m_var_type; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(VARIANT_TYPE, String()); \
+ } \
+ };
+
+#define MAKE_TYPE_INFO_WITH_META(m_type, m_var_type, m_metadata) \
+ template <> \
+ struct GetTypeInfo<m_type> { \
+ static const Variant::Type VARIANT_TYPE = m_var_type; \
+ static const GodotTypeInfo::Metadata METADATA = m_metadata; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(VARIANT_TYPE, String()); \
+ } \
+ }; \
+ template <> \
+ struct GetTypeInfo<const m_type &> { \
+ static const Variant::Type VARIANT_TYPE = m_var_type; \
+ static const GodotTypeInfo::Metadata METADATA = m_metadata; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(VARIANT_TYPE, String()); \
+ } \
};
MAKE_TYPE_INFO(bool, Variant::BOOL)
-MAKE_TYPE_INFO(uint8_t, Variant::INT)
-MAKE_TYPE_INFO(int8_t, Variant::INT)
-MAKE_TYPE_INFO(uint16_t, Variant::INT)
-MAKE_TYPE_INFO(int16_t, Variant::INT)
-MAKE_TYPE_INFO(uint32_t, Variant::INT)
-MAKE_TYPE_INFO(int32_t, Variant::INT)
-MAKE_TYPE_INFO(int64_t, Variant::INT)
-MAKE_TYPE_INFO(uint64_t, Variant::INT)
+MAKE_TYPE_INFO_WITH_META(uint8_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_UINT8)
+MAKE_TYPE_INFO_WITH_META(int8_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_INT8)
+MAKE_TYPE_INFO_WITH_META(uint16_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_UINT16)
+MAKE_TYPE_INFO_WITH_META(int16_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_INT16)
+MAKE_TYPE_INFO_WITH_META(uint32_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_UINT32)
+MAKE_TYPE_INFO_WITH_META(int32_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_INT32)
+MAKE_TYPE_INFO_WITH_META(uint64_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_UINT64)
+MAKE_TYPE_INFO_WITH_META(int64_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_INT64)
MAKE_TYPE_INFO(wchar_t, Variant::INT)
-MAKE_TYPE_INFO(float, Variant::REAL)
-MAKE_TYPE_INFO(double, Variant::REAL)
+MAKE_TYPE_INFO_WITH_META(float, Variant::REAL, GodotTypeInfo::METADATA_REAL_IS_FLOAT)
+MAKE_TYPE_INFO_WITH_META(double, Variant::REAL, GodotTypeInfo::METADATA_REAL_IS_DOUBLE)
MAKE_TYPE_INFO(String, Variant::STRING)
MAKE_TYPE_INFO(Vector2, Variant::VECTOR2)
@@ -138,6 +175,7 @@ MAKE_TYPE_INFO(BSP_Tree, Variant::DICTIONARY)
template <>
struct GetTypeInfo<RefPtr> {
static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
static inline PropertyInfo get_class_info() {
return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference");
}
@@ -145,6 +183,7 @@ struct GetTypeInfo<RefPtr> {
template <>
struct GetTypeInfo<const RefPtr &> {
static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
static inline PropertyInfo get_class_info() {
return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference");
}
@@ -154,6 +193,7 @@ struct GetTypeInfo<const RefPtr &> {
template <>
struct GetTypeInfo<Variant> {
static const Variant::Type VARIANT_TYPE = Variant::NIL;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
static inline PropertyInfo get_class_info() {
return PropertyInfo(Variant::NIL, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT);
}
@@ -162,25 +202,28 @@ struct GetTypeInfo<Variant> {
template <>
struct GetTypeInfo<const Variant &> {
static const Variant::Type VARIANT_TYPE = Variant::NIL;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
static inline PropertyInfo get_class_info() {
return PropertyInfo(Variant::NIL, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT);
}
};
-#define MAKE_TEMPLATE_TYPE_INFO(m_template, m_type, m_var_type) \
- template <> \
- struct GetTypeInfo<m_template<m_type> > { \
- static const Variant::Type VARIANT_TYPE = m_var_type; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo(VARIANT_TYPE, String()); \
- } \
- }; \
- template <> \
- struct GetTypeInfo<const m_template<m_type> &> { \
- static const Variant::Type VARIANT_TYPE = m_var_type; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo(VARIANT_TYPE, String()); \
- } \
+#define MAKE_TEMPLATE_TYPE_INFO(m_template, m_type, m_var_type) \
+ template <> \
+ struct GetTypeInfo<m_template<m_type> > { \
+ static const Variant::Type VARIANT_TYPE = m_var_type; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(VARIANT_TYPE, String()); \
+ } \
+ }; \
+ template <> \
+ struct GetTypeInfo<const m_template<m_type> &> { \
+ static const Variant::Type VARIANT_TYPE = m_var_type; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(VARIANT_TYPE, String()); \
+ } \
};
MAKE_TEMPLATE_TYPE_INFO(Vector, uint8_t, Variant::POOL_BYTE_ARRAY)
@@ -202,6 +245,7 @@ MAKE_TEMPLATE_TYPE_INFO(PoolVector, Face3, Variant::POOL_VECTOR3_ARRAY)
template <typename T>
struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
static inline PropertyInfo get_class_info() {
return PropertyInfo(StringName(T::get_class_static()));
}
@@ -210,6 +254,7 @@ struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type>
template <typename T>
struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
static inline PropertyInfo get_class_info() {
return PropertyInfo(StringName(T::get_class_static()));
}
@@ -219,6 +264,7 @@ struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>:
template <> \
struct GetTypeInfo<m_impl> { \
static const Variant::Type VARIANT_TYPE = Variant::INT; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
static inline PropertyInfo get_class_info() { \
return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, String(#m_enum).replace("::", ".")); \
} \
diff --git a/core/ustring.cpp b/core/ustring.cpp
index d60bd16921..78feddb229 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -123,6 +123,31 @@ const char *CharString::get_data() const {
return "";
}
+CharString &CharString::operator=(const char *p_cstr) {
+
+ copy_from(p_cstr);
+ return *this;
+}
+
+void CharString::copy_from(const char *p_cstr) {
+
+ if (!p_cstr) {
+ resize(0);
+ return;
+ }
+
+ size_t len = strlen(p_cstr);
+
+ if (len == 0) {
+ resize(0);
+ return;
+ }
+
+ resize(len + 1); // include terminating null char
+
+ strcpy(ptrw(), p_cstr);
+}
+
void String::copy_from(const char *p_cstr) {
if (!p_cstr) {
diff --git a/core/ustring.h b/core/ustring.h
index 85103057df..e2e62874d6 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -101,12 +101,17 @@ public:
_cowdata._ref(p_str._cowdata);
return *this;
}
+ _FORCE_INLINE_ CharString(const char *p_cstr) { copy_from(p_cstr); }
+ CharString &operator=(const char *p_cstr);
bool operator<(const CharString &p_right) const;
CharString &operator+=(char p_char);
int length() const { return size() ? size() - 1 : 0; }
const char *get_data() const;
operator const char *() const { return get_data(); };
+
+protected:
+ void copy_from(const char *p_cstr);
};
typedef wchar_t CharType;
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 143b07418e..f9f73b4e51 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -36,6 +36,7 @@
#include "core/object.h"
#include "core/os/os.h"
#include "core/script_language.h"
+#include "thirdparty/misc/sha256.h"
typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args);
typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args);
@@ -587,6 +588,19 @@ struct _VariantCall {
r_ret = decompressed;
}
+ static void _call_PoolByteArray_sha256_string(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem);
+ PoolByteArray::Read r = ba->read();
+ String s;
+ unsigned char hash[32];
+ sha256_context sha256;
+ sha256_init(&sha256);
+ sha256_hash(&sha256, (unsigned char *)r.ptr(), ba->size());
+ sha256_done(&sha256, hash);
+ s = String::hex_encode_buffer(hash, 32);
+ r_ret = s;
+ }
+
VCALL_LOCALMEM0R(PoolByteArray, size);
VCALL_LOCALMEM2(PoolByteArray, set);
VCALL_LOCALMEM1R(PoolByteArray, get);
@@ -1733,6 +1747,7 @@ void register_variant_methods() {
ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_ascii, varray());
ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_utf8, varray());
+ ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, sha256_string, varray());
ADDFUNC1R(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, compress, INT, "compression_mode", varray(0));
ADDFUNC2R(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, decompress, INT, "buffer_size", INT, "compression_mode", varray(0));
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index 6377197282..d7371b0434 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -1542,6 +1542,9 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r
} else if (c != '=') {
what += String::chr(c);
} else {
+ if (p_stream->is_utf8()) {
+ what.parse_utf8(what.ascii(true).get_data());
+ }
r_assign = what;
Token token;
get_token(p_stream, token, line, r_err_str);