diff options
Diffstat (limited to 'core')
51 files changed, 637 insertions, 238 deletions
diff --git a/core/array.cpp b/core/array.cpp index c35bf5bf0..2e3fbf858 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 777116ab5..8a647dd13 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/bind/core_bind.cpp b/core/bind/core_bind.cpp index abe8b9b71..0f217c823 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -568,7 +568,7 @@ Dictionary _OS::get_time(bool utc) const { } /** - * Get a epoch time value from a dictionary of time values + * Get an epoch time value from a dictionary of time values * @p datetime must be populated with the following keys: * day, hour, minute, month, second, year. (dst is ignored). * @@ -1705,7 +1705,7 @@ Variant _File::get_var() const { ERR_FAIL_COND_V(!f, Variant()); uint32_t len = get_32(); PoolVector<uint8_t> buff = get_buffer(len); - ERR_FAIL_COND_V(buff.size() != len, Variant()); + ERR_FAIL_COND_V((uint32_t)buff.size() != len, Variant()); PoolVector<uint8_t>::Read r = buff.read(); diff --git a/core/class_db.cpp b/core/class_db.cpp index 1cb287a14..f5ddd9c76 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -535,7 +535,11 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b minfo.return_val = method->get_return_info(); minfo.flags = method->get_hint_flags(); - minfo.default_arguments = method->get_default_arguments(); + + for (int i = 0; i < method->get_argument_count(); i++) { + if (method->has_default_argument(i)) + minfo.default_arguments.push_back(method->get_default_argument(i)); + } p_methods->push_back(minfo); } diff --git a/core/image.cpp b/core/image.cpp index bb1ce2cee..4d1f32c36 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -1256,9 +1256,9 @@ void Image::create(const char **p_xpm) { if (*line_ptr == '#') { line_ptr++; - uint8_t col_r; - uint8_t col_g; - uint8_t col_b; + uint8_t col_r = 0; + uint8_t col_g = 0; + uint8_t col_b = 0; //uint8_t col_a=255; for (int i = 0; i < 6; i++) { diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h index 2fe142875..ba84c9767 100644 --- a/core/io/file_access_compressed.h +++ b/core/io/file_access_compressed.h @@ -37,11 +37,11 @@ class FileAccessCompressed : public FileAccess { Compression::Mode cmode; bool writing; - int write_pos; + uint32_t write_pos; uint8_t *write_ptr; - int write_buffer_size; - int write_max; - int block_size; + uint32_t write_buffer_size; + uint32_t write_max; + uint32_t block_size; mutable bool read_eof; mutable bool at_end; @@ -57,7 +57,7 @@ class FileAccessCompressed : public FileAccess { mutable int read_block_size; mutable int read_pos; Vector<ReadBlock> read_blocks; - int read_total; + uint32_t read_total; String magic; mutable Vector<uint8_t> buffer; diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index cf82d04ac..12503f3be 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -73,14 +73,14 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8 length = p_base->get_64(); base = p_base->get_pos(); ERR_FAIL_COND_V(p_base->get_len() < base + length, ERR_FILE_CORRUPT); - int ds = length; + uint32_t ds = length; if (ds % 16) { ds += 16 - (ds % 16); } data.resize(ds); - int blen = p_base->get_buffer(data.ptr(), ds); + uint32_t blen = p_base->get_buffer(data.ptr(), ds); ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT); aes256_context ctx; diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h index 3df2806a7..74d00a5a8 100644 --- a/core/io/file_access_encrypted.h +++ b/core/io/file_access_encrypted.h @@ -48,7 +48,7 @@ private: size_t base; size_t length; Vector<uint8_t> data; - mutable size_t pos; + mutable int pos; mutable bool eofed; public: diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index be3107655..58ca2d4c5 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)); @@ -244,14 +246,14 @@ FileAccessNetworkClient::~FileAccessNetworkClient() { memdelete(sem); } -void FileAccessNetwork::_set_block(size_t p_offset, const Vector<uint8_t> &p_block) { +void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block) { int page = p_offset / page_size; ERR_FAIL_INDEX(page, pages.size()); if (page < pages.size() - 1) { ERR_FAIL_COND(p_block.size() != page_size); } else { - ERR_FAIL_COND((p_block.size() != (total_size % page_size))); + ERR_FAIL_COND((p_block.size() != (int)(total_size % page_size))); } buffer_mutex->lock(); diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index d6010cdba..cd5046f00 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -97,7 +97,7 @@ class FileAccessNetwork : public FileAccess { mutable int last_page; mutable uint8_t *last_page_buff; - uint32_t page_size; + int page_size; int read_ahead; int max_pages; @@ -121,7 +121,7 @@ class FileAccessNetwork : public FileAccess { friend class FileAccessNetworkClient; void _queue_page(int p_page) const; void _respond(size_t p_len, Error p_status); - void _set_block(size_t p_offset, const Vector<uint8_t> &p_block); + void _set_block(int p_offset, const Vector<uint8_t> &p_block); public: enum Command { diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index e36ff2822..e511085ac 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/marshalls.cpp b/core/io/marshalls.cpp index af7db904e..0834d6c32 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -333,14 +333,14 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int len -= 12; buf += 12; - int total = namecount + subnamecount; + uint32_t total = namecount + subnamecount; if (flags & 2) total++; if (r_len) (*r_len) += 12; - for (int i = 0; i < total; i++) { + for (uint32_t i = 0; i < total; i++) { ERR_FAIL_COND_V((int)len < 4, ERR_INVALID_DATA); strlen = decode_uint32(buf); @@ -566,7 +566,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int if (count) { data.resize(count); PoolVector<uint8_t>::Write w = data.write(); - for (int i = 0; i < count; i++) { + for (uint32_t i = 0; i < count; i++) { w[i] = buf[i]; } @@ -597,7 +597,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int //const int*rbuf=(const int*)buf; data.resize(count); PoolVector<int>::Write w = data.write(); - for (int i = 0; i < count; i++) { + for (uint32_t i = 0; i < count; i++) { w[i] = decode_uint32(&buf[i * 4]); } @@ -624,7 +624,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int //const float*rbuf=(const float*)buf; data.resize(count); PoolVector<float>::Write w = data.write(); - for (int i = 0; i < count; i++) { + for (uint32_t i = 0; i < count; i++) { w[i] = decode_float(&buf[i * 4]); } diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index f44492248..16ec6cd3c 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 { @@ -102,7 +102,7 @@ StringName ResourceInteractiveLoaderBinary::_get_string() { uint32_t id = f->get_32(); if (id & 0x80000000) { - uint32_t len = id & 0x7FFFFFFF; + int len = id & 0x7FFFFFFF; if (len > str_buf.size()) { str_buf.resize(len); } @@ -336,9 +336,9 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { } break; case OBJECT_EXTERNAL_RESOURCE_INDEX: { //new file format, just refers to an index in the external list - uint32_t erindex = f->get_32(); + int erindex = f->get_32(); - if (erindex >= external_resources.size()) { + if (erindex < 0 || erindex >= external_resources.size()) { WARN_PRINT("Broken external resource! (index out of size"); r_v = Variant(); } else { @@ -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)); @@ -878,7 +876,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) { f->close(); - ERR_EXPLAIN("File Format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a a new engine version: " + local_path); + ERR_EXPLAIN("File Format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path); ERR_FAIL(); } @@ -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; } @@ -1117,19 +1107,20 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons memdelete(f); } ERR_FAIL_COND_V(!fw, ERR_CANT_CREATE); + + uint8_t magic[4] = { 'R', 'S', 'R', 'C' }; + fw->store_buffer(magic, 4); } 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 @@ -1178,7 +1169,7 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons memdelete(f); memdelete(fw); - ERR_EXPLAIN("File Format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a a new engine version: " + local_path); + ERR_EXPLAIN("File Format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path); ERR_FAIL_V(ERR_FILE_UNRECOGNIZED); } @@ -1790,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 @@ -1811,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 ab77c2c9d..2316f05b3 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 100615800..f4f81f080 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/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index 353eabea4..92af24782 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -51,8 +51,8 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S Ref<Translation> translation = Ref<Translation>(memnew(Translation)); int line = 1; - bool skip_this; - bool skip_next; + bool skip_this = false; + bool skip_next = false; while (true) { diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index 62110bfe2..3a4be7cd1 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -385,7 +385,7 @@ void XMLParser::_bind_methods() { Error XMLParser::read() { // if not end reached, parse the node - if (P && (P - data) < length - 1 && *P != 0) { + if (P && (P - data) < (int64_t)length - 1 && *P != 0) { _parse_current_node(); return OK; } diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h index 28c57b567..26616ed94 100644 --- a/core/io/xml_parser.h +++ b/core/io/xml_parser.h @@ -67,7 +67,7 @@ public: private: char *data; char *P; - int length; + uint64_t length; void unescape(String &p_str); Vector<String> special_characters; String node_name; diff --git a/core/list.h b/core/list.h index 0cad6038f..da201e986 100644 --- a/core/list.h +++ b/core/list.h @@ -180,7 +180,7 @@ private: public: /** - * return an const iterator to the beginning of the list. + * return a const iterator to the beginning of the list. */ _FORCE_INLINE_ const Element *front() const { @@ -195,7 +195,7 @@ public: }; /** - * return an const iterator to the last member of the list. + * return a const iterator to the last member of the list. */ _FORCE_INLINE_ const Element *back() const { @@ -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 75a38a344..a37d898a9 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 0512cdd79..7132b6573 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 175d0cdb1..3145d7335 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/face3.cpp b/core/math/face3.cpp index 748faad28..e1b172e49 100644 --- a/core/math/face3.cpp +++ b/core/math/face3.cpp @@ -296,7 +296,7 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V /** FIND SUPPORT VERTEX **/ int vert_support_idx = -1; - real_t support_max; + real_t support_max = 0; for (int i = 0; i < 3; i++) { diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp index 9732a1ff3..4051de7af 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 9c9080ac4..23429888e 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/quick_hull.cpp b/core/math/quick_hull.cpp index e9a383df4..e0137b692 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -76,7 +76,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me int simplex[4]; { - real_t max, min; + real_t max = 0, min = 0; for (int i = 0; i < p_points.size(); i++) { @@ -99,7 +99,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me //third vertex is one most further away from the line { - real_t maxd; + real_t maxd = 0; Vector3 rel12 = p_points[simplex[0]] - p_points[simplex[1]]; for (int i = 0; i < p_points.size(); i++) { @@ -121,7 +121,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me //fourth vertex is the one most further away from the plane { - real_t maxd; + real_t maxd = 0; Plane p(p_points[simplex[0]], p_points[simplex[1]], p_points[simplex[2]]); for (int i = 0; i < p_points.size(); i++) { @@ -389,8 +389,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me for (int i = 0; i < f.indices.size(); i++) { - uint32_t a = E->get().indices[i]; - uint32_t b = E->get().indices[(i + 1) % f.indices.size()]; + int a = E->get().indices[i]; + int b = E->get().indices[(i + 1) % f.indices.size()]; Edge e(a, b); Map<Edge, RetFaceConnect>::Element *F = ret_edges.find(e); diff --git a/core/math/transform.cpp b/core/math/transform.cpp index 60df69a50..638a39ab7 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/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 614104f69..3b246cb18 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/method_bind.h b/core/method_bind.h index 75f09b2cd..3c43f86b5 100644 --- a/core/method_bind.h +++ b/core/method_bind.h @@ -369,7 +369,7 @@ MethodBind *create_vararg_method_bind(Variant (T::*p_method)(const Variant **, i // tale of an amazing hack.. // -// if you declare an nonexistent class.. +// if you declare a nonexistent class.. class __UnexistingClass; #include "method_bind.gen.inc" diff --git a/core/object.h b/core/object.h index 6e1ed4308..644e2b827 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/ordered_hash_map.h b/core/ordered_hash_map.h index 3e619d2b2..9e95f963e 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/os/os.cpp b/core/os/os.cpp index 1292b7eee..764f7fe6e 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -64,12 +64,13 @@ void OS::debug_break(){ void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) { - const char *err_type; + const char *err_type = "**ERROR**"; switch (p_type) { case ERR_ERROR: err_type = "**ERROR**"; break; case ERR_WARNING: err_type = "**WARNING**"; break; case ERR_SCRIPT: err_type = "**SCRIPT ERROR**"; break; case ERR_SHADER: err_type = "**SHADER ERROR**"; break; + default: ERR_PRINT("Unknown error type"); break; } if (p_rationale && *p_rationale) diff --git a/core/packed_data_container.cpp b/core/packed_data_container.cpp index 4040680c6..ad8438e41 100644 --- a/core/packed_data_container.cpp +++ b/core/packed_data_container.cpp @@ -61,7 +61,7 @@ Variant PackedDataContainer::_iter_init_ofs(const Array &p_iter, uint32_t p_offs Variant PackedDataContainer::_iter_next_ofs(const Array &p_iter, uint32_t p_offset) { Array ref = p_iter; - uint32_t size = _size(p_offset); + int size = _size(p_offset); if (ref.size() != 1) return false; int pos = ref[0]; @@ -74,7 +74,7 @@ Variant PackedDataContainer::_iter_next_ofs(const Array &p_iter, uint32_t p_offs Variant PackedDataContainer::_iter_get_ofs(const Variant &p_iter, uint32_t p_offset) { - uint32_t size = _size(p_offset); + int size = _size(p_offset); int pos = p_iter; if (pos < 0 || pos >= size) return Variant(); @@ -164,7 +164,7 @@ Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, b if (p_key.is_num()) { int idx = p_key; - uint32_t len = decode_uint32(r + 4); + int len = decode_uint32(r + 4); if (idx < 0 || idx >= len) { err = true; return Variant(); @@ -183,7 +183,7 @@ Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, b uint32_t len = decode_uint32(r + 4); bool found = false; - for (int i = 0; i < len; i++) { + for (uint32_t i = 0; i < len; i++) { uint32_t khash = decode_uint32(r + 8 + i * 12 + 0); if (khash == hash) { Variant key = _get_at_ofs(decode_uint32(r + 8 + i * 12 + 4), rd.ptr(), err); diff --git a/core/pool_allocator.cpp b/core/pool_allocator.cpp index c122d2154..c5f6d0dde 100644 --- a/core/pool_allocator.cpp +++ b/core/pool_allocator.cpp @@ -339,9 +339,9 @@ Error PoolAllocator::resize(ID p_mem, int p_new_size) { ERR_FAIL_COND_V(e->lock, ERR_ALREADY_IN_USE); } - int alloc_size = aligned(p_new_size); + uint32_t alloc_size = aligned(p_new_size); - if (aligned(e->len) == alloc_size) { + if ((uint32_t)aligned(e->len) == alloc_size) { e->len = p_new_size; mt_unlock(); @@ -374,7 +374,7 @@ Error PoolAllocator::resize(ID p_mem, int p_new_size) { } //no need to move stuff around, it fits before the next block - int next_pos; + uint32_t next_pos; if (entry_indices_pos + 1 == entry_count) { next_pos = pool_size; // - static_area_size; } else { diff --git a/core/project_settings.cpp b/core/project_settings.cpp index a74917162..23e496113 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/reference.h b/core/reference.h index 5fe829631..ca3ae6041 100644 --- a/core/reference.h +++ b/core/reference.h @@ -62,7 +62,7 @@ public: template <class T> class Ref { - T *reference; + T *reference = NULL; void ref(const Ref &p_from) { diff --git a/core/resource.cpp b/core/resource.cpp index 37d42226b..78e20bada 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 8875732b8..f0097054b 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 bde80a30b..5ead91f26 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/script_language.h b/core/script_language.h index 342d8c807..2261737f9 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/set.h b/core/set.h index 317e18086..f68d78cea 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 000000000..195068f88 --- /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 000000000..3f3624914 --- /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 000000000..18c710ed2 --- /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 000000000..7cf2f0787 --- /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/type_info.h b/core/type_info.h index da6047450..9fb80af0e 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/ustring.cpp b/core/ustring.cpp index ee07c7b11..8273ed144 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -588,7 +588,7 @@ String String::camelcase_to_underscore(bool lowercase) const { const char a = 'a', z = 'z'; int start_index = 0; - for (size_t i = 1; i < this->size(); i++) { + for (int i = 1; i < this->size(); i++) { bool is_upper = cstr[i] >= A && cstr[i] <= Z; bool is_number = cstr[i] >= '0' && cstr[i] <= '9'; bool are_next_2_lower = false; @@ -3655,12 +3655,12 @@ String String::sprintf(const Array &values, bool *error) const { CharType *self = (CharType *)c_str(); bool in_format = false; int value_index = 0; - int min_chars; - int min_decimals; - bool in_decimals; - bool pad_with_zeroes; - bool left_justified; - bool show_sign; + int min_chars = 0; + int min_decimals = 0; + bool in_decimals = false; + bool pad_with_zeroes = false; + bool left_justified = false; + bool show_sign = false; *error = true; @@ -3687,12 +3687,12 @@ String String::sprintf(const Array &values, bool *error) const { } int64_t value = values[value_index]; - int base; + int base = 16; bool capitalize = false; switch (c) { case 'd': base = 10; break; case 'o': base = 8; break; - case 'x': base = 16; break; + case 'x': break; case 'X': base = 16; capitalize = true; @@ -3842,7 +3842,7 @@ String String::sprintf(const Array &values, bool *error) const { } break; } - case '.': { // Float separtor. + case '.': { // Float separator. if (in_decimals) { return "too many decimal points in format"; } @@ -3851,7 +3851,7 @@ String String::sprintf(const Array &values, bool *error) const { break; } - case '*': { // Dyanmic width, based on value. + case '*': { // Dynamic width, based on value. if (value_index >= values.size()) { return "not enough arguments for format string"; } diff --git a/core/variant_call.cpp b/core/variant_call.cpp index ad15f8f5c..dc1c24d23 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 65c7b7cfe..d60d10cd3 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."; diff --git a/core/vmap.h b/core/vmap.h index f0977341e..8165a919b 100644 --- a/core/vmap.h +++ b/core/vmap.h @@ -60,9 +60,13 @@ class VMap { int low = 0; int high = _data.size() - 1; - int middle; const _Pair *a = &_data[0]; + int middle = 0; +#if DEBUG_ENABLED + if (low > high) + ERR_PRINT("low > high, this may be a bug"); +#endif while (low <= high) { middle = (low + high) / 2; diff --git a/core/vset.h b/core/vset.h index 7b12ae0b2..67af6c1a4 100644 --- a/core/vset.h +++ b/core/vset.h @@ -46,8 +46,13 @@ class VSet { int low = 0; int high = _data.size() - 1; - int middle; const T *a = &_data[0]; + int middle = 0; + +#if DEBUG_ENABLED + if (low > high) + ERR_PRINT("low > high, this may be a bug"); +#endif while (low <= high) { middle = (low + high) / 2; |
