diff options
Diffstat (limited to 'core')
| -rw-r--r-- | core/array.cpp | 11 | ||||
| -rw-r--r-- | core/array.h | 2 | ||||
| -rw-r--r-- | core/io/file_access_network.cpp | 2 | ||||
| -rw-r--r-- | core/io/file_access_pack.cpp | 4 | ||||
| -rw-r--r-- | core/io/resource_format_binary.cpp | 45 | ||||
| -rw-r--r-- | core/io/resource_format_binary.h | 2 | ||||
| -rw-r--r-- | core/io/stream_peer.cpp | 3 | ||||
| -rw-r--r-- | core/list.h | 48 | ||||
| -rw-r--r-- | core/map.h | 3 | ||||
| -rw-r--r-- | core/math/camera_matrix.cpp | 85 | ||||
| -rw-r--r-- | core/math/camera_matrix.h | 1 | ||||
| -rw-r--r-- | core/math/triangle_mesh.cpp | 2 | ||||
| -rw-r--r-- | core/ordered_hash_map.h | 6 | ||||
| -rw-r--r-- | core/project_settings.cpp | 10 | ||||
| -rw-r--r-- | core/resource.cpp | 3 | ||||
| -rw-r--r-- | core/script_debugger_remote.cpp | 3 | ||||
| -rw-r--r-- | core/script_language.cpp | 1 | ||||
| -rw-r--r-- | core/set.h | 3 | ||||
| -rw-r--r-- | core/string_buffer.cpp | 102 | ||||
| -rw-r--r-- | core/string_buffer.h | 82 | ||||
| -rw-r--r-- | core/type_info.h | 75 | ||||
| -rw-r--r-- | core/variant_call.cpp | 2 | ||||
| -rw-r--r-- | core/variant_parser.cpp | 22 |
23 files changed, 360 insertions, 157 deletions
diff --git a/core/array.cpp b/core/array.cpp index c35bf5bf0c..2e3fbf858d 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -210,6 +210,17 @@ const Variant &Array::get(int p_idx) const { return operator[](p_idx); } +Array Array::duplicate() const { + + Array new_arr; + int element_count = size(); + new_arr.resize(element_count); + for (int i = 0; i < element_count; i++) { + new_arr[i] = get(i); + } + + return new_arr; +} struct _ArrayVariantSort { _FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const { diff --git a/core/array.h b/core/array.h index 777116ab56..8a647dd13b 100644 --- a/core/array.h +++ b/core/array.h @@ -84,6 +84,8 @@ public: Variant pop_back(); Variant pop_front(); + Array duplicate() const; + Array(const Array &p_from); Array(); ~Array(); diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index d8b8c8c200..58ca2d4c58 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -87,6 +87,8 @@ void FileAccessNetworkClient::_thread_func() { DEBUG_PRINT("SEM WAIT - " + itos(sem->get())); Error err = sem->wait(); + if (err != OK) + ERR_PRINT("sem->wait() failed"); DEBUG_TIME("sem_unlock"); //DEBUG_PRINT("semwait returned "+itos(werr)); DEBUG_PRINT("MUTEX LOCK " + itos(lockcount)); diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index e36ff28220..e511085ac5 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -166,9 +166,9 @@ bool PackedSourcePCK::try_open_pack(const String &p_path) { uint32_t ver_rev = f->get_32(); ERR_EXPLAIN("Pack version unsupported: " + itos(version)); - ERR_FAIL_COND_V(version != PACK_VERSION, ERR_INVALID_DATA); + ERR_FAIL_COND_V(version != PACK_VERSION, false); ERR_EXPLAIN("Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + "." + itos(ver_rev)); - ERR_FAIL_COND_V(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), ERR_INVALID_DATA); + ERR_FAIL_COND_V(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false); for (int i = 0; i < 16; i++) { //reserved diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 084d8ffcab..16ec6cd3c5 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -37,7 +37,7 @@ #include "core/version.h" //#define print_bl(m_what) print_line(m_what) -#define print_bl(m_what) +#define print_bl(m_what) (void)(m_what) enum { @@ -854,12 +854,6 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { } bool big_endian = f->get_32(); -#ifdef BIG_ENDIAN_ENABLED - endian_swap = !big_endian; -#else - bool endian_swap = big_endian; -#endif - bool use_real64 = f->get_32(); f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian @@ -869,7 +863,11 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { uint32_t ver_format = f->get_32(); print_bl("big endian: " + itos(big_endian)); - print_bl("endian swap: " + itos(endian_swap)); +#ifdef BIG_ENDIAN_ENABLED + print_bl("endian swap: " + itos(!big_endian)); +#else + print_bl("endian swap: " + itos(big_endian)); +#endif print_bl("real64: " + itos(use_real64)); print_bl("major: " + itos(ver_major)); print_bl("minor: " + itos(ver_minor)); @@ -964,18 +962,12 @@ String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) { } bool big_endian = f->get_32(); -#ifdef BIG_ENDIAN_ENABLED - endian_swap = !big_endian; -#else - bool endian_swap = big_endian; -#endif - - bool use_real64 = f->get_32(); + f->get_32(); // use_real64 f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian uint32_t ver_major = f->get_32(); - uint32_t ver_minor = f->get_32(); + f->get_32(); // ver_minor uint32_t ver_format = f->get_32(); if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) { @@ -993,8 +985,6 @@ ResourceInteractiveLoaderBinary::ResourceInteractiveLoaderBinary() { f = NULL; stage = 0; - endian_swap = false; - use_real64 = false; error = OK; translation_remapped = false; } @@ -1123,16 +1113,14 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons } bool big_endian = f->get_32(); -#ifdef BIG_ENDIAN_ENABLED - endian_swap = !big_endian; -#else - bool endian_swap = big_endian; -#endif - bool use_real64 = f->get_32(); f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian - fw->store_32(endian_swap); +#ifdef BIG_ENDIAN_ENABLED + fw->store_32(!big_endian); +#else + fw->store_32(big_endian); +#endif fw->set_endian_swap(big_endian != 0); fw->store_32(use_real64); //use real64 @@ -1793,8 +1781,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p } save_unicode_string(p_resource->get_class()); - uint64_t md_at = f->get_pos(); - f->store_64(0); //offset to impoty metadata + f->store_64(0); //offset to import metadata for (int i = 0; i < 14; i++) f->store_32(0); // reserved @@ -1814,11 +1801,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p if (skip_editor && F->get().name.begins_with("__editor")) continue; - if (F->get().usage & PROPERTY_USAGE_STORAGE) { + if ((F->get().usage & PROPERTY_USAGE_STORAGE)) { Property p; p.name_idx = get_string_index(F->get().name); p.value = E->get()->get(F->get().name); - if ((F->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO && p.value.is_zero()) || (F->get().usage & PROPERTY_USAGE_STORE_IF_NONONE && p.value.is_one())) + if (((F->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO) && p.value.is_zero()) || ((F->get().usage & PROPERTY_USAGE_STORE_IF_NONONE) && p.value.is_one())) continue; p.pi = F->get(); diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index ab77c2c9d3..2316f05b3c 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -44,8 +44,6 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader { FileAccess *f; - bool endian_swap; - bool use_real64; uint64_t importmd_ofs; Vector<char> str_buf; diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index 1006158003..f4f81f0807 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -446,6 +446,7 @@ Error StreamPeerBuffer::get_data(uint8_t *p_buffer, int p_bytes) { return OK; } + Error StreamPeerBuffer::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) { if (pointer + p_bytes > data.size()) { @@ -463,6 +464,8 @@ Error StreamPeerBuffer::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_ pointer += r_received; // FIXME: return what? OK or ERR_* + // return OK for now so we don't maybe return garbage + return OK; } int StreamPeerBuffer::get_available_bytes() const { 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/map.h b/core/map.h index 75a38a3440..a37d898a9c 100644 --- a/core/map.h +++ b/core/map.h @@ -453,8 +453,9 @@ private: if (!rp) rp = _data._nil; Element *node = (rp->left == _data._nil) ? rp->right : rp->left; + node->parent = rp->parent; - if (_data._root == (node->parent = rp->parent)) { + if (_data._root == node->parent) { _data._root->left = node; } else { if (rp == rp->parent->left) { diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 0512cdd798..7132b6573e 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -131,7 +131,6 @@ void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_ void CameraMatrix::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far) { // we first calculate our base frustum on our values without taking our lens magnification into account. - real_t display_to_eye = 2.0 * p_display_to_lens; real_t f1 = (p_intraocular_dist * 0.5) / p_display_to_lens; real_t f2 = ((p_display_width - p_intraocular_dist) * 0.5) / p_display_to_lens; real_t f3 = (p_display_width / 4.0) / p_display_to_lens; @@ -265,75 +264,26 @@ void CameraMatrix::get_viewport_size(real_t &r_width, real_t &r_height) const { bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8points) const { - const real_t *matrix = (const real_t *)this->matrix; - - ///////--- Near Plane ---/////// - Plane near_plane = Plane(matrix[3] + matrix[2], - matrix[7] + matrix[6], - matrix[11] + matrix[10], - -matrix[15] - matrix[14]); - near_plane.normalize(); - - ///////--- Far Plane ---/////// - Plane far_plane = Plane(matrix[2] - matrix[3], - matrix[6] - matrix[7], - matrix[10] - matrix[11], - matrix[15] - matrix[14]); - far_plane.normalize(); - - ///////--- Right Plane ---/////// - Plane right_plane = Plane(matrix[0] - matrix[3], - matrix[4] - matrix[7], - matrix[8] - matrix[11], - -matrix[15] + matrix[12]); - right_plane.normalize(); - - ///////--- Top Plane ---/////// - Plane top_plane = Plane(matrix[1] - matrix[3], - matrix[5] - matrix[7], - matrix[9] - matrix[11], - -matrix[15] + matrix[13]); - top_plane.normalize(); - - Vector3 near_endpoint_left, near_endpoint_right; - Vector3 far_endpoint_left, far_endpoint_right; - - bool res = near_plane.intersect_3(right_plane, top_plane, &near_endpoint_right); - ERR_FAIL_COND_V(!res, false); - - res = far_plane.intersect_3(right_plane, top_plane, &far_endpoint_right); - ERR_FAIL_COND_V(!res, false); - - if ((matrix[8] == 0) && (matrix[9] == 0)) { - near_endpoint_left = near_endpoint_right; - near_endpoint_left.x = -near_endpoint_left.x; - - far_endpoint_left = far_endpoint_right; - far_endpoint_left.x = -far_endpoint_left.x; - } else { - ///////--- Left Plane ---/////// - Plane left_plane = Plane(matrix[0] + matrix[3], - matrix[4] + matrix[7], - matrix[8] + matrix[11], - -matrix[15] - matrix[12]); - left_plane.normalize(); + Vector<Plane> planes = get_projection_planes(Transform()); + const Planes intersections[8][3] = { + { PLANE_FAR, PLANE_LEFT, PLANE_TOP }, + { PLANE_FAR, PLANE_LEFT, PLANE_BOTTOM }, + { PLANE_FAR, PLANE_RIGHT, PLANE_TOP }, + { PLANE_FAR, PLANE_RIGHT, PLANE_BOTTOM }, + { PLANE_NEAR, PLANE_LEFT, PLANE_TOP }, + { PLANE_NEAR, PLANE_LEFT, PLANE_BOTTOM }, + { PLANE_NEAR, PLANE_RIGHT, PLANE_TOP }, + { PLANE_NEAR, PLANE_RIGHT, PLANE_BOTTOM }, + }; - res = near_plane.intersect_3(left_plane, top_plane, &near_endpoint_left); - ERR_FAIL_COND_V(!res, false); + for (int i = 0; i < 8; i++) { - res = far_plane.intersect_3(left_plane, top_plane, &far_endpoint_left); + Vector3 point; + bool res = planes[intersections[i][0]].intersect_3(planes[intersections[i][1]], planes[intersections[i][2]], &point); ERR_FAIL_COND_V(!res, false); + p_8points[i] = p_transform.xform(point); } - p_8points[0] = p_transform.xform(Vector3(near_endpoint_right.x, near_endpoint_right.y, near_endpoint_right.z)); - p_8points[1] = p_transform.xform(Vector3(near_endpoint_right.x, -near_endpoint_right.y, near_endpoint_right.z)); - p_8points[2] = p_transform.xform(Vector3(near_endpoint_left.x, near_endpoint_left.y, near_endpoint_left.z)); - p_8points[3] = p_transform.xform(Vector3(near_endpoint_left.x, -near_endpoint_left.y, near_endpoint_left.z)); - p_8points[4] = p_transform.xform(Vector3(far_endpoint_right.x, far_endpoint_right.y, far_endpoint_right.z)); - p_8points[5] = p_transform.xform(Vector3(far_endpoint_right.x, -far_endpoint_right.y, far_endpoint_right.z)); - p_8points[6] = p_transform.xform(Vector3(far_endpoint_left.x, far_endpoint_left.y, far_endpoint_left.z)); - p_8points[7] = p_transform.xform(Vector3(far_endpoint_left.x, -far_endpoint_left.y, far_endpoint_left.z)); - return true; } @@ -610,6 +560,11 @@ int CameraMatrix::get_pixels_per_meter(int p_for_pixel_width) const { return int((result.x * 0.5 + 0.5) * p_for_pixel_width); } +bool CameraMatrix::is_orthogonal() const { + + return matrix[3][3] == 1.0; +} + real_t CameraMatrix::get_fov() 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 175d0cdb1b..3145d73356 100644 --- a/core/math/camera_matrix.h +++ b/core/math/camera_matrix.h @@ -69,6 +69,7 @@ struct CameraMatrix { real_t get_z_near() const; real_t get_aspect() const; real_t get_fov() const; + bool is_orthogonal() const; Vector<Plane> get_projection_planes(const Transform &p_transform) const; diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 614104f698..3b246cb183 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -158,7 +158,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) { max_depth = 0; int max_alloc = fc; - int max = _create_bvh(bw.ptr(), bwp.ptr(), 0, fc, 1, max_depth, max_alloc); + _create_bvh(bw.ptr(), bwp.ptr(), 0, fc, 1, max_depth, max_alloc); bw = PoolVector<BVH>::Write(); //clearup bvh.resize(max_alloc); //resize back diff --git a/core/ordered_hash_map.h b/core/ordered_hash_map.h index 3e619d2b2e..9e95f963e1 100644 --- a/core/ordered_hash_map.h +++ b/core/ordered_hash_map.h @@ -55,8 +55,8 @@ public: friend class OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>; typename InternalList::Element *list_element; - typename InternalList::Element *next_element; typename InternalList::Element *prev_element; + typename InternalList::Element *next_element; Element(typename InternalList::Element *p_element) { list_element = p_element; @@ -69,7 +69,7 @@ public: public: _FORCE_INLINE_ Element() - : list_element(NULL), next_element(NULL), prev_element(NULL) { + : list_element(NULL), prev_element(NULL), next_element(NULL) { } Element next() const { @@ -312,4 +312,4 @@ bool operator!=(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH return (first.list_element != second.list_element); } -#endif // ORDERED_HASH_MAP_H
\ No newline at end of file +#endif // ORDERED_HASH_MAP_H diff --git a/core/project_settings.cpp b/core/project_settings.cpp index a74917162b..23e4961138 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -114,7 +114,15 @@ String ProjectSettings::globalize_path(const String &p_path) const { return p_path.replace("res:/", resource_path); }; return p_path.replace("res://", ""); - }; + } else if (p_path.begins_with("user://")) { + + String data_dir = OS::get_singleton()->get_data_dir(); + if (data_dir != "") { + + return p_path.replace("user:/", data_dir); + }; + return p_path.replace("user://", ""); + } return p_path; } 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_debugger_remote.cpp b/core/script_debugger_remote.cpp index 8875732b8e..f0097054b1 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -125,6 +125,9 @@ void ScriptDebuggerRemote::_put_variable(const String &p_name, const Variant &p_ packet_peer_stream->put_var(p_name); int len = 0; Error err = encode_variant(p_variable, NULL, len); + if (err != OK) + ERR_PRINT("Failed to encode variant"); + if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size packet_peer_stream->put_var(Variant()); } else { diff --git a/core/script_language.cpp b/core/script_language.cpp index bde80a30bc..5ead91f26e 100644 --- a/core/script_language.cpp +++ b/core/script_language.cpp @@ -184,7 +184,6 @@ void ScriptInstance::call_multilevel(const StringName &p_method, VARIANT_ARG_DEC argc++; } - Variant::CallError error; call_multilevel(p_method, argptr, argc); } diff --git a/core/set.h b/core/set.h index 317e180869..f68d78cea1 100644 --- a/core/set.h +++ b/core/set.h @@ -438,8 +438,9 @@ private: if (!rp) rp = _data._nil; Element *node = (rp->left == _data._nil) ? rp->right : rp->left; + node->parent = rp->parent; - if (_data._root == (node->parent = rp->parent)) { + if (_data._root == node->parent) { _data._root->left = node; } else { if (rp == rp->parent->left) { 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/type_info.h b/core/type_info.h index da6047450c..9fb80af0eb 100644 --- a/core/type_info.h +++ b/core/type_info.h @@ -39,28 +39,27 @@ struct TypeInherits { template <class T, typename = void> struct GetTypeInfo { - enum { VARIANT_TYPE = Variant::NIL }; - + static const Variant::Type VARIANT_TYPE = Variant::NIL; 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> { \ - enum { VARIANT_TYPE = m_var_type }; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \ - } \ - }; \ - template <> \ - struct GetTypeInfo<const m_type &> { \ - enum { VARIANT_TYPE = m_var_type }; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo((Variant::Type)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 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()); \ + } \ }; MAKE_TYPE_INFO(bool, Variant::BOOL) @@ -108,14 +107,14 @@ MAKE_TYPE_INFO(BSP_Tree, Variant::DICTIONARY) //for RefPtr template <> struct GetTypeInfo<RefPtr> { - enum { VARIANT_TYPE = Variant::OBJECT }; + static const Variant::Type VARIANT_TYPE = Variant::OBJECT; static inline PropertyInfo get_class_info() { return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference"); } }; template <> struct GetTypeInfo<const RefPtr &> { - enum { VARIANT_TYPE = Variant::OBJECT }; + static const Variant::Type VARIANT_TYPE = Variant::OBJECT; static inline PropertyInfo get_class_info() { return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference"); } @@ -124,7 +123,7 @@ struct GetTypeInfo<const RefPtr &> { //for variant template <> struct GetTypeInfo<Variant> { - enum { VARIANT_TYPE = Variant::NIL }; + static const Variant::Type VARIANT_TYPE = Variant::NIL; static inline PropertyInfo get_class_info() { return PropertyInfo(Variant::NIL, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); } @@ -132,26 +131,26 @@ struct GetTypeInfo<Variant> { template <> struct GetTypeInfo<const Variant &> { - enum { VARIANT_TYPE = Variant::NIL }; + static const Variant::Type VARIANT_TYPE = Variant::NIL; 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> > { \ - enum { VARIANT_TYPE = m_var_type }; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \ - } \ - }; \ - template <> \ - struct GetTypeInfo<const m_template<m_type> &> { \ - enum { VARIANT_TYPE = m_var_type }; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo((Variant::Type)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 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()); \ + } \ }; MAKE_TEMPLATE_TYPE_INFO(Vector, uint8_t, Variant::POOL_BYTE_ARRAY) @@ -171,8 +170,7 @@ MAKE_TEMPLATE_TYPE_INFO(PoolVector, Face3, Variant::POOL_VECTOR3_ARRAY) template <typename T> struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type> { - enum { VARIANT_TYPE = Variant::OBJECT }; - + static const Variant::Type VARIANT_TYPE = Variant::OBJECT; static inline PropertyInfo get_class_info() { return PropertyInfo(StringName(T::get_class_static())); } @@ -180,8 +178,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> { - enum { VARIANT_TYPE = Variant::OBJECT }; - + static const Variant::Type VARIANT_TYPE = Variant::OBJECT; static inline PropertyInfo get_class_info() { return PropertyInfo(StringName(T::get_class_static())); } @@ -190,7 +187,7 @@ struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>: #define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \ template <> \ struct GetTypeInfo<m_impl> { \ - enum { VARIANT_TYPE = Variant::INT }; \ + static const Variant::Type VARIANT_TYPE = Variant::INT; \ 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/variant_call.cpp b/core/variant_call.cpp index ad15f8f5cb..dc1c24d234 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -481,6 +481,7 @@ struct _VariantCall { VCALL_LOCALMEM1(Array, erase); VCALL_LOCALMEM0(Array, sort); VCALL_LOCALMEM2(Array, sort_custom); + VCALL_LOCALMEM0R(Array, duplicate); VCALL_LOCALMEM0(Array, invert); static void _call_PoolByteArray_get_string_from_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) { @@ -1575,6 +1576,7 @@ void register_variant_methods() { ADDFUNC0(ARRAY, NIL, Array, sort, varray()); ADDFUNC2(ARRAY, NIL, Array, sort_custom, OBJECT, "obj", STRING, "func", varray()); ADDFUNC0(ARRAY, NIL, Array, invert, varray()); + ADDFUNC0(ARRAY, ARRAY, Array, duplicate, varray()); ADDFUNC0(POOL_BYTE_ARRAY, INT, PoolByteArray, size, varray()); ADDFUNC2(POOL_BYTE_ARRAY, NIL, PoolByteArray, set, INT, "idx", INT, "byte", varray()); 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."; |