diff --git a/sfw/core/aabb.h b/sfw/core/aabb.h index 407b225..cc074cc 100644 --- a/sfw/core/aabb.h +++ b/sfw/core/aabb.h @@ -163,11 +163,11 @@ inline bool AABB::encloses(const AABB &p_aabb) const { return ( (src_min.x <= dst_min.x) && - (src_max.x > dst_max.x) && + (src_max.x >= dst_max.x) && (src_min.y <= dst_min.y) && - (src_max.y > dst_max.y) && + (src_max.y >= dst_max.y) && (src_min.z <= dst_min.z) && - (src_max.z > dst_max.z)); + (src_max.z >= dst_max.z)); } Vector3 AABB::get_support(const Vector3 &p_normal) const { diff --git a/sfw/core/basis.cpp b/sfw/core/basis.cpp index 89b8687..988f507 100644 --- a/sfw/core/basis.cpp +++ b/sfw/core/basis.cpp @@ -1160,12 +1160,16 @@ void Basis::rotate_sh(real_t *p_values) { p_values[8] = d4 * s_scale_dst4; } -Basis Basis::looking_at(const Vector3 &p_target, const Vector3 &p_up) { +Basis Basis::looking_at(const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front) { #ifdef MATH_CHECKS ERR_FAIL_COND_V_MSG(p_target.is_equal_approx(Vector3()), Basis(), "The target vector can't be zero."); ERR_FAIL_COND_V_MSG(p_up.is_equal_approx(Vector3()), Basis(), "The up vector can't be zero."); #endif - Vector3 v_z = -p_target.normalized(); + Vector3 v_z = p_target.normalized(); + + if (!p_use_model_front) { + v_z = -v_z; + } Vector3 v_x = p_up.cross(v_z); #ifdef MATH_CHECKS ERR_FAIL_COND_V_MSG(v_x.is_equal_approx(Vector3()), Basis(), "The target vector and up vector can't be parallel to each other."); diff --git a/sfw/core/basis.h b/sfw/core/basis.h index 6f94b91..9dab121 100644 --- a/sfw/core/basis.h +++ b/sfw/core/basis.h @@ -264,7 +264,7 @@ struct _NO_DISCARD_CLASS_ Basis { // only be used in cases of single normals, or when the basis changes each time. Vector3 xform_normal(const Vector3 &p_vector) const { return get_normal_xform_basis().xform_normal_fast(p_vector); } - static Basis looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)); + static Basis looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0), bool p_use_model_front = false); static Basis from_scale(const Vector3 &p_scale); operator Quaternion() const { return get_quaternion(); } diff --git a/sfw/core/math_funcs.h b/sfw/core/math_funcs.h index 7fb67ac..e70542a 100644 --- a/sfw/core/math_funcs.h +++ b/sfw/core/math_funcs.h @@ -105,6 +105,9 @@ public: static _ALWAYS_INLINE_ double exp(double p_x) { return ::exp(p_x); } static _ALWAYS_INLINE_ float exp(float p_x) { return ::expf(p_x); } + static _ALWAYS_INLINE_ double exp2(double p_x) { return ::exp2(p_x); } + static _ALWAYS_INLINE_ float exp2(float p_x) { return ::exp2f(p_x); } + static _ALWAYS_INLINE_ double erf(double p_x) { return ::erf(p_x); } static _ALWAYS_INLINE_ float erf(float p_x) { return ::erff(p_x); } diff --git a/sfw/core/transform.cpp b/sfw/core/transform.cpp index f118401..8b8165e 100644 --- a/sfw/core/transform.cpp +++ b/sfw/core/transform.cpp @@ -58,34 +58,7 @@ void Transform::rotate_basis(const Vector3 &p_axis, real_t p_phi) { } void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up) { -#ifdef MATH_CHECKS - ERR_FAIL_COND(p_eye == p_target); - ERR_FAIL_COND(p_up.length() == 0); -#endif - // Reference: MESA source code - Vector3 v_x, v_y, v_z; - - /* Make rotation matrix */ - - /* Z vector */ - v_z = p_eye - p_target; - - v_z.normalize(); - - v_y = p_up; - - v_x = v_y.cross(v_z); -#ifdef MATH_CHECKS - ERR_FAIL_COND(v_x.length() == 0); -#endif - - /* Recompute Y = Z cross X */ - v_y = v_z.cross(v_x); - - v_x.normalize(); - v_y.normalize(); - - basis.set(v_x, v_y, v_z); + basis = Basis::looking_at(p_target - p_eye, p_up); origin = p_eye; } diff --git a/sfw/core/ustring.cpp b/sfw/core/ustring.cpp index 822ef3d..aca7161 100644 --- a/sfw/core/ustring.cpp +++ b/sfw/core/ustring.cpp @@ -24,6 +24,8 @@ #endif //--STRIP +#define PRINT_UNICODE_ERRORS 0 + #if defined(MINGW_ENABLED) || defined(_MSC_VER) #define snprintf _snprintf_s #endif @@ -234,7 +236,9 @@ void String::copy_from(const char *p_cstr) { for (size_t i = 0; i <= len; i++) { uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]); if (c == 0 && i < len) { +#if PRINT_UNICODE_ERRORS print_unicode_error("NUL character", true); +#endif dst[i] = 0x20; } else { dst[i] = c; @@ -267,7 +271,10 @@ void String::copy_from(const char *p_cstr, const int p_clip_to) { for (int i = 0; i < len; i++) { uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]); if (c == 0) { +#if PRINT_UNICODE_ERRORS print_unicode_error("NUL character", true); +#endif + dst[i] = 0x20; } else { dst[i] = c; @@ -296,9 +303,16 @@ void String::copy_from(const wchar_t *p_cstr, const int p_clip_to) { #endif } +void String::copy_from(const Char16String &p_str) { + parse_utf16(p_str.ptr()); +} + void String::copy_from(const CharType &p_char) { if (p_char == 0) { +#if PRINT_UNICODE_ERRORS print_unicode_error("NUL character", true); +#endif + return; } /* @@ -368,7 +382,10 @@ void String::copy_from_unchecked(const CharType *p_char, const int p_length) { for (int i = 0; i < p_length; i++) { if (p_char[i] == 0) { +#if PRINT_UNICODE_ERRORS print_unicode_error("NUL character", true); +#endif + dst[i] = 0x20; continue; } @@ -449,7 +466,10 @@ String &String::operator+=(const String &p_str) { String &String::operator+=(CharType p_char) { if (p_char == 0) { +#if PRINT_UNICODE_ERRORS print_unicode_error("NUL character", true); +#endif + return *this; } /* @@ -484,7 +504,10 @@ String &String::operator+=(const char *p_str) { for (size_t i = 0; i <= rhs_len; i++) { uint8_t c = p_str[i] >= 0 ? p_str[i] : uint8_t(256 + p_str[i]); if (c == 0 && i < rhs_len) { +#if PRINT_UNICODE_ERRORS print_unicode_error("NUL character", true); +#endif + dst[i] = 0x20; } else { dst[i] = c; @@ -889,7 +912,7 @@ String String::substr_index(const int start_index, const int end_index) const { return ""; } - if (end_index >= s) { + if (end_index > s) { return substr(start_index, (s - 1) - start_index); } @@ -2385,13 +2408,16 @@ Vector String::split_floats(const String &p_splitter, bool p_allow_empty) int from = 0; int len = length(); + String buffer = *this; while (true) { int end = find(p_splitter, from); if (end < 0) { end = len; } if (p_allow_empty || (end > from)) { - ret.push_back(String::to_double(&get_data()[from])); + buffer[end] = 0; + ret.push_back(String::to_double(&buffer.get_data()[from])); + buffer[end] = _cowdata.get(end); } if (end == len) { @@ -2409,6 +2435,7 @@ Vector String::split_floats_mk(const Vector &p_splitters, bool p_ int from = 0; int len = length(); + String buffer = *this; while (true) { int idx; int end = findmk(p_splitters, from, &idx); @@ -2420,7 +2447,9 @@ Vector String::split_floats_mk(const Vector &p_splitters, bool p_ } if (p_allow_empty || (end > from)) { - ret.push_back(String::to_double(&get_data()[from])); + buffer[end] = 0; + ret.push_back(String::to_double(&buffer.get_data()[from])); + buffer[end] = _cowdata.get(end); } if (end == len) { @@ -4696,6 +4725,10 @@ String::String(const CharType *p_str) { copy_from(p_str); } +String::String(const Char16String &p_str) { + copy_from(p_str); +} + String::String(const char *p_str, int p_clip_to_len) { copy_from(p_str, p_clip_to_len); } diff --git a/sfw/core/ustring.h b/sfw/core/ustring.h index f5318b9..9376fe3 100644 --- a/sfw/core/ustring.h +++ b/sfw/core/ustring.h @@ -9,10 +9,11 @@ /*************************************************************************/ //--STRIP -#include "cowdata.h" -#include "core/vector.h" #include "char_utils.h" +#include "core/math_defs.h" #include "core/typedefs.h" +#include "core/vector.h" +#include "cowdata.h" //--STRIP /*************************************************************************/ @@ -349,6 +350,13 @@ public: int to_int() const; bool to_bool() const; uint32_t to_uint() const; + _FORCE_INLINE_ real_t to_real() const { +#ifdef REAL_T_IS_DOUBLE + return to_double(); +#else + return to_float(); +#endif + } int hex_to_int(bool p_with_prefix = true) const; int64_t hex_to_int64(bool p_with_prefix = true) const; @@ -367,6 +375,31 @@ public: static double to_double(const wchar_t *p_str, const wchar_t **r_end = nullptr); static double to_double(const CharType *p_str, const CharType **r_end = nullptr); + _FORCE_INLINE_ static real_t to_real(const char *p_str) { +#ifdef REAL_T_IS_DOUBLE + return to_double(p_str); +#else + return to_float(p_str); +#endif + } + + _FORCE_INLINE_ static real_t to_real(const wchar_t *p_str, const wchar_t **r_end = nullptr) { +#ifdef REAL_T_IS_DOUBLE + return to_double(p_str, r_end); +#else + return to_float(p_str, r_end); +#endif + } + + _FORCE_INLINE_ static real_t to_real(const CharType *p_str, const CharType **r_end = nullptr) { +#ifdef REAL_T_IS_DOUBLE + return to_double(p_str, r_end); +#else + return to_float(p_str, r_end); + +#endif + } + static uint32_t num_characters(int64_t p_int); String capitalize() const; @@ -508,6 +541,7 @@ public: String(const char *p_str); String(const wchar_t *p_str); String(const CharType *p_str); + String(const Char16String &p_str); String(const char *p_str, int p_clip_to_len); String(const wchar_t *p_str, int p_clip_to_len); String(const CharType *p_str, int p_clip_to_len); @@ -521,6 +555,7 @@ private: void copy_from(const char *p_cstr, const int p_clip_to); void copy_from(const wchar_t *p_cstr); void copy_from(const wchar_t *p_cstr, const int p_clip_to); + void copy_from(const Char16String &p_str); void copy_from(const CharType *p_cstr); void copy_from(const CharType *p_cstr, const int p_clip_to); diff --git a/sfw/core/vector2.cpp b/sfw/core/vector2.cpp index aad7a62..93571a5 100644 --- a/sfw/core/vector2.cpp +++ b/sfw/core/vector2.cpp @@ -5,6 +5,7 @@ //--STRIP #include "core/vector2.h" +#include "core/vector2i.h" #include "core/ustring.h" //--STRIP @@ -147,6 +148,14 @@ bool Vector2::is_equal_approx(const Vector2 &p_v) const { return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y); } +bool Vector2::is_zero_approx() const { + return Math::is_zero_approx(x) && Math::is_zero_approx(y); +} + Vector2::operator String() const { return "(" + String::num_real(x) + ", " + String::num_real(y) + ")"; } + +Vector2::operator Vector2i() const { + return Vector2i(x, y); +} diff --git a/sfw/core/vector2.h b/sfw/core/vector2.h index 45a16c6..8c29893 100644 --- a/sfw/core/vector2.h +++ b/sfw/core/vector2.h @@ -15,6 +15,7 @@ //--STRIP class String; +struct Vector2i; struct _NO_DISCARD_CLASS_ Vector2 { static const int AXIS_COUNT = 2; @@ -103,6 +104,7 @@ struct _NO_DISCARD_CLASS_ Vector2 { Vector2 reflect(const Vector2 &p_normal) const; bool is_equal_approx(const Vector2 &p_v) const; + bool is_zero_approx() const; Vector2 operator+(const Vector2 &p_v) const; void operator+=(const Vector2 &p_v); @@ -158,6 +160,7 @@ struct _NO_DISCARD_CLASS_ Vector2 { real_t aspect() const { return width / height; } operator String() const; + operator Vector2i() const; _FORCE_INLINE_ Vector2(real_t p_x, real_t p_y) { x = p_x; diff --git a/sfw/core/vector2i.h b/sfw/core/vector2i.h index 2a3e164..1e03428 100644 --- a/sfw/core/vector2i.h +++ b/sfw/core/vector2i.h @@ -107,10 +107,6 @@ struct _NO_DISCARD_CLASS_ Vector2i { operator String() const; operator Vector2() const { return Vector2(x, y); } - inline Vector2i(const Vector2 &p_vec2) { - x = (int)p_vec2.x; - y = (int)p_vec2.y; - } inline Vector2i(int p_x, int p_y) { x = p_x; y = p_y; diff --git a/sfw/core/vector3.cpp b/sfw/core/vector3.cpp index ccdf5e8..d47a708 100644 --- a/sfw/core/vector3.cpp +++ b/sfw/core/vector3.cpp @@ -82,6 +82,10 @@ bool Vector3::is_equal_approx(const Vector3 &p_v) const { 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::is_zero_approx() const { + return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z); +} + Vector3::operator String() const { return "(" + String::num_real(x) + ", " + String::num_real(y) + ", " + String::num_real(z) + ")"; } diff --git a/sfw/core/vector3.h b/sfw/core/vector3.h index 0b7fded..5356847 100644 --- a/sfw/core/vector3.h +++ b/sfw/core/vector3.h @@ -115,6 +115,7 @@ struct _NO_DISCARD_CLASS_ Vector3 { bool is_equal_approx(const Vector3 &p_v) const; inline bool is_equal_approx(const Vector3 &p_v, real_t p_tolerance) const; inline bool is_equal_approxt(const Vector3 &p_v, real_t p_tolerance) const; + bool is_zero_approx() const; /* Operators */ diff --git a/sfw/core/vector4.cpp b/sfw/core/vector4.cpp index dad471d..e1c49c8 100644 --- a/sfw/core/vector4.cpp +++ b/sfw/core/vector4.cpp @@ -47,6 +47,10 @@ bool Vector4::is_equal_approx(const Vector4 &p_vec4) const { return Math::is_equal_approx(x, p_vec4.x) && Math::is_equal_approx(y, p_vec4.y) && Math::is_equal_approx(z, p_vec4.z) && Math::is_equal_approx(w, p_vec4.w); } +bool Vector4::is_zero_approx() const { + return Math::is_zero_approx(x) && Math::is_zero_approx(y) && Math::is_zero_approx(z) && Math::is_zero_approx(w); +} + real_t Vector4::length() const { return Math::sqrt(length_squared()); } diff --git a/sfw/core/vector4.h b/sfw/core/vector4.h index ada22c8..064bcca 100644 --- a/sfw/core/vector4.h +++ b/sfw/core/vector4.h @@ -51,6 +51,7 @@ struct _NO_DISCARD_CLASS_ Vector4 { _FORCE_INLINE_ real_t length_squared() const; bool is_equal_approx(const Vector4 &p_vec4) const; + bool is_zero_approx() const; real_t length() const; void normalize(); Vector4 normalized() const; diff --git a/sfw/object/array.cpp b/sfw/object/array.cpp index ba5fd87..5358fdb 100644 --- a/sfw/object/array.cpp +++ b/sfw/object/array.cpp @@ -7,10 +7,10 @@ #include "array.h" #include "core/hashfuncs.h" +#include "core/ustring.h" #include "core/vector.h" #include "object/object.h" #include "object/variant.h" -#include "core/ustring.h" //--STRIP class ArrayPrivate { @@ -461,6 +461,37 @@ Variant Array::max() const { return maxval; } +bool Array::operator<(const Array &p_array) const { + int a_len = size(); + + int b_len = p_array.size(); + + int min_cmp = MIN(a_len, b_len); + + for (int i = 0; i < min_cmp; i++) { + if (operator[](i) < p_array[i]) { + return true; + + } else if (p_array[i] < operator[](i)) { + return false; + } + } + + return a_len < b_len; +} + +bool Array::operator<=(const Array &p_array) const { + return !operator>(p_array); +} + +bool Array::operator>(const Array &p_array) const { + return p_array < *this; +} + +bool Array::operator>=(const Array &p_array) const { + return !operator<(p_array); +} + const void *Array::id() const { return _p; } diff --git a/sfw/object/array.h b/sfw/object/array.h index 09b8978..e7da9e2 100644 --- a/sfw/object/array.h +++ b/sfw/object/array.h @@ -82,6 +82,11 @@ public: Variant min() const; Variant max() const; + bool operator<(const Array &p_array) const; + bool operator<=(const Array &p_array) const; + bool operator>(const Array &p_array) const; + bool operator>=(const Array &p_array) const; + const void *id() const; String sprintf(const String &p_format, bool *error) const; diff --git a/sfw/object/dictionary.cpp b/sfw/object/dictionary.cpp index bcf3916..fe42660 100644 --- a/sfw/object/dictionary.cpp +++ b/sfw/object/dictionary.cpp @@ -94,6 +94,18 @@ Variant Dictionary::get(const Variant &p_key, const Variant &p_default) const { return *result; } +Variant Dictionary::get_or_add(const Variant &p_key, const Variant &p_default) { + const Variant *result = getptr(p_key); + + if (!result) { + operator[](p_key) = p_default; + + return p_default; + } + + return *result; +} + int Dictionary::size() const { return _p->variant_map.size(); } diff --git a/sfw/object/dictionary.h b/sfw/object/dictionary.h index 9526fea..ff65419 100644 --- a/sfw/object/dictionary.h +++ b/sfw/object/dictionary.h @@ -37,6 +37,7 @@ public: Variant get_valid(const Variant &p_key) const; Variant get(const Variant &p_key, const Variant &p_default) const; + Variant get_or_add(const Variant &p_key, const Variant &p_default); int size() const; bool empty() const; diff --git a/sfw/render_core/input_event.cpp b/sfw/render_core/input_event.cpp index a94d610..cd302c4 100644 --- a/sfw/render_core/input_event.cpp +++ b/sfw/render_core/input_event.cpp @@ -238,6 +238,42 @@ String InputEventKey::as_text() const { return kc; } +Ref InputEventKey::create_reference(uint32_t p_keycode, bool p_physical) { + Ref ie; + + ie.instance(); + + if (p_physical) { + ie->set_physical_scancode(p_keycode & KEY_CODE_MASK); + } else { + ie->set_scancode(p_keycode & KEY_CODE_MASK); + } + + char32_t ch = char32_t(p_keycode & KEY_CODE_MASK); + + if (ch < 0xd800 || (ch > 0xdfff && ch <= 0x10ffff)) { + ie->set_unicode(ch); + } + + if ((p_keycode & KEY_MASK_SHIFT)) { + ie->set_shift(true); + } + + if ((p_keycode & KEY_MASK_ALT)) { + ie->set_alt(true); + } + + if ((p_keycode & KEY_MASK_CTRL)) { + ie->set_control(true); + } + + if ((p_keycode & KEY_MASK_META)) { + ie->set_command(true); + } + + return ie; +} + bool InputEventKey::action_match(const Ref &p_event, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const { Ref key = p_event; if (key.is_null()) { diff --git a/sfw/render_core/input_event.h b/sfw/render_core/input_event.h index 94953f5..957efec 100644 --- a/sfw/render_core/input_event.h +++ b/sfw/render_core/input_event.h @@ -167,6 +167,8 @@ public: virtual String as_text() const; + static Ref create_reference(uint32_t p_keycode_with_modifier_masks, bool p_physical = false); + InputEventKey(); }; diff --git a/sfwl/core/math_funcs.h b/sfwl/core/math_funcs.h index 7fb67ac..e70542a 100644 --- a/sfwl/core/math_funcs.h +++ b/sfwl/core/math_funcs.h @@ -105,6 +105,9 @@ public: static _ALWAYS_INLINE_ double exp(double p_x) { return ::exp(p_x); } static _ALWAYS_INLINE_ float exp(float p_x) { return ::expf(p_x); } + static _ALWAYS_INLINE_ double exp2(double p_x) { return ::exp2(p_x); } + static _ALWAYS_INLINE_ float exp2(float p_x) { return ::exp2f(p_x); } + static _ALWAYS_INLINE_ double erf(double p_x) { return ::erf(p_x); } static _ALWAYS_INLINE_ float erf(float p_x) { return ::erff(p_x); } diff --git a/sfwl/core/ustring.cpp b/sfwl/core/ustring.cpp index 822ef3d..389c7f5 100644 --- a/sfwl/core/ustring.cpp +++ b/sfwl/core/ustring.cpp @@ -24,6 +24,8 @@ #endif //--STRIP +#define PRINT_UNICODE_ERRORS 0 + #if defined(MINGW_ENABLED) || defined(_MSC_VER) #define snprintf _snprintf_s #endif @@ -131,6 +133,10 @@ const char16_t *Char16String::get_data() const { } } +void String::copy_from(const Char16String &p_str) { + parse_utf16(p_str.ptr()); +} + void Char16String::copy_from(const char16_t *p_cstr) { if (!p_cstr) { resize(0); @@ -234,7 +240,9 @@ void String::copy_from(const char *p_cstr) { for (size_t i = 0; i <= len; i++) { uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]); if (c == 0 && i < len) { +#if PRINT_UNICODE_ERRORS print_unicode_error("NUL character", true); +#endif dst[i] = 0x20; } else { dst[i] = c; @@ -267,7 +275,9 @@ void String::copy_from(const char *p_cstr, const int p_clip_to) { for (int i = 0; i < len; i++) { uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]); if (c == 0) { +#if PRINT_UNICODE_ERRORS print_unicode_error("NUL character", true); +#endif dst[i] = 0x20; } else { dst[i] = c; @@ -298,7 +308,9 @@ void String::copy_from(const wchar_t *p_cstr, const int p_clip_to) { void String::copy_from(const CharType &p_char) { if (p_char == 0) { +#if PRINT_UNICODE_ERRORS print_unicode_error("NUL character", true); +#endif return; } /* @@ -368,7 +380,9 @@ void String::copy_from_unchecked(const CharType *p_char, const int p_length) { for (int i = 0; i < p_length; i++) { if (p_char[i] == 0) { +#if PRINT_UNICODE_ERRORS print_unicode_error("NUL character", true); +#endif dst[i] = 0x20; continue; } @@ -449,7 +463,9 @@ String &String::operator+=(const String &p_str) { String &String::operator+=(CharType p_char) { if (p_char == 0) { +#if PRINT_UNICODE_ERRORS print_unicode_error("NUL character", true); +#endif return *this; } /* @@ -484,7 +500,9 @@ String &String::operator+=(const char *p_str) { for (size_t i = 0; i <= rhs_len; i++) { uint8_t c = p_str[i] >= 0 ? p_str[i] : uint8_t(256 + p_str[i]); if (c == 0 && i < rhs_len) { +#if PRINT_UNICODE_ERRORS print_unicode_error("NUL character", true); +#endif dst[i] = 0x20; } else { dst[i] = c; @@ -889,7 +907,7 @@ String String::substr_index(const int start_index, const int end_index) const { return ""; } - if (end_index >= s) { + if (end_index > s) { return substr(start_index, (s - 1) - start_index); } @@ -2385,13 +2403,16 @@ Vector String::split_floats(const String &p_splitter, bool p_allow_empty) int from = 0; int len = length(); + String buffer = *this; while (true) { int end = find(p_splitter, from); if (end < 0) { end = len; } if (p_allow_empty || (end > from)) { - ret.push_back(String::to_double(&get_data()[from])); + buffer[end] = 0; + ret.push_back(String::to_double(&buffer.get_data()[from])); + buffer[end] = _cowdata.get(end); } if (end == len) { @@ -2409,6 +2430,7 @@ Vector String::split_floats_mk(const Vector &p_splitters, bool p_ int from = 0; int len = length(); + String buffer = *this; while (true) { int idx; int end = findmk(p_splitters, from, &idx); @@ -2420,7 +2442,9 @@ Vector String::split_floats_mk(const Vector &p_splitters, bool p_ } if (p_allow_empty || (end > from)) { - ret.push_back(String::to_double(&get_data()[from])); + buffer[end] = 0; + ret.push_back(String::to_double(&buffer.get_data()[from])); + buffer[end] = _cowdata.get(end); } if (end == len) { @@ -4696,6 +4720,10 @@ String::String(const CharType *p_str) { copy_from(p_str); } +String::String(const Char16String &p_str) { + copy_from(p_str); +} + String::String(const char *p_str, int p_clip_to_len) { copy_from(p_str, p_clip_to_len); } diff --git a/sfwl/core/ustring.h b/sfwl/core/ustring.h index f5318b9..b14c6db 100644 --- a/sfwl/core/ustring.h +++ b/sfwl/core/ustring.h @@ -9,10 +9,11 @@ /*************************************************************************/ //--STRIP -#include "cowdata.h" -#include "core/vector.h" #include "char_utils.h" +#include "core/math_defs.h" #include "core/typedefs.h" +#include "core/vector.h" +#include "cowdata.h" //--STRIP /*************************************************************************/ @@ -350,6 +351,14 @@ public: bool to_bool() const; uint32_t to_uint() const; + _FORCE_INLINE_ real_t to_real() const { +#ifdef REAL_T_IS_DOUBLE + return to_double(); +#else + return to_float(); +#endif + } + int hex_to_int(bool p_with_prefix = true) const; int64_t hex_to_int64(bool p_with_prefix = true) const; int64_t bin_to_int64(bool p_with_prefix = true) const; @@ -367,6 +376,31 @@ public: static double to_double(const wchar_t *p_str, const wchar_t **r_end = nullptr); static double to_double(const CharType *p_str, const CharType **r_end = nullptr); + _FORCE_INLINE_ static real_t to_real(const char *p_str) { +#ifdef REAL_T_IS_DOUBLE + return to_double(p_str); +#else + return to_float(p_str); +#endif + } + + _FORCE_INLINE_ static real_t to_real(const wchar_t *p_str, const wchar_t **r_end = nullptr) { +#ifdef REAL_T_IS_DOUBLE + return to_double(p_str, r_end); +#else + return to_float(p_str, r_end); +#endif + } + + _FORCE_INLINE_ static real_t to_real(const CharType *p_str, const CharType **r_end = nullptr) { +#ifdef REAL_T_IS_DOUBLE + return to_double(p_str, r_end); +#else + return to_float(p_str, r_end); + +#endif + } + static uint32_t num_characters(int64_t p_int); String capitalize() const; @@ -508,6 +542,7 @@ public: String(const char *p_str); String(const wchar_t *p_str); String(const CharType *p_str); + String(const Char16String &p_str); String(const char *p_str, int p_clip_to_len); String(const wchar_t *p_str, int p_clip_to_len); String(const CharType *p_str, int p_clip_to_len); @@ -521,6 +556,7 @@ private: void copy_from(const char *p_cstr, const int p_clip_to); void copy_from(const wchar_t *p_cstr); void copy_from(const wchar_t *p_cstr, const int p_clip_to); + void copy_from(const Char16String &p_str); void copy_from(const CharType *p_cstr); void copy_from(const CharType *p_cstr, const int p_clip_to); diff --git a/sfwl/object/array.cpp b/sfwl/object/array.cpp index ba5fd87..5358fdb 100644 --- a/sfwl/object/array.cpp +++ b/sfwl/object/array.cpp @@ -7,10 +7,10 @@ #include "array.h" #include "core/hashfuncs.h" +#include "core/ustring.h" #include "core/vector.h" #include "object/object.h" #include "object/variant.h" -#include "core/ustring.h" //--STRIP class ArrayPrivate { @@ -461,6 +461,37 @@ Variant Array::max() const { return maxval; } +bool Array::operator<(const Array &p_array) const { + int a_len = size(); + + int b_len = p_array.size(); + + int min_cmp = MIN(a_len, b_len); + + for (int i = 0; i < min_cmp; i++) { + if (operator[](i) < p_array[i]) { + return true; + + } else if (p_array[i] < operator[](i)) { + return false; + } + } + + return a_len < b_len; +} + +bool Array::operator<=(const Array &p_array) const { + return !operator>(p_array); +} + +bool Array::operator>(const Array &p_array) const { + return p_array < *this; +} + +bool Array::operator>=(const Array &p_array) const { + return !operator<(p_array); +} + const void *Array::id() const { return _p; } diff --git a/sfwl/object/array.h b/sfwl/object/array.h index 09b8978..e7da9e2 100644 --- a/sfwl/object/array.h +++ b/sfwl/object/array.h @@ -82,6 +82,11 @@ public: Variant min() const; Variant max() const; + bool operator<(const Array &p_array) const; + bool operator<=(const Array &p_array) const; + bool operator>(const Array &p_array) const; + bool operator>=(const Array &p_array) const; + const void *id() const; String sprintf(const String &p_format, bool *error) const; diff --git a/sfwl/object/dictionary.cpp b/sfwl/object/dictionary.cpp index bcf3916..fe42660 100644 --- a/sfwl/object/dictionary.cpp +++ b/sfwl/object/dictionary.cpp @@ -94,6 +94,18 @@ Variant Dictionary::get(const Variant &p_key, const Variant &p_default) const { return *result; } +Variant Dictionary::get_or_add(const Variant &p_key, const Variant &p_default) { + const Variant *result = getptr(p_key); + + if (!result) { + operator[](p_key) = p_default; + + return p_default; + } + + return *result; +} + int Dictionary::size() const { return _p->variant_map.size(); } diff --git a/sfwl/object/dictionary.h b/sfwl/object/dictionary.h index 9526fea..ff65419 100644 --- a/sfwl/object/dictionary.h +++ b/sfwl/object/dictionary.h @@ -37,6 +37,7 @@ public: Variant get_valid(const Variant &p_key) const; Variant get(const Variant &p_key, const Variant &p_default) const; + Variant get_or_add(const Variant &p_key, const Variant &p_default); int size() const; bool empty() const; diff --git a/tools/merger/sfw_core.cpp.inl b/tools/merger/sfw_core.cpp.inl index 53638b9..969a03c 100644 --- a/tools/merger/sfw_core.cpp.inl +++ b/tools/merger/sfw_core.cpp.inl @@ -133,7 +133,13 @@ //--STRIP {{FILE:sfw/core/pcg.cpp}} //--STRIP +//#include "core/vector2i.h" +//#include "core/ustring.h" +//--STRIP +{{FILE:sfw/core/vector2i.cpp}} +//--STRIP //#include "core/vector2.h" +//#include "core/vector2i.h" //#include "core/ustring.h" //--STRIP {{FILE:sfw/core/vector2.cpp}} @@ -173,11 +179,6 @@ //--STRIP {{FILE:sfw/core/plane.cpp}} //--STRIP -//#include "core/vector2i.h" -//#include "core/ustring.h" -//--STRIP -{{FILE:sfw/core/vector2i.cpp}} -//--STRIP //#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D //#include "core/rect2i.h" //--STRIP diff --git a/tools/merger/sfw_full.cpp.inl b/tools/merger/sfw_full.cpp.inl index 422af03..cfdae49 100644 --- a/tools/merger/sfw_full.cpp.inl +++ b/tools/merger/sfw_full.cpp.inl @@ -339,7 +339,13 @@ //--STRIP {{FILE:sfw/core/pcg.cpp}} //--STRIP +//#include "core/vector2i.h" +//#include "core/ustring.h" +//--STRIP +{{FILE:sfw/core/vector2i.cpp}} +//--STRIP //#include "core/vector2.h" +//#include "core/vector2i.h" //#include "core/ustring.h" //--STRIP {{FILE:sfw/core/vector2.cpp}} @@ -379,11 +385,6 @@ //--STRIP {{FILE:sfw/core/plane.cpp}} //--STRIP -//#include "core/vector2i.h" -//#include "core/ustring.h" -//--STRIP -{{FILE:sfw/core/vector2i.cpp}} -//--STRIP //#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D //#include "core/rect2i.h" //--STRIP diff --git a/tools/merger/sfw_gui.cpp.inl b/tools/merger/sfw_gui.cpp.inl index d4c189e..cefeddc 100644 --- a/tools/merger/sfw_gui.cpp.inl +++ b/tools/merger/sfw_gui.cpp.inl @@ -340,7 +340,13 @@ //--STRIP {{FILE:sfw/core/pcg.cpp}} //--STRIP +//#include "core/vector2i.h" +//#include "core/ustring.h" +//--STRIP +{{FILE:sfw/core/vector2i.cpp}} +//--STRIP //#include "core/vector2.h" +//#include "core/vector2i.h" //#include "core/ustring.h" //--STRIP {{FILE:sfw/core/vector2.cpp}} @@ -380,11 +386,6 @@ //--STRIP {{FILE:sfw/core/plane.cpp}} //--STRIP -//#include "core/vector2i.h" -//#include "core/ustring.h" -//--STRIP -{{FILE:sfw/core/vector2i.cpp}} -//--STRIP //#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D //#include "core/rect2i.h" //--STRIP diff --git a/tools/merger/sfw_object.cpp.inl b/tools/merger/sfw_object.cpp.inl index d936bd3..6e5450c 100644 --- a/tools/merger/sfw_object.cpp.inl +++ b/tools/merger/sfw_object.cpp.inl @@ -141,7 +141,13 @@ //--STRIP {{FILE:sfw/core/pcg.cpp}} //--STRIP +//#include "core/vector2i.h" +//#include "core/ustring.h" +//--STRIP +{{FILE:sfw/core/vector2i.cpp}} +//--STRIP //#include "core/vector2.h" +//#include "core/vector2i.h" //#include "core/ustring.h" //--STRIP {{FILE:sfw/core/vector2.cpp}} @@ -181,11 +187,6 @@ //--STRIP {{FILE:sfw/core/plane.cpp}} //--STRIP -//#include "core/vector2i.h" -//#include "core/ustring.h" -//--STRIP -{{FILE:sfw/core/vector2i.cpp}} -//--STRIP //#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D //#include "core/rect2i.h" //--STRIP diff --git a/tools/merger/sfw_render_core.cpp.inl b/tools/merger/sfw_render_core.cpp.inl index 4da849d..4927be1 100644 --- a/tools/merger/sfw_render_core.cpp.inl +++ b/tools/merger/sfw_render_core.cpp.inl @@ -339,7 +339,13 @@ //--STRIP {{FILE:sfw/core/pcg.cpp}} //--STRIP +//#include "core/vector2i.h" +//#include "core/ustring.h" +//--STRIP +{{FILE:sfw/core/vector2i.cpp}} +//--STRIP //#include "core/vector2.h" +//#include "core/vector2i.h" //#include "core/ustring.h" //--STRIP {{FILE:sfw/core/vector2.cpp}} @@ -379,11 +385,6 @@ //--STRIP {{FILE:sfw/core/plane.cpp}} //--STRIP -//#include "core/vector2i.h" -//#include "core/ustring.h" -//--STRIP -{{FILE:sfw/core/vector2i.cpp}} -//--STRIP //#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D //#include "core/rect2i.h" //--STRIP diff --git a/tools/merger/sfw_render_immediate.cpp.inl b/tools/merger/sfw_render_immediate.cpp.inl index 6b02e67..5880867 100644 --- a/tools/merger/sfw_render_immediate.cpp.inl +++ b/tools/merger/sfw_render_immediate.cpp.inl @@ -339,7 +339,13 @@ //--STRIP {{FILE:sfw/core/pcg.cpp}} //--STRIP +//#include "core/vector2i.h" +//#include "core/ustring.h" +//--STRIP +{{FILE:sfw/core/vector2i.cpp}} +//--STRIP //#include "core/vector2.h" +//#include "core/vector2i.h" //#include "core/ustring.h" //--STRIP {{FILE:sfw/core/vector2.cpp}} @@ -379,11 +385,6 @@ //--STRIP {{FILE:sfw/core/plane.cpp}} //--STRIP -//#include "core/vector2i.h" -//#include "core/ustring.h" -//--STRIP -{{FILE:sfw/core/vector2i.cpp}} -//--STRIP //#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D //#include "core/rect2i.h" //--STRIP diff --git a/tools/merger/sfw_render_objects.cpp.inl b/tools/merger/sfw_render_objects.cpp.inl index d0251b0..5c1bc41 100644 --- a/tools/merger/sfw_render_objects.cpp.inl +++ b/tools/merger/sfw_render_objects.cpp.inl @@ -339,7 +339,13 @@ //--STRIP {{FILE:sfw/core/pcg.cpp}} //--STRIP +//#include "core/vector2i.h" +//#include "core/ustring.h" +//--STRIP +{{FILE:sfw/core/vector2i.cpp}} +//--STRIP //#include "core/vector2.h" +//#include "core/vector2i.h" //#include "core/ustring.h" //--STRIP {{FILE:sfw/core/vector2.cpp}} @@ -379,11 +385,6 @@ //--STRIP {{FILE:sfw/core/plane.cpp}} //--STRIP -//#include "core/vector2i.h" -//#include "core/ustring.h" -//--STRIP -{{FILE:sfw/core/vector2i.cpp}} -//--STRIP //#include "core/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D //#include "core/rect2i.h" //--STRIP