summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/array.cpp11
-rw-r--r--core/array.h2
-rw-r--r--core/class_db.cpp8
-rw-r--r--core/color.cpp12
-rw-r--r--core/color.h6
-rw-r--r--core/io/file_access_network.cpp2
-rw-r--r--core/io/file_access_pack.cpp4
-rw-r--r--core/io/resource_format_binary.cpp48
-rw-r--r--core/io/resource_format_binary.h2
-rw-r--r--core/io/stream_peer.cpp3
-rw-r--r--core/list.h48
-rw-r--r--core/map.h3
-rw-r--r--core/math/a_star.cpp11
-rw-r--r--core/math/a_star.h1
-rw-r--r--core/math/camera_matrix.cpp85
-rw-r--r--core/math/camera_matrix.h1
-rw-r--r--core/math/matrix3.cpp15
-rw-r--r--core/math/matrix3.h2
-rw-r--r--core/math/transform.cpp12
-rw-r--r--core/math/triangle_mesh.cpp2
-rw-r--r--core/object.h12
-rw-r--r--core/ordered_hash_map.h6
-rw-r--r--core/project_settings.cpp10
-rw-r--r--core/resource.cpp3
-rw-r--r--core/script_debugger_remote.cpp3
-rw-r--r--core/script_language.cpp1
-rw-r--r--core/script_language.h1
-rw-r--r--core/set.h3
-rw-r--r--core/string_buffer.cpp102
-rw-r--r--core/string_buffer.h82
-rw-r--r--core/string_builder.cpp94
-rw-r--r--core/string_builder.h79
-rw-r--r--core/type_info.h75
-rw-r--r--core/variant_call.cpp12
-rw-r--r--core/variant_parser.cpp22
35 files changed, 589 insertions, 194 deletions
diff --git a/core/array.cpp b/core/array.cpp
index c35bf5bf0c..2e3fbf858d 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -210,6 +210,17 @@ const Variant &Array::get(int p_idx) const {
return operator[](p_idx);
}
+Array Array::duplicate() const {
+
+ Array new_arr;
+ int element_count = size();
+ new_arr.resize(element_count);
+ for (int i = 0; i < element_count; i++) {
+ new_arr[i] = get(i);
+ }
+
+ return new_arr;
+}
struct _ArrayVariantSort {
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
diff --git a/core/array.h b/core/array.h
index 777116ab56..8a647dd13b 100644
--- a/core/array.h
+++ b/core/array.h
@@ -84,6 +84,8 @@ public:
Variant pop_back();
Variant pop_front();
+ Array duplicate() const;
+
Array(const Array &p_from);
Array();
~Array();
diff --git a/core/class_db.cpp b/core/class_db.cpp
index 872e466e72..f5ddd9c761 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -536,11 +536,9 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
minfo.return_val = method->get_return_info();
minfo.flags = method->get_hint_flags();
- int defval_count = method->get_default_argument_count();
- minfo.default_arguments.resize(defval_count);
-
- for (int i = 0; i < defval_count; i++) {
- minfo.default_arguments[i] = method->get_default_argument(defval_count - i - 1);
+ for (int i = 0; i < method->get_argument_count(); i++) {
+ if (method->has_default_argument(i))
+ minfo.default_arguments.push_back(method->get_default_argument(i));
}
p_methods->push_back(minfo);
diff --git a/core/color.cpp b/core/color.cpp
index ab264d31d4..259a4988b1 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -34,7 +34,7 @@
#include "math_funcs.h"
#include "print_string.h"
-uint32_t Color::to_ARGB32() const {
+uint32_t Color::to_argb32() const {
uint32_t c = (uint8_t)(a * 255);
c <<= 8;
@@ -47,7 +47,7 @@ uint32_t Color::to_ARGB32() const {
return c;
}
-uint32_t Color::to_ABGR32() const {
+uint32_t Color::to_abgr32() const {
uint32_t c = (uint8_t)(a * 255);
c <<= 8;
c |= (uint8_t)(b * 255);
@@ -59,15 +59,15 @@ uint32_t Color::to_ABGR32() const {
return c;
}
-uint32_t Color::to_32() const {
+uint32_t Color::to_rgba32() const {
- uint32_t c = (uint8_t)(a * 255);
- c <<= 8;
- c |= (uint8_t)(r * 255);
+ uint32_t c = (uint8_t)(r * 255);
c <<= 8;
c |= (uint8_t)(g * 255);
c <<= 8;
c |= (uint8_t)(b * 255);
+ c <<= 8;
+ c |= (uint8_t)(a * 255);
return c;
}
diff --git a/core/color.h b/core/color.h
index cd5510cf01..d3d5db09f9 100644
--- a/core/color.h
+++ b/core/color.h
@@ -51,9 +51,9 @@ struct Color {
bool operator==(const Color &p_color) const { return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a); }
bool operator!=(const Color &p_color) const { return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a); }
- uint32_t to_32() const;
- uint32_t to_ARGB32() const;
- uint32_t to_ABGR32() const;
+ uint32_t to_rgba32() const;
+ uint32_t to_argb32() const;
+ uint32_t to_abgr32() const;
float gray() const;
float get_h() const;
float get_s() const;
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index d8b8c8c200..58ca2d4c58 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -87,6 +87,8 @@ void FileAccessNetworkClient::_thread_func() {
DEBUG_PRINT("SEM WAIT - " + itos(sem->get()));
Error err = sem->wait();
+ if (err != OK)
+ ERR_PRINT("sem->wait() failed");
DEBUG_TIME("sem_unlock");
//DEBUG_PRINT("semwait returned "+itos(werr));
DEBUG_PRINT("MUTEX LOCK " + itos(lockcount));
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index e36ff28220..e511085ac5 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -166,9 +166,9 @@ bool PackedSourcePCK::try_open_pack(const String &p_path) {
uint32_t ver_rev = f->get_32();
ERR_EXPLAIN("Pack version unsupported: " + itos(version));
- ERR_FAIL_COND_V(version != PACK_VERSION, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(version != PACK_VERSION, false);
ERR_EXPLAIN("Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + "." + itos(ver_rev));
- ERR_FAIL_COND_V(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false);
for (int i = 0; i < 16; i++) {
//reserved
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index c5909981ea..16ec6cd3c5 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -37,7 +37,7 @@
#include "core/version.h"
//#define print_bl(m_what) print_line(m_what)
-#define print_bl(m_what)
+#define print_bl(m_what) (void)(m_what)
enum {
@@ -854,12 +854,6 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
}
bool big_endian = f->get_32();
-#ifdef BIG_ENDIAN_ENABLED
- endian_swap = !big_endian;
-#else
- bool endian_swap = big_endian;
-#endif
-
bool use_real64 = f->get_32();
f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian
@@ -869,7 +863,11 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
uint32_t ver_format = f->get_32();
print_bl("big endian: " + itos(big_endian));
- print_bl("endian swap: " + itos(endian_swap));
+#ifdef BIG_ENDIAN_ENABLED
+ print_bl("endian swap: " + itos(!big_endian));
+#else
+ print_bl("endian swap: " + itos(big_endian));
+#endif
print_bl("real64: " + itos(use_real64));
print_bl("major: " + itos(ver_major));
print_bl("minor: " + itos(ver_minor));
@@ -964,18 +962,12 @@ String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) {
}
bool big_endian = f->get_32();
-#ifdef BIG_ENDIAN_ENABLED
- endian_swap = !big_endian;
-#else
- bool endian_swap = big_endian;
-#endif
-
- bool use_real64 = f->get_32();
+ f->get_32(); // use_real64
f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian
uint32_t ver_major = f->get_32();
- uint32_t ver_minor = f->get_32();
+ f->get_32(); // ver_minor
uint32_t ver_format = f->get_32();
if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
@@ -993,8 +985,6 @@ ResourceInteractiveLoaderBinary::ResourceInteractiveLoaderBinary() {
f = NULL;
stage = 0;
- endian_swap = false;
- use_real64 = false;
error = OK;
translation_remapped = false;
}
@@ -1117,19 +1107,20 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
memdelete(f);
}
ERR_FAIL_COND_V(!fw, ERR_CANT_CREATE);
+
+ uint8_t magic[4] = { 'R', 'S', 'R', 'C' };
+ fw->store_buffer(magic, 4);
}
bool big_endian = f->get_32();
-#ifdef BIG_ENDIAN_ENABLED
- endian_swap = !big_endian;
-#else
- bool endian_swap = big_endian;
-#endif
-
bool use_real64 = f->get_32();
f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian
- fw->store_32(endian_swap);
+#ifdef BIG_ENDIAN_ENABLED
+ fw->store_32(!big_endian);
+#else
+ fw->store_32(big_endian);
+#endif
fw->set_endian_swap(big_endian != 0);
fw->store_32(use_real64); //use real64
@@ -1790,8 +1781,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
}
save_unicode_string(p_resource->get_class());
- uint64_t md_at = f->get_pos();
- f->store_64(0); //offset to impoty metadata
+ f->store_64(0); //offset to import metadata
for (int i = 0; i < 14; i++)
f->store_32(0); // reserved
@@ -1811,11 +1801,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
if (skip_editor && F->get().name.begins_with("__editor"))
continue;
- if (F->get().usage & PROPERTY_USAGE_STORAGE) {
+ if ((F->get().usage & PROPERTY_USAGE_STORAGE)) {
Property p;
p.name_idx = get_string_index(F->get().name);
p.value = E->get()->get(F->get().name);
- if ((F->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO && p.value.is_zero()) || (F->get().usage & PROPERTY_USAGE_STORE_IF_NONONE && p.value.is_one()))
+ if (((F->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO) && p.value.is_zero()) || ((F->get().usage & PROPERTY_USAGE_STORE_IF_NONONE) && p.value.is_one()))
continue;
p.pi = F->get();
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index ab77c2c9d3..2316f05b3c 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -44,8 +44,6 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
FileAccess *f;
- bool endian_swap;
- bool use_real64;
uint64_t importmd_ofs;
Vector<char> str_buf;
diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp
index 1006158003..f4f81f0807 100644
--- a/core/io/stream_peer.cpp
+++ b/core/io/stream_peer.cpp
@@ -446,6 +446,7 @@ Error StreamPeerBuffer::get_data(uint8_t *p_buffer, int p_bytes) {
return OK;
}
+
Error StreamPeerBuffer::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) {
if (pointer + p_bytes > data.size()) {
@@ -463,6 +464,8 @@ Error StreamPeerBuffer::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_
pointer += r_received;
// FIXME: return what? OK or ERR_*
+ // return OK for now so we don't maybe return garbage
+ return OK;
}
int StreamPeerBuffer::get_available_bytes() const {
diff --git a/core/list.h b/core/list.h
index a67287a9ab..da201e9868 100644
--- a/core/list.h
+++ b/core/list.h
@@ -291,6 +291,54 @@ public:
erase(_data->first);
}
+ Element *insert_after(Element *p_element, const T &p_value) {
+ CRASH_COND(p_element && (!_data || p_element->data != _data));
+
+ if (!p_element) {
+ return push_back(p_value);
+ }
+
+ Element *n = memnew_allocator(Element, A);
+ n->value = (T &)p_value;
+ n->prev_ptr = p_element;
+ n->next_ptr = p_element->next_ptr;
+ n->data = _data;
+
+ if (!p_element->next_ptr) {
+ _data->last = n;
+ }
+
+ p_element->next_ptr = n;
+
+ _data->size_cache++;
+
+ return n;
+ }
+
+ Element *insert_before(Element *p_element, const T &p_value) {
+ CRASH_COND(p_element && (!_data || p_element->data != _data));
+
+ if (!p_element) {
+ return push_back(p_value);
+ }
+
+ Element *n = memnew_allocator(Element, A);
+ n->value = (T &)p_value;
+ n->prev_ptr = p_element->prev_ptr;
+ n->next_ptr = p_element;
+ n->data = _data;
+
+ if (!p_element->prev_ptr) {
+ _data->first = n;
+ }
+
+ p_element->prev_ptr = n;
+
+ _data->size_cache++;
+
+ return n;
+ }
+
/**
* find an element in the list,
*/
diff --git a/core/map.h b/core/map.h
index 75a38a3440..a37d898a9c 100644
--- a/core/map.h
+++ b/core/map.h
@@ -453,8 +453,9 @@ private:
if (!rp)
rp = _data._nil;
Element *node = (rp->left == _data._nil) ? rp->right : rp->left;
+ node->parent = rp->parent;
- if (_data._root == (node->parent = rp->parent)) {
+ if (_data._root == node->parent) {
_data._root->left = node;
} else {
if (rp == rp->parent->left) {
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index 21516ac768..d1afcec18f 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -129,6 +129,16 @@ bool AStar::has_point(int p_id) const {
return points.has(p_id);
}
+Array AStar::get_points() {
+ Array point_list;
+
+ for (const Map<int, Point *>::Element *E = points.front(); E; E = E->next()) {
+ point_list.push_back(E->key());
+ }
+
+ return point_list;
+}
+
bool AStar::are_points_connected(int p_id, int p_with_id) const {
Segment s(p_id, p_with_id);
@@ -407,6 +417,7 @@ void AStar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_point_weight_scale", "id"), &AStar::get_point_weight_scale);
ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar::remove_point);
ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar::has_point);
+ ClassDB::bind_method(D_METHOD("get_points"), &AStar::get_points);
ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id", "bidirectional"), &AStar::connect_points, DEFVAL(true));
ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar::disconnect_points);
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 75b860d0a4..38d13d510b 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -105,6 +105,7 @@ public:
real_t get_point_weight_scale(int p_id) const;
void remove_point(int p_id);
bool has_point(int p_id) const;
+ Array get_points();
void connect_points(int p_id, int p_with_id, bool bidirectional = true);
void disconnect_points(int p_id, int p_with_id);
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 0512cdd798..7132b6573e 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -131,7 +131,6 @@ void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_
void CameraMatrix::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far) {
// we first calculate our base frustum on our values without taking our lens magnification into account.
- real_t display_to_eye = 2.0 * p_display_to_lens;
real_t f1 = (p_intraocular_dist * 0.5) / p_display_to_lens;
real_t f2 = ((p_display_width - p_intraocular_dist) * 0.5) / p_display_to_lens;
real_t f3 = (p_display_width / 4.0) / p_display_to_lens;
@@ -265,75 +264,26 @@ void CameraMatrix::get_viewport_size(real_t &r_width, real_t &r_height) const {
bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8points) const {
- const real_t *matrix = (const real_t *)this->matrix;
-
- ///////--- Near Plane ---///////
- Plane near_plane = Plane(matrix[3] + matrix[2],
- matrix[7] + matrix[6],
- matrix[11] + matrix[10],
- -matrix[15] - matrix[14]);
- near_plane.normalize();
-
- ///////--- Far Plane ---///////
- Plane far_plane = Plane(matrix[2] - matrix[3],
- matrix[6] - matrix[7],
- matrix[10] - matrix[11],
- matrix[15] - matrix[14]);
- far_plane.normalize();
-
- ///////--- Right Plane ---///////
- Plane right_plane = Plane(matrix[0] - matrix[3],
- matrix[4] - matrix[7],
- matrix[8] - matrix[11],
- -matrix[15] + matrix[12]);
- right_plane.normalize();
-
- ///////--- Top Plane ---///////
- Plane top_plane = Plane(matrix[1] - matrix[3],
- matrix[5] - matrix[7],
- matrix[9] - matrix[11],
- -matrix[15] + matrix[13]);
- top_plane.normalize();
-
- Vector3 near_endpoint_left, near_endpoint_right;
- Vector3 far_endpoint_left, far_endpoint_right;
-
- bool res = near_plane.intersect_3(right_plane, top_plane, &near_endpoint_right);
- ERR_FAIL_COND_V(!res, false);
-
- res = far_plane.intersect_3(right_plane, top_plane, &far_endpoint_right);
- ERR_FAIL_COND_V(!res, false);
-
- if ((matrix[8] == 0) && (matrix[9] == 0)) {
- near_endpoint_left = near_endpoint_right;
- near_endpoint_left.x = -near_endpoint_left.x;
-
- far_endpoint_left = far_endpoint_right;
- far_endpoint_left.x = -far_endpoint_left.x;
- } else {
- ///////--- Left Plane ---///////
- Plane left_plane = Plane(matrix[0] + matrix[3],
- matrix[4] + matrix[7],
- matrix[8] + matrix[11],
- -matrix[15] - matrix[12]);
- left_plane.normalize();
+ Vector<Plane> planes = get_projection_planes(Transform());
+ const Planes intersections[8][3] = {
+ { PLANE_FAR, PLANE_LEFT, PLANE_TOP },
+ { PLANE_FAR, PLANE_LEFT, PLANE_BOTTOM },
+ { PLANE_FAR, PLANE_RIGHT, PLANE_TOP },
+ { PLANE_FAR, PLANE_RIGHT, PLANE_BOTTOM },
+ { PLANE_NEAR, PLANE_LEFT, PLANE_TOP },
+ { PLANE_NEAR, PLANE_LEFT, PLANE_BOTTOM },
+ { PLANE_NEAR, PLANE_RIGHT, PLANE_TOP },
+ { PLANE_NEAR, PLANE_RIGHT, PLANE_BOTTOM },
+ };
- res = near_plane.intersect_3(left_plane, top_plane, &near_endpoint_left);
- ERR_FAIL_COND_V(!res, false);
+ for (int i = 0; i < 8; i++) {
- res = far_plane.intersect_3(left_plane, top_plane, &far_endpoint_left);
+ Vector3 point;
+ bool res = planes[intersections[i][0]].intersect_3(planes[intersections[i][1]], planes[intersections[i][2]], &point);
ERR_FAIL_COND_V(!res, false);
+ p_8points[i] = p_transform.xform(point);
}
- p_8points[0] = p_transform.xform(Vector3(near_endpoint_right.x, near_endpoint_right.y, near_endpoint_right.z));
- p_8points[1] = p_transform.xform(Vector3(near_endpoint_right.x, -near_endpoint_right.y, near_endpoint_right.z));
- p_8points[2] = p_transform.xform(Vector3(near_endpoint_left.x, near_endpoint_left.y, near_endpoint_left.z));
- p_8points[3] = p_transform.xform(Vector3(near_endpoint_left.x, -near_endpoint_left.y, near_endpoint_left.z));
- p_8points[4] = p_transform.xform(Vector3(far_endpoint_right.x, far_endpoint_right.y, far_endpoint_right.z));
- p_8points[5] = p_transform.xform(Vector3(far_endpoint_right.x, -far_endpoint_right.y, far_endpoint_right.z));
- p_8points[6] = p_transform.xform(Vector3(far_endpoint_left.x, far_endpoint_left.y, far_endpoint_left.z));
- p_8points[7] = p_transform.xform(Vector3(far_endpoint_left.x, -far_endpoint_left.y, far_endpoint_left.z));
-
return true;
}
@@ -610,6 +560,11 @@ int CameraMatrix::get_pixels_per_meter(int p_for_pixel_width) const {
return int((result.x * 0.5 + 0.5) * p_for_pixel_width);
}
+bool CameraMatrix::is_orthogonal() const {
+
+ return matrix[3][3] == 1.0;
+}
+
real_t CameraMatrix::get_fov() const {
const real_t *matrix = (const real_t *)this->matrix;
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index 175d0cdb1b..3145d73356 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -69,6 +69,7 @@ struct CameraMatrix {
real_t get_z_near() const;
real_t get_aspect() const;
real_t get_fov() const;
+ bool is_orthogonal() const;
Vector<Plane> get_projection_planes(const Transform &p_transform) const;
diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp
index 9732a1ff37..4051de7afb 100644
--- a/core/math/matrix3.cpp
+++ b/core/math/matrix3.cpp
@@ -234,7 +234,22 @@ Basis Basis::scaled(const Vector3 &p_scale) const {
return m;
}
+void Basis::set_scale(const Vector3 &p_scale) {
+
+ set_axis(0, get_axis(0).normalized() * p_scale.x);
+ set_axis(1, get_axis(1).normalized() * p_scale.y);
+ set_axis(2, get_axis(2).normalized() * p_scale.z);
+}
+
Vector3 Basis::get_scale() const {
+
+ return Vector3(
+ Vector3(elements[0][0], elements[1][0], elements[2][0]).length(),
+ Vector3(elements[0][1], elements[1][1], elements[2][1]).length(),
+ Vector3(elements[0][2], elements[1][2], elements[2][2]).length());
+}
+
+Vector3 Basis::get_signed_scale() const {
// FIXME: We are assuming M = R.S (R is rotation and S is scaling), and use polar decomposition to extract R and S.
// A polar decomposition is M = O.P, where O is an orthogonal matrix (meaning rotation and reflection) and
// P is a positive semi-definite matrix (meaning it contains absolute values of scaling along its diagonal).
diff --git a/core/math/matrix3.h b/core/math/matrix3.h
index 9c9080ac46..23429888e0 100644
--- a/core/math/matrix3.h
+++ b/core/math/matrix3.h
@@ -97,7 +97,9 @@ public:
void scale(const Vector3 &p_scale);
Basis scaled(const Vector3 &p_scale) const;
+ void set_scale(const Vector3 &p_scale);
Vector3 get_scale() const;
+ Vector3 get_signed_scale() const;
// transposed dot products
_FORCE_INLINE_ real_t tdotx(const Vector3 &v) const {
diff --git a/core/math/transform.cpp b/core/math/transform.cpp
index 60df69a509..638a39ab73 100644
--- a/core/math/transform.cpp
+++ b/core/math/transform.cpp
@@ -118,17 +118,17 @@ Transform Transform::interpolate_with(const Transform &p_transform, real_t p_c)
/* not sure if very "efficient" but good enough? */
- Vector3 src_scale = basis.get_scale();
- Quat src_rot = basis;
+ Vector3 src_scale = basis.get_signed_scale();
+ Quat src_rot = basis.orthonormalized();
Vector3 src_loc = origin;
- Vector3 dst_scale = p_transform.basis.get_scale();
+ Vector3 dst_scale = p_transform.basis.get_signed_scale();
Quat dst_rot = p_transform.basis;
Vector3 dst_loc = p_transform.origin;
- Transform dst;
- dst.basis = src_rot.slerp(dst_rot, p_c);
- dst.basis.scale(src_scale.linear_interpolate(dst_scale, p_c));
+ Transform dst; //this could be made faster by using a single function in Basis..
+ dst.basis = src_rot.slerp(dst_rot, p_c).normalized();
+ dst.basis.set_scale(src_scale.linear_interpolate(dst_scale, p_c));
dst.origin = src_loc.linear_interpolate(dst_loc, p_c);
return dst;
diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp
index 614104f698..3b246cb183 100644
--- a/core/math/triangle_mesh.cpp
+++ b/core/math/triangle_mesh.cpp
@@ -158,7 +158,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) {
max_depth = 0;
int max_alloc = fc;
- int max = _create_bvh(bw.ptr(), bwp.ptr(), 0, fc, 1, max_depth, max_alloc);
+ _create_bvh(bw.ptr(), bwp.ptr(), 0, fc, 1, max_depth, max_alloc);
bw = PoolVector<BVH>::Write(); //clearup
bvh.resize(max_alloc); //resize back
diff --git a/core/object.h b/core/object.h
index 6e1ed4308e..644e2b8270 100644
--- a/core/object.h
+++ b/core/object.h
@@ -567,12 +567,6 @@ public:
template <class T>
static T *cast_to(Object *p_object) {
-#ifdef DEBUG_ENABLED
- // TODO there are some legitimate reasons to pass NULL as p_object.
- // we need to figure out how to deal with that in debug mode.
- // This code will return NULL for a NULL input in release mode also.
- ERR_FAIL_COND_V(p_object == NULL, NULL);
-#endif
#ifndef NO_SAFE_CAST
return dynamic_cast<T *>(p_object);
#else
@@ -587,12 +581,6 @@ public:
template <class T>
static const T *cast_to(const Object *p_object) {
-#ifdef DEBUG_ENABLED
- // TODO there are some legitimate reasons to pass NULL as p_object.
- // we need to figure out how to deal with that in debug mode.
- // This code will return NULL for a NULL input in release mode also.
- ERR_FAIL_COND_V(p_object == NULL, NULL);
-#endif
#ifndef NO_SAFE_CAST
return dynamic_cast<const T *>(p_object);
#else
diff --git a/core/ordered_hash_map.h b/core/ordered_hash_map.h
index 3e619d2b2e..9e95f963e1 100644
--- a/core/ordered_hash_map.h
+++ b/core/ordered_hash_map.h
@@ -55,8 +55,8 @@ public:
friend class OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>;
typename InternalList::Element *list_element;
- typename InternalList::Element *next_element;
typename InternalList::Element *prev_element;
+ typename InternalList::Element *next_element;
Element(typename InternalList::Element *p_element) {
list_element = p_element;
@@ -69,7 +69,7 @@ public:
public:
_FORCE_INLINE_ Element()
- : list_element(NULL), next_element(NULL), prev_element(NULL) {
+ : list_element(NULL), prev_element(NULL), next_element(NULL) {
}
Element next() const {
@@ -312,4 +312,4 @@ bool operator!=(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH
return (first.list_element != second.list_element);
}
-#endif // ORDERED_HASH_MAP_H \ No newline at end of file
+#endif // ORDERED_HASH_MAP_H
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index a74917162b..23e4961138 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -114,7 +114,15 @@ String ProjectSettings::globalize_path(const String &p_path) const {
return p_path.replace("res:/", resource_path);
};
return p_path.replace("res://", "");
- };
+ } else if (p_path.begins_with("user://")) {
+
+ String data_dir = OS::get_singleton()->get_data_dir();
+ if (data_dir != "") {
+
+ return p_path.replace("user:/", data_dir);
+ };
+ return p_path.replace("user://", "");
+ }
return p_path;
}
diff --git a/core/resource.cpp b/core/resource.cpp
index 37d42226b4..78e20bada4 100644
--- a/core/resource.cpp
+++ b/core/resource.cpp
@@ -69,12 +69,11 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
ResourceCache::resources.get(p_path)->set_name("");
ResourceCache::lock->write_unlock();
} else {
- ERR_EXPLAIN("Another resource is loaded from path: " + p_path);
-
ResourceCache::lock->read_lock();
bool exists = ResourceCache::resources.has(p_path);
ResourceCache::lock->read_unlock();
+ ERR_EXPLAIN("Another resource is loaded from path: " + p_path);
ERR_FAIL_COND(exists);
}
}
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index 8875732b8e..f0097054b1 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -125,6 +125,9 @@ void ScriptDebuggerRemote::_put_variable(const String &p_name, const Variant &p_
packet_peer_stream->put_var(p_name);
int len = 0;
Error err = encode_variant(p_variable, NULL, len);
+ if (err != OK)
+ ERR_PRINT("Failed to encode variant");
+
if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size
packet_peer_stream->put_var(Variant());
} else {
diff --git a/core/script_language.cpp b/core/script_language.cpp
index bde80a30bc..5ead91f26e 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -184,7 +184,6 @@ void ScriptInstance::call_multilevel(const StringName &p_method, VARIANT_ARG_DEC
argc++;
}
- Variant::CallError error;
call_multilevel(p_method, argptr, argc);
}
diff --git a/core/script_language.h b/core/script_language.h
index 342d8c8072..2261737f9a 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -206,6 +206,7 @@ public:
virtual int find_function(const String &p_function, const String &p_code) const = 0;
virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const = 0;
virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; }
+ virtual bool overrides_external_editor() { return false; }
virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; }
diff --git a/core/set.h b/core/set.h
index 317e180869..f68d78cea1 100644
--- a/core/set.h
+++ b/core/set.h
@@ -438,8 +438,9 @@ private:
if (!rp)
rp = _data._nil;
Element *node = (rp->left == _data._nil) ? rp->right : rp->left;
+ node->parent = rp->parent;
- if (_data._root == (node->parent = rp->parent)) {
+ if (_data._root == node->parent) {
_data._root->left = node;
} else {
if (rp == rp->parent->left) {
diff --git a/core/string_buffer.cpp b/core/string_buffer.cpp
new file mode 100644
index 0000000000..195068f887
--- /dev/null
+++ b/core/string_buffer.cpp
@@ -0,0 +1,102 @@
+/*************************************************************************/
+/* string_buffer.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "string_buffer.h"
+
+#include <string.h>
+
+StringBuffer &StringBuffer::append(CharType p_char) {
+ reserve(string_length + 2);
+ current_buffer_ptr()[string_length++] = p_char;
+ return *this;
+}
+
+StringBuffer &StringBuffer::append(const String &p_string) {
+ return append(p_string.c_str());
+}
+
+StringBuffer &StringBuffer::append(const char *p_str) {
+ int len = strlen(p_str);
+ reserve(string_length + len + 1);
+
+ CharType *buf = current_buffer_ptr();
+ for (const char *c_ptr = p_str; c_ptr; ++c_ptr) {
+ buf[string_length++] = *c_ptr;
+ }
+ return *this;
+}
+
+StringBuffer &StringBuffer::append(const CharType *p_str, int p_clip_to_len) {
+ int len = 0;
+ while ((p_clip_to_len < 0 || len < p_clip_to_len) && p_str[len]) {
+ ++len;
+ }
+ reserve(string_length + len + 1);
+ memcpy(&(current_buffer_ptr()[string_length]), p_str, len * sizeof(CharType));
+ string_length += len;
+
+ return *this;
+}
+
+StringBuffer &StringBuffer::reserve(int p_size) {
+ if (p_size < SHORT_BUFFER_SIZE || p_size < buffer.size())
+ return *this;
+
+ bool need_copy = string_length > 0 && buffer.empty();
+ buffer.resize(next_power_of_2(p_size));
+ if (need_copy) {
+ memcpy(buffer.ptr(), short_buffer, string_length * sizeof(CharType));
+ }
+
+ return *this;
+}
+
+int StringBuffer::length() const {
+ return string_length;
+}
+
+String StringBuffer::as_string() {
+ current_buffer_ptr()[string_length] = '\0';
+ if (buffer.empty()) {
+ return String(short_buffer);
+ } else {
+ buffer.resize(string_length + 1);
+ return buffer;
+ }
+}
+
+double StringBuffer::as_double() {
+ current_buffer_ptr()[string_length] = '\0';
+ return String::to_double(current_buffer_ptr());
+}
+
+int64_t StringBuffer::as_int() {
+ current_buffer_ptr()[string_length] = '\0';
+ return String::to_int(current_buffer_ptr());
+}
diff --git a/core/string_buffer.h b/core/string_buffer.h
new file mode 100644
index 0000000000..3f36249148
--- /dev/null
+++ b/core/string_buffer.h
@@ -0,0 +1,82 @@
+/*************************************************************************/
+/* string_buffer.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef STRING_BUFFER_H
+#define STRING_BUFFER_H
+
+#include "ustring.h"
+
+class StringBuffer {
+ static const int SHORT_BUFFER_SIZE = 64;
+
+ CharType short_buffer[SHORT_BUFFER_SIZE];
+ String buffer;
+ int string_length = 0;
+
+ _FORCE_INLINE_ CharType *current_buffer_ptr() {
+ return static_cast<Vector<CharType> &>(buffer).empty() ? short_buffer : buffer.ptr();
+ }
+
+public:
+ StringBuffer &append(CharType p_char);
+ StringBuffer &append(const String &p_string);
+ StringBuffer &append(const char *p_str);
+ StringBuffer &append(const CharType *p_str, int p_clip_to_len = -1);
+
+ _FORCE_INLINE_ void operator+=(CharType p_char) {
+ append(p_char);
+ }
+
+ _FORCE_INLINE_ void operator+=(const String &p_string) {
+ append(p_string);
+ }
+
+ _FORCE_INLINE_ void operator+=(const char *p_str) {
+ append(p_str);
+ }
+
+ _FORCE_INLINE_ void operator+=(const CharType *p_str) {
+ append(p_str);
+ }
+
+ StringBuffer &reserve(int p_size);
+
+ int length() const;
+
+ String as_string();
+
+ double as_double();
+ int64_t as_int();
+
+ _FORCE_INLINE_ operator String() {
+ return as_string();
+ }
+};
+
+#endif
diff --git a/core/string_builder.cpp b/core/string_builder.cpp
new file mode 100644
index 0000000000..18c710ed2d
--- /dev/null
+++ b/core/string_builder.cpp
@@ -0,0 +1,94 @@
+/*************************************************************************/
+/* string_builder.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "string_builder.h"
+
+#include <string.h>
+
+StringBuilder &StringBuilder::append(const String &p_string) {
+
+ strings.push_back(p_string);
+ appended_strings.push_back(-1);
+
+ string_length += p_string.length();
+
+ return *this;
+}
+
+StringBuilder &StringBuilder::append(const char *p_cstring) {
+
+ int32_t len = strlen(p_cstring);
+
+ c_strings.push_back(p_cstring);
+ appended_strings.push_back(len);
+
+ string_length += len;
+
+ return *this;
+}
+
+String StringBuilder::as_string() const {
+
+ CharType *buffer = memnew_arr(CharType, string_length);
+
+ int current_position = 0;
+
+ int godot_string_elem = 0;
+ int c_string_elem = 0;
+
+ for (int i = 0; i < appended_strings.size(); i++) {
+ if (appended_strings[i] == -1) {
+ // Godot string
+ const String &s = strings[godot_string_elem];
+
+ memcpy(buffer + current_position, s.ptr(), s.length() * sizeof(CharType));
+
+ current_position += s.length();
+
+ godot_string_elem++;
+ } else {
+
+ const char *s = c_strings[c_string_elem];
+
+ for (int32_t j = 0; j < appended_strings[i]; j++) {
+ buffer[current_position + j] = s[j];
+ }
+
+ current_position += appended_strings[i];
+
+ c_string_elem++;
+ }
+ }
+
+ String final_string = String(buffer, string_length);
+
+ memdelete_arr(buffer);
+
+ return final_string;
+}
diff --git a/core/string_builder.h b/core/string_builder.h
new file mode 100644
index 0000000000..7cf2f07872
--- /dev/null
+++ b/core/string_builder.h
@@ -0,0 +1,79 @@
+/*************************************************************************/
+/* string_builder.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef STRING_BUILDER_H
+#define STRING_BUILDER_H
+
+#include "core/ustring.h"
+
+#include "core/vector.h"
+
+class StringBuilder {
+
+ uint32_t string_length = 0;
+
+ Vector<String> strings;
+ Vector<const char *> c_strings;
+
+ // -1 means it's a Godot String
+ // a natural number means C string.
+ Vector<int32_t> appended_strings;
+
+public:
+ StringBuilder &append(const String &p_string);
+ StringBuilder &append(const char *p_cstring);
+
+ _FORCE_INLINE_ StringBuilder &operator+(const String &p_string) {
+ return append(p_string);
+ }
+
+ _FORCE_INLINE_ StringBuilder &operator+(const char *p_cstring) {
+ return append(p_cstring);
+ }
+
+ _FORCE_INLINE_ void operator+=(const String &p_string) {
+ append(p_string);
+ }
+
+ _FORCE_INLINE_ void operator+=(const char *p_cstring) {
+ append(p_cstring);
+ }
+
+ _FORCE_INLINE_ int num_strings_appended() const {
+ return appended_strings.size();
+ }
+
+ String as_string() const;
+
+ _FORCE_INLINE_ operator String() const {
+ return as_string();
+ }
+};
+
+#endif // STRING_BUILDER_H
diff --git a/core/type_info.h b/core/type_info.h
index da6047450c..9fb80af0eb 100644
--- a/core/type_info.h
+++ b/core/type_info.h
@@ -39,28 +39,27 @@ struct TypeInherits {
template <class T, typename = void>
struct GetTypeInfo {
- enum { VARIANT_TYPE = Variant::NIL };
-
+ static const Variant::Type VARIANT_TYPE = Variant::NIL;
static inline PropertyInfo get_class_info() {
ERR_PRINT("GetTypeInfo fallback. Bug!");
return PropertyInfo(); // Not "Nil", this is an error
}
};
-#define MAKE_TYPE_INFO(m_type, m_var_type) \
- template <> \
- struct GetTypeInfo<m_type> { \
- enum { VARIANT_TYPE = m_var_type }; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \
- } \
- }; \
- template <> \
- struct GetTypeInfo<const m_type &> { \
- enum { VARIANT_TYPE = m_var_type }; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \
- } \
+#define MAKE_TYPE_INFO(m_type, m_var_type) \
+ template <> \
+ struct GetTypeInfo<m_type> { \
+ static const Variant::Type VARIANT_TYPE = m_var_type; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(VARIANT_TYPE, String()); \
+ } \
+ }; \
+ template <> \
+ struct GetTypeInfo<const m_type &> { \
+ static const Variant::Type VARIANT_TYPE = m_var_type; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(VARIANT_TYPE, String()); \
+ } \
};
MAKE_TYPE_INFO(bool, Variant::BOOL)
@@ -108,14 +107,14 @@ MAKE_TYPE_INFO(BSP_Tree, Variant::DICTIONARY)
//for RefPtr
template <>
struct GetTypeInfo<RefPtr> {
- enum { VARIANT_TYPE = Variant::OBJECT };
+ static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
static inline PropertyInfo get_class_info() {
return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference");
}
};
template <>
struct GetTypeInfo<const RefPtr &> {
- enum { VARIANT_TYPE = Variant::OBJECT };
+ static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
static inline PropertyInfo get_class_info() {
return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference");
}
@@ -124,7 +123,7 @@ struct GetTypeInfo<const RefPtr &> {
//for variant
template <>
struct GetTypeInfo<Variant> {
- enum { VARIANT_TYPE = Variant::NIL };
+ static const Variant::Type VARIANT_TYPE = Variant::NIL;
static inline PropertyInfo get_class_info() {
return PropertyInfo(Variant::NIL, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT);
}
@@ -132,26 +131,26 @@ struct GetTypeInfo<Variant> {
template <>
struct GetTypeInfo<const Variant &> {
- enum { VARIANT_TYPE = Variant::NIL };
+ static const Variant::Type VARIANT_TYPE = Variant::NIL;
static inline PropertyInfo get_class_info() {
return PropertyInfo(Variant::NIL, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT);
}
};
-#define MAKE_TEMPLATE_TYPE_INFO(m_template, m_type, m_var_type) \
- template <> \
- struct GetTypeInfo<m_template<m_type> > { \
- enum { VARIANT_TYPE = m_var_type }; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \
- } \
- }; \
- template <> \
- struct GetTypeInfo<const m_template<m_type> &> { \
- enum { VARIANT_TYPE = m_var_type }; \
- static inline PropertyInfo get_class_info() { \
- return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \
- } \
+#define MAKE_TEMPLATE_TYPE_INFO(m_template, m_type, m_var_type) \
+ template <> \
+ struct GetTypeInfo<m_template<m_type> > { \
+ static const Variant::Type VARIANT_TYPE = m_var_type; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(VARIANT_TYPE, String()); \
+ } \
+ }; \
+ template <> \
+ struct GetTypeInfo<const m_template<m_type> &> { \
+ static const Variant::Type VARIANT_TYPE = m_var_type; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(VARIANT_TYPE, String()); \
+ } \
};
MAKE_TEMPLATE_TYPE_INFO(Vector, uint8_t, Variant::POOL_BYTE_ARRAY)
@@ -171,8 +170,7 @@ MAKE_TEMPLATE_TYPE_INFO(PoolVector, Face3, Variant::POOL_VECTOR3_ARRAY)
template <typename T>
struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
- enum { VARIANT_TYPE = Variant::OBJECT };
-
+ static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
static inline PropertyInfo get_class_info() {
return PropertyInfo(StringName(T::get_class_static()));
}
@@ -180,8 +178,7 @@ struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type>
template <typename T>
struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
- enum { VARIANT_TYPE = Variant::OBJECT };
-
+ static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
static inline PropertyInfo get_class_info() {
return PropertyInfo(StringName(T::get_class_static()));
}
@@ -190,7 +187,7 @@ struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>:
#define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \
template <> \
struct GetTypeInfo<m_impl> { \
- enum { VARIANT_TYPE = Variant::INT }; \
+ static const Variant::Type VARIANT_TYPE = Variant::INT; \
static inline PropertyInfo get_class_info() { \
return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, String(#m_enum).replace("::", ".")); \
} \
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index ad15f8f5cb..19d9b0297f 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -428,8 +428,8 @@ struct _VariantCall {
VCALL_LOCALMEM2R(Quat, slerpni);
VCALL_LOCALMEM4R(Quat, cubic_slerp);
- VCALL_LOCALMEM0R(Color, to_32);
- VCALL_LOCALMEM0R(Color, to_ARGB32);
+ VCALL_LOCALMEM0R(Color, to_rgba32);
+ VCALL_LOCALMEM0R(Color, to_argb32);
VCALL_LOCALMEM0R(Color, gray);
VCALL_LOCALMEM0R(Color, inverted);
VCALL_LOCALMEM0R(Color, contrasted);
@@ -481,6 +481,7 @@ struct _VariantCall {
VCALL_LOCALMEM1(Array, erase);
VCALL_LOCALMEM0(Array, sort);
VCALL_LOCALMEM2(Array, sort_custom);
+ VCALL_LOCALMEM0R(Array, duplicate);
VCALL_LOCALMEM0(Array, invert);
static void _call_PoolByteArray_get_string_from_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) {
@@ -1523,8 +1524,8 @@ void register_variant_methods() {
ADDFUNC2(QUAT, QUAT, Quat, slerpni, QUAT, "b", REAL, "t", varray());
ADDFUNC4(QUAT, QUAT, Quat, cubic_slerp, QUAT, "b", QUAT, "pre_a", QUAT, "post_b", REAL, "t", varray());
- ADDFUNC0(COLOR, INT, Color, to_32, varray());
- ADDFUNC0(COLOR, INT, Color, to_ARGB32, varray());
+ ADDFUNC0(COLOR, INT, Color, to_rgba32, varray());
+ ADDFUNC0(COLOR, INT, Color, to_argb32, varray());
ADDFUNC0(COLOR, REAL, Color, gray, varray());
ADDFUNC0(COLOR, COLOR, Color, inverted, varray());
ADDFUNC0(COLOR, COLOR, Color, contrasted, varray());
@@ -1575,6 +1576,7 @@ void register_variant_methods() {
ADDFUNC0(ARRAY, NIL, Array, sort, varray());
ADDFUNC2(ARRAY, NIL, Array, sort_custom, OBJECT, "obj", STRING, "func", varray());
ADDFUNC0(ARRAY, NIL, Array, invert, varray());
+ ADDFUNC0(ARRAY, ARRAY, Array, duplicate, varray());
ADDFUNC0(POOL_BYTE_ARRAY, INT, PoolByteArray, size, varray());
ADDFUNC2(POOL_BYTE_ARRAY, NIL, PoolByteArray, set, INT, "idx", INT, "byte", varray());
@@ -1621,7 +1623,7 @@ void register_variant_methods() {
ADDFUNC2(POOL_STRING_ARRAY, INT, PoolStringArray, insert, INT, "idx", STRING, "string", varray());
ADDFUNC1(POOL_STRING_ARRAY, NIL, PoolStringArray, resize, INT, "idx", varray());
ADDFUNC0(POOL_STRING_ARRAY, NIL, PoolStringArray, invert, varray());
- ADDFUNC1(POOL_STRING_ARRAY, STRING, PoolStringArray, join, STRING, "string", varray());
+ ADDFUNC1(POOL_STRING_ARRAY, STRING, PoolStringArray, join, STRING, "delimiter", varray());
ADDFUNC0(POOL_VECTOR2_ARRAY, INT, PoolVector2Array, size, varray());
ADDFUNC2(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, set, INT, "idx", VECTOR2, "vector2", varray());
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index 65c7b7cfec..d60d10cd3a 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "variant_parser.h"
+#include "core/string_buffer.h"
#include "io/resource_loader.h"
#include "os/input_event.h"
#include "os/keyboard.h"
@@ -176,14 +177,15 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
};
case '#': {
- String color_str = "#";
+ StringBuffer color_str;
+ color_str += '#';
while (true) {
CharType ch = p_stream->get_char();
if (p_stream->is_eof()) {
r_token.type = TK_EOF;
return OK;
} else if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
- color_str += String::chr(ch);
+ color_str += ch;
} else {
p_stream->saved = ch;
@@ -191,7 +193,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
}
}
- r_token.value = Color::html(color_str);
+ r_token.value = Color::html(color_str.as_string());
r_token.type = TK_COLOR;
return OK;
};
@@ -296,7 +298,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
if (cchar == '-' || (cchar >= '0' && cchar <= '9')) {
//a number
- String num;
+ StringBuffer num;
#define READING_SIGN 0
#define READING_INT 1
#define READING_DEC 2
@@ -359,7 +361,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
if (reading == READING_DONE)
break;
- num += String::chr(c);
+ num += c;
c = p_stream->get_char();
}
@@ -368,19 +370,19 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
r_token.type = TK_NUMBER;
if (is_float)
- r_token.value = num.to_double();
+ r_token.value = num.as_double();
else
- r_token.value = num.to_int();
+ r_token.value = num.as_int();
return OK;
} else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') {
- String id;
+ StringBuffer id;
bool first = true;
while ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_' || (!first && cchar >= '0' && cchar <= '9')) {
- id += String::chr(cchar);
+ id += cchar;
cchar = p_stream->get_char();
first = false;
}
@@ -388,7 +390,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
p_stream->saved = cchar;
r_token.type = TK_IDENTIFIER;
- r_token.value = id;
+ r_token.value = id.as_string();
return OK;
} else {
r_err_str = "Unexpected character.";