summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/allocators.h195
-rw-r--r--core/bind/core_bind.cpp13
-rw-r--r--core/bind/core_bind.h9
-rw-r--r--core/command_queue_mt.cpp4
-rw-r--r--core/command_queue_mt.h19
-rw-r--r--core/core_string_names.h2
-rw-r--r--core/engine.cpp1
-rw-r--r--core/error_macros.h14
-rw-r--r--core/global_constants.h2
-rw-r--r--core/hashfuncs.h2
-rw-r--r--core/image.cpp12
-rw-r--r--core/image.h2
-rw-r--r--core/io/file_access_buffered.h2
-rw-r--r--core/io/file_access_buffered_fa.h2
-rw-r--r--core/io/file_access_zip.cpp6
-rw-r--r--core/io/http_client.cpp98
-rw-r--r--core/io/http_client.h1
-rw-r--r--core/io/marshalls.cpp6
-rw-r--r--core/io/resource_format_binary.cpp42
-rw-r--r--core/io/resource_format_binary.h8
-rw-r--r--core/io/resource_importer.cpp (renamed from core/io/resource_import.cpp)4
-rw-r--r--core/io/resource_importer.h (renamed from core/io/resource_import.h)8
-rw-r--r--core/io/resource_loader.cpp48
-rw-r--r--core/io/resource_loader.h20
-rw-r--r--core/io/resource_saver.cpp6
-rw-r--r--core/list.h2
-rw-r--r--core/math/a_star.cpp23
-rw-r--r--core/math/basis.cpp (renamed from core/math/matrix3.cpp)8
-rw-r--r--core/math/basis.h (renamed from core/math/matrix3.h)8
-rw-r--r--core/math/bsp_tree.h2
-rw-r--r--core/math/expression.cpp62
-rw-r--r--core/math/face3.h10
-rw-r--r--core/math/geometry.h2
-rw-r--r--core/math/math_funcs.h4
-rw-r--r--core/math/octree.h20
-rw-r--r--core/math/quat.cpp2
-rw-r--r--core/math/quick_hull.cpp10
-rw-r--r--core/math/random_pcg.h5
-rw-r--r--core/math/transform.h2
-rw-r--r--core/math/transform_2d.cpp12
-rw-r--r--core/math/transform_2d.h1
-rw-r--r--core/math/triangle_mesh.cpp2
-rw-r--r--core/math/vector3.cpp2
-rw-r--r--core/math/vector3.h2
-rw-r--r--core/node_path.h2
-rw-r--r--core/object.cpp47
-rw-r--r--core/object.h2
-rw-r--r--core/os/input_event.cpp14
-rw-r--r--core/os/input_event.h1
-rw-r--r--core/os/os.h13
-rw-r--r--core/os/shell.cpp46
-rw-r--r--core/os/shell.h52
-rw-r--r--core/pair.h6
-rw-r--r--core/pool_vector.cpp (renamed from core/dvector.cpp)6
-rw-r--r--core/pool_vector.h (renamed from core/dvector.h)24
-rw-r--r--core/project_settings.cpp6
-rw-r--r--core/register_core_types.cpp2
-rw-r--r--core/script_language.cpp6
-rw-r--r--core/script_language.h3
-rw-r--r--core/sort_array.h (renamed from core/sort.h)8
-rw-r--r--core/string_name.cpp (renamed from core/string_db.cpp)4
-rw-r--r--core/string_name.h (renamed from core/string_db.h)8
-rw-r--r--core/translation.cpp2
-rw-r--r--core/typedefs.h2
-rw-r--r--core/undo_redo.cpp43
-rw-r--r--core/ustring.cpp21
-rw-r--r--core/ustring.h8
-rw-r--r--core/variant.cpp77
-rw-r--r--core/variant.h14
-rw-r--r--core/variant_call.cpp36
-rw-r--r--core/variant_construct_string.cpp438
-rw-r--r--core/variant_op.cpp18
-rw-r--r--core/variant_parser.cpp34
-rw-r--r--core/vector.h2
-rw-r--r--core/version.h5
75 files changed, 552 insertions, 1103 deletions
diff --git a/core/allocators.h b/core/allocators.h
deleted file mode 100644
index 8d4af7a9fb..0000000000
--- a/core/allocators.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*************************************************************************/
-/* allocators.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 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 ALLOCATORS_H
-#define ALLOCATORS_H
-
-#include "core/os/memory.h"
-
-template <int PREALLOC_COUNT = 64, int MAX_HANDS = 8>
-class BalloonAllocator {
-
- enum {
-
- USED_FLAG = (1 << 30),
- USED_MASK = USED_FLAG - 1
- };
-
- struct Balloon {
-
- Balloon *next;
- Balloon *prev;
- uint32_t hand;
- };
-
- struct Hand {
-
- int used;
- int allocated;
- Balloon *first;
- Balloon *last;
- };
-
- Hand hands[MAX_HANDS];
-
-public:
- void *alloc(size_t p_size) {
-
- size_t max = (1 << MAX_HANDS);
- ERR_FAIL_COND_V(p_size > max, NULL);
-
- unsigned int hand = 0;
-
- while (p_size > (size_t)(1 << hand))
- ++hand;
-
- Hand &h = hands[hand];
-
- if (h.used == h.allocated) {
-
- for (int i = 0; i < PREALLOC_COUNT; i++) {
-
- Balloon *b = (Balloon *)memalloc(sizeof(Balloon) + (1 << hand));
- b->hand = hand;
- if (h.last) {
-
- b->prev = h.last;
- h.last->next = b;
- h.last = b;
- } else {
-
- b->prev = NULL;
- h.last = b;
- h.first = b;
- }
- }
-
- h.last->next = NULL;
- h.allocated += PREALLOC_COUNT;
- }
-
- Balloon *pick = h.last;
-
- ERR_FAIL_COND_V((pick->hand & USED_FLAG), NULL);
-
- // remove last
- h.last = h.last->prev;
- h.last->next = NULL;
-
- pick->next = h.first;
- h.first->prev = pick;
- pick->prev = NULL;
- h.first = pick;
- h.used++;
- pick->hand |= USED_FLAG;
-
- return (void *)(pick + 1);
- }
-
- void free(void *p_ptr) {
-
- Balloon *b = (Balloon *)p_ptr;
- b -= 1;
-
- ERR_FAIL_COND(!(b->hand & USED_FLAG));
-
- b->hand = b->hand & USED_MASK; // not used
- int hand = b->hand;
-
- Hand &h = hands[hand];
-
- if (b == h.first)
- h.first = b->next;
-
- if (b->prev)
- b->prev->next = b->next;
- if (b->next)
- b->next->prev = b->prev;
-
- if (h.last != b) {
- h.last->next = b;
- b->prev = h.last;
- b->next = NULL;
- h.last = b;
- }
-
- h.used--;
-
- if (h.used <= (h.allocated - (PREALLOC_COUNT * 2))) { // this is done to ensure no alloc/free is done constantly
-
- for (int i = 0; i < PREALLOC_COUNT; i++) {
- ERR_CONTINUE(h.last->hand & USED_FLAG);
-
- Balloon *new_last = h.last->prev;
- if (new_last)
- new_last->next = NULL;
- memfree(h.last);
- h.last = new_last;
- }
- h.allocated -= PREALLOC_COUNT;
- }
- }
-
- BalloonAllocator() {
-
- for (int i = 0; i < MAX_HANDS; i++) {
-
- hands[i].allocated = 0;
- hands[i].used = 0;
- hands[i].first = NULL;
- hands[i].last = NULL;
- }
- }
-
- void clear() {
-
- for (int i = 0; i < MAX_HANDS; i++) {
-
- while (hands[i].first) {
-
- Balloon *b = hands[i].first;
- hands[i].first = b->next;
- memfree(b);
- }
-
- hands[i].allocated = 0;
- hands[i].used = 0;
- hands[i].first = NULL;
- hands[i].last = NULL;
- }
- }
-
- ~BalloonAllocator() {
-
- clear();
- }
-};
-
-#endif // ALLOCATORS_H
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index f17d7372e2..f6828ea76a 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -225,8 +225,12 @@ int _OS::get_video_driver_count() const {
return OS::get_singleton()->get_video_driver_count();
}
-String _OS::get_video_driver_name(int p_driver) const {
- return OS::get_singleton()->get_video_driver_name(p_driver);
+String _OS::get_video_driver_name(VideoDriver p_driver) const {
+ return OS::get_singleton()->get_video_driver_name((int)p_driver);
+}
+
+_OS::VideoDriver _OS::get_current_video_driver() const {
+ return (VideoDriver)OS::get_singleton()->get_current_video_driver();
}
int _OS::get_audio_driver_count() const {
@@ -1108,6 +1112,8 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_video_driver_count"), &_OS::get_video_driver_count);
ClassDB::bind_method(D_METHOD("get_video_driver_name", "driver"), &_OS::get_video_driver_name);
+ ClassDB::bind_method(D_METHOD("get_current_video_driver"), &_OS::get_current_video_driver);
+
ClassDB::bind_method(D_METHOD("get_audio_driver_count"), &_OS::get_audio_driver_count);
ClassDB::bind_method(D_METHOD("get_audio_driver_name", "driver"), &_OS::get_audio_driver_name);
ClassDB::bind_method(D_METHOD("get_connected_midi_inputs"), &_OS::get_connected_midi_inputs);
@@ -1276,6 +1282,9 @@ void _OS::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "window_position"), "set_window_position", "get_window_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "window_size"), "set_window_size", "get_window_size");
+ BIND_ENUM_CONSTANT(VIDEO_DRIVER_GLES2);
+ BIND_ENUM_CONSTANT(VIDEO_DRIVER_GLES3);
+
BIND_ENUM_CONSTANT(DAY_SUNDAY);
BIND_ENUM_CONSTANT(DAY_MONDAY);
BIND_ENUM_CONSTANT(DAY_TUESDAY);
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 1c8b985d73..f3bc4644d8 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -103,6 +103,11 @@ protected:
static _OS *singleton;
public:
+ enum VideoDriver {
+ VIDEO_DRIVER_GLES3,
+ VIDEO_DRIVER_GLES2,
+ };
+
enum PowerState {
POWERSTATE_UNKNOWN, /**< cannot determine power status */
POWERSTATE_ON_BATTERY, /**< Not plugged in, running on the battery */
@@ -152,7 +157,8 @@ public:
Array get_fullscreen_mode_list(int p_screen = 0) const;
virtual int get_video_driver_count() const;
- virtual String get_video_driver_name(int p_driver) const;
+ virtual String get_video_driver_name(VideoDriver p_driver) const;
+ virtual VideoDriver get_current_video_driver() const;
virtual int get_audio_driver_count() const;
virtual String get_audio_driver_name(int p_driver) const;
@@ -355,6 +361,7 @@ public:
_OS();
};
+VARIANT_ENUM_CAST(_OS::VideoDriver);
VARIANT_ENUM_CAST(_OS::PowerState);
VARIANT_ENUM_CAST(_OS::Weekday);
VARIANT_ENUM_CAST(_OS::Month);
diff --git a/core/command_queue_mt.cpp b/core/command_queue_mt.cpp
index 36d4b0a32f..2bdf02295c 100644
--- a/core/command_queue_mt.cpp
+++ b/core/command_queue_mt.cpp
@@ -97,7 +97,7 @@ tryagain:
return false;
}
- dealloc_ptr += (size >> 1) + sizeof(uint32_t);
+ dealloc_ptr += (size >> 1) + 8;
return true;
}
@@ -107,6 +107,7 @@ CommandQueueMT::CommandQueueMT(bool p_sync) {
write_ptr = 0;
dealloc_ptr = 0;
mutex = Mutex::create();
+ command_mem = (uint8_t *)memalloc(COMMAND_MEM_SIZE);
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
@@ -128,4 +129,5 @@ CommandQueueMT::~CommandQueueMT() {
memdelete(sync_sems[i].sem);
}
+ memfree(command_mem);
}
diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h
index 3fd660a3db..59eabd8786 100644
--- a/core/command_queue_mt.h
+++ b/core/command_queue_mt.h
@@ -36,6 +36,7 @@
#include "core/os/semaphore.h"
#include "core/simple_type.h"
#include "core/typedefs.h"
+
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -254,6 +255,7 @@
unlock(); \
if (sync) sync->post(); \
ss->sem->wait(); \
+ ss->in_use = false; \
}
#define CMD_SYNC_TYPE(N) CommandSync##N<T, M COMMA(N) COMMA_SEP_LIST(TYPE_ARG, N)>
@@ -270,6 +272,7 @@
unlock(); \
if (sync) sync->post(); \
ss->sem->wait(); \
+ ss->in_use = false; \
}
#define MAX_CMD_PARAMS 13
@@ -295,7 +298,6 @@ class CommandQueueMT {
virtual void post() {
sync_sem->sem->post();
- sync_sem->in_use = false;
}
};
@@ -318,7 +320,7 @@ class CommandQueueMT {
SYNC_SEMAPHORES = 8
};
- uint8_t command_mem[COMMAND_MEM_SIZE];
+ uint8_t *command_mem;
uint32_t read_ptr;
uint32_t write_ptr;
uint32_t dealloc_ptr;
@@ -330,7 +332,7 @@ class CommandQueueMT {
T *allocate() {
// alloc size is size+T+safeguard
- uint32_t alloc_size = sizeof(T) + sizeof(uint32_t);
+ uint32_t alloc_size = ((sizeof(T) + 8 - 1) & ~(8 - 1)) + 8;
tryagain:
@@ -360,7 +362,7 @@ class CommandQueueMT {
}
// if this happens, it's a bug
- ERR_FAIL_COND_V((COMMAND_MEM_SIZE - write_ptr) < sizeof(uint32_t), NULL);
+ ERR_FAIL_COND_V((COMMAND_MEM_SIZE - write_ptr) < 8, NULL);
// zero means, wrap to beginning
uint32_t *p = (uint32_t *)&command_mem[write_ptr];
@@ -372,12 +374,13 @@ class CommandQueueMT {
// Allocate the size and the 'in use' bit.
// First bit used to mark if command is still in use (1)
// or if it has been destroyed and can be deallocated (0).
+ uint32_t size = (sizeof(T) + 8 - 1) & ~(8 - 1);
uint32_t *p = (uint32_t *)&command_mem[write_ptr];
- *p = (sizeof(T) << 1) | 1;
- write_ptr += sizeof(uint32_t);
+ *p = (size << 1) | 1;
+ write_ptr += 8;
// allocate the command
T *cmd = memnew_placement(&command_mem[write_ptr], T);
- write_ptr += sizeof(T);
+ write_ptr += size;
return cmd;
}
@@ -415,7 +418,7 @@ class CommandQueueMT {
goto tryagain;
}
- read_ptr += sizeof(uint32_t);
+ read_ptr += 8;
CommandBase *cmd = reinterpret_cast<CommandBase *>(&command_mem[read_ptr]);
diff --git a/core/core_string_names.h b/core/core_string_names.h
index 1a837cdc2e..6fea40e1b2 100644
--- a/core/core_string_names.h
+++ b/core/core_string_names.h
@@ -31,7 +31,7 @@
#ifndef CORE_STRING_NAMES_H
#define CORE_STRING_NAMES_H
-#include "core/string_db.h"
+#include "core/string_name.h"
class CoreStringNames {
diff --git a/core/engine.cpp b/core/engine.cpp
index 4dba41853d..9607dedb3c 100644
--- a/core/engine.cpp
+++ b/core/engine.cpp
@@ -98,6 +98,7 @@ Dictionary Engine::get_version_info() const {
#else
dict["patch"] = 0;
#endif
+ dict["hex"] = VERSION_HEX;
dict["status"] = VERSION_STATUS;
dict["build"] = VERSION_BUILD;
dict["year"] = VERSION_YEAR;
diff --git a/core/error_macros.h b/core/error_macros.h
index 60a0e8a7dc..3aa8ed4596 100644
--- a/core/error_macros.h
+++ b/core/error_macros.h
@@ -154,6 +154,20 @@ extern bool _err_error_exists;
_err_error_exists = false; \
} while (0); // (*)
+/** An index has failed if m_index >=m_size, the function exists.
+* This function returns an error value, if returning Error, please select the most
+* appropriate error condition from error_macros.h
+*/
+
+#define ERR_FAIL_UNSIGNED_INDEX_V(m_index, m_size, m_retval) \
+ do { \
+ if (unlikely((m_index) >= (m_size))) { \
+ _err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
+ return m_retval; \
+ } else \
+ _err_error_exists = false; \
+ } while (0); // (*)
+
/** Use this one if there is no sensible fallback, that is, the error is unrecoverable.
* We'll return a null reference and try to keep running.
*/
diff --git a/core/global_constants.h b/core/global_constants.h
index 47c1a4dafc..c798a3b9bc 100644
--- a/core/global_constants.h
+++ b/core/global_constants.h
@@ -31,7 +31,7 @@
#ifndef GLOBAL_CONSTANTS_H
#define GLOBAL_CONSTANTS_H
-#include "core/string_db.h"
+#include "core/string_name.h"
class GlobalConstants {
public:
diff --git a/core/hashfuncs.h b/core/hashfuncs.h
index 811ce6264e..07d78dcbde 100644
--- a/core/hashfuncs.h
+++ b/core/hashfuncs.h
@@ -34,7 +34,7 @@
#include "core/math/math_defs.h"
#include "core/math/math_funcs.h"
#include "core/node_path.h"
-#include "core/string_db.h"
+#include "core/string_name.h"
#include "core/typedefs.h"
#include "core/ustring.h"
diff --git a/core/image.cpp b/core/image.cpp
index 91c3d05a29..5a287ca50e 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -1789,7 +1789,7 @@ Error Image::decompress() {
_image_decompress_pvrtc(this);
else if (format == FORMAT_ETC && _image_decompress_etc1)
_image_decompress_etc1(this);
- else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RGB8A1 && _image_decompress_etc1)
+ else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RGB8A1 && _image_decompress_etc2)
_image_decompress_etc2(this);
else
return ERR_UNAVAILABLE;
@@ -2901,15 +2901,15 @@ void Image::fix_alpha_edges() {
if (dist >= closest_dist)
continue;
- const uint8_t *rp = &srcptr[(k * width + l) << 2];
+ const uint8_t *rp2 = &srcptr[(k * width + l) << 2];
- if (rp[3] < alpha_threshold)
+ if (rp2[3] < alpha_threshold)
continue;
closest_dist = dist;
- closest_color[0] = rp[0];
- closest_color[1] = rp[1];
- closest_color[2] = rp[2];
+ closest_color[0] = rp2[0];
+ closest_color[1] = rp2[1];
+ closest_color[2] = rp2[2];
}
}
diff --git a/core/image.h b/core/image.h
index b23f8cac46..872b84d565 100644
--- a/core/image.h
+++ b/core/image.h
@@ -32,8 +32,8 @@
#define IMAGE_H
#include "core/color.h"
-#include "core/dvector.h"
#include "core/math/rect2.h"
+#include "core/pool_vector.h"
#include "core/resource.h"
/**
diff --git a/core/io/file_access_buffered.h b/core/io/file_access_buffered.h
index 756045a674..4065d77c58 100644
--- a/core/io/file_access_buffered.h
+++ b/core/io/file_access_buffered.h
@@ -31,8 +31,8 @@
#ifndef FILE_ACCESS_BUFFERED_H
#define FILE_ACCESS_BUFFERED_H
-#include "core/dvector.h"
#include "core/os/file_access.h"
+#include "core/pool_vector.h"
#include "core/ustring.h"
class FileAccessBuffered : public FileAccess {
diff --git a/core/io/file_access_buffered_fa.h b/core/io/file_access_buffered_fa.h
index 5180f2344f..be960fbc25 100644
--- a/core/io/file_access_buffered_fa.h
+++ b/core/io/file_access_buffered_fa.h
@@ -54,7 +54,7 @@ class FileAccessBufferedFA : public FileAccessBuffered {
cache.offset = p_offset;
cache.buffer.resize(p_size);
- // on dvector
+ // on PoolVector
//PoolVector<uint8_t>::Write write = cache.buffer.write();
//f.get_buffer(write.ptrw(), p_size);
diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp
index 66b911e83c..be28c9a877 100644
--- a/core/io/file_access_zip.cpp
+++ b/core/io/file_access_zip.cpp
@@ -168,10 +168,10 @@ bool ZipArchive::try_open_pack(const String &p_path) {
zlib_filefunc_def io;
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- if (!f)
+ FileAccess *fa = FileAccess::open(p_path, FileAccess::READ);
+ if (!fa)
return false;
- io.opaque = f;
+ io.opaque = fa;
io.zopen_file = godot_open;
io.zread_file = godot_read;
io.zwrite_file = godot_write;
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index b3fd814870..e5c6d2a4f2 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -278,6 +278,7 @@ void HTTPClient::close() {
body_size = -1;
body_left = 0;
chunk_left = 0;
+ chunk_trailer_part = 0;
read_until_eof = false;
response_num = 0;
handshaking = false;
@@ -421,16 +422,16 @@ Error HTTPClient::poll() {
chunked = false;
body_left = 0;
chunk_left = 0;
+ chunk_trailer_part = false;
read_until_eof = false;
response_str.clear();
response_headers.clear();
response_num = RESPONSE_OK;
- // Per the HTTP 1.1 spec, keep-alive is the default, but in practice
- // it's safe to assume it only if the explicit header is found, allowing
- // to handle body-up-to-EOF responses on naive servers; that's what Curl
- // and browsers do
- bool keep_alive = false;
+ // Per the HTTP 1.1 spec, keep-alive is the default.
+ // Not following that specification breaks standard implemetations.
+ // Broken web servers should be fixed.
+ bool keep_alive = true;
for (int i = 0; i < responses.size(); i++) {
@@ -447,8 +448,8 @@ Error HTTPClient::poll() {
if (encoding == "chunked") {
chunked = true;
}
- } else if (s.begins_with("connection: keep-alive")) {
- keep_alive = true;
+ } else if (s.begins_with("connection: close")) {
+ keep_alive = false;
}
if (i == 0 && responses[i].begins_with("HTTP")) {
@@ -505,13 +506,37 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
ERR_FAIL_COND_V(status != STATUS_BODY, PoolByteArray());
+ PoolByteArray ret;
Error err = OK;
if (chunked) {
while (true) {
- if (chunk_left == 0) {
+ if (chunk_trailer_part) {
+ // We need to consume the trailer part too or keep-alive will break
+ uint8_t b;
+ int rec = 0;
+ err = _get_http_data(&b, 1, rec);
+
+ if (rec == 0)
+ break;
+
+ chunk.push_back(b);
+ int cs = chunk.size();
+ if ((cs >= 2 && chunk[cs - 2] == '\r' && chunk[cs - 1] == '\n')) {
+ if (cs == 2) {
+ // Finally over
+ chunk_trailer_part = false;
+ status = STATUS_CONNECTED;
+ chunk.clear();
+ break;
+ } else {
+ // We do not process nor return the trailer data
+ chunk.clear();
+ }
+ }
+ } else if (chunk_left == 0) {
// Reading length
uint8_t b;
int rec = 0;
@@ -525,7 +550,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
if (chunk.size() > 32) {
ERR_PRINT("HTTP Invalid chunk hex len");
status = STATUS_CONNECTION_ERROR;
- return PoolByteArray();
+ break;
}
if (chunk.size() > 2 && chunk[chunk.size() - 2] == '\r' && chunk[chunk.size() - 1] == '\n') {
@@ -543,22 +568,22 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
else {
ERR_PRINT("HTTP Chunk len not in hex!!");
status = STATUS_CONNECTION_ERROR;
- return PoolByteArray();
+ break;
}
len <<= 4;
len |= v;
if (len > (1 << 24)) {
ERR_PRINT("HTTP Chunk too big!! >16mb");
status = STATUS_CONNECTION_ERROR;
- return PoolByteArray();
+ break;
}
}
if (len == 0) {
// End reached!
- status = STATUS_CONNECTED;
+ chunk_trailer_part = true;
chunk.clear();
- return PoolByteArray();
+ break;
}
chunk_left = len + 2;
@@ -578,18 +603,13 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
if (chunk[chunk.size() - 2] != '\r' || chunk[chunk.size() - 1] != '\n') {
ERR_PRINT("HTTP Invalid chunk terminator (not \\r\\n)");
status = STATUS_CONNECTION_ERROR;
- return PoolByteArray();
+ break;
}
- PoolByteArray ret;
ret.resize(chunk.size() - 2);
- {
- PoolByteArray::Write w = ret.write();
- copymem(w.ptr(), chunk.ptr(), chunk.size() - 2);
- }
+ PoolByteArray::Write w = ret.write();
+ copymem(w.ptr(), chunk.ptr(), chunk.size() - 2);
chunk.clear();
-
- return ret;
}
break;
@@ -599,45 +619,26 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
} else {
int to_read = !read_until_eof ? MIN(body_left, read_chunk_size) : read_chunk_size;
- PoolByteArray ret;
ret.resize(to_read);
int _offset = 0;
- while (read_until_eof || to_read > 0) {
+ while (to_read > 0) {
int rec = 0;
{
PoolByteArray::Write w = ret.write();
err = _get_http_data(w.ptr() + _offset, to_read, rec);
}
- if (rec < 0) {
- if (to_read > 0) // Ended up reading less
- ret.resize(_offset);
+ if (rec <= 0) { // Ended up reading less
+ ret.resize(_offset);
break;
} else {
_offset += rec;
+ to_read -= rec;
if (!read_until_eof) {
body_left -= rec;
- to_read -= rec;
- } else {
- if (rec < to_read) {
- ret.resize(_offset);
- err = ERR_FILE_EOF;
- break;
- }
- ret.resize(_offset + to_read);
}
}
- }
- if (!read_until_eof) {
- if (body_left == 0) {
- status = STATUS_CONNECTED;
- }
- return ret;
- } else {
- if (err == ERR_FILE_EOF) {
- err = OK; // EOF is expected here
- close();
- return ret;
- }
+ if (err != OK)
+ break;
}
}
@@ -652,12 +653,12 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
status = STATUS_CONNECTION_ERROR;
}
- } else if (body_left == 0 && !chunked) {
+ } else if (body_left == 0 && !chunked && !read_until_eof) {
status = STATUS_CONNECTED;
}
- return PoolByteArray();
+ return ret;
}
HTTPClient::Status HTTPClient::get_status() const {
@@ -719,6 +720,7 @@ HTTPClient::HTTPClient() {
body_left = 0;
read_until_eof = false;
chunk_left = 0;
+ chunk_trailer_part = false;
response_num = 0;
ssl = false;
blocking = false;
diff --git a/core/io/http_client.h b/core/io/http_client.h
index 1ad44d5f01..85ee1959a2 100644
--- a/core/io/http_client.h
+++ b/core/io/http_client.h
@@ -172,6 +172,7 @@ private:
bool chunked;
Vector<uint8_t> chunk;
int chunk_left;
+ bool chunk_trailer_part;
int body_size;
int body_left;
bool read_until_eof;
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index eec1c55744..5087a63b68 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -889,11 +889,11 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
if (buf) {
encode_uint32(uint32_t(np.get_name_count()) | 0x80000000, buf); //for compatibility with the old format
encode_uint32(np.get_subname_count(), buf + 4);
- uint32_t flags = 0;
+ uint32_t np_flags = 0;
if (np.is_absolute())
- flags |= 1;
+ np_flags |= 1;
- encode_uint32(flags, buf + 8);
+ encode_uint32(np_flags, buf + 8);
buf += 12;
}
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 4d4134b745..d2c656b8eb 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -296,9 +296,9 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_OBJECT: {
- uint32_t type = f->get_32();
+ uint32_t objtype = f->get_32();
- switch (type) {
+ switch (objtype) {
case OBJECT_EMPTY: {
//do none
@@ -317,7 +317,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
case OBJECT_EXTERNAL_RESOURCE: {
//old file format, still around for compatibility
- String type = get_unicode_string();
+ String exttype = get_unicode_string();
String path = get_unicode_string();
if (path.find("://") == -1 && path.is_rel_path()) {
@@ -329,7 +329,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
path = remaps[path];
}
- RES res = ResourceLoader::load(path, type);
+ RES res = ResourceLoader::load(path, exttype);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
@@ -346,7 +346,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
r_v = Variant();
} else {
- String type = external_resources[erindex].type;
+ String exttype = external_resources[erindex].type;
String path = external_resources[erindex].path;
if (path.find("://") == -1 && path.is_rel_path()) {
@@ -354,7 +354,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
}
- RES res = ResourceLoader::load(path, type);
+ RES res = ResourceLoader::load(path, exttype);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
@@ -1314,8 +1314,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} else {
f->store_32(VARIANT_INT);
- int val = p_property;
- f->store_32(int32_t(val));
+ f->store_32(int32_t(p_property));
}
} break;
@@ -1667,7 +1666,20 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
if (E->get().usage & PROPERTY_USAGE_STORAGE) {
- _find_resources(res->get(E->get().name));
+ Variant value = res->get(E->get().name);
+ if (E->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
+ RES sres = value;
+ if (sres.is_valid()) {
+ NonPersistentKey npk;
+ npk.base = res;
+ npk.property = E->get().name;
+ non_persistent_map[npk] = sres;
+ resource_set.insert(sres);
+ saved_resources.push_back(sres);
+ }
+ } else {
+ _find_resources(value);
+ }
}
}
@@ -1811,7 +1823,17 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
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_RESOURCE_NOT_PERSISTENT) {
+ NonPersistentKey npk;
+ npk.base = E->get();
+ npk.property = F->get().name;
+ if (non_persistent_map.has(npk)) {
+ p.value = non_persistent_map[npk];
+ }
+ } else {
+ p.value = E->get()->get(F->get().name);
+ }
Variant default_value = ClassDB::class_get_default_property_value(E->get()->get_class(), F->get().name);
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index 8f2c48e745..c3c477b805 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -123,6 +123,14 @@ class ResourceFormatSaverBinaryInstance {
FileAccess *f;
String magic;
Set<RES> resource_set;
+
+ struct NonPersistentKey { //for resource properties generated on the fly
+ RES base;
+ StringName property;
+ bool operator<(const NonPersistentKey &p_key) const { return base == p_key.base ? property < p_key.property : base < p_key.base; }
+ };
+
+ Map<NonPersistentKey, RES> non_persistent_map;
Map<StringName, int> string_map;
Vector<StringName> strings;
diff --git a/core/io/resource_import.cpp b/core/io/resource_importer.cpp
index 63dc0b6a26..9327e000f5 100644
--- a/core/io/resource_import.cpp
+++ b/core/io/resource_importer.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* resource_import.cpp */
+/* resource_importer.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "resource_import.h"
+#include "resource_importer.h"
#include "core/os/os.h"
#include "core/variant_parser.h"
diff --git a/core/io/resource_import.h b/core/io/resource_importer.h
index 96dd7983e6..32c39a8085 100644
--- a/core/io/resource_import.h
+++ b/core/io/resource_importer.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* resource_import.h */
+/* resource_importer.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RESOURCE_IMPORT_H
-#define RESOURCE_IMPORT_H
+#ifndef RESOURCE_IMPORTER_H
+#define RESOURCE_IMPORTER_H
#include "core/io/resource_loader.h"
@@ -110,4 +110,4 @@ public:
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL) = 0;
};
-#endif // RESOURCE_IMPORT_H
+#endif // RESOURCE_IMPORTER_H
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 02e4d8dc7a..98309048bb 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -30,7 +30,7 @@
#include "resource_loader.h"
-#include "core/io/resource_import.h"
+#include "core/io/resource_importer.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
#include "core/path_remap.h"
@@ -55,7 +55,7 @@ Error ResourceInteractiveLoader::wait() {
ResourceInteractiveLoader::~ResourceInteractiveLoader() {
if (path_loading != String()) {
- ResourceLoader::_remove_from_loading_map(path_loading);
+ ResourceLoader::_remove_from_loading_map_and_thread(path_loading, path_loading_thread);
}
}
@@ -293,10 +293,14 @@ bool ResourceLoader::_add_to_loading_map(const String &p_path) {
loading_map_mutex->lock();
}
- if (loading_map.has(p_path)) {
+ LoadingMapKey key;
+ key.path = p_path;
+ key.thread = Thread::get_caller_id();
+
+ if (loading_map.has(key)) {
success = false;
} else {
- loading_map[p_path] = true;
+ loading_map[key] = true;
success = true;
}
@@ -312,7 +316,27 @@ void ResourceLoader::_remove_from_loading_map(const String &p_path) {
loading_map_mutex->lock();
}
- loading_map.erase(p_path);
+ LoadingMapKey key;
+ key.path = p_path;
+ key.thread = Thread::get_caller_id();
+
+ loading_map.erase(key);
+
+ if (loading_map_mutex) {
+ loading_map_mutex->unlock();
+ }
+}
+
+void ResourceLoader::_remove_from_loading_map_and_thread(const String &p_path, Thread::ID p_thread) {
+ if (loading_map_mutex) {
+ loading_map_mutex->lock();
+ }
+
+ LoadingMapKey key;
+ key.path = p_path;
+ key.thread = p_thread;
+
+ loading_map.erase(key);
if (loading_map_mutex) {
loading_map_mutex->unlock();
@@ -471,6 +495,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
ril->resource = res_cached;
ril->path_loading = local_path;
+ ril->path_loading_thread = Thread::get_caller_id();
return ril;
}
}
@@ -499,6 +524,7 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
if (!p_no_cache) {
ril->set_local_path(local_path);
ril->path_loading = local_path;
+ ril->path_loading_thread = Thread::get_caller_id();
}
if (xl_remapped)
@@ -879,9 +905,9 @@ bool ResourceLoader::add_custom_resource_format_loader(String script_path) {
void ResourceLoader::remove_custom_resource_format_loader(String script_path) {
- Ref<ResourceFormatLoader> loader = _find_custom_resource_format_loader(script_path);
- if (loader.is_valid())
- remove_resource_format_loader(loader);
+ Ref<ResourceFormatLoader> custom_loader = _find_custom_resource_format_loader(script_path);
+ if (custom_loader.is_valid())
+ remove_resource_format_loader(custom_loader);
}
void ResourceLoader::add_custom_loaders() {
@@ -919,7 +945,7 @@ void ResourceLoader::remove_custom_loaders() {
}
Mutex *ResourceLoader::loading_map_mutex = NULL;
-HashMap<String, int> ResourceLoader::loading_map;
+HashMap<ResourceLoader::LoadingMapKey, int, ResourceLoader::LoadingMapKeyHasher> ResourceLoader::loading_map;
void ResourceLoader::initialize() {
#ifndef NO_THREADS
@@ -929,9 +955,9 @@ void ResourceLoader::initialize() {
void ResourceLoader::finalize() {
#ifndef NO_THREADS
- const String *K = NULL;
+ const LoadingMapKey *K = NULL;
while ((K = loading_map.next(K))) {
- ERR_PRINTS("Exited while resource is being loaded: " + *K);
+ ERR_PRINTS("Exited while resource is being loaded: " + K->path);
}
loading_map.clear();
memdelete(loading_map_mutex);
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 622b74a998..70eb1a3de0 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -31,8 +31,8 @@
#ifndef RESOURCE_LOADER_H
#define RESOURCE_LOADER_H
+#include "core/os/thread.h"
#include "core/resource.h"
-
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -42,6 +42,7 @@ class ResourceInteractiveLoader : public Reference {
GDCLASS(ResourceInteractiveLoader, Reference);
friend class ResourceLoader;
String path_loading;
+ Thread::ID path_loading_thread;
protected:
static void _bind_methods();
@@ -121,10 +122,25 @@ class ResourceLoader {
static Ref<ResourceFormatLoader> _find_custom_resource_format_loader(String path);
static Mutex *loading_map_mutex;
- static HashMap<String, int> loading_map;
+
+ //used to track paths being loaded in a thread, avoids cyclic recursion
+ struct LoadingMapKey {
+ String path;
+ Thread::ID thread;
+ bool operator==(const LoadingMapKey &p_key) const {
+ return (thread == p_key.thread && path == p_key.path);
+ }
+ };
+ struct LoadingMapKeyHasher {
+
+ static _FORCE_INLINE_ uint32_t hash(const LoadingMapKey &p_key) { return p_key.path.hash() + HashMapHasherDefault::hash(p_key.thread); }
+ };
+
+ static HashMap<LoadingMapKey, int, LoadingMapKeyHasher> loading_map;
static bool _add_to_loading_map(const String &p_path);
static void _remove_from_loading_map(const String &p_path);
+ static void _remove_from_loading_map_and_thread(const String &p_path, Thread::ID p_thread);
public:
static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp
index 279788796c..c992e2bf94 100644
--- a/core/io/resource_saver.cpp
+++ b/core/io/resource_saver.cpp
@@ -233,9 +233,9 @@ bool ResourceSaver::add_custom_resource_format_saver(String script_path) {
void ResourceSaver::remove_custom_resource_format_saver(String script_path) {
- Ref<ResourceFormatSaver> saver = _find_custom_resource_format_saver(script_path);
- if (saver.is_valid())
- remove_resource_format_saver(saver);
+ Ref<ResourceFormatSaver> custom_saver = _find_custom_resource_format_saver(script_path);
+ if (custom_saver.is_valid())
+ remove_resource_format_saver(custom_saver);
}
void ResourceSaver::add_custom_savers() {
diff --git a/core/list.h b/core/list.h
index dd4ea3bd89..c26aad6463 100644
--- a/core/list.h
+++ b/core/list.h
@@ -32,7 +32,7 @@
#define GLOBALS_LIST_H
#include "core/os/memory.h"
-#include "core/sort.h"
+#include "core/sort_array.h"
/**
* Generic Templatized Linked List Implementation.
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index b885a06834..6c3b84d49a 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -97,11 +97,14 @@ void AStar::remove_point(int p_id) {
Point *p = points[p_id];
- for (Set<Point *>::Element *E = p->neighbours.front(); E; E = E->next()) {
-
- Segment s(p_id, E->get()->id);
- segments.erase(s);
- E->get()->neighbours.erase(p);
+ Map<int, Point *>::Element *PE = points.front();
+ while (PE) {
+ for (Set<Point *>::Element *E = PE->get()->neighbours.front(); E; E = E->next()) {
+ Segment s(p_id, E->get()->id);
+ segments.erase(s);
+ E->get()->neighbours.erase(p);
+ }
+ PE = PE->next();
}
memdelete(p);
@@ -371,14 +374,14 @@ PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
{
PoolVector<Vector3>::Write w = path.write();
- Point *p = end_point;
+ Point *p2 = end_point;
int idx = pc - 1;
- while (p != begin_point) {
- w[idx--] = p->pos;
- p = p->prev_point;
+ while (p2 != begin_point) {
+ w[idx--] = p2->pos;
+ p2 = p2->prev_point;
}
- w[0] = p->pos; // Assign first
+ w[0] = p2->pos; // Assign first
}
return path;
diff --git a/core/math/matrix3.cpp b/core/math/basis.cpp
index 0aa67078fb..7f60b7962c 100644
--- a/core/math/matrix3.cpp
+++ b/core/math/basis.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* matrix3.cpp */
+/* basis.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "matrix3.h"
+#include "basis.h"
#include "core/math/math_funcs.h"
#include "core/os/copymem.h"
@@ -258,7 +258,7 @@ Vector3 Basis::get_scale_abs() const {
}
Vector3 Basis::get_scale_local() const {
- real_t det_sign = determinant() > 0 ? 1 : -1;
+ real_t det_sign = SGN(determinant());
return det_sign * Vector3(elements[0].length(), elements[1].length(), elements[2].length());
}
@@ -284,7 +284,7 @@ Vector3 Basis::get_scale() const {
// matrix elements.
//
// The rotation part of this decomposition is returned by get_rotation* functions.
- real_t det_sign = determinant() > 0 ? 1 : -1;
+ real_t det_sign = SGN(determinant());
return det_sign * Vector3(
Vector3(elements[0][0], elements[1][0], elements[2][0]).length(),
Vector3(elements[0][1], elements[1][1], elements[2][1]).length(),
diff --git a/core/math/matrix3.h b/core/math/basis.h
index e7d6ab4522..128e56b494 100644
--- a/core/math/matrix3.h
+++ b/core/math/basis.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* matrix3.h */
+/* basis.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -31,8 +31,8 @@
// Circular dependency between Vector3 and Basis :/
#include "core/math/vector3.h"
-#ifndef MATRIX3_H
-#define MATRIX3_H
+#ifndef BASIS_H
+#define BASIS_H
#include "core/math/quat.h"
@@ -341,4 +341,4 @@ real_t Basis::determinant() const {
elements[1][0] * (elements[0][1] * elements[2][2] - elements[2][1] * elements[0][2]) +
elements[2][0] * (elements[0][1] * elements[1][2] - elements[1][1] * elements[0][2]);
}
-#endif
+#endif // BASIS_H
diff --git a/core/math/bsp_tree.h b/core/math/bsp_tree.h
index 0af532a2d5..a7a3697990 100644
--- a/core/math/bsp_tree.h
+++ b/core/math/bsp_tree.h
@@ -31,11 +31,11 @@
#ifndef BSP_TREE_H
#define BSP_TREE_H
-#include "core/dvector.h"
#include "core/math/aabb.h"
#include "core/math/face3.h"
#include "core/math/plane.h"
#include "core/method_ptrcall.h"
+#include "core/pool_vector.h"
#include "core/variant.h"
#include "core/vector.h"
/**
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 61e5154f44..99251d80e3 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -1264,10 +1264,10 @@ Expression::ENode *Expression::_parse_expression() {
}
str_ofs = cofs; //revert
//parse an expression
- ENode *expr = _parse_expression();
- if (!expr)
+ ENode *subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- dn->dict.push_back(expr);
+ dn->dict.push_back(subexpr);
_get_token(tk);
if (tk.type != TK_COLON) {
@@ -1275,11 +1275,11 @@ Expression::ENode *Expression::_parse_expression() {
return NULL;
}
- expr = _parse_expression();
- if (!expr)
+ subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- dn->dict.push_back(expr);
+ dn->dict.push_back(subexpr);
cofs = str_ofs;
_get_token(tk);
@@ -1308,10 +1308,10 @@ Expression::ENode *Expression::_parse_expression() {
}
str_ofs = cofs; //revert
//parse an expression
- ENode *expr = _parse_expression();
- if (!expr)
+ ENode *subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- an->array.push_back(expr);
+ an->array.push_back(subexpr);
cofs = str_ofs;
_get_token(tk);
@@ -1355,25 +1355,25 @@ Expression::ENode *Expression::_parse_expression() {
while (true) {
- int cofs = str_ofs;
+ int cofs2 = str_ofs;
_get_token(tk);
if (tk.type == TK_PARENTHESIS_CLOSE) {
break;
}
- str_ofs = cofs; //revert
+ str_ofs = cofs2; //revert
//parse an expression
- ENode *expr = _parse_expression();
- if (!expr)
+ ENode *subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- func_call->arguments.push_back(expr);
+ func_call->arguments.push_back(subexpr);
- cofs = str_ofs;
+ cofs2 = str_ofs;
_get_token(tk);
if (tk.type == TK_COMMA) {
//all good
} else if (tk.type == TK_PARENTHESIS_CLOSE) {
- str_ofs = cofs;
+ str_ofs = cofs2;
} else {
_set_error("Expected ',' or ')'");
}
@@ -1444,11 +1444,11 @@ Expression::ENode *Expression::_parse_expression() {
}
str_ofs = cofs; //revert
//parse an expression
- ENode *expr = _parse_expression();
- if (!expr)
+ ENode *subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- constructor->arguments.push_back(expr);
+ constructor->arguments.push_back(subexpr);
cofs = str_ofs;
_get_token(tk);
@@ -1485,11 +1485,11 @@ Expression::ENode *Expression::_parse_expression() {
}
str_ofs = cofs; //revert
//parse an expression
- ENode *expr = _parse_expression();
- if (!expr)
+ ENode *subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- bifunc->arguments.push_back(expr);
+ bifunc->arguments.push_back(subexpr);
cofs = str_ofs;
_get_token(tk);
@@ -1584,25 +1584,25 @@ Expression::ENode *Expression::_parse_expression() {
while (true) {
- int cofs = str_ofs;
+ int cofs3 = str_ofs;
_get_token(tk);
if (tk.type == TK_PARENTHESIS_CLOSE) {
break;
}
- str_ofs = cofs; //revert
+ str_ofs = cofs3; //revert
//parse an expression
- ENode *expr = _parse_expression();
- if (!expr)
+ ENode *subexpr = _parse_expression();
+ if (!subexpr)
return NULL;
- func_call->arguments.push_back(expr);
+ func_call->arguments.push_back(subexpr);
- cofs = str_ofs;
+ cofs3 = str_ofs;
_get_token(tk);
if (tk.type == TK_COMMA) {
//all good
} else if (tk.type == TK_PARENTHESIS_CLOSE) {
- str_ofs = cofs;
+ str_ofs = cofs3;
} else {
_set_error("Expected ',' or ')'");
}
@@ -1902,7 +1902,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
Variant b;
if (op->nodes[1]) {
- bool ret = _execute(p_inputs, p_instance, op->nodes[1], b, r_error_str);
+ ret = _execute(p_inputs, p_instance, op->nodes[1], b, r_error_str);
if (ret)
return true;
}
@@ -2070,7 +2070,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
for (int i = 0; i < call->arguments.size(); i++) {
Variant value;
- bool ret = _execute(p_inputs, p_instance, call->arguments[i], value, r_error_str);
+ ret = _execute(p_inputs, p_instance, call->arguments[i], value, r_error_str);
if (ret)
return true;
diff --git a/core/math/face3.h b/core/math/face3.h
index 1a00851eab..184e80ff77 100644
--- a/core/math/face3.h
+++ b/core/math/face3.h
@@ -241,13 +241,13 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const {
real_t minT = 1e20, maxT = -1e20;
for (int k = 0; k < 3; k++) {
- real_t d = axis.dot(vertex[k]);
+ real_t vert_d = axis.dot(vertex[k]);
- if (d > maxT)
- maxT = d;
+ if (vert_d > maxT)
+ maxT = vert_d;
- if (d < minT)
- minT = d;
+ if (vert_d < minT)
+ minT = vert_d;
}
if (maxB < minT || maxT < minB)
diff --git a/core/math/geometry.h b/core/math/geometry.h
index 29493516b8..f927a63ed5 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -31,12 +31,12 @@
#ifndef GEOMETRY_H
#define GEOMETRY_H
-#include "core/dvector.h"
#include "core/math/face3.h"
#include "core/math/rect2.h"
#include "core/math/triangulate.h"
#include "core/math/vector3.h"
#include "core/object.h"
+#include "core/pool_vector.h"
#include "core/print_string.h"
#include "core/vector.h"
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index ea0bfd88cc..629002ced6 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -242,8 +242,8 @@ public:
static void randomize();
static uint32_t rand_from_seed(uint64_t *seed);
static uint32_t rand();
- static _ALWAYS_INLINE_ double randf() { return (double)rand() / (double)Math::RANDOM_MAX; }
- static _ALWAYS_INLINE_ float randd() { return (float)rand() / (float)Math::RANDOM_MAX; }
+ static _ALWAYS_INLINE_ double randd() { return (double)rand() / (double)Math::RANDOM_MAX; }
+ static _ALWAYS_INLINE_ float randf() { return (float)rand() / (float)Math::RANDOM_MAX; }
static double random(double from, double to);
static float random(float from, float to);
diff --git a/core/math/octree.h b/core/math/octree.h
index 36a77663f4..d6fc9776bc 100644
--- a/core/math/octree.h
+++ b/core/math/octree.h
@@ -916,34 +916,34 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
pass++;
- for (typename List<typename Element::OctantOwner, AL>::Element *E = owners.front(); E;) {
+ for (typename List<typename Element::OctantOwner, AL>::Element *F = owners.front(); F;) {
- Octant *o = E->get().octant;
- typename List<typename Element::OctantOwner, AL>::Element *N = E->next();
+ Octant *o = F->get().octant;
+ typename List<typename Element::OctantOwner, AL>::Element *N = F->next();
/*
if (!use_pairs)
- o->elements.erase( E->get().E );
+ o->elements.erase( F->get().E );
*/
if (use_pairs && e.pairable)
- o->pairable_elements.erase(E->get().E);
+ o->pairable_elements.erase(F->get().E);
else
- o->elements.erase(E->get().E);
+ o->elements.erase(F->get().E);
if (_remove_element_from_octant(&e, o, common_parent->parent)) {
- owners.erase(E);
+ owners.erase(F);
}
- E = N;
+ F = N;
}
if (use_pairs) {
//unpair child elements in anything that survived
- for (typename List<typename Element::OctantOwner, AL>::Element *E = owners.front(); E; E = E->next()) {
+ for (typename List<typename Element::OctantOwner, AL>::Element *F = owners.front(); F; F = F->next()) {
- Octant *o = E->get().octant;
+ Octant *o = F->get().octant;
// erase children pairs, unref ONCE
pass++;
diff --git a/core/math/quat.cpp b/core/math/quat.cpp
index c1e45f36f0..6833d5de55 100644
--- a/core/math/quat.cpp
+++ b/core/math/quat.cpp
@@ -30,7 +30,7 @@
#include "quat.h"
-#include "core/math/matrix3.h"
+#include "core/math/basis.h"
#include "core/print_string.h"
// set_euler_xyz expects a vector containing the Euler angles in the format
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index 1aa345db1f..bc2b4e6fe0 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -438,12 +438,12 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
}
// remove all edge connections to this face
- for (Map<Edge, RetFaceConnect>::Element *E = ret_edges.front(); E; E = E->next()) {
- if (E->get().left == O)
- E->get().left = NULL;
+ for (Map<Edge, RetFaceConnect>::Element *G = ret_edges.front(); G; G = G->next()) {
+ if (G->get().left == O)
+ G->get().left = NULL;
- if (E->get().right == O)
- E->get().right = NULL;
+ if (G->get().right == O)
+ G->get().right = NULL;
}
ret_edges.erase(F); //remove the edge
diff --git a/core/math/random_pcg.h b/core/math/random_pcg.h
index ef69bf7120..2a69d43904 100644
--- a/core/math/random_pcg.h
+++ b/core/math/random_pcg.h
@@ -45,7 +45,10 @@ public:
RandomPCG(uint64_t seed = DEFAULT_SEED, uint64_t inc = PCG_DEFAULT_INC_64);
- _FORCE_INLINE_ void seed(uint64_t seed) { pcg.state = seed; }
+ _FORCE_INLINE_ void seed(uint64_t seed) {
+ pcg.state = seed;
+ pcg32_random_r(&pcg); // Force changing internal state to avoid initial 0
+ }
_FORCE_INLINE_ uint64_t get_seed() { return pcg.state; }
void randomize();
diff --git a/core/math/transform.h b/core/math/transform.h
index 9b323a6f0f..2f43f6b035 100644
--- a/core/math/transform.h
+++ b/core/math/transform.h
@@ -32,7 +32,7 @@
#define TRANSFORM_H
#include "core/math/aabb.h"
-#include "core/math/matrix3.h"
+#include "core/math/basis.h"
#include "core/math/plane.h"
/**
diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp
index 295e60babb..7d00158f3d 100644
--- a/core/math/transform_2d.cpp
+++ b/core/math/transform_2d.cpp
@@ -80,13 +80,14 @@ real_t Transform2D::get_rotation() const {
}
void Transform2D::set_rotation(real_t p_rot) {
-
+ Size2 scale = get_scale();
real_t cr = Math::cos(p_rot);
real_t sr = Math::sin(p_rot);
elements[0][0] = cr;
elements[0][1] = sr;
elements[1][0] = -sr;
elements[1][1] = cr;
+ set_scale(scale);
}
Transform2D::Transform2D(real_t p_rot, const Vector2 &p_pos) {
@@ -101,10 +102,17 @@ Transform2D::Transform2D(real_t p_rot, const Vector2 &p_pos) {
}
Size2 Transform2D::get_scale() const {
- real_t det_sign = basis_determinant() > 0 ? 1 : -1;
+ real_t det_sign = SGN(basis_determinant());
return Size2(elements[0].length(), det_sign * elements[1].length());
}
+void Transform2D::set_scale(Size2 &p_scale) {
+ elements[0].normalize();
+ elements[1].normalize();
+ elements[0] *= p_scale.x;
+ elements[1] *= p_scale.y;
+}
+
void Transform2D::scale(const Size2 &p_scale) {
scale_basis(p_scale);
elements[2] *= p_scale;
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index 507e6a16eb..b9e7a36fb3 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -81,6 +81,7 @@ struct Transform2D {
real_t basis_determinant() const;
Size2 get_scale() const;
+ void set_scale(Size2 &p_scale);
_FORCE_INLINE_ const Vector2 &get_origin() const { return elements[2]; }
_FORCE_INLINE_ void set_origin(const Vector2 &p_origin) { elements[2] = p_origin; }
diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp
index cdf3d16b72..83784a1fa7 100644
--- a/core/math/triangle_mesh.cpp
+++ b/core/math/triangle_mesh.cpp
@@ -30,7 +30,7 @@
#include "triangle_mesh.h"
-#include "core/sort.h"
+#include "core/sort_array.h"
int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc) {
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index b2e89ac7b8..1c28934422 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -30,7 +30,7 @@
#include "vector3.h"
-#include "core/math/matrix3.h"
+#include "core/math/basis.h"
void Vector3::rotate(const Vector3 &p_axis, real_t p_phi) {
diff --git a/core/math/vector3.h b/core/math/vector3.h
index b0eef35635..8d6e093c4c 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -151,7 +151,7 @@ struct Vector3 {
};
// Should be included after class definition, otherwise we get circular refs
-#include "core/math/matrix3.h"
+#include "core/math/basis.h"
Vector3 Vector3::cross(const Vector3 &p_b) const {
diff --git a/core/node_path.h b/core/node_path.h
index 17b1435723..24725123d6 100644
--- a/core/node_path.h
+++ b/core/node_path.h
@@ -31,7 +31,7 @@
#ifndef NODE_PATH_H
#define NODE_PATH_H
-#include "core/string_db.h"
+#include "core/string_name.h"
#include "core/ustring.h"
/**
diff --git a/core/object.cpp b/core/object.cpp
index 05e661baab..4e0416ccb0 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -703,40 +703,38 @@ Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Vari
}
#ifdef DEBUG_ENABLED
-static bool _test_call_error(const StringName &p_func, const Variant::CallError &error) {
+static void _test_call_error(const StringName &p_func, const Variant::CallError &error) {
switch (error.error) {
case Variant::CallError::CALL_OK:
- return true;
case Variant::CallError::CALL_ERROR_INVALID_METHOD:
- return false;
+ break;
case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT: {
ERR_EXPLAIN("Error Calling Function: " + String(p_func) + " - Invalid type for argument " + itos(error.argument) + ", expected " + Variant::get_type_name(error.expected));
- ERR_FAIL_V(true);
- } break;
+ ERR_FAIL();
+ break;
+ }
case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
ERR_EXPLAIN("Error Calling Function: " + String(p_func) + " - Too many arguments, expected " + itos(error.argument));
- ERR_FAIL_V(true);
-
- } break;
+ ERR_FAIL();
+ break;
+ }
case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
ERR_EXPLAIN("Error Calling Function: " + String(p_func) + " - Too few arguments, expected " + itos(error.argument));
- ERR_FAIL_V(true);
-
- } break;
- case Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL: {
- } //?
+ ERR_FAIL();
+ break;
+ }
+ case Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL:
+ break;
}
-
- return true;
}
#else
-#define _test_call_error(m_str, m_err) ((m_err.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) ? false : true)
+#define _test_call_error(m_str, m_err)
#endif
@@ -1247,7 +1245,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
bool disconnect = c.flags & CONNECT_ONESHOT;
#ifdef TOOLS_ENABLED
if (disconnect && (c.flags & CONNECT_PERSIST) && Engine::get_singleton()->is_editor_hint()) {
- //this signal was connected from the editor, and is being edited. just dont disconnect for now
+ //this signal was connected from the editor, and is being edited. just don't disconnect for now
disconnect = false;
}
#endif
@@ -1929,6 +1927,13 @@ bool Object::has_script_instance_binding(int p_script_language_index) {
return _script_instance_bindings[p_script_language_index] != NULL;
}
+void Object::set_script_instance_binding(int p_script_language_index, void *p_data) {
+#ifdef DEBUG_ENABLED
+ CRASH_COND(_script_instance_bindings[p_script_language_index] != NULL);
+#endif
+ _script_instance_bindings[p_script_language_index] = p_data;
+}
+
Object::Object() {
_class_ptr = NULL;
@@ -1992,9 +1997,11 @@ Object::~Object() {
_instance_ID = 0;
_predelete_ok = 2;
- for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
- if (_script_instance_bindings[i]) {
- ScriptServer::get_language(i)->free_instance_binding_data(_script_instance_bindings[i]);
+ if (!ScriptServer::are_languages_finished()) {
+ for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
+ if (_script_instance_bindings[i]) {
+ ScriptServer::get_language(i)->free_instance_binding_data(_script_instance_bindings[i]);
+ }
}
}
}
diff --git a/core/object.h b/core/object.h
index 5bfef8a439..e8a6178052 100644
--- a/core/object.h
+++ b/core/object.h
@@ -119,6 +119,7 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE = 1 << 21, // If the object is duplicated also this property will be duplicated
PROPERTY_USAGE_HIGH_END_GFX = 1 << 22,
PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT = 1 << 23,
+ PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT = 1 << 24,
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
@@ -730,6 +731,7 @@ public:
//used by script languages to store binding data
void *get_script_instance_binding(int p_script_language_index);
bool has_script_instance_binding(int p_script_language_index);
+ void set_script_instance_binding(int p_script_language_index, void *p_data);
void clear_internal_resource_paths();
diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp
index 1e0e83c8d2..24ec8a1963 100644
--- a/core/os/input_event.cpp
+++ b/core/os/input_event.cpp
@@ -749,6 +749,15 @@ bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *
return match;
}
+bool InputEventJoypadButton::shortcut_match(const Ref<InputEvent> &p_event) const {
+
+ Ref<InputEventJoypadButton> button = p_event;
+ if (button.is_null())
+ return false;
+
+ return button_index == button->button_index;
+}
+
String InputEventJoypadButton::as_text() const {
return "InputEventJoypadButton : button_index=" + itos(button_index) + ", pressed=" + (pressed ? "true" : "false") + ", pressure=" + String(Variant(pressure));
@@ -950,11 +959,10 @@ bool InputEventAction::is_pressed() const {
}
bool InputEventAction::shortcut_match(const Ref<InputEvent> &p_event) const {
- Ref<InputEventKey> event = p_event;
- if (event.is_null())
+ if (p_event.is_null())
return false;
- return event->is_action(action);
+ return p_event->is_action(action);
}
bool InputEventAction::is_action(const StringName &p_action) const {
diff --git a/core/os/input_event.h b/core/os/input_event.h
index db31055b5f..a6a7012298 100644
--- a/core/os/input_event.h
+++ b/core/os/input_event.h
@@ -400,6 +400,7 @@ public:
float get_pressure() const;
virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const;
+ virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
virtual bool is_action_type() const { return true; }
virtual String as_text() const;
diff --git a/core/os/os.h b/core/os/os.h
index 20a3494e11..396555970a 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -45,12 +45,6 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
-enum VideoDriver {
- VIDEO_DRIVER_GLES3,
- VIDEO_DRIVER_GLES2,
- VIDEO_DRIVER_MAX,
-};
-
class OS {
static OS *singleton;
@@ -184,9 +178,16 @@ public:
virtual VideoMode get_video_mode(int p_screen = 0) const = 0;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const = 0;
+ enum VideoDriver {
+ VIDEO_DRIVER_GLES3,
+ VIDEO_DRIVER_GLES2,
+ VIDEO_DRIVER_MAX,
+ };
+
virtual int get_video_driver_count() const;
virtual const char *get_video_driver_name(int p_driver) const;
virtual int get_current_video_driver() const = 0;
+
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
diff --git a/core/os/shell.cpp b/core/os/shell.cpp
deleted file mode 100644
index a859241cb6..0000000000
--- a/core/os/shell.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*************************************************************************/
-/* shell.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 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 "shell.h"
-
-Shell *Shell::singleton = NULL;
-
-Shell *Shell::get_singleton() {
-
- return singleton;
-}
-
-Shell::~Shell() {
-}
-
-Shell::Shell() {
-
- singleton = this;
-}
diff --git a/core/os/shell.h b/core/os/shell.h
deleted file mode 100644
index c1bd995b5b..0000000000
--- a/core/os/shell.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*************************************************************************/
-/* shell.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 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 SHELL_H
-#define SHELL_H
-
-#include "core/typedefs.h"
-#include "core/ustring.h"
-
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-class Shell {
-
- static Shell *singleton;
-
-public:
- static Shell *get_singleton();
- virtual void execute(String p_path) = 0;
-
- Shell();
- virtual ~Shell();
-};
-
-#endif
diff --git a/core/pair.h b/core/pair.h
index cb661160b5..9afaa726cb 100644
--- a/core/pair.h
+++ b/core/pair.h
@@ -37,7 +37,11 @@ struct Pair {
F first;
S second;
- Pair() {}
+ Pair() :
+ first(),
+ second() {
+ }
+
Pair(F p_first, const S &p_second) :
first(p_first),
second(p_second) {
diff --git a/core/dvector.cpp b/core/pool_vector.cpp
index 592c3c053d..b9d2316315 100644
--- a/core/dvector.cpp
+++ b/core/pool_vector.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* dvector.cpp */
+/* pool_vector.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,9 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "dvector.h"
+#include "pool_vector.h"
-Mutex *dvector_lock = NULL;
+Mutex *pool_vector_lock = NULL;
PoolAllocator *MemoryPool::memory_pool = NULL;
uint8_t *MemoryPool::pool_memory = NULL;
diff --git a/core/dvector.h b/core/pool_vector.h
index fc962b4940..102a620f17 100644
--- a/core/dvector.h
+++ b/core/pool_vector.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* dvector.h */
+/* pool_vector.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef DVECTOR_H
-#define DVECTOR_H
+#ifndef POOL_VECTOR_H
+#define POOL_VECTOR_H
#include "core/os/copymem.h"
#include "core/os/memory.h"
@@ -188,19 +188,19 @@ class PoolVector {
}
}
- void _reference(const PoolVector &p_dvector) {
+ void _reference(const PoolVector &p_pool_vector) {
- if (alloc == p_dvector.alloc)
+ if (alloc == p_pool_vector.alloc)
return;
_unreference();
- if (!p_dvector.alloc) {
+ if (!p_pool_vector.alloc) {
return;
}
- if (p_dvector.alloc->refcount.ref()) {
- alloc = p_dvector.alloc;
+ if (p_pool_vector.alloc->refcount.ref()) {
+ alloc = p_pool_vector.alloc;
}
}
@@ -460,11 +460,11 @@ public:
void invert();
- void operator=(const PoolVector &p_dvector) { _reference(p_dvector); }
+ void operator=(const PoolVector &p_pool_vector) { _reference(p_pool_vector); }
PoolVector() { alloc = NULL; }
- PoolVector(const PoolVector &p_dvector) {
+ PoolVector(const PoolVector &p_pool_vector) {
alloc = NULL;
- _reference(p_dvector);
+ _reference(p_pool_vector);
}
~PoolVector() { _unreference(); }
};
@@ -640,4 +640,4 @@ void PoolVector<T>::invert() {
}
}
-#endif
+#endif // POOL_VECTOR_H
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index 8d05d7cc74..6b4895d688 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -501,7 +501,7 @@ Error ProjectSettings::_load_settings_binary(const String p_path) {
d.resize(vlen);
f->get_buffer(d.ptrw(), vlen);
Variant value;
- Error err = decode_variant(value, d.ptr(), d.size());
+ err = decode_variant(value, d.ptr(), d.size());
ERR_EXPLAIN("Error decoding property: " + key);
ERR_CONTINUE(err != OK);
set(key, value);
@@ -656,7 +656,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
file->store_string(key);
int len;
- Error err = encode_variant(p_custom_features, NULL, len);
+ err = encode_variant(p_custom_features, NULL, len);
if (err != OK) {
memdelete(file);
ERR_FAIL_V(err);
@@ -694,7 +694,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
file->store_string(key);
int len;
- Error err = encode_variant(value, NULL, len);
+ err = encode_variant(value, NULL, len);
if (err != OK)
memdelete(file);
ERR_FAIL_COND_V(err != OK, ERR_INVALID_DATA);
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index 60c2778603..97c96b4018 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -47,7 +47,7 @@
#include "core/io/packet_peer_udp.h"
#include "core/io/pck_packer.h"
#include "core/io/resource_format_binary.h"
-#include "core/io/resource_import.h"
+#include "core/io/resource_importer.h"
#include "core/io/stream_peer_ssl.h"
#include "core/io/tcp_server.h"
#include "core/io/translation_loader_po.h"
diff --git a/core/script_language.cpp b/core/script_language.cpp
index 632fa3b336..f0310ffc31 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -37,6 +37,7 @@ int ScriptServer::_language_count = 0;
bool ScriptServer::scripting_enabled = true;
bool ScriptServer::reload_scripts_on_save = false;
+bool ScriptServer::languages_finished = false;
ScriptEditRequestFunction ScriptServer::edit_request_func = NULL;
void Script::_notification(int p_what) {
@@ -130,6 +131,7 @@ void ScriptServer::finish_languages() {
_languages[i]->finish();
}
global_classes_clear();
+ languages_finished = true;
}
void ScriptServer::set_reload_scripts_on_save(bool p_enable) {
@@ -525,8 +527,8 @@ void PlaceHolderScriptInstance::property_set_fallback(const StringName &p_name,
}
bool found = false;
- for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
- if (E->get().name == p_name) {
+ for (const List<PropertyInfo>::Element *F = properties.front(); F; F = F->next()) {
+ if (F->get().name == p_name) {
found = true;
break;
}
diff --git a/core/script_language.h b/core/script_language.h
index b0f12dc291..2d35097692 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -54,6 +54,7 @@ class ScriptServer {
static int _language_count;
static bool scripting_enabled;
static bool reload_scripts_on_save;
+ static bool languages_finished;
struct GlobalScriptClass {
StringName language;
@@ -91,6 +92,8 @@ public:
static void init_languages();
static void finish_languages();
+
+ static bool are_languages_finished() { return languages_finished; }
};
class ScriptInstance;
diff --git a/core/sort.h b/core/sort_array.h
index 4da7c323c7..0f258aec3e 100644
--- a/core/sort.h
+++ b/core/sort_array.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* sort.h */
+/* sort_array.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SORT_H
-#define SORT_H
+#ifndef SORT_ARRAY_H
+#define SORT_ARRAY_H
#include "core/typedefs.h"
@@ -327,4 +327,4 @@ public:
}
};
-#endif
+#endif // SORT_ARRAY_H
diff --git a/core/string_db.cpp b/core/string_name.cpp
index c776c56023..10b71ad3ac 100644
--- a/core/string_db.cpp
+++ b/core/string_name.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* string_db.cpp */
+/* string_name.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "string_db.h"
+#include "string_name.h"
#include "core/os/os.h"
#include "core/print_string.h"
diff --git a/core/string_db.h b/core/string_name.h
index 06b24c28da..0984b0181f 100644
--- a/core/string_db.h
+++ b/core/string_name.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* string_db.h */
+/* string_name.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef STRING_DB_H
-#define STRING_DB_H
+#ifndef STRING_NAME_H
+#define STRING_NAME_H
#include "core/os/mutex.h"
#include "core/safe_refcount.h"
@@ -169,4 +169,4 @@ public:
StringName _scs_create(const char *p_chr);
-#endif
+#endif // STRING_NAME_H
diff --git a/core/translation.cpp b/core/translation.cpp
index a402df3eea..6921f1d9f1 100644
--- a/core/translation.cpp
+++ b/core/translation.cpp
@@ -1052,7 +1052,7 @@ StringName TranslationServer::translate(const StringName &p_message) const {
if (fallback.length() >= 2) {
const CharType *fptr = &fallback[0];
- bool near_match = false;
+ near_match = false;
for (const Set<Ref<Translation> >::Element *E = translations.front(); E; E = E->next()) {
const Ref<Translation> &t = E->get();
diff --git a/core/typedefs.h b/core/typedefs.h
index 0005e5e6ee..e01e1c00b9 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -116,6 +116,8 @@ T *_nullptr() {
#define ABS(m_v) (((m_v) < 0) ? (-(m_v)) : (m_v))
#endif
+#define ABSDIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y)))
+
#ifndef SGN
#define SGN(m_v) (((m_v) < 0) ? (-1.0) : (+1.0))
#endif
diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp
index 6bc882eaec..40ccd95758 100644
--- a/core/undo_redo.cpp
+++ b/core/undo_redo.cpp
@@ -63,43 +63,37 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
_discard_redo();
// Check if the merge operation is valid
- if (p_mode != MERGE_DISABLE && actions.size() && actions[actions.size() - 1].name == p_name && actions[actions.size() - 1].last_tick + 800 > ticks) {
+ if (p_mode == MERGE_ENDS && actions.size() && actions[actions.size() - 1].name == p_name && actions[actions.size() - 1].last_tick + 800 > ticks) {
current_action = actions.size() - 2;
- if (p_mode == MERGE_ENDS) {
+ // Clear all do ops from last action, and delete all object references
+ List<Operation>::Element *E = actions.write[current_action + 1].do_ops.front();
- // Clear all do ops from last action, and delete all object references
- List<Operation>::Element *E = actions.write[current_action + 1].do_ops.front();
+ while (E) {
- while (E) {
+ if (E->get().type == Operation::TYPE_REFERENCE) {
- if (E->get().type == Operation::TYPE_REFERENCE) {
+ Object *obj = ObjectDB::get_instance(E->get().object);
- Object *obj = ObjectDB::get_instance(E->get().object);
-
- if (obj)
- memdelete(obj);
- }
-
- E = E->next();
- actions.write[current_action + 1].do_ops.pop_front();
+ if (obj)
+ memdelete(obj);
}
+
+ E = E->next();
+ actions.write[current_action + 1].do_ops.pop_front();
}
actions.write[actions.size() - 1].last_tick = ticks;
-
- merge_mode = p_mode;
-
} else {
Action new_action;
new_action.name = p_name;
new_action.last_tick = ticks;
actions.push_back(new_action);
-
- merge_mode = MERGE_DISABLE;
}
+
+ merge_mode = p_mode;
}
action_level++;
@@ -234,7 +228,9 @@ void UndoRedo::_pop_history_tail() {
}
actions.remove(0);
- current_action--;
+ if (current_action >= 0) {
+ current_action--;
+ }
}
void UndoRedo::commit_action() {
@@ -258,11 +254,8 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
Operation &op = E->get();
Object *obj = ObjectDB::get_instance(op.object);
- if (!obj) {
- //corruption
- clear_history();
- ERR_FAIL_COND(!obj);
- }
+ if (!obj) //may have been deleted and this is fine
+ continue;
switch (op.type) {
diff --git a/core/ustring.cpp b/core/ustring.cpp
index c1888c87a7..ff8fcaaaaf 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -603,13 +603,13 @@ String String::camelcase_to_underscore(bool lowercase) const {
is_next_number = cstr[i + 1] >= '0' && cstr[i + 1] <= '9';
}
- const bool a = is_upper && !was_precedent_upper && !was_precedent_number;
- const bool b = was_precedent_upper && is_upper && are_next_2_lower;
- const bool c = is_number && !was_precedent_number;
+ const bool cond_a = is_upper && !was_precedent_upper && !was_precedent_number;
+ const bool cond_b = was_precedent_upper && is_upper && are_next_2_lower;
+ const bool cond_c = is_number && !was_precedent_number;
const bool can_break_number_letter = is_number && !was_precedent_number && is_next_lower;
const bool can_break_letter_number = !is_number && was_precedent_number && (is_next_lower || is_next_number);
- bool should_split = a || b || c || can_break_number_letter || can_break_letter_number;
+ bool should_split = cond_a || cond_b || cond_c || can_break_number_letter || can_break_letter_number;
if (should_split) {
new_string += this->substr(start_index, i - start_index) + "_";
start_index = i;
@@ -1359,6 +1359,9 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
#define _UNICERROR(m_err) print_line("Unicode error: " + String(m_err));
+ if (!p_utf8)
+ return true;
+
String aux;
int cstr_size = 0;
@@ -2393,7 +2396,7 @@ int String::find(const char *p_str, int p_from) const {
return -1;
}
-int String::find_char(CharType p_char, int p_from) const {
+int String::find_char(const CharType &p_char, int p_from) const {
return _cowdata.find(p_char, p_from);
}
@@ -2945,12 +2948,12 @@ String String::left(int p_pos) const {
String String::right(int p_pos) const {
- if (p_pos >= size())
- return *this;
-
- if (p_pos < 0)
+ if (p_pos >= length())
return "";
+ if (p_pos <= 0)
+ return *this;
+
return substr(p_pos, (length() - p_pos));
}
diff --git a/core/ustring.h b/core/ustring.h
index 5ec5c79e2d..cb3d87378a 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -85,8 +85,7 @@ public:
_FORCE_INLINE_ int size() const { return _cowdata.size(); }
Error resize(int p_size) { return _cowdata.resize(p_size); }
- _FORCE_INLINE_ char get(int p_index) { return _cowdata.get(p_index); }
- _FORCE_INLINE_ const char get(int p_index) const { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ char get(int p_index) const { return _cowdata.get(p_index); }
_FORCE_INLINE_ void set(int p_index, const char &p_elem) { _cowdata.set(p_index, p_elem); }
_FORCE_INLINE_ const char &operator[](int p_index) const {
if (unlikely(p_index == _cowdata.size()))
@@ -143,8 +142,7 @@ public:
_FORCE_INLINE_ void clear() { resize(0); }
- _FORCE_INLINE_ CharType get(int p_index) { return _cowdata.get(p_index); }
- _FORCE_INLINE_ const CharType get(int p_index) const { return _cowdata.get(p_index); }
+ _FORCE_INLINE_ CharType get(int p_index) const { return _cowdata.get(p_index); }
_FORCE_INLINE_ void set(int p_index, const CharType &p_elem) { _cowdata.set(p_index, p_elem); }
_FORCE_INLINE_ int size() const { return _cowdata.size(); }
Error resize(int p_size) { return _cowdata.resize(p_size); }
@@ -197,7 +195,7 @@ public:
String substr(int p_from, int p_chars) const;
int find(const String &p_str, int p_from = 0) const; ///< return <0 if failed
int find(const char *p_str, int p_from = 0) const; ///< return <0 if failed
- int find_char(CharType p_char, int p_from = 0) const; ///< return <0 if failed
+ int find_char(const CharType &p_char, int p_from = 0) const; ///< return <0 if failed
int find_last(const String &p_str) const; ///< return <0 if failed
int findn(const String &p_str, int p_from = 0) const; ///< return <0 if failed, case insensitive
int rfind(const String &p_str, int p_from = -1) const; ///< return <0 if failed
diff --git a/core/variant.cpp b/core/variant.cpp
index 56b272cccf..2ee2e8e293 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -2816,27 +2816,37 @@ uint32_t Variant::hash() const {
const PoolVector<uint8_t> &arr = *reinterpret_cast<const PoolVector<uint8_t> *>(_data._mem);
int len = arr.size();
- PoolVector<uint8_t>::Read r = arr.read();
-
- return hash_djb2_buffer((uint8_t *)&r[0], len);
+ if (likely(len)) {
+ PoolVector<uint8_t>::Read r = arr.read();
+ return hash_djb2_buffer((uint8_t *)&r[0], len);
+ } else {
+ return hash_djb2_one_64(0);
+ }
} break;
case POOL_INT_ARRAY: {
const PoolVector<int> &arr = *reinterpret_cast<const PoolVector<int> *>(_data._mem);
int len = arr.size();
- PoolVector<int>::Read r = arr.read();
-
- return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int));
+ if (likely(len)) {
+ PoolVector<int>::Read r = arr.read();
+ return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int));
+ } else {
+ return hash_djb2_one_64(0);
+ }
} break;
case POOL_REAL_ARRAY: {
const PoolVector<real_t> &arr = *reinterpret_cast<const PoolVector<real_t> *>(_data._mem);
int len = arr.size();
- PoolVector<real_t>::Read r = arr.read();
- return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(real_t));
+ if (likely(len)) {
+ PoolVector<real_t>::Read r = arr.read();
+ return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(real_t));
+ } else {
+ return hash_djb2_one_float(0.0);
+ }
} break;
case POOL_STRING_ARRAY: {
@@ -2844,10 +2854,13 @@ uint32_t Variant::hash() const {
uint32_t hash = 5831;
const PoolVector<String> &arr = *reinterpret_cast<const PoolVector<String> *>(_data._mem);
int len = arr.size();
- PoolVector<String>::Read r = arr.read();
- for (int i = 0; i < len; i++) {
- hash = hash_djb2_one_32(r[i].hash(), hash);
+ if (likely(len)) {
+ PoolVector<String>::Read r = arr.read();
+
+ for (int i = 0; i < len; i++) {
+ hash = hash_djb2_one_32(r[i].hash(), hash);
+ }
}
return hash;
@@ -2857,48 +2870,54 @@ uint32_t Variant::hash() const {
uint32_t hash = 5831;
const PoolVector<Vector2> &arr = *reinterpret_cast<const PoolVector<Vector2> *>(_data._mem);
int len = arr.size();
- PoolVector<Vector2>::Read r = arr.read();
- for (int i = 0; i < len; i++) {
- hash = hash_djb2_one_float(r[i].x, hash);
- hash = hash_djb2_one_float(r[i].y, hash);
+ if (likely(len)) {
+ PoolVector<Vector2>::Read r = arr.read();
+
+ for (int i = 0; i < len; i++) {
+ hash = hash_djb2_one_float(r[i].x, hash);
+ hash = hash_djb2_one_float(r[i].y, hash);
+ }
}
return hash;
-
} break;
case POOL_VECTOR3_ARRAY: {
uint32_t hash = 5831;
const PoolVector<Vector3> &arr = *reinterpret_cast<const PoolVector<Vector3> *>(_data._mem);
int len = arr.size();
- PoolVector<Vector3>::Read r = arr.read();
- for (int i = 0; i < len; i++) {
- hash = hash_djb2_one_float(r[i].x, hash);
- hash = hash_djb2_one_float(r[i].y, hash);
- hash = hash_djb2_one_float(r[i].z, hash);
+ if (likely(len)) {
+ PoolVector<Vector3>::Read r = arr.read();
+
+ for (int i = 0; i < len; i++) {
+ hash = hash_djb2_one_float(r[i].x, hash);
+ hash = hash_djb2_one_float(r[i].y, hash);
+ hash = hash_djb2_one_float(r[i].z, hash);
+ }
}
return hash;
-
} break;
case POOL_COLOR_ARRAY: {
uint32_t hash = 5831;
const PoolVector<Color> &arr = *reinterpret_cast<const PoolVector<Color> *>(_data._mem);
int len = arr.size();
- PoolVector<Color>::Read r = arr.read();
- for (int i = 0; i < len; i++) {
- hash = hash_djb2_one_float(r[i].r, hash);
- hash = hash_djb2_one_float(r[i].g, hash);
- hash = hash_djb2_one_float(r[i].b, hash);
- hash = hash_djb2_one_float(r[i].a, hash);
+ if (likely(len)) {
+ PoolVector<Color>::Read r = arr.read();
+
+ for (int i = 0; i < len; i++) {
+ hash = hash_djb2_one_float(r[i].r, hash);
+ hash = hash_djb2_one_float(r[i].g, hash);
+ hash = hash_djb2_one_float(r[i].b, hash);
+ hash = hash_djb2_one_float(r[i].a, hash);
+ }
}
return hash;
-
} break;
default: {}
}
diff --git a/core/variant.h b/core/variant.h
index 0377c78ea8..9215d15bf0 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -38,17 +38,17 @@
#include "core/array.h"
#include "core/color.h"
#include "core/dictionary.h"
-#include "core/dvector.h"
#include "core/io/ip_address.h"
#include "core/math/aabb.h"
+#include "core/math/basis.h"
#include "core/math/face3.h"
-#include "core/math/matrix3.h"
#include "core/math/plane.h"
#include "core/math/quat.h"
#include "core/math/transform.h"
#include "core/math/transform_2d.h"
#include "core/math/vector3.h"
#include "core/node_path.h"
+#include "core/pool_vector.h"
#include "core/ref_ptr.h"
#include "core/rid.h"
#include "core/ustring.h"
@@ -69,6 +69,13 @@ typedef PoolVector<Vector2> PoolVector2Array;
typedef PoolVector<Vector3> PoolVector3Array;
typedef PoolVector<Color> PoolColorArray;
+// Temporary workaround until c++11 alignas()
+#ifdef __GNUC__
+#define GCC_ALIGNED_8 __attribute__((aligned(8)))
+#else
+#define GCC_ALIGNED_8
+#endif
+
class Variant {
public:
// If this changes the table in variant_op must be updated
@@ -132,7 +139,6 @@ private:
_FORCE_INLINE_ const ObjData &_get_obj() const;
union {
-
bool _bool;
int64_t _int;
double _real;
@@ -142,7 +148,7 @@ private:
Transform *_transform;
void *_ptr; //generic pointer
uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)];
- } _data;
+ } _data GCC_ALIGNED_8;
void reference(const Variant &p_variant);
void clear();
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index f6f4569dfa..25a0f3957c 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -480,7 +480,7 @@ struct _VariantCall {
VCALL_LOCALMEM0(Dictionary, clear);
VCALL_LOCALMEM1R(Dictionary, has);
VCALL_LOCALMEM1R(Dictionary, has_all);
- VCALL_LOCALMEM1(Dictionary, erase);
+ VCALL_LOCALMEM1R(Dictionary, erase);
VCALL_LOCALMEM0R(Dictionary, hash);
VCALL_LOCALMEM0R(Dictionary, keys);
VCALL_LOCALMEM0R(Dictionary, values);
@@ -1227,15 +1227,15 @@ bool Variant::has_method(const StringName &p_method) const {
#endif
}
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[type];
- return fd.functions.has(p_method);
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[type];
+ return tf.functions.has(p_method);
}
Vector<Variant::Type> Variant::get_method_argument_types(Variant::Type p_type, const StringName &p_method) {
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[p_type];
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
- const Map<StringName, _VariantCall::FuncData>::Element *E = fd.functions.find(p_method);
+ const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
if (!E)
return Vector<Variant::Type>();
@@ -1244,9 +1244,9 @@ Vector<Variant::Type> Variant::get_method_argument_types(Variant::Type p_type, c
bool Variant::is_method_const(Variant::Type p_type, const StringName &p_method) {
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[p_type];
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
- const Map<StringName, _VariantCall::FuncData>::Element *E = fd.functions.find(p_method);
+ const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
if (!E)
return false;
@@ -1255,9 +1255,9 @@ bool Variant::is_method_const(Variant::Type p_type, const StringName &p_method)
Vector<StringName> Variant::get_method_argument_names(Variant::Type p_type, const StringName &p_method) {
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[p_type];
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
- const Map<StringName, _VariantCall::FuncData>::Element *E = fd.functions.find(p_method);
+ const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
if (!E)
return Vector<StringName>();
@@ -1266,9 +1266,9 @@ Vector<StringName> Variant::get_method_argument_names(Variant::Type p_type, cons
Variant::Type Variant::get_method_return_type(Variant::Type p_type, const StringName &p_method, bool *r_has_return) {
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[p_type];
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
- const Map<StringName, _VariantCall::FuncData>::Element *E = fd.functions.find(p_method);
+ const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
if (!E)
return Variant::NIL;
@@ -1280,9 +1280,9 @@ Variant::Type Variant::get_method_return_type(Variant::Type p_type, const String
Vector<Variant> Variant::get_method_default_arguments(Variant::Type p_type, const StringName &p_method) {
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[p_type];
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
- const Map<StringName, _VariantCall::FuncData>::Element *E = fd.functions.find(p_method);
+ const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
if (!E)
return Vector<Variant>();
@@ -1291,9 +1291,9 @@ Vector<Variant> Variant::get_method_default_arguments(Variant::Type p_type, cons
void Variant::get_method_list(List<MethodInfo> *p_list) const {
- const _VariantCall::TypeFunc &fd = _VariantCall::type_funcs[type];
+ const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[type];
- for (const Map<StringName, _VariantCall::FuncData>::Element *E = fd.functions.front(); E; E = E->next()) {
+ for (const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.front(); E; E = E->next()) {
const _VariantCall::FuncData &fd = E->get();
@@ -1405,11 +1405,11 @@ Variant Variant::get_constant_value(Variant::Type p_type, const StringName &p_va
Map<StringName, int>::Element *E = cd.value.find(p_value);
if (!E) {
- Map<StringName, Variant>::Element *E = cd.variant_value.find(p_value);
- if (E) {
+ Map<StringName, Variant>::Element *F = cd.variant_value.find(p_value);
+ if (F) {
if (r_valid)
*r_valid = true;
- return E->get();
+ return F->get();
} else {
return -1;
}
diff --git a/core/variant_construct_string.cpp b/core/variant_construct_string.cpp
deleted file mode 100644
index 2cb7481634..0000000000
--- a/core/variant_construct_string.cpp
+++ /dev/null
@@ -1,438 +0,0 @@
-/*************************************************************************/
-/* variant_construct_string.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 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 "variant.h"
-
-class VariantConstruct {
-
- enum TokenType {
- TK_CURLY_BRACKET_OPEN,
- TK_CURLY_BRACKET_CLOSE,
- TK_BRACKET_OPEN,
- TK_BRACKET_CLOSE,
- TK_IDENTIFIER,
- TK_STRING,
- TK_NUMBER,
- TK_COLON,
- TK_COMMA,
- TK_EOF,
- TK_MAX
- };
-
- enum Expecting {
-
- EXPECT_OBJECT,
- EXPECT_OBJECT_KEY,
- EXPECT_COLON,
- EXPECT_OBJECT_VALUE,
- };
-
- struct Token {
-
- TokenType type;
- Variant value;
- };
-
- static const char *tk_name[TK_MAX];
-
- static String _print_var(const Variant &p_var);
-
- static Error _get_token(const CharType *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str);
- static Error _parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud);
- static Error _parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud);
- static Error _parse_dict(Dictionary &dict, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud);
-
-public:
- static Error parse(const String &p_string, Variant &r_ret, String &r_err_str, int &r_err_line, Variant::ObjectConstruct *p_construct, void *p_ud);
-};
-
-const char *VariantConstruct::tk_name[TK_MAX] = {
- "'{'",
- "'}'",
- "'['",
- "']'",
- "identifier",
- "string",
- "number",
- "':'",
- "','",
- "EOF",
-};
-
-Error VariantConstruct::_get_token(const CharType *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str) {
-
- while (true) {
- switch (p_str[index]) {
-
- case '\n': {
-
- line++;
- index++;
- break;
- };
- case 0: {
- r_token.type = TK_EOF;
- return OK;
- } break;
- case '{': {
-
- r_token.type = TK_CURLY_BRACKET_OPEN;
- index++;
- return OK;
- };
- case '}': {
-
- r_token.type = TK_CURLY_BRACKET_CLOSE;
- index++;
- return OK;
- };
- case '[': {
-
- r_token.type = TK_BRACKET_OPEN;
- index++;
- return OK;
- };
- case ']': {
-
- r_token.type = TK_BRACKET_CLOSE;
- index++;
- return OK;
- };
- case ':': {
-
- r_token.type = TK_COLON;
- index++;
- return OK;
- };
- case ',': {
-
- r_token.type = TK_COMMA;
- index++;
- return OK;
- };
- case '"': {
-
- index++;
- String str;
- while (true) {
- if (p_str[index] == 0) {
- r_err_str = "Unterminated String";
- return ERR_PARSE_ERROR;
- } else if (p_str[index] == '"') {
- index++;
- break;
- } else if (p_str[index] == '\\') {
- //escaped characters...
- index++;
- CharType next = p_str[index];
- if (next == 0) {
- r_err_str = "Unterminated String";
- return ERR_PARSE_ERROR;
- }
- CharType res = 0;
-
- switch (next) {
-
- case 'b': res = 8; break;
- case 't': res = 9; break;
- case 'n': res = 10; break;
- case 'f': res = 12; break;
- case 'r': res = 13; break;
- case '\"': res = '\"'; break;
- case '\\': res = '\\'; break;
- case '/': res = '/'; break;
- case 'u': {
- //hexnumbarh - oct is deprecated
-
- for (int j = 0; j < 4; j++) {
- CharType c = p_str[index + j + 1];
- if (c == 0) {
- r_err_str = "Unterminated String";
- return ERR_PARSE_ERROR;
- }
- if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
-
- r_err_str = "Malformed hex constant in string";
- return ERR_PARSE_ERROR;
- }
- CharType v;
- if (c >= '0' && c <= '9') {
- v = c - '0';
- } else if (c >= 'a' && c <= 'f') {
- v = c - 'a';
- v += 10;
- } else if (c >= 'A' && c <= 'F') {
- v = c - 'A';
- v += 10;
- } else {
- ERR_PRINT("BUG");
- v = 0;
- }
-
- res <<= 4;
- res |= v;
- }
- index += 4; //will add at the end anyway
-
- } break;
- default: {
-
- r_err_str = "Invalid escape sequence";
- return ERR_PARSE_ERROR;
- } break;
- }
-
- str += res;
-
- } else {
- if (p_str[index] == '\n')
- line++;
- str += p_str[index];
- }
- index++;
- }
-
- r_token.type = TK_STRING;
- r_token.value = str;
- return OK;
-
- } break;
- default: {
-
- if (p_str[index] <= 32) {
- index++;
- break;
- }
-
- if (p_str[index] == '-' || (p_str[index] >= '0' && p_str[index] <= '9')) {
- //a number
- const CharType *rptr;
- double number = String::to_double(&p_str[index], &rptr);
- index += (rptr - &p_str[index]);
- r_token.type = TK_NUMBER;
- r_token.value = number;
- return OK;
-
- } else if ((p_str[index] >= 'A' && p_str[index] <= 'Z') || (p_str[index] >= 'a' && p_str[index] <= 'z')) {
-
- String id;
-
- while ((p_str[index] >= 'A' && p_str[index] <= 'Z') || (p_str[index] >= 'a' && p_str[index] <= 'z')) {
-
- id += p_str[index];
- index++;
- }
-
- r_token.type = TK_IDENTIFIER;
- r_token.value = id;
- return OK;
- } else {
- r_err_str = "Unexpected character.";
- return ERR_PARSE_ERROR;
- }
- }
- }
- }
-
- return ERR_PARSE_ERROR;
-}
-
-Error VariantConstruct::_parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud) {
-
- if (token.type == TK_CURLY_BRACKET_OPEN) {
-
- Dictionary d;
- Error err = _parse_dict(d, p_str, index, p_len, line, r_err_str, p_construct, p_ud);
- if (err)
- return err;
- value = d;
- return OK;
- } else if (token.type == TK_BRACKET_OPEN) {
-
- Array a;
- Error err = _parse_array(a, p_str, index, p_len, line, r_err_str, p_construct, p_ud);
- if (err)
- return err;
- value = a;
- return OK;
-
- } else if (token.type == TK_IDENTIFIER) {
-
- String id = token.value;
- if (id == "true")
- value = true;
- else if (id == "false")
- value = false;
- else if (id == "null")
- value = Variant();
- else {
- r_err_str = "Expected 'true','false' or 'null', got '" + id + "'.";
- return ERR_PARSE_ERROR;
- }
- return OK;
-
- } else if (token.type == TK_NUMBER) {
-
- value = token.value;
- return OK;
- } else if (token.type == TK_STRING) {
-
- value = token.value;
- return OK;
- } else {
- r_err_str = "Expected value, got " + String(tk_name[token.type]) + ".";
- return ERR_PARSE_ERROR;
- }
-
- return ERR_PARSE_ERROR;
-}
-
-Error VariantConstruct::_parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud) {
-
- Token token;
- bool need_comma = false;
-
- while (index < p_len) {
-
- Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
- if (err != OK)
- return err;
-
- if (token.type == TK_BRACKET_CLOSE) {
-
- return OK;
- }
-
- if (need_comma) {
-
- if (token.type != TK_COMMA) {
-
- r_err_str = "Expected ','";
- return ERR_PARSE_ERROR;
- } else {
- need_comma = false;
- continue;
- }
- }
-
- Variant v;
- err = _parse_value(v, token, p_str, index, p_len, line, r_err_str, p_construct, p_ud);
- if (err)
- return err;
-
- array.push_back(v);
- need_comma = true;
- }
-
- return OK;
-}
-
-Error VariantConstruct::_parse_dict(Dictionary &dict, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud) {
-
- bool at_key = true;
- Variant key;
- Token token;
- bool need_comma = false;
-
- while (index < p_len) {
-
- if (at_key) {
-
- Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
- if (err != OK)
- return err;
-
- if (token.type == TK_CURLY_BRACKET_CLOSE) {
-
- return OK;
- }
-
- if (need_comma) {
-
- if (token.type != TK_COMMA) {
-
- r_err_str = "Expected '}' or ','";
- return ERR_PARSE_ERROR;
- } else {
- need_comma = false;
- continue;
- }
- }
-
- err = _parse_value(key, token, p_str, index, p_len, line, r_err_str, p_construct, p_ud);
-
- if (err != OK)
- return err;
-
- err = _get_token(p_str, index, p_len, token, line, r_err_str);
-
- if (err != OK)
- return err;
-
- if (token.type != TK_COLON) {
-
- r_err_str = "Expected ':'";
- return ERR_PARSE_ERROR;
- }
- at_key = false;
- } else {
-
- Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
- if (err != OK)
- return err;
-
- Variant v;
- err = _parse_value(v, token, p_str, index, p_len, line, r_err_str, p_construct, p_ud);
- if (err)
- return err;
- dict[key] = v;
- need_comma = true;
- at_key = true;
- }
- }
-
- return OK;
-}
-
-Error VariantConstruct::parse(const String &p_string, Variant &r_ret, String &r_err_str, int &r_err_line, Variant::ObjectConstruct *p_construct, void *p_ud) {
-
- const CharType *str = p_string.ptr();
- int idx = 0;
- int len = p_string.length();
- Token token;
- r_err_line = 0;
- String aux_key;
-
- Error err = _get_token(str, idx, len, token, r_err_line, r_err_str);
- if (err)
- return err;
-
- return _parse_value(r_ret, token, str, idx, len, r_err_line, r_err_str, p_construct, p_ud);
-}
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index 93654d3389..26851e4c23 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -3496,15 +3496,15 @@ void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst)
case COLOR: {
const Color *ca = reinterpret_cast<const Color *>(a._data._mem);
const Color *cb = reinterpret_cast<const Color *>(b._data._mem);
- float r = ca->r + cb->r * c;
- float g = ca->g + cb->g * c;
- float b = ca->b + cb->b * c;
- float a = ca->a + cb->a * c;
- r = r > 1.0 ? 1.0 : r;
- g = g > 1.0 ? 1.0 : g;
- b = b > 1.0 ? 1.0 : b;
- a = a > 1.0 ? 1.0 : a;
- r_dst = Color(r, g, b, a);
+ float new_r = ca->r + cb->r * c;
+ float new_g = ca->g + cb->g * c;
+ float new_b = ca->b + cb->b * c;
+ float new_a = ca->a + cb->a * c;
+ new_r = new_r > 1.0 ? 1.0 : new_r;
+ new_g = new_g > 1.0 ? 1.0 : new_g;
+ new_b = new_b > 1.0 ? 1.0 : new_b;
+ new_a = new_a > 1.0 ? 1.0 : new_a;
+ r_dst = Color(new_r, new_g, new_b, new_a);
}
return;
default: {
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index 84fb85e812..0056fc75b6 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -728,7 +728,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
bool at_key = true;
String key;
- Token token;
+ Token token2;
bool need_comma = false;
while (true) {
@@ -740,11 +740,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
if (at_key) {
- Error err = get_token(p_stream, token, line, r_err_str);
+ Error err = get_token(p_stream, token2, line, r_err_str);
if (err != OK)
return err;
- if (token.type == TK_PARENTHESIS_CLOSE) {
+ if (token2.type == TK_PARENTHESIS_CLOSE) {
Reference *reference = Object::cast_to<Reference>(obj);
if (reference) {
value = REF(reference);
@@ -756,7 +756,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
if (need_comma) {
- if (token.type != TK_COMMA) {
+ if (token2.type != TK_COMMA) {
r_err_str = "Expected '}' or ','";
return ERR_PARSE_ERROR;
@@ -766,18 +766,18 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
}
- if (token.type != TK_STRING) {
+ if (token2.type != TK_STRING) {
r_err_str = "Expected property name as string";
return ERR_PARSE_ERROR;
}
- key = token.value;
+ key = token2.value;
- err = get_token(p_stream, token, line, r_err_str);
+ err = get_token(p_stream, token2, line, r_err_str);
if (err != OK)
return err;
- if (token.type != TK_COLON) {
+ if (token2.type != TK_COLON) {
r_err_str = "Expected ':'";
return ERR_PARSE_ERROR;
@@ -785,12 +785,12 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
at_key = false;
} else {
- Error err = get_token(p_stream, token, line, r_err_str);
+ Error err = get_token(p_stream, token2, line, r_err_str);
if (err != OK)
return err;
Variant v;
- err = parse_value(token, v, p_stream, line, r_err_str, p_res_parser);
+ err = parse_value(token2, v, p_stream, line, r_err_str, p_res_parser);
if (err)
return err;
obj->set(key, v);
@@ -882,11 +882,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
- String id = token.value;
+ String id2 = token.value;
Ref<InputEvent> ie;
- if (id == "NONE") {
+ if (id2 == "NONE") {
get_token(p_stream, token, line, r_err_str);
@@ -895,7 +895,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
- } else if (id == "KEY") {
+ } else if (id2 == "KEY") {
Ref<InputEventKey> key;
key.instance();
@@ -954,7 +954,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
- } else if (id == "MBUTTON") {
+ } else if (id2 == "MBUTTON") {
Ref<InputEventMouseButton> mb;
mb.instance();
@@ -980,7 +980,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
- } else if (id == "JBUTTON") {
+ } else if (id2 == "JBUTTON") {
Ref<InputEventJoypadButton> jb;
jb.instance();
@@ -1006,7 +1006,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
- } else if (id == "JAXIS") {
+ } else if (id2 == "JAXIS") {
Ref<InputEventJoypadMotion> jm;
jm.instance();
@@ -1597,7 +1597,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::INT: {
- p_store_string_func(p_store_string_ud, itos(p_variant.operator int()));
+ p_store_string_func(p_store_string_ud, itos(p_variant.operator int64_t()));
} break;
case Variant::REAL: {
diff --git a/core/vector.h b/core/vector.h
index 90b3d90826..93ee003519 100644
--- a/core/vector.h
+++ b/core/vector.h
@@ -40,7 +40,7 @@
#include "core/cowdata.h"
#include "core/error_macros.h"
#include "core/os/memory.h"
-#include "core/sort.h"
+#include "core/sort_array.h"
template <class T>
class VectorWriteProxy {
diff --git a/core/version.h b/core/version.h
index 46eecf6125..05fec9d0a6 100644
--- a/core/version.h
+++ b/core/version.h
@@ -41,9 +41,14 @@
#ifdef VERSION_PATCH
// Example: "3.1.4"
#define VERSION_NUMBER "" VERSION_BRANCH "." _MKSTR(VERSION_PATCH)
+// Version number encoded as hexadecimal int with one byte for each number,
+// for easy comparison from code.
+// Example: 3.1.4 will be 0x030104, making comparison easy from script.
+#define VERSION_HEX 0x10000 * VERSION_MAJOR + 0x100 * VERSION_MINOR + VERSION_PATCH
#else
// Example: "3.1"
#define VERSION_NUMBER "" VERSION_BRANCH
+#define VERSION_HEX 0x10000 * VERSION_MAJOR + 0x100 * VERSION_MINOR
#endif // VERSION_PATCH
// Describes the full configuration of that Godot version, including the version number,