diff options
Diffstat (limited to 'core')
| -rw-r--r-- | core/list.h | 48 | ||||
| -rw-r--r-- | core/math/matrix3.cpp | 15 | ||||
| -rw-r--r-- | core/math/matrix3.h | 2 | ||||
| -rw-r--r-- | core/math/transform.cpp | 12 | ||||
| -rw-r--r-- | core/object.h | 12 | ||||
| -rw-r--r-- | core/resource.cpp | 3 | ||||
| -rw-r--r-- | core/script_language.h | 1 | ||||
| -rw-r--r-- | core/string_buffer.cpp | 102 | ||||
| -rw-r--r-- | core/string_buffer.h | 82 | ||||
| -rw-r--r-- | core/string_builder.cpp | 94 | ||||
| -rw-r--r-- | core/string_builder.h | 79 | ||||
| -rw-r--r-- | core/variant_parser.cpp | 22 |
12 files changed, 442 insertions, 30 deletions
diff --git a/core/list.h b/core/list.h index a67287a9ab..da201e9868 100644 --- a/core/list.h +++ b/core/list.h @@ -291,6 +291,54 @@ public: erase(_data->first); } + Element *insert_after(Element *p_element, const T &p_value) { + CRASH_COND(p_element && (!_data || p_element->data != _data)); + + if (!p_element) { + return push_back(p_value); + } + + Element *n = memnew_allocator(Element, A); + n->value = (T &)p_value; + n->prev_ptr = p_element; + n->next_ptr = p_element->next_ptr; + n->data = _data; + + if (!p_element->next_ptr) { + _data->last = n; + } + + p_element->next_ptr = n; + + _data->size_cache++; + + return n; + } + + Element *insert_before(Element *p_element, const T &p_value) { + CRASH_COND(p_element && (!_data || p_element->data != _data)); + + if (!p_element) { + return push_back(p_value); + } + + Element *n = memnew_allocator(Element, A); + n->value = (T &)p_value; + n->prev_ptr = p_element->prev_ptr; + n->next_ptr = p_element; + n->data = _data; + + if (!p_element->prev_ptr) { + _data->first = n; + } + + p_element->prev_ptr = n; + + _data->size_cache++; + + return n; + } + /** * find an element in the list, */ diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp index 9732a1ff37..4051de7afb 100644 --- a/core/math/matrix3.cpp +++ b/core/math/matrix3.cpp @@ -234,7 +234,22 @@ Basis Basis::scaled(const Vector3 &p_scale) const { return m; } +void Basis::set_scale(const Vector3 &p_scale) { + + set_axis(0, get_axis(0).normalized() * p_scale.x); + set_axis(1, get_axis(1).normalized() * p_scale.y); + set_axis(2, get_axis(2).normalized() * p_scale.z); +} + Vector3 Basis::get_scale() const { + + return Vector3( + Vector3(elements[0][0], elements[1][0], elements[2][0]).length(), + Vector3(elements[0][1], elements[1][1], elements[2][1]).length(), + Vector3(elements[0][2], elements[1][2], elements[2][2]).length()); +} + +Vector3 Basis::get_signed_scale() const { // FIXME: We are assuming M = R.S (R is rotation and S is scaling), and use polar decomposition to extract R and S. // A polar decomposition is M = O.P, where O is an orthogonal matrix (meaning rotation and reflection) and // P is a positive semi-definite matrix (meaning it contains absolute values of scaling along its diagonal). diff --git a/core/math/matrix3.h b/core/math/matrix3.h index 9c9080ac46..23429888e0 100644 --- a/core/math/matrix3.h +++ b/core/math/matrix3.h @@ -97,7 +97,9 @@ public: void scale(const Vector3 &p_scale); Basis scaled(const Vector3 &p_scale) const; + void set_scale(const Vector3 &p_scale); Vector3 get_scale() const; + Vector3 get_signed_scale() const; // transposed dot products _FORCE_INLINE_ real_t tdotx(const Vector3 &v) const { diff --git a/core/math/transform.cpp b/core/math/transform.cpp index 60df69a509..638a39ab73 100644 --- a/core/math/transform.cpp +++ b/core/math/transform.cpp @@ -118,17 +118,17 @@ Transform Transform::interpolate_with(const Transform &p_transform, real_t p_c) /* not sure if very "efficient" but good enough? */ - Vector3 src_scale = basis.get_scale(); - Quat src_rot = basis; + Vector3 src_scale = basis.get_signed_scale(); + Quat src_rot = basis.orthonormalized(); Vector3 src_loc = origin; - Vector3 dst_scale = p_transform.basis.get_scale(); + Vector3 dst_scale = p_transform.basis.get_signed_scale(); Quat dst_rot = p_transform.basis; Vector3 dst_loc = p_transform.origin; - Transform dst; - dst.basis = src_rot.slerp(dst_rot, p_c); - dst.basis.scale(src_scale.linear_interpolate(dst_scale, p_c)); + Transform dst; //this could be made faster by using a single function in Basis.. + dst.basis = src_rot.slerp(dst_rot, p_c).normalized(); + dst.basis.set_scale(src_scale.linear_interpolate(dst_scale, p_c)); dst.origin = src_loc.linear_interpolate(dst_loc, p_c); return dst; diff --git a/core/object.h b/core/object.h index 6e1ed4308e..644e2b8270 100644 --- a/core/object.h +++ b/core/object.h @@ -567,12 +567,6 @@ public: template <class T> static T *cast_to(Object *p_object) { -#ifdef DEBUG_ENABLED - // TODO there are some legitimate reasons to pass NULL as p_object. - // we need to figure out how to deal with that in debug mode. - // This code will return NULL for a NULL input in release mode also. - ERR_FAIL_COND_V(p_object == NULL, NULL); -#endif #ifndef NO_SAFE_CAST return dynamic_cast<T *>(p_object); #else @@ -587,12 +581,6 @@ public: template <class T> static const T *cast_to(const Object *p_object) { -#ifdef DEBUG_ENABLED - // TODO there are some legitimate reasons to pass NULL as p_object. - // we need to figure out how to deal with that in debug mode. - // This code will return NULL for a NULL input in release mode also. - ERR_FAIL_COND_V(p_object == NULL, NULL); -#endif #ifndef NO_SAFE_CAST return dynamic_cast<const T *>(p_object); #else diff --git a/core/resource.cpp b/core/resource.cpp index 37d42226b4..78e20bada4 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -69,12 +69,11 @@ void Resource::set_path(const String &p_path, bool p_take_over) { ResourceCache::resources.get(p_path)->set_name(""); ResourceCache::lock->write_unlock(); } else { - ERR_EXPLAIN("Another resource is loaded from path: " + p_path); - ResourceCache::lock->read_lock(); bool exists = ResourceCache::resources.has(p_path); ResourceCache::lock->read_unlock(); + ERR_EXPLAIN("Another resource is loaded from path: " + p_path); ERR_FAIL_COND(exists); } } diff --git a/core/script_language.h b/core/script_language.h index 342d8c8072..2261737f9a 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -206,6 +206,7 @@ public: virtual int find_function(const String &p_function, const String &p_code) const = 0; virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const = 0; virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; } + virtual bool overrides_external_editor() { return false; } virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; } diff --git a/core/string_buffer.cpp b/core/string_buffer.cpp new file mode 100644 index 0000000000..195068f887 --- /dev/null +++ b/core/string_buffer.cpp @@ -0,0 +1,102 @@ +/*************************************************************************/ +/* string_buffer.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 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. */ +/*************************************************************************/ +#include "string_buffer.h" + +#include <string.h> + +StringBuffer &StringBuffer::append(CharType p_char) { + reserve(string_length + 2); + current_buffer_ptr()[string_length++] = p_char; + return *this; +} + +StringBuffer &StringBuffer::append(const String &p_string) { + return append(p_string.c_str()); +} + +StringBuffer &StringBuffer::append(const char *p_str) { + int len = strlen(p_str); + reserve(string_length + len + 1); + + CharType *buf = current_buffer_ptr(); + for (const char *c_ptr = p_str; c_ptr; ++c_ptr) { + buf[string_length++] = *c_ptr; + } + return *this; +} + +StringBuffer &StringBuffer::append(const CharType *p_str, int p_clip_to_len) { + int len = 0; + while ((p_clip_to_len < 0 || len < p_clip_to_len) && p_str[len]) { + ++len; + } + reserve(string_length + len + 1); + memcpy(&(current_buffer_ptr()[string_length]), p_str, len * sizeof(CharType)); + string_length += len; + + return *this; +} + +StringBuffer &StringBuffer::reserve(int p_size) { + if (p_size < SHORT_BUFFER_SIZE || p_size < buffer.size()) + return *this; + + bool need_copy = string_length > 0 && buffer.empty(); + buffer.resize(next_power_of_2(p_size)); + if (need_copy) { + memcpy(buffer.ptr(), short_buffer, string_length * sizeof(CharType)); + } + + return *this; +} + +int StringBuffer::length() const { + return string_length; +} + +String StringBuffer::as_string() { + current_buffer_ptr()[string_length] = '\0'; + if (buffer.empty()) { + return String(short_buffer); + } else { + buffer.resize(string_length + 1); + return buffer; + } +} + +double StringBuffer::as_double() { + current_buffer_ptr()[string_length] = '\0'; + return String::to_double(current_buffer_ptr()); +} + +int64_t StringBuffer::as_int() { + current_buffer_ptr()[string_length] = '\0'; + return String::to_int(current_buffer_ptr()); +} diff --git a/core/string_buffer.h b/core/string_buffer.h new file mode 100644 index 0000000000..3f36249148 --- /dev/null +++ b/core/string_buffer.h @@ -0,0 +1,82 @@ +/*************************************************************************/ +/* string_buffer.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 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_BUFFER_H +#define STRING_BUFFER_H + +#include "ustring.h" + +class StringBuffer { + static const int SHORT_BUFFER_SIZE = 64; + + CharType short_buffer[SHORT_BUFFER_SIZE]; + String buffer; + int string_length = 0; + + _FORCE_INLINE_ CharType *current_buffer_ptr() { + return static_cast<Vector<CharType> &>(buffer).empty() ? short_buffer : buffer.ptr(); + } + +public: + StringBuffer &append(CharType p_char); + StringBuffer &append(const String &p_string); + StringBuffer &append(const char *p_str); + StringBuffer &append(const CharType *p_str, int p_clip_to_len = -1); + + _FORCE_INLINE_ void operator+=(CharType p_char) { + append(p_char); + } + + _FORCE_INLINE_ void operator+=(const String &p_string) { + append(p_string); + } + + _FORCE_INLINE_ void operator+=(const char *p_str) { + append(p_str); + } + + _FORCE_INLINE_ void operator+=(const CharType *p_str) { + append(p_str); + } + + StringBuffer &reserve(int p_size); + + int length() const; + + String as_string(); + + double as_double(); + int64_t as_int(); + + _FORCE_INLINE_ operator String() { + return as_string(); + } +}; + +#endif diff --git a/core/string_builder.cpp b/core/string_builder.cpp new file mode 100644 index 0000000000..18c710ed2d --- /dev/null +++ b/core/string_builder.cpp @@ -0,0 +1,94 @@ +/*************************************************************************/ +/* string_builder.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 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. */ +/*************************************************************************/ +#include "string_builder.h" + +#include <string.h> + +StringBuilder &StringBuilder::append(const String &p_string) { + + strings.push_back(p_string); + appended_strings.push_back(-1); + + string_length += p_string.length(); + + return *this; +} + +StringBuilder &StringBuilder::append(const char *p_cstring) { + + int32_t len = strlen(p_cstring); + + c_strings.push_back(p_cstring); + appended_strings.push_back(len); + + string_length += len; + + return *this; +} + +String StringBuilder::as_string() const { + + CharType *buffer = memnew_arr(CharType, string_length); + + int current_position = 0; + + int godot_string_elem = 0; + int c_string_elem = 0; + + for (int i = 0; i < appended_strings.size(); i++) { + if (appended_strings[i] == -1) { + // Godot string + const String &s = strings[godot_string_elem]; + + memcpy(buffer + current_position, s.ptr(), s.length() * sizeof(CharType)); + + current_position += s.length(); + + godot_string_elem++; + } else { + + const char *s = c_strings[c_string_elem]; + + for (int32_t j = 0; j < appended_strings[i]; j++) { + buffer[current_position + j] = s[j]; + } + + current_position += appended_strings[i]; + + c_string_elem++; + } + } + + String final_string = String(buffer, string_length); + + memdelete_arr(buffer); + + return final_string; +} diff --git a/core/string_builder.h b/core/string_builder.h new file mode 100644 index 0000000000..7cf2f07872 --- /dev/null +++ b/core/string_builder.h @@ -0,0 +1,79 @@ +/*************************************************************************/ +/* string_builder.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 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_BUILDER_H +#define STRING_BUILDER_H + +#include "core/ustring.h" + +#include "core/vector.h" + +class StringBuilder { + + uint32_t string_length = 0; + + Vector<String> strings; + Vector<const char *> c_strings; + + // -1 means it's a Godot String + // a natural number means C string. + Vector<int32_t> appended_strings; + +public: + StringBuilder &append(const String &p_string); + StringBuilder &append(const char *p_cstring); + + _FORCE_INLINE_ StringBuilder &operator+(const String &p_string) { + return append(p_string); + } + + _FORCE_INLINE_ StringBuilder &operator+(const char *p_cstring) { + return append(p_cstring); + } + + _FORCE_INLINE_ void operator+=(const String &p_string) { + append(p_string); + } + + _FORCE_INLINE_ void operator+=(const char *p_cstring) { + append(p_cstring); + } + + _FORCE_INLINE_ int num_strings_appended() const { + return appended_strings.size(); + } + + String as_string() const; + + _FORCE_INLINE_ operator String() const { + return as_string(); + } +}; + +#endif // STRING_BUILDER_H diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index 65c7b7cfec..d60d10cd3a 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "variant_parser.h" +#include "core/string_buffer.h" #include "io/resource_loader.h" #include "os/input_event.h" #include "os/keyboard.h" @@ -176,14 +177,15 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri }; case '#': { - String color_str = "#"; + StringBuffer color_str; + color_str += '#'; while (true) { CharType ch = p_stream->get_char(); if (p_stream->is_eof()) { r_token.type = TK_EOF; return OK; } else if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) { - color_str += String::chr(ch); + color_str += ch; } else { p_stream->saved = ch; @@ -191,7 +193,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri } } - r_token.value = Color::html(color_str); + r_token.value = Color::html(color_str.as_string()); r_token.type = TK_COLOR; return OK; }; @@ -296,7 +298,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri if (cchar == '-' || (cchar >= '0' && cchar <= '9')) { //a number - String num; + StringBuffer num; #define READING_SIGN 0 #define READING_INT 1 #define READING_DEC 2 @@ -359,7 +361,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri if (reading == READING_DONE) break; - num += String::chr(c); + num += c; c = p_stream->get_char(); } @@ -368,19 +370,19 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri r_token.type = TK_NUMBER; if (is_float) - r_token.value = num.to_double(); + r_token.value = num.as_double(); else - r_token.value = num.to_int(); + r_token.value = num.as_int(); return OK; } else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') { - String id; + StringBuffer id; bool first = true; while ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_' || (!first && cchar >= '0' && cchar <= '9')) { - id += String::chr(cchar); + id += cchar; cchar = p_stream->get_char(); first = false; } @@ -388,7 +390,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri p_stream->saved = cchar; r_token.type = TK_IDENTIFIER; - r_token.value = id; + r_token.value = id.as_string(); return OK; } else { r_err_str = "Unexpected character."; |