summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/array.cpp4
-rw-r--r--core/bind/core_bind.cpp210
-rw-r--r--core/bind/core_bind.h81
-rw-r--r--core/callable.cpp359
-rw-r--r--core/callable.h161
-rw-r--r--core/callable_method_pointer.cpp94
-rw-r--r--core/callable_method_pointer.h292
-rw-r--r--core/class_db.cpp20
-rw-r--r--core/class_db.h8
-rw-r--r--core/command_queue_mt.cpp15
-rw-r--r--core/command_queue_mt.h12
-rw-r--r--core/compressed_translation.cpp18
-rw-r--r--core/compressed_translation.h6
-rw-r--r--core/core_string_names.cpp6
-rw-r--r--core/core_string_names.h5
-rw-r--r--core/crypto/crypto.cpp6
-rw-r--r--core/crypto/crypto.h4
-rw-r--r--core/crypto/crypto_core.cpp4
-rw-r--r--core/crypto/hashing_context.cpp18
-rw-r--r--core/crypto/hashing_context.h4
-rw-r--r--core/error_macros.h20
-rw-r--r--core/func_ref.cpp6
-rw-r--r--core/func_ref.h2
-rw-r--r--core/global_constants.cpp37
-rw-r--r--core/image.cpp335
-rw-r--r--core/image.h43
-rw-r--r--core/input_map.cpp30
-rw-r--r--core/io/config_file.cpp26
-rw-r--r--core/io/config_file.h6
-rw-r--r--core/io/dtls_server.cpp (renamed from core/pool_vector.cpp)48
-rw-r--r--core/io/dtls_server.h57
-rw-r--r--core/io/file_access_buffered.cpp4
-rw-r--r--core/io/file_access_buffered.h2
-rw-r--r--core/io/file_access_buffered_fa.h4
-rw-r--r--core/io/file_access_network.cpp98
-rw-r--r--core/io/file_access_network.h12
-rw-r--r--core/io/file_access_pack.cpp2
-rw-r--r--core/io/file_access_pack.h2
-rw-r--r--core/io/http_client.cpp26
-rw-r--r--core/io/http_client.h6
-rw-r--r--core/io/image_loader.cpp2
-rw-r--r--core/io/image_loader.h2
-rw-r--r--core/io/ip.cpp65
-rw-r--r--core/io/json.cpp10
-rw-r--r--core/io/marshalls.cpp281
-rw-r--r--core/io/multiplayer_api.cpp162
-rw-r--r--core/io/multiplayer_api.h2
-rw-r--r--core/io/net_socket.h2
-rw-r--r--core/io/packet_peer.cpp20
-rw-r--r--core/io/packet_peer.h10
-rw-r--r--core/io/packet_peer_dtls.cpp62
-rw-r--r--core/io/packet_peer_dtls.h68
-rw-r--r--core/io/packet_peer_udp.cpp75
-rw-r--r--core/io/packet_peer_udp.h6
-rw-r--r--core/io/resource_format_binary.cpp589
-rw-r--r--core/io/resource_format_binary.h25
-rw-r--r--core/io/resource_importer.cpp4
-rw-r--r--core/io/resource_importer.h2
-rw-r--r--core/io/resource_loader.cpp626
-rw-r--r--core/io/resource_loader.h85
-rw-r--r--core/io/resource_saver.cpp6
-rw-r--r--core/io/stream_peer.cpp35
-rw-r--r--core/io/stream_peer.h10
-rw-r--r--core/io/translation_loader_po.cpp2
-rw-r--r--core/io/translation_loader_po.h2
-rw-r--r--core/io/udp_server.cpp119
-rw-r--r--core/io/udp_server.h (renamed from core/os/thread_safe.cpp)37
-rw-r--r--core/make_binders.py24
-rw-r--r--core/math/a_star.cpp52
-rw-r--r--core/math/a_star.h12
-rw-r--r--core/math/bsp_tree.cpp581
-rw-r--r--core/math/bsp_tree.h159
-rw-r--r--core/math/expression.cpp82
-rw-r--r--core/math/expression.h2
-rw-r--r--core/math/geometry.cpp49
-rw-r--r--core/math/geometry.h16
-rw-r--r--core/math/rect2.h47
-rw-r--r--core/math/transform.h21
-rw-r--r--core/math/transform_2d.h21
-rw-r--r--core/math/triangle_mesh.cpp80
-rw-r--r--core/math/triangle_mesh.h16
-rw-r--r--core/math/vector2.h7
-rw-r--r--core/message_queue.cpp110
-rw-r--r--core/message_queue.h6
-rw-r--r--core/method_bind.h21
-rw-r--r--core/method_ptrcall.h336
-rw-r--r--core/node_path.h9
-rw-r--r--core/object.cpp277
-rw-r--r--core/object.h54
-rw-r--r--core/object_id.h30
-rw-r--r--core/os/dir_access.cpp5
-rw-r--r--core/os/dir_access.h3
-rw-r--r--core/os/file_access.cpp8
-rw-r--r--core/os/input.cpp2
-rw-r--r--core/os/input.h2
-rw-r--r--core/os/input_event.cpp92
-rw-r--r--core/os/input_event.h13
-rw-r--r--core/os/main_loop.cpp6
-rw-r--r--core/os/memory.h2
-rw-r--r--core/os/midi_driver.cpp4
-rw-r--r--core/os/midi_driver.h2
-rw-r--r--core/os/mutex.cpp32
-rw-r--r--core/os/mutex.h73
-rw-r--r--core/os/os.cpp8
-rw-r--r--core/os/os.h5
-rw-r--r--core/os/semaphore.cpp14
-rw-r--r--core/os/semaphore.h31
-rw-r--r--core/os/thread_dummy.cpp16
-rw-r--r--core/os/thread_dummy.h25
-rw-r--r--core/os/thread_safe.h49
-rw-r--r--core/packed_data_container.cpp57
-rw-r--r--core/packed_data_container.h6
-rw-r--r--core/pool_vector.h648
-rw-r--r--core/project_settings.cpp37
-rw-r--r--core/reference.h9
-rw-r--r--core/register_core_types.cpp23
-rw-r--r--core/resource.cpp2
-rw-r--r--core/rid_owner.h4
-rw-r--r--core/script_debugger_remote.cpp1143
-rw-r--r--core/script_debugger_remote.h316
-rw-r--r--core/script_language.cpp6
-rw-r--r--core/script_language.h10
-rw-r--r--core/string_name.cpp42
-rw-r--r--core/string_name.h2
-rw-r--r--core/translation.cpp18
-rw-r--r--core/translation.h6
-rw-r--r--core/type_info.h43
-rw-r--r--core/typedefs.h30
-rw-r--r--core/undo_redo.cpp48
-rw-r--r--core/undo_redo.h14
-rw-r--r--core/ustring.cpp1
-rw-r--r--core/variant.cpp1493
-rw-r--r--core/variant.h216
-rw-r--r--core/variant_call.cpp945
-rw-r--r--core/variant_op.cpp1675
-rw-r--r--core/variant_parser.cpp300
-rw-r--r--core/variant_parser.h3
-rw-r--r--core/vector.h29
138 files changed, 8656 insertions, 5276 deletions
diff --git a/core/array.cpp b/core/array.cpp
index 2253d05605..7eb15ea934 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -308,9 +308,9 @@ struct _ArrayVariantSortCustom {
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
const Variant *args[2] = { &p_l, &p_r };
- Variant::CallError err;
+ Callable::CallError err;
bool res = obj->call(func, args, 2, err);
- if (err.error != Variant::CallError::CALL_OK)
+ if (err.error != Callable::CallError::CALL_OK)
res = false;
return res;
}
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index d7614c5a82..bfe07d61c5 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -64,8 +64,21 @@ static const unsigned int MONTH_DAYS_TABLE[2][12] = {
_ResourceLoader *_ResourceLoader::singleton = NULL;
-Ref<ResourceInteractiveLoader> _ResourceLoader::load_interactive(const String &p_path, const String &p_type_hint) {
- return ResourceLoader::load_interactive(p_path, p_type_hint);
+Error _ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads) {
+
+ return ResourceLoader::load_threaded_request(p_path, p_type_hint, p_use_sub_threads);
+}
+_ResourceLoader::ThreadLoadStatus _ResourceLoader::load_threaded_get_status(const String &p_path, Array r_progress) {
+ float progress = 0;
+ ResourceLoader::ThreadLoadStatus tls = ResourceLoader::load_threaded_get_status(p_path, &progress);
+ r_progress.resize(1);
+ r_progress[0] = progress;
+ return (ThreadLoadStatus)tls;
+}
+RES _ResourceLoader::load_threaded_get(const String &p_path) {
+ Error error;
+ RES res = ResourceLoader::load_threaded_get(p_path, &error);
+ return res;
}
RES _ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache) {
@@ -77,11 +90,11 @@ RES _ResourceLoader::load(const String &p_path, const String &p_type_hint, bool
return ret;
}
-PoolVector<String> _ResourceLoader::get_recognized_extensions_for_type(const String &p_type) {
+Vector<String> _ResourceLoader::get_recognized_extensions_for_type(const String &p_type) {
List<String> exts;
ResourceLoader::get_recognized_extensions_for_type(p_type, &exts);
- PoolVector<String> ret;
+ Vector<String> ret;
for (List<String>::Element *E = exts.front(); E; E = E->next()) {
ret.push_back(E->get());
@@ -95,12 +108,12 @@ void _ResourceLoader::set_abort_on_missing_resources(bool p_abort) {
ResourceLoader::set_abort_on_missing_resources(p_abort);
}
-PoolStringArray _ResourceLoader::get_dependencies(const String &p_path) {
+PackedStringArray _ResourceLoader::get_dependencies(const String &p_path) {
List<String> deps;
ResourceLoader::get_dependencies(p_path, &deps);
- PoolStringArray ret;
+ PackedStringArray ret;
for (List<String>::Element *E = deps.front(); E; E = E->next()) {
ret.push_back(E->get());
}
@@ -120,13 +133,21 @@ bool _ResourceLoader::exists(const String &p_path, const String &p_type_hint) {
void _ResourceLoader::_bind_methods() {
- ClassDB::bind_method(D_METHOD("load_interactive", "path", "type_hint"), &_ResourceLoader::load_interactive, DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("load_threaded_request", "path", "type_hint", "use_sub_threads"), &_ResourceLoader::load_threaded_request, DEFVAL(""), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("load_threaded_get_status", "path", "progress"), &_ResourceLoader::load_threaded_get_status, DEFVAL(Array()));
+ ClassDB::bind_method(D_METHOD("load_threaded_get", "path"), &_ResourceLoader::load_threaded_get);
+
ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "no_cache"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_recognized_extensions_for_type", "type"), &_ResourceLoader::get_recognized_extensions_for_type);
ClassDB::bind_method(D_METHOD("set_abort_on_missing_resources", "abort"), &_ResourceLoader::set_abort_on_missing_resources);
ClassDB::bind_method(D_METHOD("get_dependencies", "path"), &_ResourceLoader::get_dependencies);
ClassDB::bind_method(D_METHOD("has_cached", "path"), &_ResourceLoader::has_cached);
ClassDB::bind_method(D_METHOD("exists", "path", "type_hint"), &_ResourceLoader::exists, DEFVAL(""));
+
+ BIND_ENUM_CONSTANT(THREAD_LOAD_INVALID_RESOURCE);
+ BIND_ENUM_CONSTANT(THREAD_LOAD_IN_PROGRESS);
+ BIND_ENUM_CONSTANT(THREAD_LOAD_FAILED);
+ BIND_ENUM_CONSTANT(THREAD_LOAD_LOADED);
}
_ResourceLoader::_ResourceLoader() {
@@ -139,12 +160,12 @@ Error _ResourceSaver::save(const String &p_path, const RES &p_resource, SaverFla
return ResourceSaver::save(p_path, p_resource, p_flags);
}
-PoolVector<String> _ResourceSaver::get_recognized_extensions(const RES &p_resource) {
+Vector<String> _ResourceSaver::get_recognized_extensions(const RES &p_resource) {
- ERR_FAIL_COND_V_MSG(p_resource.is_null(), PoolVector<String>(), "It's not a reference to a valid Resource object.");
+ ERR_FAIL_COND_V_MSG(p_resource.is_null(), Vector<String>(), "It's not a reference to a valid Resource object.");
List<String> exts;
ResourceSaver::get_recognized_extensions(p_resource, &exts);
- PoolVector<String> ret;
+ Vector<String> ret;
for (List<String>::Element *E = exts.front(); E; E = E->next()) {
ret.push_back(E->get());
@@ -249,7 +270,7 @@ String _OS::get_audio_driver_name(int p_driver) const {
return OS::get_singleton()->get_audio_driver_name(p_driver);
}
-PoolStringArray _OS::get_connected_midi_inputs() {
+PackedStringArray _OS::get_connected_midi_inputs() {
return OS::get_singleton()->get_connected_midi_inputs();
}
@@ -646,11 +667,6 @@ uint64_t _OS::get_static_memory_peak_usage() const {
return OS::get_singleton()->get_static_memory_peak_usage();
}
-uint64_t _OS::get_dynamic_memory_usage() const {
-
- return OS::get_singleton()->get_dynamic_memory_usage();
-}
-
void _OS::set_native_icon(const String &p_filename) {
OS::get_singleton()->set_native_icon(p_filename);
@@ -1118,15 +1134,17 @@ String _OS::get_system_dir(SystemDir p_dir) const {
return OS::get_singleton()->get_system_dir(OS::SystemDir(p_dir));
}
-String _OS::get_scancode_string(uint32_t p_code) const {
+String _OS::get_keycode_string(uint32_t p_code) const {
return keycode_get_string(p_code);
}
-bool _OS::is_scancode_unicode(uint32_t p_unicode) const {
+
+bool _OS::is_keycode_unicode(uint32_t p_unicode) const {
return keycode_has_unicode(p_unicode);
}
-int _OS::find_scancode_from_string(const String &p_code) const {
+
+int _OS::find_keycode_from_string(const String &p_code) const {
return find_keycode(p_code);
}
@@ -1301,7 +1319,6 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_static_memory_usage"), &_OS::get_static_memory_usage);
ClassDB::bind_method(D_METHOD("get_static_memory_peak_usage"), &_OS::get_static_memory_peak_usage);
- ClassDB::bind_method(D_METHOD("get_dynamic_memory_usage"), &_OS::get_dynamic_memory_usage);
ClassDB::bind_method(D_METHOD("get_user_data_dir"), &_OS::get_user_data_dir);
ClassDB::bind_method(D_METHOD("get_system_dir", "dir"), &_OS::get_system_dir);
@@ -1318,9 +1335,9 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("native_video_pause"), &_OS::native_video_pause);
ClassDB::bind_method(D_METHOD("native_video_unpause"), &_OS::native_video_unpause);
- ClassDB::bind_method(D_METHOD("get_scancode_string", "code"), &_OS::get_scancode_string);
- ClassDB::bind_method(D_METHOD("is_scancode_unicode", "code"), &_OS::is_scancode_unicode);
- ClassDB::bind_method(D_METHOD("find_scancode_from_string", "string"), &_OS::find_scancode_from_string);
+ ClassDB::bind_method(D_METHOD("get_keycode_string", "code"), &_OS::get_keycode_string);
+ ClassDB::bind_method(D_METHOD("is_keycode_unicode", "code"), &_OS::is_keycode_unicode);
+ ClassDB::bind_method(D_METHOD("find_keycode_from_string", "string"), &_OS::find_keycode_from_string);
ClassDB::bind_method(D_METHOD("set_use_file_access_save_and_swap", "enabled"), &_OS::set_use_file_access_save_and_swap);
@@ -1439,16 +1456,16 @@ _Geometry *_Geometry::get_singleton() {
return singleton;
}
-PoolVector<Plane> _Geometry::build_box_planes(const Vector3 &p_extents) {
+Vector<Plane> _Geometry::build_box_planes(const Vector3 &p_extents) {
return Geometry::build_box_planes(p_extents);
}
-PoolVector<Plane> _Geometry::build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis) {
+Vector<Plane> _Geometry::build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis) {
return Geometry::build_cylinder_planes(p_radius, p_height, p_sides, p_axis);
}
-PoolVector<Plane> _Geometry::build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
+Vector<Plane> _Geometry::build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
return Geometry::build_capsule_planes(p_radius, p_height, p_sides, p_lats, p_axis);
}
@@ -1484,22 +1501,22 @@ Variant _Geometry::line_intersects_line_2d(const Vector2 &p_from_a, const Vector
}
}
-PoolVector<Vector2> _Geometry::get_closest_points_between_segments_2d(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2) {
+Vector<Vector2> _Geometry::get_closest_points_between_segments_2d(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2) {
Vector2 r1, r2;
Geometry::get_closest_points_between_segments(p1, q1, p2, q2, r1, r2);
- PoolVector<Vector2> r;
+ Vector<Vector2> r;
r.resize(2);
r.set(0, r1);
r.set(1, r2);
return r;
}
-PoolVector<Vector3> _Geometry::get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2) {
+Vector<Vector3> _Geometry::get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2) {
Vector3 r1, r2;
Geometry::get_closest_points_between_segments(p1, p2, q1, q2, r1, r2);
- PoolVector<Vector3> r;
+ Vector<Vector3> r;
r.resize(2);
r.set(0, r1);
r.set(1, r2);
@@ -1547,9 +1564,9 @@ bool _Geometry::point_is_inside_triangle(const Vector2 &s, const Vector2 &a, con
return Geometry::is_point_in_triangle(s, a, b, c);
}
-PoolVector<Vector3> _Geometry::segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius) {
+Vector<Vector3> _Geometry::segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius) {
- PoolVector<Vector3> r;
+ Vector<Vector3> r;
Vector3 res, norm;
if (!Geometry::segment_intersects_sphere(p_from, p_to, p_sphere_pos, p_sphere_radius, &res, &norm))
return r;
@@ -1559,9 +1576,9 @@ PoolVector<Vector3> _Geometry::segment_intersects_sphere(const Vector3 &p_from,
r.set(1, norm);
return r;
}
-PoolVector<Vector3> _Geometry::segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius) {
+Vector<Vector3> _Geometry::segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius) {
- PoolVector<Vector3> r;
+ Vector<Vector3> r;
Vector3 res, norm;
if (!Geometry::segment_intersects_cylinder(p_from, p_to, p_height, p_radius, &res, &norm))
return r;
@@ -1571,9 +1588,9 @@ PoolVector<Vector3> _Geometry::segment_intersects_cylinder(const Vector3 &p_from
r.set(1, norm);
return r;
}
-PoolVector<Vector3> _Geometry::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes) {
+Vector<Vector3> _Geometry::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes) {
- PoolVector<Vector3> r;
+ Vector<Vector3> r;
Vector3 res, norm;
if (!Geometry::segment_intersects_convex(p_from, p_to, p_planes.ptr(), p_planes.size(), &res, &norm))
return r;
@@ -1962,9 +1979,9 @@ real_t _File::get_real() const {
return f->get_real();
}
-PoolVector<uint8_t> _File::get_buffer(int p_length) const {
+Vector<uint8_t> _File::get_buffer(int p_length) const {
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
ERR_FAIL_COND_V_MSG(!f, data, "File must be opened before use.");
ERR_FAIL_COND_V_MSG(p_length < 0, data, "Length of buffer cannot be smaller than 0.");
@@ -1974,11 +1991,9 @@ PoolVector<uint8_t> _File::get_buffer(int p_length) const {
Error err = data.resize(p_length);
ERR_FAIL_COND_V_MSG(err != OK, data, "Can't resize data to " + itos(p_length) + " elements.");
- PoolVector<uint8_t>::Write w = data.write();
+ uint8_t *w = data.ptrw();
int len = f->get_buffer(&w[0], p_length);
- ERR_FAIL_COND_V(len < 0, PoolVector<uint8_t>());
-
- w.release();
+ ERR_FAIL_COND_V(len < 0, Vector<uint8_t>());
if (len < p_length)
data.resize(p_length);
@@ -2126,7 +2141,7 @@ void _File::store_csv_line(const Vector<String> &p_values, const String &p_delim
f->store_csv_line(p_values, p_delim);
}
-void _File::store_buffer(const PoolVector<uint8_t> &p_buffer) {
+void _File::store_buffer(const Vector<uint8_t> &p_buffer) {
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
@@ -2134,7 +2149,7 @@ void _File::store_buffer(const PoolVector<uint8_t> &p_buffer) {
if (len == 0)
return;
- PoolVector<uint8_t>::Read r = p_buffer.read();
+ const uint8_t *r = p_buffer.ptr();
f->store_buffer(&r[0], len);
}
@@ -2151,13 +2166,12 @@ void _File::store_var(const Variant &p_var, bool p_full_objects) {
Error err = encode_variant(p_var, NULL, len, p_full_objects);
ERR_FAIL_COND_MSG(err != OK, "Error when trying to encode Variant.");
- PoolVector<uint8_t> buff;
+ Vector<uint8_t> buff;
buff.resize(len);
- PoolVector<uint8_t>::Write w = buff.write();
+ uint8_t *w = buff.ptrw();
err = encode_variant(p_var, &w[0], len, p_full_objects);
ERR_FAIL_COND_MSG(err != OK, "Error when trying to encode Variant.");
- w.release();
store_32(len);
store_buffer(buff);
@@ -2167,10 +2181,10 @@ Variant _File::get_var(bool p_allow_objects) const {
ERR_FAIL_COND_V_MSG(!f, Variant(), "File must be opened before use.");
uint32_t len = get_32();
- PoolVector<uint8_t> buff = get_buffer(len);
+ Vector<uint8_t> buff = get_buffer(len);
ERR_FAIL_COND_V((uint32_t)buff.size() != len, Variant());
- PoolVector<uint8_t>::Read r = buff.read();
+ const uint8_t *r = buff.ptr();
Variant v;
Error err = decode_variant(v, &r[0], len, NULL, p_allow_objects);
@@ -2330,10 +2344,10 @@ Error _Directory::change_dir(String p_dir) {
ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use.");
return d->change_dir(p_dir);
}
-String _Directory::get_current_dir() {
+String _Directory::get_current_dir(bool p_include_drive) {
ERR_FAIL_COND_V_MSG(!d, "", "Directory must be opened before use.");
- return d->get_current_dir();
+ return d->get_current_dir(p_include_drive);
}
Error _Directory::make_dir(String p_dir) {
@@ -2430,7 +2444,7 @@ void _Directory::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_drive", "idx"), &_Directory::get_drive);
ClassDB::bind_method(D_METHOD("get_current_drive"), &_Directory::get_current_drive);
ClassDB::bind_method(D_METHOD("change_dir", "todir"), &_Directory::change_dir);
- ClassDB::bind_method(D_METHOD("get_current_dir"), &_Directory::get_current_dir);
+ ClassDB::bind_method(D_METHOD("get_current_dir", "include_drive"), &_Directory::get_current_dir, DEFVAL(true));
ClassDB::bind_method(D_METHOD("make_dir", "path"), &_Directory::make_dir);
ClassDB::bind_method(D_METHOD("make_dir_recursive", "path"), &_Directory::make_dir_recursive);
ClassDB::bind_method(D_METHOD("file_exists", "path"), &_Directory::file_exists);
@@ -2465,9 +2479,9 @@ String _Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects)
Error err = encode_variant(p_var, NULL, len, p_full_objects);
ERR_FAIL_COND_V_MSG(err != OK, "", "Error when trying to encode Variant.");
- PoolVector<uint8_t> buff;
+ Vector<uint8_t> buff;
buff.resize(len);
- PoolVector<uint8_t>::Write w = buff.write();
+ uint8_t *w = buff.ptrw();
err = encode_variant(p_var, &w[0], len, p_full_objects);
ERR_FAIL_COND_V_MSG(err != OK, "", "Error when trying to encode Variant.");
@@ -2483,9 +2497,9 @@ Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects)
int strlen = p_str.length();
CharString cstr = p_str.ascii();
- PoolVector<uint8_t> buf;
+ Vector<uint8_t> buf;
buf.resize(strlen / 4 * 3 + 1);
- PoolVector<uint8_t>::Write w = buf.write();
+ uint8_t *w = buf.ptrw();
size_t len = 0;
ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &len, (unsigned char *)cstr.get_data(), strlen) != OK, Variant());
@@ -2497,25 +2511,25 @@ Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects)
return v;
};
-String _Marshalls::raw_to_base64(const PoolVector<uint8_t> &p_arr) {
+String _Marshalls::raw_to_base64(const Vector<uint8_t> &p_arr) {
- String ret = CryptoCore::b64_encode_str(p_arr.read().ptr(), p_arr.size());
+ String ret = CryptoCore::b64_encode_str(p_arr.ptr(), p_arr.size());
ERR_FAIL_COND_V(ret == "", ret);
return ret;
};
-PoolVector<uint8_t> _Marshalls::base64_to_raw(const String &p_str) {
+Vector<uint8_t> _Marshalls::base64_to_raw(const String &p_str) {
int strlen = p_str.length();
CharString cstr = p_str.ascii();
size_t arr_len = 0;
- PoolVector<uint8_t> buf;
+ Vector<uint8_t> buf;
{
buf.resize(strlen / 4 * 3 + 1);
- PoolVector<uint8_t>::Write w = buf.write();
+ uint8_t *w = buf.ptrw();
- ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &arr_len, (unsigned char *)cstr.get_data(), strlen) != OK, PoolVector<uint8_t>());
+ ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &arr_len, (unsigned char *)cstr.get_data(), strlen) != OK, Vector<uint8_t>());
}
buf.resize(arr_len);
@@ -2535,9 +2549,9 @@ String _Marshalls::base64_to_utf8(const String &p_str) {
int strlen = p_str.length();
CharString cstr = p_str.ascii();
- PoolVector<uint8_t> buf;
+ Vector<uint8_t> buf;
buf.resize(strlen / 4 * 3 + 1 + 1);
- PoolVector<uint8_t>::Write w = buf.write();
+ uint8_t *w = buf.ptrw();
size_t len = 0;
ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &len, (unsigned char *)cstr.get_data(), strlen) != OK, String());
@@ -2562,47 +2576,43 @@ void _Marshalls::_bind_methods() {
////////////////
-Error _Semaphore::wait() {
-
- return semaphore->wait();
-}
-
-Error _Semaphore::post() {
+void _Semaphore::wait() {
- return semaphore->post();
+ semaphore.wait();
}
-void _Semaphore::_bind_methods() {
+Error _Semaphore::try_wait() {
- ClassDB::bind_method(D_METHOD("wait"), &_Semaphore::wait);
- ClassDB::bind_method(D_METHOD("post"), &_Semaphore::post);
+ return semaphore.try_wait() ? OK : ERR_BUSY;
}
-_Semaphore::_Semaphore() {
+void _Semaphore::post() {
- semaphore = SemaphoreOld::create();
+ semaphore.post();
}
-_Semaphore::~_Semaphore() {
+void _Semaphore::_bind_methods() {
- memdelete(semaphore);
+ ClassDB::bind_method(D_METHOD("wait"), &_Semaphore::wait);
+ ClassDB::bind_method(D_METHOD("try_wait"), &_Semaphore::try_wait);
+ ClassDB::bind_method(D_METHOD("post"), &_Semaphore::post);
}
///////////////
void _Mutex::lock() {
- mutex->lock();
+ mutex.lock();
}
Error _Mutex::try_lock() {
- return mutex->try_lock();
+ return mutex.try_lock();
}
void _Mutex::unlock() {
- mutex->unlock();
+ mutex.unlock();
}
void _Mutex::_bind_methods() {
@@ -2612,16 +2622,6 @@ void _Mutex::_bind_methods() {
ClassDB::bind_method(D_METHOD("unlock"), &_Mutex::unlock);
}
-_Mutex::_Mutex() {
-
- mutex = Mutex::create();
-}
-
-_Mutex::~_Mutex() {
-
- memdelete(mutex);
-}
-
///////////////
void _Thread::_start_func(void *ud) {
@@ -2629,29 +2629,29 @@ void _Thread::_start_func(void *ud) {
Ref<_Thread> *tud = (Ref<_Thread> *)ud;
Ref<_Thread> t = *tud;
memdelete(tud);
- Variant::CallError ce;
+ Callable::CallError ce;
const Variant *arg[1] = { &t->userdata };
Thread::set_name(t->target_method);
t->ret = t->target_instance->call(t->target_method, arg, 1, ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
String reason;
switch (ce.error) {
- case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT: {
+ case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
reason = "Invalid Argument #" + itos(ce.argument);
} break;
- case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
+ case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
reason = "Too Many Arguments";
} break;
- case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
+ case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
reason = "Too Few Arguments";
} break;
- case Variant::CallError::CALL_ERROR_INVALID_METHOD: {
+ case Callable::CallError::CALL_ERROR_INVALID_METHOD: {
reason = "Method Not Found";
} break;
@@ -2746,12 +2746,12 @@ _Thread::~_Thread() {
/////////////////////////////////////
-PoolStringArray _ClassDB::get_class_list() const {
+PackedStringArray _ClassDB::get_class_list() const {
List<StringName> classes;
ClassDB::get_class_list(&classes);
- PoolStringArray ret;
+ PackedStringArray ret;
ret.resize(classes.size());
int idx = 0;
for (List<StringName>::Element *E = classes.front(); E; E = E->next()) {
@@ -2760,12 +2760,12 @@ PoolStringArray _ClassDB::get_class_list() const {
return ret;
}
-PoolStringArray _ClassDB::get_inheriters_from_class(const StringName &p_class) const {
+PackedStringArray _ClassDB::get_inheriters_from_class(const StringName &p_class) const {
List<StringName> classes;
ClassDB::get_inheriters_from_class(p_class, &classes);
- PoolStringArray ret;
+ PackedStringArray ret;
ret.resize(classes.size());
int idx = 0;
for (List<StringName>::Element *E = classes.front(); E; E = E->next()) {
@@ -2883,12 +2883,12 @@ Array _ClassDB::get_method_list(StringName p_class, bool p_no_inheritance) const
return ret;
}
-PoolStringArray _ClassDB::get_integer_constant_list(const StringName &p_class, bool p_no_inheritance) const {
+PackedStringArray _ClassDB::get_integer_constant_list(const StringName &p_class, bool p_no_inheritance) const {
List<String> constants;
ClassDB::get_integer_constant_list(p_class, &constants, p_no_inheritance);
- PoolStringArray ret;
+ PackedStringArray ret;
ret.resize(constants.size());
int idx = 0;
for (List<String>::Element *E = constants.front(); E; E = E->next()) {
@@ -3110,8 +3110,8 @@ void _Engine::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_hint"), "set_editor_hint", "is_editor_hint");
ADD_PROPERTY(PropertyInfo(Variant::INT, "iterations_per_second"), "set_iterations_per_second", "get_iterations_per_second");
ADD_PROPERTY(PropertyInfo(Variant::INT, "target_fps"), "set_target_fps", "get_target_fps");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_scale"), "set_time_scale", "get_time_scale");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "physics_jitter_fix"), "set_physics_jitter_fix", "get_physics_jitter_fix");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_scale"), "set_time_scale", "get_time_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "physics_jitter_fix"), "set_physics_jitter_fix", "get_physics_jitter_fix");
}
_Engine *_Engine::singleton = NULL;
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 39bed791d0..fc6419b7d8 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -49,18 +49,31 @@ protected:
static _ResourceLoader *singleton;
public:
+ enum ThreadLoadStatus {
+ THREAD_LOAD_INVALID_RESOURCE,
+ THREAD_LOAD_IN_PROGRESS,
+ THREAD_LOAD_FAILED,
+ THREAD_LOAD_LOADED
+ };
+
static _ResourceLoader *get_singleton() { return singleton; }
- Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "");
+
+ Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false);
+ ThreadLoadStatus load_threaded_get_status(const String &p_path, Array r_progress = Array());
+ RES load_threaded_get(const String &p_path);
+
RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false);
- PoolVector<String> get_recognized_extensions_for_type(const String &p_type);
+ Vector<String> get_recognized_extensions_for_type(const String &p_type);
void set_abort_on_missing_resources(bool p_abort);
- PoolStringArray get_dependencies(const String &p_path);
+ PackedStringArray get_dependencies(const String &p_path);
bool has_cached(const String &p_path);
bool exists(const String &p_path, const String &p_type_hint = "");
_ResourceLoader();
};
+VARIANT_ENUM_CAST(_ResourceLoader::ThreadLoadStatus);
+
class _ResourceSaver : public Object {
GDCLASS(_ResourceSaver, Object);
@@ -83,7 +96,7 @@ public:
static _ResourceSaver *get_singleton() { return singleton; }
Error save(const String &p_path, const RES &p_resource, SaverFlags p_flags);
- PoolVector<String> get_recognized_extensions(const RES &p_resource);
+ Vector<String> get_recognized_extensions(const RES &p_resource);
_ResourceSaver();
};
@@ -157,7 +170,7 @@ public:
virtual int get_audio_driver_count() const;
virtual String get_audio_driver_name(int p_driver) const;
- virtual PoolStringArray get_connected_midi_inputs();
+ virtual PackedStringArray get_connected_midi_inputs();
virtual void open_midi_inputs();
virtual void close_midi_inputs();
@@ -253,9 +266,9 @@ public:
String get_unique_id() const;
- String get_scancode_string(uint32_t p_code) const;
- bool is_scancode_unicode(uint32_t p_unicode) const;
- int find_scancode_from_string(const String &p_code) const;
+ String get_keycode_string(uint32_t p_code) const;
+ bool is_keycode_unicode(uint32_t p_unicode) const;
+ int find_keycode_from_string(const String &p_code) const;
void set_use_file_access_save_and_swap(bool p_enable);
@@ -276,7 +289,6 @@ public:
uint64_t get_static_memory_usage() const;
uint64_t get_static_memory_peak_usage() const;
- uint64_t get_dynamic_memory_usage() const;
void delay_usec(uint32_t p_usec) const;
void delay_msec(uint32_t p_msec) const;
@@ -366,13 +378,13 @@ protected:
public:
static _Geometry *get_singleton();
- PoolVector<Plane> build_box_planes(const Vector3 &p_extents);
- PoolVector<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z);
- PoolVector<Plane> build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis = Vector3::AXIS_Z);
+ Vector<Plane> build_box_planes(const Vector3 &p_extents);
+ Vector<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z);
+ Vector<Plane> build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis = Vector3::AXIS_Z);
Variant segment_intersects_segment_2d(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b);
Variant line_intersects_line_2d(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b);
- PoolVector<Vector2> get_closest_points_between_segments_2d(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2);
- PoolVector<Vector3> get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2);
+ Vector<Vector2> get_closest_points_between_segments_2d(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2);
+ Vector<Vector3> get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2);
Vector2 get_closest_point_to_segment_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b);
Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b);
Vector2 get_closest_point_to_segment_uncapped_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b);
@@ -381,9 +393,9 @@ public:
Variant segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2);
bool point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const;
- PoolVector<Vector3> segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius);
- PoolVector<Vector3> segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius);
- PoolVector<Vector3> segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes);
+ Vector<Vector3> segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius);
+ Vector<Vector3> segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius);
+ Vector<Vector3> segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes);
bool is_point_in_circle(const Vector2 &p_point, const Vector2 &p_circle_pos, real_t p_circle_radius);
real_t segment_intersects_circle(const Vector2 &p_from, const Vector2 &p_to, const Vector2 &p_circle_pos, real_t p_circle_radius);
int get_uv84_normal_bit(const Vector3 &p_vector);
@@ -490,7 +502,7 @@ public:
Variant get_var(bool p_allow_objects = false) const;
- PoolVector<uint8_t> get_buffer(int p_length) const; // Get an array of bytes.
+ Vector<uint8_t> get_buffer(int p_length) const; // Get an array of bytes.
String get_line() const;
Vector<String> get_csv_line(const String &p_delim = ",") const;
String get_as_text() const;
@@ -523,7 +535,7 @@ public:
virtual void store_pascal_string(const String &p_string);
virtual String get_pascal_string();
- void store_buffer(const PoolVector<uint8_t> &p_buffer); // Store an array of bytes.
+ void store_buffer(const Vector<uint8_t> &p_buffer); // Store an array of bytes.
void store_var(const Variant &p_var, bool p_full_objects = false);
@@ -560,7 +572,7 @@ public:
int get_current_drive();
Error change_dir(String p_dir); // Can be relative or absolute, return false on success.
- String get_current_dir(); // Return current dir location.
+ String get_current_dir(bool p_include_drive = true); // Return current dir location.
Error make_dir(String p_dir);
Error make_dir_recursive(String p_dir);
@@ -582,9 +594,9 @@ private:
bool _list_skip_hidden;
};
-class _Marshalls : public Reference {
+class _Marshalls : public Object {
- GDCLASS(_Marshalls, Reference);
+ GDCLASS(_Marshalls, Object);
static _Marshalls *singleton;
@@ -597,8 +609,8 @@ public:
String variant_to_base64(const Variant &p_var, bool p_full_objects = false);
Variant base64_to_variant(const String &p_str, bool p_allow_objects = false);
- String raw_to_base64(const PoolVector<uint8_t> &p_arr);
- PoolVector<uint8_t> base64_to_raw(const String &p_str);
+ String raw_to_base64(const Vector<uint8_t> &p_arr);
+ Vector<uint8_t> base64_to_raw(const String &p_str);
String utf8_to_base64(const String &p_str);
String base64_to_utf8(const String &p_str);
@@ -610,7 +622,7 @@ public:
class _Mutex : public Reference {
GDCLASS(_Mutex, Reference);
- Mutex *mutex;
+ Mutex mutex;
static void _bind_methods();
@@ -618,24 +630,19 @@ public:
void lock();
Error try_lock();
void unlock();
-
- _Mutex();
- ~_Mutex();
};
class _Semaphore : public Reference {
GDCLASS(_Semaphore, Reference);
- SemaphoreOld *semaphore;
+ Semaphore semaphore;
static void _bind_methods();
public:
- Error wait();
- Error post();
-
- _Semaphore();
- ~_Semaphore();
+ void wait();
+ Error try_wait();
+ void post();
};
class _Thread : public Reference {
@@ -680,8 +687,8 @@ protected:
static void _bind_methods();
public:
- PoolStringArray get_class_list() const;
- PoolStringArray get_inheriters_from_class(const StringName &p_class) const;
+ PackedStringArray get_class_list() const;
+ PackedStringArray get_inheriters_from_class(const StringName &p_class) const;
StringName get_parent_class(const StringName &p_class) const;
bool class_exists(const StringName &p_class) const;
bool is_parent_class(const StringName &p_class, const StringName &p_inherits) const;
@@ -700,7 +707,7 @@ public:
Array get_method_list(StringName p_class, bool p_no_inheritance = false) const;
- PoolStringArray get_integer_constant_list(const StringName &p_class, bool p_no_inheritance = false) const;
+ PackedStringArray get_integer_constant_list(const StringName &p_class, bool p_no_inheritance = false) const;
bool has_integer_constant(const StringName &p_class, const StringName &p_name) const;
int get_integer_constant(const StringName &p_class, const StringName &p_name) const;
StringName get_category(const StringName &p_node) const;
diff --git a/core/callable.cpp b/core/callable.cpp
new file mode 100644
index 0000000000..4a5ae3a248
--- /dev/null
+++ b/core/callable.cpp
@@ -0,0 +1,359 @@
+/*************************************************************************/
+/* callable.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 "callable.h"
+#include "core/script_language.h"
+#include "message_queue.h"
+#include "object.h"
+#include "reference.h"
+
+void Callable::call_deferred(const Variant **p_arguments, int p_argcount) const {
+ MessageQueue::get_singleton()->push_callable(*this, p_arguments, p_argcount);
+}
+
+void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const {
+
+ if (is_null()) {
+ r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_call_error.argument = 0;
+ r_call_error.expected = 0;
+ r_return_value = Variant();
+ } else if (is_custom()) {
+ custom->call(p_arguments, p_argcount, r_return_value, r_call_error);
+ } else {
+ Object *obj = ObjectDB::get_instance(ObjectID(object));
+ r_return_value = obj->call(method, p_arguments, p_argcount, r_call_error);
+ }
+}
+
+Object *Callable::get_object() const {
+ if (is_null()) {
+ return nullptr;
+ } else if (is_custom()) {
+ return ObjectDB::get_instance(custom->get_object());
+ } else {
+ return ObjectDB::get_instance(ObjectID(object));
+ }
+}
+
+ObjectID Callable::get_object_id() const {
+ if (is_null()) {
+ return ObjectID();
+ } else if (is_custom()) {
+ return custom->get_object();
+ } else {
+ return ObjectID(object);
+ }
+}
+StringName Callable::get_method() const {
+ ERR_FAIL_COND_V_MSG(is_custom(), StringName(),
+ vformat("Can't get method on CallableCustom \"%s\".", operator String()));
+ return method;
+}
+
+uint32_t Callable::hash() const {
+ if (is_custom()) {
+ return custom->hash();
+ } else {
+ uint32_t hash = method.hash();
+ return hash_djb2_one_64(object, hash);
+ }
+}
+
+bool Callable::operator==(const Callable &p_callable) const {
+ bool custom_a = is_custom();
+ bool custom_b = p_callable.is_custom();
+
+ if (custom_a == custom_b) {
+ if (custom_a) {
+ if (custom == p_callable.custom) {
+ return true; //same pointer, dont even compare
+ }
+
+ CallableCustom::CompareEqualFunc eq_a = custom->get_compare_equal_func();
+ CallableCustom::CompareEqualFunc eq_b = p_callable.custom->get_compare_equal_func();
+ if (eq_a == eq_b) {
+ return eq_a(custom, p_callable.custom);
+ } else {
+ return false;
+ }
+ } else {
+ return object == p_callable.object && method == p_callable.method;
+ }
+ } else {
+ return false;
+ }
+}
+bool Callable::operator!=(const Callable &p_callable) const {
+ return !(*this == p_callable);
+}
+bool Callable::operator<(const Callable &p_callable) const {
+ bool custom_a = is_custom();
+ bool custom_b = p_callable.is_custom();
+
+ if (custom_a == custom_b) {
+ if (custom_a) {
+ if (custom == p_callable.custom) {
+ return false; //same pointer, dont even compare
+ }
+
+ CallableCustom::CompareLessFunc less_a = custom->get_compare_less_func();
+ CallableCustom::CompareLessFunc less_b = p_callable.custom->get_compare_less_func();
+ if (less_a == less_b) {
+ return less_a(custom, p_callable.custom);
+ } else {
+ return less_a < less_b; //it's something..
+ }
+
+ } else {
+ if (object == p_callable.object) {
+ return method < p_callable.method;
+ } else {
+ return object < p_callable.object;
+ }
+ }
+ } else {
+ return int(custom_a ? 1 : 0) < int(custom_b ? 1 : 0);
+ }
+}
+
+void Callable::operator=(const Callable &p_callable) {
+ if (is_custom()) {
+ if (p_callable.is_custom()) {
+ if (custom == p_callable.custom) {
+ return;
+ }
+ }
+
+ if (custom->ref_count.unref()) {
+ memdelete(custom);
+ }
+ }
+
+ if (p_callable.is_custom()) {
+ method = StringName();
+ if (!p_callable.custom->ref_count.ref()) {
+ object = 0;
+ } else {
+ object = 0;
+ custom = p_callable.custom;
+ }
+ } else {
+ method = p_callable.method;
+ object = p_callable.object;
+ }
+}
+
+Callable::operator String() const {
+
+ if (is_custom()) {
+ return custom->get_as_text();
+ } else {
+ if (is_null()) {
+ return "null::null";
+ }
+
+ Object *base = get_object();
+ if (base) {
+ String class_name = base->get_class();
+ Ref<Script> script = base->get_script();
+ if (script.is_valid() && script->get_path().is_resource_file()) {
+
+ class_name += "(" + script->get_path().get_file() + ")";
+ }
+ return class_name + "::" + String(method);
+ } else {
+ return "null::" + String(method);
+ }
+ }
+}
+
+Callable::Callable(const Object *p_object, const StringName &p_method) {
+ if (p_method == StringName()) {
+ object = 0;
+ ERR_FAIL_MSG("Method argument to Callable constructor must be a non-empty string");
+ }
+ if (p_object == nullptr) {
+ object = 0;
+ ERR_FAIL_MSG("Object argument to Callable constructor must be non-null");
+ }
+
+ object = p_object->get_instance_id();
+ method = p_method;
+}
+
+Callable::Callable(ObjectID p_object, const StringName &p_method) {
+ if (p_method == StringName()) {
+ object = 0;
+ ERR_FAIL_MSG("Method argument to Callable constructor must be a non-empty string");
+ }
+
+ object = p_object;
+ method = p_method;
+}
+Callable::Callable(CallableCustom *p_custom) {
+ if (p_custom->referenced) {
+ object = 0;
+ ERR_FAIL_MSG("Callable custom is already referenced");
+ }
+ p_custom->referenced = true;
+ object = 0; //ensure object is all zero, since pointer may be 32 bits
+ custom = p_custom;
+}
+Callable::Callable(const Callable &p_callable) {
+ if (p_callable.is_custom()) {
+ if (!p_callable.custom->ref_count.ref()) {
+ object = 0;
+ } else {
+ object = 0;
+ custom = p_callable.custom;
+ }
+ } else {
+ method = p_callable.method;
+ object = p_callable.object;
+ }
+}
+
+Callable::~Callable() {
+ if (is_custom()) {
+ if (custom->ref_count.unref()) {
+ memdelete(custom);
+ }
+ }
+}
+
+Callable::Callable() {
+ object = 0;
+}
+
+CallableCustom::CallableCustom() {
+ referenced = false;
+ ref_count.init();
+}
+
+//////////////////////////////////
+
+Object *Signal::get_object() const {
+ return ObjectDB::get_instance(object);
+}
+ObjectID Signal::get_object_id() const {
+ return object;
+}
+StringName Signal::get_name() const {
+ return name;
+}
+
+bool Signal::operator==(const Signal &p_signal) const {
+ return object == p_signal.object && name == p_signal.name;
+}
+
+bool Signal::operator!=(const Signal &p_signal) const {
+ return object != p_signal.object || name != p_signal.name;
+}
+
+bool Signal::operator<(const Signal &p_signal) const {
+ if (object == p_signal.object) {
+ return name < p_signal.name;
+ } else {
+ return object < p_signal.object;
+ }
+}
+
+Signal::operator String() const {
+ Object *base = get_object();
+ if (base) {
+ String class_name = base->get_class();
+ Ref<Script> script = base->get_script();
+ if (script.is_valid() && script->get_path().is_resource_file()) {
+
+ class_name += "(" + script->get_path().get_file() + ")";
+ }
+ return class_name + "::[signal]" + String(name);
+ } else {
+ return "null::[signal]" + String(name);
+ }
+}
+
+Error Signal::emit(const Variant **p_arguments, int p_argcount) const {
+ Object *obj = ObjectDB::get_instance(object);
+ if (!obj) {
+ return ERR_INVALID_DATA;
+ }
+
+ return obj->emit_signal(name, p_arguments, p_argcount);
+}
+Error Signal::connect(const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) {
+
+ Object *object = get_object();
+ ERR_FAIL_COND_V(!object, ERR_UNCONFIGURED);
+
+ return object->connect(name, p_callable, p_binds, p_flags);
+}
+void Signal::disconnect(const Callable &p_callable) {
+ Object *object = get_object();
+ ERR_FAIL_COND(!object);
+ object->disconnect(name, p_callable);
+}
+bool Signal::is_connected(const Callable &p_callable) const {
+ Object *object = get_object();
+ ERR_FAIL_COND_V(!object, false);
+
+ return object->is_connected(name, p_callable);
+}
+
+Array Signal::get_connections() const {
+ Object *object = get_object();
+ if (!object) {
+ return Array();
+ }
+
+ List<Object::Connection> connections;
+ object->get_signal_connection_list(name, &connections);
+
+ Array arr;
+ for (List<Object::Connection>::Element *E = connections.front(); E; E = E->next()) {
+ arr.push_back(E->get());
+ }
+ return arr;
+}
+Signal::Signal(const Object *p_object, const StringName &p_name) {
+
+ ERR_FAIL_COND_MSG(p_object == nullptr, "Object argument to Signal constructor must be non-null");
+
+ object = p_object->get_instance_id();
+ name = p_name;
+}
+Signal::Signal(ObjectID p_object, const StringName &p_name) {
+
+ object = p_object;
+ name = p_name;
+}
+Signal::Signal() {
+}
diff --git a/core/callable.h b/core/callable.h
new file mode 100644
index 0000000000..cecf2264a3
--- /dev/null
+++ b/core/callable.h
@@ -0,0 +1,161 @@
+/*************************************************************************/
+/* callable.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 CALLABLE_H
+#define CALLABLE_H
+
+#include "core/list.h"
+#include "core/object_id.h"
+#include "core/string_name.h"
+
+class Object;
+class Variant;
+class CallableCustom;
+
+// This is an abstraction of things that can be called.
+// It is used for signals and other cases where efficient calling of functions
+// is required. It is designed for the standard case (object and method)
+// but can be optimized or customized.
+
+class Callable {
+
+ //needs to be max 16 bytes in 64 bits
+ StringName method;
+ union {
+ uint64_t object;
+ CallableCustom *custom;
+ };
+
+public:
+ struct CallError {
+ enum Error {
+ CALL_OK,
+ CALL_ERROR_INVALID_METHOD,
+ CALL_ERROR_INVALID_ARGUMENT, // expected is variant type
+ CALL_ERROR_TOO_MANY_ARGUMENTS, // expected is number of arguments
+ CALL_ERROR_TOO_FEW_ARGUMENTS, // expected is number of arguments
+ CALL_ERROR_INSTANCE_IS_NULL,
+ };
+ Error error;
+ int argument;
+ int expected;
+ };
+
+ void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const;
+ void call_deferred(const Variant **p_arguments, int p_argcount) const;
+
+ _FORCE_INLINE_ bool is_null() const {
+ return method == StringName() && object == 0;
+ }
+ _FORCE_INLINE_ bool is_custom() const {
+ return method == StringName() && custom != 0;
+ }
+ _FORCE_INLINE_ bool is_standard() const {
+ return method != StringName();
+ }
+
+ Object *get_object() const;
+ ObjectID get_object_id() const;
+ StringName get_method() const;
+
+ uint32_t hash() const;
+
+ bool operator==(const Callable &p_callable) const;
+ bool operator!=(const Callable &p_callable) const;
+ bool operator<(const Callable &p_callable) const;
+
+ void operator=(const Callable &p_callable);
+
+ operator String() const;
+
+ Callable(const Object *p_object, const StringName &p_method);
+ Callable(ObjectID p_object, const StringName &p_method);
+ Callable(CallableCustom *p_custom);
+ Callable(const Callable &p_callable);
+ Callable();
+ ~Callable();
+};
+
+class CallableCustom {
+ friend class Callable;
+ SafeRefCount ref_count;
+ bool referenced;
+
+public:
+ typedef bool (*CompareEqualFunc)(const CallableCustom *p_a, const CallableCustom *p_b);
+ typedef bool (*CompareLessFunc)(const CallableCustom *p_a, const CallableCustom *p_b);
+
+ //for every type that inherits, these must always be the same for this type
+ virtual uint32_t hash() const = 0;
+ virtual String get_as_text() const = 0;
+ virtual CompareEqualFunc get_compare_equal_func() const = 0;
+ virtual CompareLessFunc get_compare_less_func() const = 0;
+ virtual ObjectID get_object() const = 0; //must always be able to provide an object
+ virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const = 0;
+
+ CallableCustom();
+ virtual ~CallableCustom() {}
+};
+
+// This is just a proxy object to object signals, its only
+// allocated on demand by/for scripting languages so it can
+// be put inside a Variant, but it is not
+// used by the engine itself.
+
+class Signal {
+ StringName name;
+ ObjectID object;
+
+public:
+ _FORCE_INLINE_ bool is_null() const {
+ return object.is_null() && name == StringName();
+ }
+ Object *get_object() const;
+ ObjectID get_object_id() const;
+ StringName get_name() const;
+
+ bool operator==(const Signal &p_signal) const;
+ bool operator!=(const Signal &p_signal) const;
+ bool operator<(const Signal &p_signal) const;
+
+ operator String() const;
+
+ Error emit(const Variant **p_arguments, int p_argcount) const;
+ Error connect(const Callable &p_callable, const Vector<Variant> &p_binds = Vector<Variant>(), uint32_t p_flags = 0);
+ void disconnect(const Callable &p_callable);
+ bool is_connected(const Callable &p_callable) const;
+
+ Array get_connections() const;
+ Signal(const Object *p_object, const StringName &p_name);
+ Signal(ObjectID p_object, const StringName &p_name);
+ Signal();
+};
+
+#endif // CALLABLE_H
diff --git a/core/callable_method_pointer.cpp b/core/callable_method_pointer.cpp
new file mode 100644
index 0000000000..8774af6add
--- /dev/null
+++ b/core/callable_method_pointer.cpp
@@ -0,0 +1,94 @@
+/*************************************************************************/
+/* callable_method_pointer.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 "callable_method_pointer.h"
+
+bool CallableCustomMethodPointerBase::compare_equal(const CallableCustom *p_a, const CallableCustom *p_b) {
+ const CallableCustomMethodPointerBase *a = static_cast<const CallableCustomMethodPointerBase *>(p_a);
+ const CallableCustomMethodPointerBase *b = static_cast<const CallableCustomMethodPointerBase *>(p_b);
+
+ if (a->comp_size != b->comp_size) {
+ return false;
+ }
+
+ for (uint32_t i = 0; i < a->comp_size; i++) {
+ if (a->comp_ptr[i] != b->comp_ptr[i]) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CallableCustomMethodPointerBase::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
+
+ const CallableCustomMethodPointerBase *a = static_cast<const CallableCustomMethodPointerBase *>(p_a);
+ const CallableCustomMethodPointerBase *b = static_cast<const CallableCustomMethodPointerBase *>(p_b);
+
+ if (a->comp_size != b->comp_size) {
+ return a->comp_size < b->comp_size;
+ }
+
+ for (uint32_t i = 0; i < a->comp_size; i++) {
+ if (a->comp_ptr[i] == b->comp_ptr[i]) {
+ continue;
+ }
+
+ return a->comp_ptr[i] < b->comp_ptr[i];
+ }
+
+ return false;
+}
+
+CallableCustom::CompareEqualFunc CallableCustomMethodPointerBase::get_compare_equal_func() const {
+ return compare_equal;
+}
+
+CallableCustom::CompareLessFunc CallableCustomMethodPointerBase::get_compare_less_func() const {
+ return compare_less;
+}
+
+uint32_t CallableCustomMethodPointerBase::hash() const {
+ return h;
+}
+
+void CallableCustomMethodPointerBase::_setup(uint32_t *p_base_ptr, uint32_t p_ptr_size) {
+ comp_ptr = p_base_ptr;
+ comp_size = p_ptr_size / 4;
+
+ // Precompute hash.
+ for (uint32_t i = 0; i < comp_size; i++) {
+ if (i == 0) {
+ h = hash_djb2_one_32(comp_ptr[i]);
+ } else {
+ h = hash_djb2_one_32(comp_ptr[i], h);
+ }
+ }
+}
diff --git a/core/callable_method_pointer.h b/core/callable_method_pointer.h
new file mode 100644
index 0000000000..a931a344e6
--- /dev/null
+++ b/core/callable_method_pointer.h
@@ -0,0 +1,292 @@
+/*************************************************************************/
+/* callable_method_pointer.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 CALLABLE_METHOD_POINTER_H
+#define CALLABLE_METHOD_POINTER_H
+
+#include "core/callable.h"
+#include "core/hashfuncs.h"
+#include "core/object.h"
+#include "core/simple_type.h"
+
+class CallableCustomMethodPointerBase : public CallableCustom {
+
+ uint32_t *comp_ptr;
+ uint32_t comp_size;
+ uint32_t h;
+#ifdef DEBUG_METHODS_ENABLED
+ const char *text = "";
+#endif
+ static bool compare_equal(const CallableCustom *p_a, const CallableCustom *p_b);
+ static bool compare_less(const CallableCustom *p_a, const CallableCustom *p_b);
+
+protected:
+ void _setup(uint32_t *p_base_ptr, uint32_t p_ptr_size);
+
+public:
+#ifdef DEBUG_METHODS_ENABLED
+ void set_text(const char *p_text) {
+ text = p_text;
+ }
+ virtual String get_as_text() const {
+ return text;
+ }
+#else
+ virtual String get_as_text() const {
+ return String();
+ }
+#endif
+ virtual CompareEqualFunc get_compare_equal_func() const;
+ virtual CompareLessFunc get_compare_less_func() const;
+
+ virtual uint32_t hash() const;
+};
+
+#ifdef DEBUG_METHODS_ENABLED
+
+template <class T>
+struct VariantCasterAndValidate {
+
+ static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
+ Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
+ if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype)) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = p_arg_idx;
+ r_error.expected = argtype;
+ }
+
+ return VariantCaster<T>::cast(*p_args[p_arg_idx]);
+ }
+};
+
+template <class T>
+struct VariantCasterAndValidate<T &> {
+
+ static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
+ Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
+ if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype)) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = p_arg_idx;
+ r_error.expected = argtype;
+ }
+
+ return VariantCaster<T>::cast(*p_args[p_arg_idx]);
+ }
+};
+
+template <class T>
+struct VariantCasterAndValidate<const T &> {
+
+ static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
+ Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
+ if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype)) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = p_arg_idx;
+ r_error.expected = argtype;
+ }
+
+ return VariantCaster<T>::cast(*p_args[p_arg_idx]);
+ }
+};
+
+#endif // DEBUG_METHODS_ENABLED
+
+// GCC 8 raises "parameter 'p_args' set but not used" here, probably using a
+// template version that does not have arguments and thus sees it unused, but
+// obviously the template can be used for functions with and without them, and
+// the optimizer will get rid of it anyway.
+#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
+#endif
+
+template <class T, class... P, size_t... Is>
+void call_with_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
+ r_error.error = Callable::CallError::CALL_OK;
+
+#ifdef DEBUG_METHODS_ENABLED
+ (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
+#else
+ (p_instance->*p_method)(VariantCaster<P>::cast(p_args[Is])...);
+#endif
+}
+
+#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+template <class T, class... P>
+void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+#ifdef DEBUG_METHODS_ENABLED
+ if ((size_t)p_argcount > sizeof...(P)) {
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.argument = sizeof...(P);
+ return;
+ }
+
+ if ((size_t)p_argcount < sizeof...(P)) {
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.argument = sizeof...(P);
+ return;
+ }
+#endif
+ call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class... P>
+class CallableCustomMethodPointer : public CallableCustomMethodPointerBase {
+
+ struct Data {
+ T *instance;
+ void (T::*method)(P...);
+ } data;
+
+public:
+ virtual ObjectID get_object() const { return data.instance->get_instance_id(); }
+
+ virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
+
+ call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
+ }
+
+ CallableCustomMethodPointer(T *p_instance, void (T::*p_method)(P...)) {
+ zeromem(&data, sizeof(Data)); // Clear beforehand, may have padding bytes.
+ data.instance = p_instance;
+ data.method = p_method;
+ _setup((uint32_t *)&data, sizeof(Data));
+ }
+};
+
+template <class T, class... P>
+Callable create_custom_callable_function_pointer(T *p_instance,
+#ifdef DEBUG_METHODS_ENABLED
+ const char *p_func_text,
+#endif
+ void (T::*p_method)(P...)) {
+
+ typedef CallableCustomMethodPointer<T, P...> CCMP; // Messes with memnew otherwise.
+ CCMP *ccmp = memnew(CCMP(p_instance, p_method));
+#ifdef DEBUG_METHODS_ENABLED
+ ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.
+#endif
+ return Callable(ccmp);
+}
+
+// VERSION WITH RETURN
+
+// GCC 8 raises "parameter 'p_args' set but not used" here, probably using a
+// template version that does not have arguments and thus sees it unused, but
+// obviously the template can be used for functions with and without them, and
+// the optimizer will get rid of it anyway.
+#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
+#endif
+
+template <class T, class R, class... P, size_t... Is>
+void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
+ r_error.error = Callable::CallError::CALL_OK;
+
+#ifdef DEBUG_METHODS_ENABLED
+ r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
+#else
+ (p_instance->*p_method)(VariantCaster<P>::cast(p_args[Is])...);
+#endif
+}
+
+#if defined(DEBUG_METHODS_ENABLED) && defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+template <class T, class R, class... P>
+void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
+#ifdef DEBUG_METHODS_ENABLED
+ if ((size_t)p_argcount > sizeof...(P)) {
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.argument = sizeof...(P);
+ return;
+ }
+
+ if ((size_t)p_argcount < sizeof...(P)) {
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.argument = sizeof...(P);
+ return;
+ }
+#endif
+ call_with_variant_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
+}
+
+template <class T, class R, class... P>
+class CallableCustomMethodPointerRet : public CallableCustomMethodPointerBase {
+
+ struct Data {
+ T *instance;
+ R(T::*method)
+ (P...);
+ } data;
+
+public:
+ virtual ObjectID get_object() const { return data.instance->get_instance_id(); }
+
+ virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
+
+ call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
+ }
+
+ CallableCustomMethodPointerRet(T *p_instance, R (T::*p_method)(P...)) {
+ zeromem(&data, sizeof(Data)); // Clear beforehand, may have padding bytes.
+ data.instance = p_instance;
+ data.method = p_method;
+ _setup((uint32_t *)&data, sizeof(Data));
+ }
+};
+
+template <class T, class R, class... P>
+Callable create_custom_callable_function_pointer(T *p_instance,
+#ifdef DEBUG_METHODS_ENABLED
+ const char *p_func_text,
+#endif
+ R (T::*p_method)(P...)) {
+
+ typedef CallableCustomMethodPointerRet<T, R, P...> CCMP; // Messes with memnew otherwise.
+ CCMP *ccmp = memnew(CCMP(p_instance, p_method));
+#ifdef DEBUG_METHODS_ENABLED
+ ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.
+#endif
+ return Callable(ccmp);
+}
+
+#ifdef DEBUG_METHODS_ENABLED
+#define callable_mp(I, M) create_custom_callable_function_pointer(I, #M, M)
+#else
+#define callable_mp(I, M) create_custom_callable_function_pointer(I, M)
+#endif
+
+#endif // CALLABLE_METHOD_POINTER_H
diff --git a/core/class_db.cpp b/core/class_db.cpp
index a2941d70f6..35e216a58f 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -1033,7 +1033,7 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const
return true; //return true but do nothing
}
- Variant::CallError ce;
+ Callable::CallError ce;
if (psg->index >= 0) {
Variant index = psg->index;
@@ -1055,7 +1055,7 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const
}
if (r_valid)
- *r_valid = ce.error == Variant::CallError::CALL_OK;
+ *r_valid = ce.error == Callable::CallError::CALL_OK;
return true;
}
@@ -1078,12 +1078,12 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia
if (psg->index >= 0) {
Variant index = psg->index;
const Variant *arg[1] = { &index };
- Variant::CallError ce;
+ Callable::CallError ce;
r_value = p_object->call(psg->getter, arg, 1, ce);
} else {
- Variant::CallError ce;
+ Callable::CallError ce;
if (psg->_getptr) {
r_value = psg->_getptr->call(p_object, NULL, 0, ce);
@@ -1094,13 +1094,23 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia
return true;
}
- const int *c = check->constant_map.getptr(p_property);
+ const int *c = check->constant_map.getptr(p_property); //constants count
if (c) {
r_value = *c;
return true;
}
+ if (check->method_map.has(p_property)) { //methods count
+ r_value = Callable(p_object, p_property);
+ return true;
+ }
+
+ if (check->signal_map.has(p_property)) { //signals count
+ r_value = Signal(p_object, p_property);
+ return true;
+ }
+
check = check->inherits_ptr;
}
diff --git a/core/class_db.h b/core/class_db.h
index 404b04f2d0..398eca9132 100644
--- a/core/class_db.h
+++ b/core/class_db.h
@@ -35,13 +35,15 @@
#include "core/object.h"
#include "core/print_string.h"
-/** To bind more then 6 parameters include this:
+/** To bind more then 6 parameters include this:
* #include "core/method_bind_ext.gen.inc"
*/
-#define DEFVAL(m_defval) (m_defval)
+// Makes callable_mp readily available in all classes connecting signals.
+// Needs to come after method_bind and object have been included.
+#include "core/callable_method_pointer.h"
-//#define SIMPLE_METHODDEF
+#define DEFVAL(m_defval) (m_defval)
#ifdef DEBUG_METHODS_ENABLED
diff --git a/core/command_queue_mt.cpp b/core/command_queue_mt.cpp
index 861ca8d1d3..85e8a847a0 100644
--- a/core/command_queue_mt.cpp
+++ b/core/command_queue_mt.cpp
@@ -34,14 +34,12 @@
void CommandQueueMT::lock() {
- if (mutex)
- mutex->lock();
+ mutex.lock();
}
void CommandQueueMT::unlock() {
- if (mutex)
- mutex->unlock();
+ mutex.unlock();
}
void CommandQueueMT::wait_for_flush() {
@@ -106,16 +104,14 @@ CommandQueueMT::CommandQueueMT(bool p_sync) {
read_ptr = 0;
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++) {
- sync_sems[i].sem = SemaphoreOld::create();
sync_sems[i].in_use = false;
}
if (p_sync)
- sync = SemaphoreOld::create();
+ sync = memnew(Semaphore);
else
sync = NULL;
}
@@ -124,10 +120,5 @@ CommandQueueMT::~CommandQueueMT() {
if (sync)
memdelete(sync);
- memdelete(mutex);
- for (int i = 0; i < SYNC_SEMAPHORES; i++) {
-
- memdelete(sync_sems[i].sem);
- }
memfree(command_mem);
}
diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h
index 2b6e0201f0..90231546ef 100644
--- a/core/command_queue_mt.h
+++ b/core/command_queue_mt.h
@@ -270,7 +270,7 @@
cmd->sync_sem = ss; \
unlock(); \
if (sync) sync->post(); \
- ss->sem->wait(); \
+ ss->sem.wait(); \
ss->in_use = false; \
}
@@ -287,7 +287,7 @@
cmd->sync_sem = ss; \
unlock(); \
if (sync) sync->post(); \
- ss->sem->wait(); \
+ ss->sem.wait(); \
ss->in_use = false; \
}
@@ -297,7 +297,7 @@ class CommandQueueMT {
struct SyncSemaphore {
- SemaphoreOld *sem;
+ Semaphore sem;
bool in_use;
};
@@ -313,7 +313,7 @@ class CommandQueueMT {
SyncSemaphore *sync_sem;
virtual void post() {
- sync_sem->sem->post();
+ sync_sem->sem.post();
}
};
@@ -341,8 +341,8 @@ class CommandQueueMT {
uint32_t write_ptr;
uint32_t dealloc_ptr;
SyncSemaphore sync_sems[SYNC_SEMAPHORES];
- Mutex *mutex;
- SemaphoreOld *sync;
+ Mutex mutex;
+ Semaphore *sync;
template <class T>
T *allocate() {
diff --git a/core/compressed_translation.cpp b/core/compressed_translation.cpp
index 69b4ec292f..ed307fd3ac 100644
--- a/core/compressed_translation.cpp
+++ b/core/compressed_translation.cpp
@@ -141,8 +141,8 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
hash_table.resize(size);
bucket_table.resize(bucket_table_size);
- PoolVector<int>::Write htwb = hash_table.write();
- PoolVector<int>::Write btwb = bucket_table.write();
+ int *htwb = hash_table.ptrw();
+ int *btwb = bucket_table.ptrw();
uint32_t *htw = (uint32_t *)&htwb[0];
uint32_t *btw = (uint32_t *)&btwb[0];
@@ -174,7 +174,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
}
strings.resize(total_compression_size);
- PoolVector<uint8_t>::Write cw = strings.write();
+ uint8_t *cw = strings.ptrw();
for (int i = 0; i < compressed.size(); i++) {
memcpy(&cw[compressed[i].offset], compressed[i].compressed.get_data(), compressed[i].compressed.size());
@@ -228,11 +228,11 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const {
CharString str = p_src_text.operator String().utf8();
uint32_t h = hash(0, str.get_data());
- PoolVector<int>::Read htr = hash_table.read();
+ const int *htr = hash_table.ptr();
const uint32_t *htptr = (const uint32_t *)&htr[0];
- PoolVector<int>::Read btr = bucket_table.read();
+ const int *btr = bucket_table.ptr();
const uint32_t *btptr = (const uint32_t *)&btr[0];
- PoolVector<uint8_t>::Read sr = strings.read();
+ const uint8_t *sr = strings.ptr();
const char *sptr = (const char *)&sr[0];
uint32_t p = htptr[h % htsize];
@@ -279,9 +279,9 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const {
void PHashTranslation::_get_property_list(List<PropertyInfo> *p_list) const {
- p_list->push_back(PropertyInfo(Variant::POOL_INT_ARRAY, "hash_table"));
- p_list->push_back(PropertyInfo(Variant::POOL_INT_ARRAY, "bucket_table"));
- p_list->push_back(PropertyInfo(Variant::POOL_BYTE_ARRAY, "strings"));
+ p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, "hash_table"));
+ p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, "bucket_table"));
+ p_list->push_back(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "strings"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "load_from", PROPERTY_HINT_RESOURCE_TYPE, "Translation", PROPERTY_USAGE_EDITOR));
}
void PHashTranslation::_bind_methods() {
diff --git a/core/compressed_translation.h b/core/compressed_translation.h
index a72be739a1..d599240dfe 100644
--- a/core/compressed_translation.h
+++ b/core/compressed_translation.h
@@ -43,9 +43,9 @@ class PHashTranslation : public Translation {
//of catching untranslated strings
//load/store friendly types
- PoolVector<int> hash_table;
- PoolVector<int> bucket_table;
- PoolVector<uint8_t> strings;
+ Vector<int> hash_table;
+ Vector<int> bucket_table;
+ Vector<uint8_t> strings;
struct Bucket {
diff --git a/core/core_string_names.cpp b/core/core_string_names.cpp
index bafb800e41..253d5f1acb 100644
--- a/core/core_string_names.cpp
+++ b/core/core_string_names.cpp
@@ -70,5 +70,9 @@ CoreStringNames::CoreStringNames() :
r8(StaticCString::create("r8")),
g8(StaticCString::create("g8")),
b8(StaticCString::create("b8")),
- a8(StaticCString::create("a8")) {
+ a8(StaticCString::create("a8")),
+ call(StaticCString::create("call")),
+ call_deferred(StaticCString::create("call_deferred")),
+ emit(StaticCString::create("emit")),
+ notification(StaticCString::create("notification")) {
}
diff --git a/core/core_string_names.h b/core/core_string_names.h
index a507a20935..42416d3f75 100644
--- a/core/core_string_names.h
+++ b/core/core_string_names.h
@@ -90,6 +90,11 @@ public:
StringName g8;
StringName b8;
StringName a8;
+
+ StringName call;
+ StringName call_deferred;
+ StringName emit;
+ StringName notification;
};
#endif // SCENE_STRING_NAMES_H
diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp
index 3bee34f8e4..793bf719b7 100644
--- a/core/crypto/crypto.cpp
+++ b/core/crypto/crypto.cpp
@@ -82,8 +82,8 @@ void Crypto::_bind_methods() {
ClassDB::bind_method(D_METHOD("generate_self_signed_certificate", "key", "issuer_name", "not_before", "not_after"), &Crypto::generate_self_signed_certificate, DEFVAL("CN=myserver,O=myorganisation,C=IT"), DEFVAL("20140101000000"), DEFVAL("20340101000000"));
}
-PoolByteArray Crypto::generate_random_bytes(int p_bytes) {
- ERR_FAIL_V_MSG(PoolByteArray(), "generate_random_bytes is not available when mbedtls module is disabled.");
+PackedByteArray Crypto::generate_random_bytes(int p_bytes) {
+ ERR_FAIL_V_MSG(PackedByteArray(), "generate_random_bytes is not available when mbedtls module is disabled.");
}
Ref<CryptoKey> Crypto::generate_rsa(int p_bytes) {
@@ -99,7 +99,7 @@ Crypto::Crypto() {
/// Resource loader/saver
-RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
String el = p_path.get_extension().to_lower();
if (el == "crt") {
diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h
index adc36255b6..3279c0620f 100644
--- a/core/crypto/crypto.h
+++ b/core/crypto/crypto.h
@@ -76,7 +76,7 @@ public:
static Crypto *create();
static void load_default_certificates(String p_path);
- virtual PoolByteArray generate_random_bytes(int p_bytes);
+ virtual PackedByteArray generate_random_bytes(int p_bytes);
virtual Ref<CryptoKey> generate_rsa(int p_bytes);
virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after);
@@ -87,7 +87,7 @@ class ResourceFormatLoaderCrypto : public ResourceFormatLoader {
GDCLASS(ResourceFormatLoaderCrypto, ResourceFormatLoader);
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/core/crypto/crypto_core.cpp b/core/crypto/crypto_core.cpp
index dec52d8ca4..ec25ee0d38 100644
--- a/core/crypto/crypto_core.cpp
+++ b/core/crypto/crypto_core.cpp
@@ -148,9 +148,9 @@ Error CryptoCore::AESContext::decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst
// CryptoCore
String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) {
int b64len = p_src_len / 3 * 4 + 4 + 1;
- PoolVector<uint8_t> b64buff;
+ Vector<uint8_t> b64buff;
b64buff.resize(b64len);
- PoolVector<uint8_t>::Write w64 = b64buff.write();
+ uint8_t *w64 = b64buff.ptrw();
size_t strlen = 0;
int ret = b64_encode(&w64[0], b64len, &strlen, p_src, p_src_len);
w64[strlen] = 0;
diff --git a/core/crypto/hashing_context.cpp b/core/crypto/hashing_context.cpp
index 7bee8f1200..a4d8a93c8a 100644
--- a/core/crypto/hashing_context.cpp
+++ b/core/crypto/hashing_context.cpp
@@ -47,11 +47,11 @@ Error HashingContext::start(HashType p_type) {
return ERR_UNAVAILABLE;
}
-Error HashingContext::update(PoolByteArray p_chunk) {
+Error HashingContext::update(PackedByteArray p_chunk) {
ERR_FAIL_COND_V(ctx == NULL, ERR_UNCONFIGURED);
size_t len = p_chunk.size();
ERR_FAIL_COND_V(len == 0, FAILED);
- PoolByteArray::Read r = p_chunk.read();
+ const uint8_t *r = p_chunk.ptr();
switch (type) {
case HASH_MD5:
return ((CryptoCore::MD5Context *)ctx)->update(&r[0], len);
@@ -63,26 +63,26 @@ Error HashingContext::update(PoolByteArray p_chunk) {
return ERR_UNAVAILABLE;
}
-PoolByteArray HashingContext::finish() {
- ERR_FAIL_COND_V(ctx == NULL, PoolByteArray());
- PoolByteArray out;
+PackedByteArray HashingContext::finish() {
+ ERR_FAIL_COND_V(ctx == NULL, PackedByteArray());
+ PackedByteArray out;
Error err = FAILED;
switch (type) {
case HASH_MD5:
out.resize(16);
- err = ((CryptoCore::MD5Context *)ctx)->finish(out.write().ptr());
+ err = ((CryptoCore::MD5Context *)ctx)->finish(out.ptrw());
break;
case HASH_SHA1:
out.resize(20);
- err = ((CryptoCore::SHA1Context *)ctx)->finish(out.write().ptr());
+ err = ((CryptoCore::SHA1Context *)ctx)->finish(out.ptrw());
break;
case HASH_SHA256:
out.resize(32);
- err = ((CryptoCore::SHA256Context *)ctx)->finish(out.write().ptr());
+ err = ((CryptoCore::SHA256Context *)ctx)->finish(out.ptrw());
break;
}
_delete_ctx();
- ERR_FAIL_COND_V(err != OK, PoolByteArray());
+ ERR_FAIL_COND_V(err != OK, PackedByteArray());
return out;
}
diff --git a/core/crypto/hashing_context.h b/core/crypto/hashing_context.h
index af6ed3aa0b..230ba7ee85 100644
--- a/core/crypto/hashing_context.h
+++ b/core/crypto/hashing_context.h
@@ -54,8 +54,8 @@ protected:
public:
Error start(HashType p_type);
- Error update(PoolByteArray p_chunk);
- PoolByteArray finish();
+ Error update(PackedByteArray p_chunk);
+ PackedByteArray finish();
HashingContext();
~HashingContext();
diff --git a/core/error_macros.h b/core/error_macros.h
index 4a3ea28957..e4d7609e04 100644
--- a/core/error_macros.h
+++ b/core/error_macros.h
@@ -502,11 +502,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
*
* The current function returns `m_retval`.
*/
-#define ERR_FAIL_V(m_retval) \
- if (1) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " __STR(m_value)); \
- return m_retval; \
- } else \
+#define ERR_FAIL_V(m_retval) \
+ if (1) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " __STR(m_retval)); \
+ return m_retval; \
+ } else \
((void)0)
/**
@@ -515,11 +515,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
*
* Prints `m_msg`, and the current function returns `m_retval`.
*/
-#define ERR_FAIL_V_MSG(m_retval, m_msg) \
- if (1) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " __STR(m_value), DEBUG_STR(m_msg)); \
- return m_retval; \
- } else \
+#define ERR_FAIL_V_MSG(m_retval, m_msg) \
+ if (1) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " __STR(m_retval), DEBUG_STR(m_msg)); \
+ return m_retval; \
+ } else \
((void)0)
/**
diff --git a/core/func_ref.cpp b/core/func_ref.cpp
index e20188c813..338c17946b 100644
--- a/core/func_ref.cpp
+++ b/core/func_ref.cpp
@@ -30,16 +30,16 @@
#include "func_ref.h"
-Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (id.is_null()) {
- r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
}
Object *obj = ObjectDB::get_instance(id);
if (!obj) {
- r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
}
diff --git a/core/func_ref.h b/core/func_ref.h
index 1d1ca47ad7..8cb3be6e61 100644
--- a/core/func_ref.h
+++ b/core/func_ref.h
@@ -43,7 +43,7 @@ protected:
static void _bind_methods();
public:
- Variant call_func(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ Variant call_func(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
Variant call_funcv(const Array &p_args);
void set_instance(Object *p_obj);
void set_function(const StringName &p_func);
diff --git a/core/global_constants.cpp b/core/global_constants.cpp
index e48556c064..0945240c1f 100644
--- a/core/global_constants.cpp
+++ b/core/global_constants.cpp
@@ -92,9 +92,6 @@ VARIANT_ENUM_CAST(JoystickList);
VARIANT_ENUM_CAST(MidiMessageList);
void register_global_constants() {
-
- //{ KEY_BACKSPACE, VK_BACK },// (0x08) // backspace
-
BIND_GLOBAL_ENUM_CONSTANT(MARGIN_LEFT);
BIND_GLOBAL_ENUM_CONSTANT(MARGIN_TOP);
BIND_GLOBAL_ENUM_CONSTANT(MARGIN_RIGHT);
@@ -116,7 +113,7 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT(VALIGN_CENTER);
BIND_GLOBAL_ENUM_CONSTANT(VALIGN_BOTTOM);
- // hueg list of keys
+ // huge list of keys
BIND_GLOBAL_CONSTANT(SPKEY);
BIND_GLOBAL_ENUM_CONSTANT(KEY_ESCAPE);
@@ -594,30 +591,38 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_BOOL", Variant::BOOL);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_INT", Variant::INT);
- BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_REAL", Variant::REAL);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_REAL", Variant::FLOAT);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_STRING", Variant::STRING);
- BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2", Variant::VECTOR2); // 5
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2", Variant::VECTOR2);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2I", Variant::VECTOR2I);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_RECT2", Variant::RECT2);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_RECT2I", Variant::RECT2I);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3", Variant::VECTOR3);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3I", Variant::VECTOR3I);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM2D", Variant::TRANSFORM2D);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_PLANE", Variant::PLANE);
- BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_QUAT", Variant::QUAT); // 10
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_QUAT", Variant::QUAT);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_AABB", Variant::AABB);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_BASIS", Variant::BASIS);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM", Variant::TRANSFORM);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_COLOR", Variant::COLOR);
- BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_NODE_PATH", Variant::NODE_PATH); // 15
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_STRING_NAME", Variant::STRING_NAME);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_NODE_PATH", Variant::NODE_PATH);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_RID", Variant::_RID);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_OBJECT", Variant::OBJECT);
- BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_DICTIONARY", Variant::DICTIONARY); // 20
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_CALLABLE", Variant::CALLABLE);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_SIGNAL", Variant::SIGNAL);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_DICTIONARY", Variant::DICTIONARY);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_ARRAY", Variant::ARRAY);
- BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_RAW_ARRAY", Variant::POOL_BYTE_ARRAY);
- BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_INT_ARRAY", Variant::POOL_INT_ARRAY);
- BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_REAL_ARRAY", Variant::POOL_REAL_ARRAY);
- BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_STRING_ARRAY", Variant::POOL_STRING_ARRAY);
- BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2_ARRAY", Variant::POOL_VECTOR2_ARRAY); // 25
- BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3_ARRAY", Variant::POOL_VECTOR3_ARRAY);
- BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_COLOR_ARRAY", Variant::POOL_COLOR_ARRAY);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_RAW_ARRAY", Variant::PACKED_BYTE_ARRAY);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_INT32_ARRAY", Variant::PACKED_INT32_ARRAY);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_INT64_ARRAY", Variant::PACKED_INT64_ARRAY);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_FLOAT32_ARRAY", Variant::PACKED_FLOAT32_ARRAY);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_FLOAT64_ARRAY", Variant::PACKED_FLOAT64_ARRAY);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_STRING_ARRAY", Variant::PACKED_STRING_ARRAY);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2_ARRAY", Variant::PACKED_VECTOR2_ARRAY);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3_ARRAY", Variant::PACKED_VECTOR3_ARRAY);
+ BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_COLOR_ARRAY", Variant::PACKED_COLOR_ARRAY);
BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_MAX", Variant::VARIANT_MAX);
//comparison
diff --git a/core/image.cpp b/core/image.cpp
index d9f84621a3..2c39c9b882 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -444,8 +444,6 @@ void Image::convert(Format p_new_format) {
if (p_new_format == format)
return;
- ERR_FAIL_COND_MSG(write_lock.ptr(), "Cannot convert image when it is locked.");
-
if (format > FORMAT_RGBE9995 || p_new_format > FORMAT_RGBE9995) {
ERR_FAIL_MSG("Cannot convert to <-> from compressed formats. Use compress() and decompress() instead.");
@@ -454,8 +452,6 @@ void Image::convert(Format p_new_format) {
//use put/set pixel which is slower but works with non byte formats
Image new_img(width, height, 0, p_new_format);
- lock();
- new_img.lock();
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
@@ -464,9 +460,6 @@ void Image::convert(Format p_new_format) {
}
}
- unlock();
- new_img.unlock();
-
if (has_mipmaps()) {
new_img.generate_mipmaps();
}
@@ -478,11 +471,8 @@ void Image::convert(Format p_new_format) {
Image new_img(width, height, 0, p_new_format);
- PoolVector<uint8_t>::Read r = data.read();
- PoolVector<uint8_t>::Write w = new_img.data.write();
-
- const uint8_t *rptr = r.ptr();
- uint8_t *wptr = w.ptr();
+ const uint8_t *rptr = data.ptr();
+ uint8_t *wptr = new_img.data.ptrw();
int conversion_type = format | p_new_format << 8;
@@ -520,9 +510,6 @@ void Image::convert(Format p_new_format) {
case FORMAT_RGBA8 | (FORMAT_RGB8 << 8): _convert<3, true, 3, false, false, false>(width, height, rptr, wptr); break;
}
- r.release();
- w.release();
-
bool gen_mipmaps = mipmaps;
_copy_internals_from(new_img);
@@ -906,7 +893,6 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
ERR_FAIL_COND_MSG(data.size() == 0, "Cannot resize image before creating it, use create() or create_from_data() first.");
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats.");
- ERR_FAIL_COND_MSG(write_lock.ptr(), "Cannot resize image when it is locked.");
bool mipmap_aware = p_interpolation == INTERPOLATE_TRILINEAR /* || p_interpolation == INTERPOLATE_TRICUBIC */;
@@ -948,11 +934,11 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
}
// --
- PoolVector<uint8_t>::Read r = data.read();
- const unsigned char *r_ptr = r.ptr();
+ const uint8_t *r = data.ptr();
+ const unsigned char *r_ptr = r;
- PoolVector<uint8_t>::Write w = dst.data.write();
- unsigned char *w_ptr = w.ptr();
+ uint8_t *w = dst.data.ptrw();
+ unsigned char *w_ptr = w;
switch (p_interpolation) {
@@ -1017,8 +1003,8 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
_get_mipmap_offset_and_size(mip2, offs, src_width, src_height);
src_ptr = r_ptr + offs;
// Switch to write to the second destination image
- w = dst2.data.write();
- w_ptr = w.ptr();
+ w = dst2.data.ptrw();
+ w_ptr = w;
}
}
@@ -1048,8 +1034,8 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
if (interpolate_mipmaps) {
// Switch to read again from the first scaled mipmap to overlay it over the second
- r = dst.data.read();
- _overlay(r.ptr(), w.ptr(), mip1_weight, p_width, p_height, get_format_pixel_size(format));
+ r = dst.data.ptr();
+ _overlay(r, w, mip1_weight, p_width, p_height, get_format_pixel_size(format));
}
} break;
@@ -1105,9 +1091,6 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
} break;
}
- r.release();
- w.release();
-
if (interpolate_mipmaps) {
dst._copy_internals_from(dst2);
}
@@ -1142,8 +1125,8 @@ void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
Image dst(p_width, p_height, 0, format);
{
- PoolVector<uint8_t>::Read r = data.read();
- PoolVector<uint8_t>::Write w = dst.data.write();
+ const uint8_t *r = data.ptr();
+ uint8_t *w = dst.data.ptrw();
int m_h = p_y + p_height;
int m_w = p_x + p_width;
@@ -1155,10 +1138,10 @@ void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
for (uint32_t i = 0; i < pixel_size; i++)
pdata[i] = 0;
} else {
- _get_pixelb(x, y, pixel_size, r.ptr(), pdata);
+ _get_pixelb(x, y, pixel_size, r, pdata);
}
- dst._put_pixelb(x - p_x, y - p_y, pixel_size, w.ptr(), pdata);
+ dst._put_pixelb(x - p_x, y - p_y, pixel_size, w, pdata);
}
}
}
@@ -1183,7 +1166,7 @@ void Image::flip_y() {
}
{
- PoolVector<uint8_t>::Write w = data.write();
+ uint8_t *w = data.ptrw();
uint8_t up[16];
uint8_t down[16];
uint32_t pixel_size = get_format_pixel_size(format);
@@ -1192,11 +1175,11 @@ void Image::flip_y() {
for (int x = 0; x < width; x++) {
- _get_pixelb(x, y, pixel_size, w.ptr(), up);
- _get_pixelb(x, height - y - 1, pixel_size, w.ptr(), down);
+ _get_pixelb(x, y, pixel_size, w, up);
+ _get_pixelb(x, height - y - 1, pixel_size, w, down);
- _put_pixelb(x, height - y - 1, pixel_size, w.ptr(), up);
- _put_pixelb(x, y, pixel_size, w.ptr(), down);
+ _put_pixelb(x, height - y - 1, pixel_size, w, up);
+ _put_pixelb(x, y, pixel_size, w, down);
}
}
}
@@ -1216,7 +1199,7 @@ void Image::flip_x() {
}
{
- PoolVector<uint8_t>::Write w = data.write();
+ uint8_t *w = data.ptrw();
uint8_t up[16];
uint8_t down[16];
uint32_t pixel_size = get_format_pixel_size(format);
@@ -1225,11 +1208,11 @@ void Image::flip_x() {
for (int x = 0; x < width / 2; x++) {
- _get_pixelb(x, y, pixel_size, w.ptr(), up);
- _get_pixelb(width - x - 1, y, pixel_size, w.ptr(), down);
+ _get_pixelb(x, y, pixel_size, w, up);
+ _get_pixelb(width - x - 1, y, pixel_size, w, down);
- _put_pixelb(width - x - 1, y, pixel_size, w.ptr(), up);
- _put_pixelb(x, y, pixel_size, w.ptr(), down);
+ _put_pixelb(width - x - 1, y, pixel_size, w, up);
+ _put_pixelb(x, y, pixel_size, w, down);
}
}
}
@@ -1348,16 +1331,16 @@ void Image::expand_x2_hq2x() {
if (current != FORMAT_RGBA8)
convert(FORMAT_RGBA8);
- PoolVector<uint8_t> dest;
+ Vector<uint8_t> dest;
dest.resize(width * 2 * height * 2 * 4);
{
- PoolVector<uint8_t>::Read r = data.read();
- PoolVector<uint8_t>::Write w = dest.write();
+ const uint8_t *r = data.ptr();
+ uint8_t *w = dest.ptrw();
- ERR_FAIL_COND(!r.ptr());
+ ERR_FAIL_COND(!r);
- hq2x_resize((const uint32_t *)r.ptr(), width, height, (uint32_t *)w.ptr());
+ hq2x_resize((const uint32_t *)r, width, height, (uint32_t *)w);
}
width *= 2;
@@ -1381,7 +1364,7 @@ void Image::shrink_x2() {
if (mipmaps) {
//just use the lower mipmap as base and copy all
- PoolVector<uint8_t> new_img;
+ Vector<uint8_t> new_img;
int ofs = get_mipmap_offset(1);
@@ -1390,10 +1373,10 @@ void Image::shrink_x2() {
ERR_FAIL_COND(new_img.size() == 0);
{
- PoolVector<uint8_t>::Write w = new_img.write();
- PoolVector<uint8_t>::Read r = data.read();
+ uint8_t *w = new_img.ptrw();
+ const uint8_t *r = data.ptr();
- copymem(w.ptr(), &r[ofs], new_size);
+ copymem(w, &r[ofs], new_size);
}
width = MAX(width / 2, 1);
@@ -1402,7 +1385,7 @@ void Image::shrink_x2() {
} else {
- PoolVector<uint8_t> new_img;
+ Vector<uint8_t> new_img;
ERR_FAIL_COND(!_can_modify(format));
int ps = get_format_pixel_size(format);
@@ -1411,29 +1394,29 @@ void Image::shrink_x2() {
ERR_FAIL_COND(data.size() == 0);
{
- PoolVector<uint8_t>::Write w = new_img.write();
- PoolVector<uint8_t>::Read r = data.read();
+ uint8_t *w = new_img.ptrw();
+ const uint8_t *r = data.ptr();
switch (format) {
case FORMAT_L8:
- case FORMAT_R8: _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break;
- case FORMAT_LA8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break;
- case FORMAT_RG8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break;
- case FORMAT_RGB8: _generate_po2_mipmap<uint8_t, 3, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break;
- case FORMAT_RGBA8: _generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(r.ptr(), w.ptr(), width, height); break;
-
- case FORMAT_RF: _generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r.ptr()), reinterpret_cast<float *>(w.ptr()), width, height); break;
- case FORMAT_RGF: _generate_po2_mipmap<float, 2, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r.ptr()), reinterpret_cast<float *>(w.ptr()), width, height); break;
- case FORMAT_RGBF: _generate_po2_mipmap<float, 3, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r.ptr()), reinterpret_cast<float *>(w.ptr()), width, height); break;
- case FORMAT_RGBAF: _generate_po2_mipmap<float, 4, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r.ptr()), reinterpret_cast<float *>(w.ptr()), width, height); break;
-
- case FORMAT_RH: _generate_po2_mipmap<uint16_t, 1, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r.ptr()), reinterpret_cast<uint16_t *>(w.ptr()), width, height); break;
- case FORMAT_RGH: _generate_po2_mipmap<uint16_t, 2, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r.ptr()), reinterpret_cast<uint16_t *>(w.ptr()), width, height); break;
- case FORMAT_RGBH: _generate_po2_mipmap<uint16_t, 3, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r.ptr()), reinterpret_cast<uint16_t *>(w.ptr()), width, height); break;
- case FORMAT_RGBAH: _generate_po2_mipmap<uint16_t, 4, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r.ptr()), reinterpret_cast<uint16_t *>(w.ptr()), width, height); break;
-
- case FORMAT_RGBE9995: _generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(r.ptr()), reinterpret_cast<uint32_t *>(w.ptr()), width, height); break;
+ case FORMAT_R8: _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
+ case FORMAT_LA8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
+ case FORMAT_RG8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
+ case FORMAT_RGB8: _generate_po2_mipmap<uint8_t, 3, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
+ case FORMAT_RGBA8: _generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
+
+ case FORMAT_RF: _generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height); break;
+ case FORMAT_RGF: _generate_po2_mipmap<float, 2, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height); break;
+ case FORMAT_RGBF: _generate_po2_mipmap<float, 3, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height); break;
+ case FORMAT_RGBAF: _generate_po2_mipmap<float, 4, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height); break;
+
+ case FORMAT_RH: _generate_po2_mipmap<uint16_t, 1, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height); break;
+ case FORMAT_RGH: _generate_po2_mipmap<uint16_t, 2, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height); break;
+ case FORMAT_RGBH: _generate_po2_mipmap<uint16_t, 3, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height); break;
+ case FORMAT_RGBAH: _generate_po2_mipmap<uint16_t, 4, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height); break;
+
+ case FORMAT_RGBE9995: _generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(r), reinterpret_cast<uint32_t *>(w), width, height); break;
default: {
}
}
@@ -1452,8 +1435,6 @@ void Image::normalize() {
clear_mipmaps();
}
- lock();
-
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
@@ -1468,8 +1449,6 @@ void Image::normalize() {
}
}
- unlock();
-
if (used_mipmaps) {
generate_mipmaps(true);
}
@@ -1479,6 +1458,8 @@ Error Image::generate_mipmaps(bool p_renormalize) {
ERR_FAIL_COND_V_MSG(!_can_modify(format), ERR_UNAVAILABLE, "Cannot generate mipmaps in compressed or custom image formats.");
+ ERR_FAIL_COND_V_MSG(format == FORMAT_RGBA4444, ERR_UNAVAILABLE, "Cannot generate mipmaps from RGBA4444 format.");
+
ERR_FAIL_COND_V_MSG(width == 0 || height == 0, ERR_UNCONFIGURED, "Cannot generate mipmaps with width or height equal to 0.");
int mmcount;
@@ -1487,7 +1468,7 @@ Error Image::generate_mipmaps(bool p_renormalize) {
data.resize(size);
- PoolVector<uint8_t>::Write wp = data.write();
+ uint8_t *wp = data.ptrw();
int prev_ofs = 0;
int prev_h = height;
@@ -1599,7 +1580,6 @@ Error Image::generate_mipmap_roughness(RoughnessChannel p_roughness_channel, con
normal_sat = normal_sat_vec.ptrw();
//create summed area table
- nm->lock();
for (int y = 0; y < normal_h; y++) {
double line_sum[3] = { 0, 0, 0 };
@@ -1642,9 +1622,7 @@ Error Image::generate_mipmap_roughness(RoughnessChannel p_roughness_channel, con
_get_dst_image_size(width, height, format, mmcount);
- lock();
-
- uint8_t *base_ptr = write_lock.ptr();
+ uint8_t *base_ptr = data.ptrw();
for (int i = 1; i <= mmcount; i++) {
@@ -1759,11 +1737,13 @@ Error Image::generate_mipmap_roughness(RoughnessChannel p_roughness_channel, con
{
int size = get_mipmap_byte_size(i);
print_line("size for mimpap " + itos(i) + ": " + itos(size));
- PoolVector<uint8_t> imgdata;
+ Vector<uint8_t> imgdata;
imgdata.resize(size);
- PoolVector<uint8_t>::Write wr = imgdata.write();
+
+
+ uint8_t* wr = imgdata.ptrw();
copymem(wr.ptr(), ptr, size);
- wr = PoolVector<uint8_t>::Write();
+ wr = uint8_t*();
Ref<Image> im;
im.instance();
im->create(w, h, false, format, imgdata);
@@ -1772,9 +1752,6 @@ Error Image::generate_mipmap_roughness(RoughnessChannel p_roughness_channel, con
#endif
}
- unlock();
- nm->unlock();
-
return OK;
}
@@ -1798,7 +1775,7 @@ bool Image::empty() const {
return (data.size() == 0);
}
-PoolVector<uint8_t> Image::get_data() const {
+Vector<uint8_t> Image::get_data() const {
return data;
}
@@ -1812,9 +1789,10 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma
int mm = 0;
int size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0);
data.resize(size);
+
{
- PoolVector<uint8_t>::Write w = data.write();
- zeromem(w.ptr(), size);
+ uint8_t *w = data.ptrw();
+ zeromem(w, size);
}
width = p_width;
@@ -1823,7 +1801,7 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma
format = p_format;
}
-void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const PoolVector<uint8_t> &p_data) {
+void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) {
ERR_FAIL_INDEX(p_width - 1, MAX_WIDTH);
ERR_FAIL_INDEX(p_height - 1, MAX_HEIGHT);
@@ -1838,6 +1816,7 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma
width = p_width;
format = p_format;
data = p_data;
+
mipmaps = p_use_mipmaps;
}
@@ -1862,7 +1841,7 @@ void Image::create(const char **p_xpm) {
HashMap<String, Color> colormap;
int colormap_size = 0;
uint32_t pixel_size = 0;
- PoolVector<uint8_t>::Write w;
+ uint8_t *w;
while (status != DONE) {
@@ -1953,7 +1932,7 @@ void Image::create(const char **p_xpm) {
status = READING_PIXELS;
create(size_width, size_height, 0, has_alpha ? FORMAT_RGBA8 : FORMAT_RGB8);
- w = data.write();
+ w = data.ptrw();
pixel_size = has_alpha ? 4 : 3;
}
} break;
@@ -1972,7 +1951,7 @@ void Image::create(const char **p_xpm) {
for (uint32_t i = 0; i < pixel_size; i++) {
pixel[i] = CLAMP((*colorptr)[i] * 255, 0, 255);
}
- _put_pixelb(x, y, pixel_size, w.ptr(), pixel);
+ _put_pixelb(x, y, pixel_size, w, pixel);
}
if (y == (size_height - 1))
@@ -2024,8 +2003,8 @@ bool Image::is_invisible() const {
int w, h;
_get_mipmap_offset_and_size(1, len, w, h);
- PoolVector<uint8_t>::Read r = data.read();
- const unsigned char *data_ptr = r.ptr();
+ const uint8_t *r = data.ptr();
+ const unsigned char *data_ptr = r;
bool detected = false;
@@ -2069,8 +2048,8 @@ Image::AlphaMode Image::detect_alpha() const {
int w, h;
_get_mipmap_offset_and_size(1, len, w, h);
- PoolVector<uint8_t>::Read r = data.read();
- const unsigned char *data_ptr = r.ptr();
+ const uint8_t *r = data.ptr();
+ const unsigned char *data_ptr = r;
bool bit = false;
bool detected = false;
@@ -2126,9 +2105,9 @@ Error Image::save_png(const String &p_path) const {
return save_png_func(p_path, Ref<Image>((Image *)this));
}
-PoolVector<uint8_t> Image::save_png_to_buffer() const {
+Vector<uint8_t> Image::save_png_to_buffer() const {
if (save_png_buffer_func == NULL) {
- return PoolVector<uint8_t>();
+ return Vector<uint8_t>();
}
return save_png_buffer_func(Ref<Image>((Image *)this));
@@ -2266,7 +2245,7 @@ Image::Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
create(p_width, p_height, p_use_mipmaps, p_format);
}
-Image::Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const PoolVector<uint8_t> &p_data) {
+Image::Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const Vector<uint8_t> &p_data) {
width = 0;
height = 0;
@@ -2286,7 +2265,6 @@ Rect2 Image::get_used_rect() const {
if (len == 0)
return Rect2();
- const_cast<Image *>(this)->lock();
int minx = 0xFFFFFF, miny = 0xFFFFFFF;
int maxx = -1, maxy = -1;
for (int j = 0; j < height; j++) {
@@ -2305,8 +2283,6 @@ Rect2 Image::get_used_rect() const {
}
}
- const_cast<Image *>(this)->unlock();
-
if (maxx == -1)
return Rect2();
else
@@ -2343,11 +2319,11 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
- PoolVector<uint8_t>::Write wp = data.write();
- uint8_t *dst_data_ptr = wp.ptr();
+ uint8_t *wp = data.ptrw();
+ uint8_t *dst_data_ptr = wp;
- PoolVector<uint8_t>::Read rp = p_src->data.read();
- const uint8_t *src_data_ptr = rp.ptr();
+ const uint8_t *rp = p_src->data.ptr();
+ const uint8_t *src_data_ptr = rp;
int pixel_size = get_format_pixel_size(format);
@@ -2398,16 +2374,15 @@ void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, co
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
- PoolVector<uint8_t>::Write wp = data.write();
- uint8_t *dst_data_ptr = wp.ptr();
+ uint8_t *wp = data.ptrw();
+ uint8_t *dst_data_ptr = wp;
- PoolVector<uint8_t>::Read rp = p_src->data.read();
- const uint8_t *src_data_ptr = rp.ptr();
+ const uint8_t *rp = p_src->data.ptr();
+ const uint8_t *src_data_ptr = rp;
int pixel_size = get_format_pixel_size(format);
Ref<Image> msk = p_mask;
- msk->lock();
for (int i = 0; i < dest_rect.size.y; i++) {
@@ -2430,8 +2405,6 @@ void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, co
}
}
}
-
- msk->unlock();
}
void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
@@ -2456,9 +2429,7 @@ void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const P
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
- lock();
Ref<Image> img = p_src;
- img->lock();
for (int i = 0; i < dest_rect.size.y; i++) {
@@ -2479,9 +2450,6 @@ void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const P
set_pixel(dst_x, dst_y, dc);
}
}
-
- img->unlock();
- unlock();
}
void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) {
@@ -2511,11 +2479,8 @@ void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, c
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
- lock();
Ref<Image> img = p_src;
Ref<Image> msk = p_mask;
- img->lock();
- msk->lock();
for (int i = 0; i < dest_rect.size.y; i++) {
@@ -2542,19 +2507,13 @@ void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, c
}
}
}
-
- msk->unlock();
- img->unlock();
- unlock();
}
void Image::fill(const Color &c) {
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill in compressed or custom image formats.");
- lock();
-
- PoolVector<uint8_t>::Write wp = data.write();
- uint8_t *dst_data_ptr = wp.ptr();
+ uint8_t *wp = data.ptrw();
+ uint8_t *dst_data_ptr = wp;
int pixel_size = get_format_pixel_size(format);
@@ -2572,8 +2531,6 @@ void Image::fill(const Color &c) {
}
}
}
-
- unlock();
}
ImageMemLoadFunc Image::_png_mem_loader_func = NULL;
@@ -2592,12 +2549,12 @@ void (*Image::_image_decompress_bptc)(Image *) = NULL;
void (*Image::_image_decompress_etc1)(Image *) = NULL;
void (*Image::_image_decompress_etc2)(Image *) = NULL;
-PoolVector<uint8_t> (*Image::lossy_packer)(const Ref<Image> &, float) = NULL;
-Ref<Image> (*Image::lossy_unpacker)(const PoolVector<uint8_t> &) = NULL;
-PoolVector<uint8_t> (*Image::lossless_packer)(const Ref<Image> &) = NULL;
-Ref<Image> (*Image::lossless_unpacker)(const PoolVector<uint8_t> &) = NULL;
-PoolVector<uint8_t> (*Image::basis_universal_packer)(const Ref<Image> &, Image::UsedChannels) = NULL;
-Ref<Image> (*Image::basis_universal_unpacker)(const PoolVector<uint8_t> &) = NULL;
+Vector<uint8_t> (*Image::lossy_packer)(const Ref<Image> &, float) = NULL;
+Ref<Image> (*Image::lossy_unpacker)(const Vector<uint8_t> &) = NULL;
+Vector<uint8_t> (*Image::lossless_packer)(const Ref<Image> &) = NULL;
+Ref<Image> (*Image::lossless_unpacker)(const Vector<uint8_t> &) = NULL;
+Vector<uint8_t> (*Image::basis_universal_packer)(const Ref<Image> &, Image::UsedChannels) = NULL;
+Ref<Image> (*Image::basis_universal_unpacker)(const Vector<uint8_t> &) = NULL;
void Image::_set_data(const Dictionary &p_data) {
@@ -2611,7 +2568,7 @@ void Image::_set_data(const Dictionary &p_data) {
int dheight = p_data["height"];
String dformat = p_data["format"];
bool dmipmaps = p_data["mipmaps"];
- PoolVector<uint8_t> ddata = p_data["data"];
+ Vector<uint8_t> ddata = p_data["data"];
Format ddformat = FORMAT_MAX;
for (int i = 0; i < FORMAT_MAX; i++) {
if (dformat == get_format_name(Format(i))) {
@@ -2636,22 +2593,11 @@ Dictionary Image::_get_data() const {
return d;
}
-void Image::lock() {
-
- ERR_FAIL_COND(data.size() == 0);
- write_lock = data.write();
-}
-
-void Image::unlock() {
-
- write_lock.release();
-}
-
Color Image::get_pixelv(const Point2 &p_src) const {
return get_pixel(p_src.x, p_src.y);
}
-Color Image::_get_color_at_ofs(uint8_t *ptr, uint32_t ofs) const {
+Color Image::_get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const {
switch (format) {
case FORMAT_L8: {
@@ -2873,18 +2819,13 @@ void Image::_set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color)
}
Color Image::get_pixel(int p_x, int p_y) const {
-
- uint8_t *ptr = write_lock.ptr();
#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_V_MSG(!ptr, Color(), "Image must be locked with 'lock()' before using get_pixel().");
-
ERR_FAIL_INDEX_V(p_x, width, Color());
ERR_FAIL_INDEX_V(p_y, height, Color());
-
#endif
uint32_t ofs = p_y * width + p_x;
- return _get_color_at_ofs(ptr, ofs);
+ return _get_color_at_ofs(data.ptr(), ofs);
}
void Image::set_pixelv(const Point2 &p_dst, const Color &p_color) {
@@ -2892,18 +2833,13 @@ void Image::set_pixelv(const Point2 &p_dst, const Color &p_color) {
}
void Image::set_pixel(int p_x, int p_y, const Color &p_color) {
-
- uint8_t *ptr = write_lock.ptr();
#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_MSG(!ptr, "Image must be locked with 'lock()' before using set_pixel().");
-
ERR_FAIL_INDEX(p_x, width);
ERR_FAIL_INDEX(p_y, height);
-
#endif
uint32_t ofs = p_y * width + p_x;
- _set_color_at_ofs(ptr, ofs, p_color);
+ _set_color_at_ofs(data.ptrw(), ofs, p_color);
}
Image::UsedChannels Image::detect_used_channels(CompressSource p_source) {
@@ -2911,7 +2847,7 @@ Image::UsedChannels Image::detect_used_channels(CompressSource p_source) {
ERR_FAIL_COND_V(data.size() == 0, USED_CHANNELS_RGBA);
ERR_FAIL_COND_V(is_compressed(), USED_CHANNELS_RGBA);
bool r = false, g = false, b = false, a = false, c = false;
- lock();
+
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
@@ -2932,8 +2868,6 @@ Image::UsedChannels Image::detect_used_channels(CompressSource p_source) {
}
}
- unlock();
-
UsedChannels used_channels;
if (!c && !a)
@@ -3036,8 +2970,6 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_data", "data"), &Image::_set_data);
ClassDB::bind_method(D_METHOD("_get_data"), &Image::_get_data);
- ClassDB::bind_method(D_METHOD("lock"), &Image::lock);
- ClassDB::bind_method(D_METHOD("unlock"), &Image::unlock);
ClassDB::bind_method(D_METHOD("get_pixelv", "src"), &Image::get_pixelv);
ClassDB::bind_method(D_METHOD("get_pixel", "x", "y"), &Image::get_pixel);
ClassDB::bind_method(D_METHOD("set_pixelv", "dst", "color"), &Image::set_pixelv);
@@ -3137,8 +3069,7 @@ void Image::normalmap_to_xy() {
{
int len = data.size() / 4;
- PoolVector<uint8_t>::Write wp = data.write();
- unsigned char *data_ptr = wp.ptr();
+ uint8_t *data_ptr = data.ptrw();
for (int i = 0; i < len; i++) {
@@ -3162,19 +3093,12 @@ Ref<Image> Image::rgbe_to_srgb() {
new_image.instance();
new_image->create(width, height, 0, Image::FORMAT_RGB8);
- lock();
-
- new_image->lock();
-
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
new_image->set_pixel(col, row, get_pixel(col, row).to_srgb());
}
}
- unlock();
- new_image->unlock();
-
if (has_mipmaps()) {
new_image->generate_mipmaps();
}
@@ -3187,12 +3111,13 @@ Ref<Image> Image::get_image_from_mipmap(int p_mipamp) const {
int ofs, size, w, h;
get_mipmap_offset_size_and_dimensions(p_mipamp, ofs, size, w, h);
- PoolVector<uint8_t> new_data;
+ Vector<uint8_t> new_data;
new_data.resize(size);
+
{
- PoolVector<uint8_t>::Write wr = new_data.write();
- PoolVector<uint8_t>::Read rd = data.read();
- copymem(wr.ptr(), rd.ptr() + ofs, size);
+ uint8_t *wr = new_data.ptrw();
+ const uint8_t *rd = data.ptr();
+ copymem(wr, rd + ofs, size);
}
Ref<Image> image;
@@ -3201,6 +3126,7 @@ Ref<Image> Image::get_image_from_mipmap(int p_mipamp) const {
image->height = h;
image->format = format;
image->data = new_data;
+
image->mipmaps = false;
return image;
}
@@ -3209,17 +3135,17 @@ void Image::bumpmap_to_normalmap(float bump_scale) {
ERR_FAIL_COND(!_can_modify(format));
convert(Image::FORMAT_RF);
- PoolVector<uint8_t> result_image; //rgba output
+ Vector<uint8_t> result_image; //rgba output
result_image.resize(width * height * 4);
{
- PoolVector<uint8_t>::Read rp = data.read();
- PoolVector<uint8_t>::Write wp = result_image.write();
+ const uint8_t *rp = data.ptr();
+ uint8_t *wp = result_image.ptrw();
- ERR_FAIL_COND(!rp.ptr());
+ ERR_FAIL_COND(!rp);
- unsigned char *write_ptr = wp.ptr();
- float *read_ptr = (float *)rp.ptr();
+ unsigned char *write_ptr = wp;
+ float *read_ptr = (float *)rp;
for (int ty = 0; ty < height; ty++) {
int py = ty + 1;
@@ -3260,8 +3186,7 @@ void Image::srgb_to_linear() {
if (format == FORMAT_RGBA8) {
int len = data.size() / 4;
- PoolVector<uint8_t>::Write wp = data.write();
- unsigned char *data_ptr = wp.ptr();
+ uint8_t *data_ptr = data.ptrw();
for (int i = 0; i < len; i++) {
@@ -3273,8 +3198,7 @@ void Image::srgb_to_linear() {
} else if (format == FORMAT_RGB8) {
int len = data.size() / 3;
- PoolVector<uint8_t>::Write wp = data.write();
- unsigned char *data_ptr = wp.ptr();
+ uint8_t *data_ptr = data.ptrw();
for (int i = 0; i < len; i++) {
@@ -3293,8 +3217,7 @@ void Image::premultiply_alpha() {
if (format != FORMAT_RGBA8)
return; //not needed
- PoolVector<uint8_t>::Write wp = data.write();
- unsigned char *data_ptr = wp.ptr();
+ uint8_t *data_ptr = data.ptrw();
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
@@ -3316,12 +3239,10 @@ void Image::fix_alpha_edges() {
if (format != FORMAT_RGBA8)
return; //not needed
- PoolVector<uint8_t> dcopy = data;
- PoolVector<uint8_t>::Read rp = dcopy.read();
- const uint8_t *srcptr = rp.ptr();
+ Vector<uint8_t> dcopy = data;
+ const uint8_t *srcptr = dcopy.ptr();
- PoolVector<uint8_t>::Write wp = data.write();
- unsigned char *data_ptr = wp.ptr();
+ uint8_t *data_ptr = data.ptrw();
const int max_radius = 4;
const int alpha_threshold = 20;
@@ -3381,15 +3302,15 @@ String Image::get_format_name(Format p_format) {
return format_names[p_format];
}
-Error Image::load_png_from_buffer(const PoolVector<uint8_t> &p_array) {
+Error Image::load_png_from_buffer(const Vector<uint8_t> &p_array) {
return _load_from_buffer(p_array, _png_mem_loader_func);
}
-Error Image::load_jpg_from_buffer(const PoolVector<uint8_t> &p_array) {
+Error Image::load_jpg_from_buffer(const Vector<uint8_t> &p_array) {
return _load_from_buffer(p_array, _jpg_mem_loader_func);
}
-Error Image::load_webp_from_buffer(const PoolVector<uint8_t> &p_array) {
+Error Image::load_webp_from_buffer(const Vector<uint8_t> &p_array) {
return _load_from_buffer(p_array, _webp_mem_loader_func);
}
@@ -3398,7 +3319,7 @@ void Image::convert_rg_to_ra_rgba8() {
ERR_FAIL_COND(!data.size());
int s = data.size();
- PoolVector<uint8_t>::Write w = data.write();
+ uint8_t *w = data.ptrw();
for (int i = 0; i < s; i += 4) {
w[i + 3] = w[i + 1];
w[i + 1] = 0;
@@ -3410,7 +3331,7 @@ void Image::convert_ra_rgba8_to_rg() {
ERR_FAIL_COND(!data.size());
int s = data.size();
- PoolVector<uint8_t>::Write w = data.write();
+ uint8_t *w = data.ptrw();
for (int i = 0; i < s; i += 4) {
w[i + 1] = w[i + 3];
w[i + 2] = 0;
@@ -3418,15 +3339,15 @@ void Image::convert_ra_rgba8_to_rg() {
}
}
-Error Image::_load_from_buffer(const PoolVector<uint8_t> &p_array, ImageMemLoadFunc p_loader) {
+Error Image::_load_from_buffer(const Vector<uint8_t> &p_array, ImageMemLoadFunc p_loader) {
int buffer_size = p_array.size();
ERR_FAIL_COND_V(buffer_size == 0, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(!p_loader, ERR_INVALID_PARAMETER);
- PoolVector<uint8_t>::Read r = p_array.read();
+ const uint8_t *r = p_array.ptr();
- Ref<Image> image = p_loader(r.ptr(), buffer_size);
+ Ref<Image> image = p_loader(r, buffer_size);
ERR_FAIL_COND_V(!image.is_valid(), ERR_PARSE_ERROR);
copy_internals_from(image);
@@ -3516,8 +3437,4 @@ Image::Image() {
}
Image::~Image() {
-
- if (write_lock.ptr()) {
- unlock();
- }
}
diff --git a/core/image.h b/core/image.h
index 1cc22420d5..4dc4bf1328 100644
--- a/core/image.h
+++ b/core/image.h
@@ -33,7 +33,7 @@
#include "core/color.h"
#include "core/math/rect2.h"
-#include "core/pool_vector.h"
+
#include "core/resource.h"
/**
@@ -47,7 +47,7 @@
class Image;
typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img);
-typedef PoolVector<uint8_t> (*SavePNGBufferFunc)(const Ref<Image> &p_img);
+typedef Vector<uint8_t> (*SavePNGBufferFunc)(const Ref<Image> &p_img);
typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size);
typedef Error (*SaveEXRFunc)(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
@@ -150,16 +150,14 @@ public:
static void (*_image_decompress_etc1)(Image *);
static void (*_image_decompress_etc2)(Image *);
- static PoolVector<uint8_t> (*lossy_packer)(const Ref<Image> &p_image, float p_quality);
- static Ref<Image> (*lossy_unpacker)(const PoolVector<uint8_t> &p_buffer);
- static PoolVector<uint8_t> (*lossless_packer)(const Ref<Image> &p_image);
- static Ref<Image> (*lossless_unpacker)(const PoolVector<uint8_t> &p_buffer);
- static PoolVector<uint8_t> (*basis_universal_packer)(const Ref<Image> &p_image, UsedChannels p_channels);
- static Ref<Image> (*basis_universal_unpacker)(const PoolVector<uint8_t> &p_buffer);
-
- PoolVector<uint8_t>::Write write_lock;
+ static Vector<uint8_t> (*lossy_packer)(const Ref<Image> &p_image, float p_quality);
+ static Ref<Image> (*lossy_unpacker)(const Vector<uint8_t> &p_buffer);
+ static Vector<uint8_t> (*lossless_packer)(const Ref<Image> &p_image);
+ static Ref<Image> (*lossless_unpacker)(const Vector<uint8_t> &p_buffer);
+ static Vector<uint8_t> (*basis_universal_packer)(const Ref<Image> &p_image, UsedChannels p_channels);
+ static Ref<Image> (*basis_universal_unpacker)(const Vector<uint8_t> &p_buffer);
- _FORCE_INLINE_ Color _get_color_at_ofs(uint8_t *ptr, uint32_t ofs) const;
+ _FORCE_INLINE_ Color _get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const;
_FORCE_INLINE_ void _set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color);
protected:
@@ -170,12 +168,12 @@ private:
create(p_width, p_height, p_use_mipmaps, p_format);
}
- void _create_from_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const PoolVector<uint8_t> &p_data) {
+ void _create_from_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) {
create(p_width, p_height, p_use_mipmaps, p_format, p_data);
}
Format format;
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
int width, height;
bool mipmaps;
@@ -198,7 +196,7 @@ private:
void _set_data(const Dictionary &p_data);
Dictionary _get_data() const;
- Error _load_from_buffer(const PoolVector<uint8_t> &p_array, ImageMemLoadFunc p_loader);
+ Error _load_from_buffer(const Vector<uint8_t> &p_array, ImageMemLoadFunc p_loader);
static void average_4_uint8(uint8_t &p_out, const uint8_t &p_a, const uint8_t &p_b, const uint8_t &p_c, const uint8_t &p_d);
static void average_4_float(float &p_out, const float &p_a, const float &p_b, const float &p_c, const float &p_d);
@@ -270,7 +268,7 @@ public:
* Create a new image of a given size and format. Current image will be lost
*/
void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
- void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const PoolVector<uint8_t> &p_data);
+ void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data);
void create(const char **p_xpm);
/**
@@ -278,11 +276,11 @@ public:
*/
bool empty() const;
- PoolVector<uint8_t> get_data() const;
+ Vector<uint8_t> get_data() const;
Error load(const String &p_path);
Error save_png(const String &p_path) const;
- PoolVector<uint8_t> save_png_to_buffer() const;
+ Vector<uint8_t> save_png_to_buffer() const;
Error save_exr(const String &p_path, bool p_grayscale) const;
/**
@@ -296,7 +294,7 @@ public:
/**
* import an image of a specific size and format from a pointer
*/
- Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const PoolVector<uint8_t> &p_data);
+ Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const Vector<uint8_t> &p_data);
enum AlphaMode {
ALPHA_NONE,
@@ -358,9 +356,9 @@ public:
static void set_compress_bptc_func(void (*p_compress_func)(Image *, float, UsedChannels));
static String get_format_name(Format p_format);
- Error load_png_from_buffer(const PoolVector<uint8_t> &p_array);
- Error load_jpg_from_buffer(const PoolVector<uint8_t> &p_array);
- Error load_webp_from_buffer(const PoolVector<uint8_t> &p_array);
+ Error load_png_from_buffer(const Vector<uint8_t> &p_array);
+ Error load_jpg_from_buffer(const Vector<uint8_t> &p_array);
+ Error load_webp_from_buffer(const Vector<uint8_t> &p_array);
void convert_rg_to_ra_rgba8();
void convert_ra_rgba8_to_rg();
@@ -370,9 +368,6 @@ public:
virtual Ref<Resource> duplicate(bool p_subresources = false) const;
- void lock();
- void unlock();
-
UsedChannels detect_used_channels(CompressSource p_source = COMPRESS_SOURCE_GENERIC);
void optimize_channels();
diff --git a/core/input_map.cpp b/core/input_map.cpp
index 36a0e88ae0..b855e14e0d 100644
--- a/core/input_map.cpp
+++ b/core/input_map.cpp
@@ -256,76 +256,76 @@ void InputMap::load_default() {
add_action("ui_accept");
key.instance();
- key->set_scancode(KEY_ENTER);
+ key->set_keycode(KEY_ENTER);
action_add_event("ui_accept", key);
key.instance();
- key->set_scancode(KEY_KP_ENTER);
+ key->set_keycode(KEY_KP_ENTER);
action_add_event("ui_accept", key);
key.instance();
- key->set_scancode(KEY_SPACE);
+ key->set_keycode(KEY_SPACE);
action_add_event("ui_accept", key);
add_action("ui_select");
key.instance();
- key->set_scancode(KEY_SPACE);
+ key->set_keycode(KEY_SPACE);
action_add_event("ui_select", key);
add_action("ui_cancel");
key.instance();
- key->set_scancode(KEY_ESCAPE);
+ key->set_keycode(KEY_ESCAPE);
action_add_event("ui_cancel", key);
add_action("ui_focus_next");
key.instance();
- key->set_scancode(KEY_TAB);
+ key->set_keycode(KEY_TAB);
action_add_event("ui_focus_next", key);
add_action("ui_focus_prev");
key.instance();
- key->set_scancode(KEY_TAB);
+ key->set_keycode(KEY_TAB);
key->set_shift(true);
action_add_event("ui_focus_prev", key);
add_action("ui_left");
key.instance();
- key->set_scancode(KEY_LEFT);
+ key->set_keycode(KEY_LEFT);
action_add_event("ui_left", key);
add_action("ui_right");
key.instance();
- key->set_scancode(KEY_RIGHT);
+ key->set_keycode(KEY_RIGHT);
action_add_event("ui_right", key);
add_action("ui_up");
key.instance();
- key->set_scancode(KEY_UP);
+ key->set_keycode(KEY_UP);
action_add_event("ui_up", key);
add_action("ui_down");
key.instance();
- key->set_scancode(KEY_DOWN);
+ key->set_keycode(KEY_DOWN);
action_add_event("ui_down", key);
add_action("ui_page_up");
key.instance();
- key->set_scancode(KEY_PAGEUP);
+ key->set_keycode(KEY_PAGEUP);
action_add_event("ui_page_up", key);
add_action("ui_page_down");
key.instance();
- key->set_scancode(KEY_PAGEDOWN);
+ key->set_keycode(KEY_PAGEDOWN);
action_add_event("ui_page_down", key);
add_action("ui_home");
key.instance();
- key->set_scancode(KEY_HOME);
+ key->set_keycode(KEY_HOME);
action_add_event("ui_home", key);
add_action("ui_end");
key.instance();
- key->set_scancode(KEY_END);
+ key->set_keycode(KEY_END);
action_add_event("ui_end", key);
//set("display/window/handheld/orientation", "landscape");
diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp
index 5968972143..531467ecd6 100644
--- a/core/io/config_file.cpp
+++ b/core/io/config_file.cpp
@@ -34,11 +34,11 @@
#include "core/os/keyboard.h"
#include "core/variant_parser.h"
-PoolStringArray ConfigFile::_get_sections() const {
+PackedStringArray ConfigFile::_get_sections() const {
List<String> s;
get_sections(&s);
- PoolStringArray arr;
+ PackedStringArray arr;
arr.resize(s.size());
int idx = 0;
for (const List<String>::Element *E = s.front(); E; E = E->next()) {
@@ -49,11 +49,11 @@ PoolStringArray ConfigFile::_get_sections() const {
return arr;
}
-PoolStringArray ConfigFile::_get_section_keys(const String &p_section) const {
+PackedStringArray ConfigFile::_get_section_keys(const String &p_section) const {
List<String> s;
get_section_keys(p_section, &s);
- PoolStringArray arr;
+ PackedStringArray arr;
arr.resize(s.size());
int idx = 0;
for (const List<String>::Element *E = s.front(); E; E = E->next()) {
@@ -86,7 +86,8 @@ void ConfigFile::set_value(const String &p_section, const String &p_key, const V
Variant ConfigFile::get_value(const String &p_section, const String &p_key, Variant p_default) const {
if (!values.has(p_section) || !values[p_section].has(p_key)) {
- ERR_FAIL_COND_V_MSG(p_default.get_type() == Variant::NIL, Variant(), "Couldn't find the given section '" + p_section + "', key '" + p_key + "' and no default was given.");
+ ERR_FAIL_COND_V_MSG(p_default.get_type() == Variant::NIL, Variant(),
+ vformat("Couldn't find the given section \"%s\" and key \"%s\", and no default was given.", p_section, p_key));
return p_default;
}
@@ -112,7 +113,7 @@ void ConfigFile::get_sections(List<String> *r_sections) const {
}
void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys) const {
- ERR_FAIL_COND_MSG(!values.has(p_section), "Cannont get keys from nonexistent section '" + p_section + "'.");
+ ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot get keys from nonexistent section \"%s\".", p_section));
for (OrderedHashMap<String, Variant>::ConstElement E = values[p_section].front(); E; E = E.next()) {
r_keys->push_back(E.key());
@@ -121,12 +122,14 @@ void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys)
void ConfigFile::erase_section(const String &p_section) {
+ ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot erase nonexistent section \"%s\".", p_section));
values.erase(p_section);
}
void ConfigFile::erase_section_key(const String &p_section, const String &p_key) {
- ERR_FAIL_COND_MSG(!values.has(p_section), "Cannot erase key from nonexistent section '" + p_section + "'.");
+ ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot erase key \"%s\" from nonexistent section \"%s\".", p_key, p_section));
+ ERR_FAIL_COND_MSG(!values[p_section].has(p_key), vformat("Cannot erase nonexistent key \"%s\" from section \"%s\".", p_key, p_section));
values[p_section].erase(p_key);
}
@@ -291,7 +294,7 @@ Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream)
if (err == ERR_FILE_EOF) {
return OK;
} else if (err != OK) {
- ERR_PRINT("ConfgFile - " + p_path + ":" + itos(lines) + " error: " + error_text + ".");
+ ERR_PRINT(vformat("ConfigFile parse error at %s:%d: %s.", p_path, lines, error_text));
return err;
}
@@ -324,11 +327,8 @@ void ConfigFile::_bind_methods() {
ClassDB::bind_method(D_METHOD("save", "path"), &ConfigFile::save);
ClassDB::bind_method(D_METHOD("load_encrypted", "path", "key"), &ConfigFile::load_encrypted);
- ClassDB::bind_method(D_METHOD("load_encrypted_pass", "path", "pass"), &ConfigFile::load_encrypted_pass);
+ ClassDB::bind_method(D_METHOD("load_encrypted_pass", "path", "password"), &ConfigFile::load_encrypted_pass);
ClassDB::bind_method(D_METHOD("save_encrypted", "path", "key"), &ConfigFile::save_encrypted);
- ClassDB::bind_method(D_METHOD("save_encrypted_pass", "path", "pass"), &ConfigFile::save_encrypted_pass);
-}
-
-ConfigFile::ConfigFile() {
+ ClassDB::bind_method(D_METHOD("save_encrypted_pass", "path", "password"), &ConfigFile::save_encrypted_pass);
}
diff --git a/core/io/config_file.h b/core/io/config_file.h
index 2d61ef6afe..7efcb5a04c 100644
--- a/core/io/config_file.h
+++ b/core/io/config_file.h
@@ -42,8 +42,8 @@ class ConfigFile : public Reference {
OrderedHashMap<String, OrderedHashMap<String, Variant> > values;
- PoolStringArray _get_sections() const;
- PoolStringArray _get_section_keys(const String &p_section) const;
+ PackedStringArray _get_sections() const;
+ PackedStringArray _get_section_keys(const String &p_section) const;
Error _internal_load(const String &p_path, FileAccess *f);
Error _internal_save(FileAccess *file);
@@ -74,8 +74,6 @@ public:
Error save_encrypted(const String &p_path, const Vector<uint8_t> &p_key);
Error save_encrypted_pass(const String &p_path, const String &p_pass);
-
- ConfigFile();
};
#endif // CONFIG_FILE_H
diff --git a/core/pool_vector.cpp b/core/io/dtls_server.cpp
index d8d53f07e9..07e6abb1c9 100644
--- a/core/pool_vector.cpp
+++ b/core/io/dtls_server.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* pool_vector.cpp */
+/* dtls_server.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,43 +28,27 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "pool_vector.h"
+#include "dtls_server.h"
+#include "core/os/file_access.h"
+#include "core/project_settings.h"
-Mutex *pool_vector_lock = NULL;
+DTLSServer *(*DTLSServer::_create)() = NULL;
+bool DTLSServer::available = false;
-PoolAllocator *MemoryPool::memory_pool = NULL;
-uint8_t *MemoryPool::pool_memory = NULL;
-size_t *MemoryPool::pool_size = NULL;
+DTLSServer *DTLSServer::create() {
-MemoryPool::Alloc *MemoryPool::allocs = NULL;
-MemoryPool::Alloc *MemoryPool::free_list = NULL;
-uint32_t MemoryPool::alloc_count = 0;
-uint32_t MemoryPool::allocs_used = 0;
-Mutex *MemoryPool::alloc_mutex = NULL;
-
-size_t MemoryPool::total_memory = 0;
-size_t MemoryPool::max_memory = 0;
-
-void MemoryPool::setup(uint32_t p_max_allocs) {
-
- allocs = memnew_arr(Alloc, p_max_allocs);
- alloc_count = p_max_allocs;
- allocs_used = 0;
-
- for (uint32_t i = 0; i < alloc_count - 1; i++) {
-
- allocs[i].free_list = &allocs[i + 1];
- }
-
- free_list = &allocs[0];
+ return _create();
+}
- alloc_mutex = Mutex::create();
+bool DTLSServer::is_available() {
+ return available;
}
-void MemoryPool::cleanup() {
+void DTLSServer::_bind_methods() {
- memdelete_arr(allocs);
- memdelete(alloc_mutex);
+ ClassDB::bind_method(D_METHOD("setup", "key", "certificate", "chain"), &DTLSServer::setup, DEFVAL(Ref<X509Certificate>()));
+ ClassDB::bind_method(D_METHOD("take_connection", "udp_peer"), &DTLSServer::take_connection);
+}
- ERR_FAIL_COND_MSG(allocs_used > 0, "There are still MemoryPool allocs in use at exit!");
+DTLSServer::DTLSServer() {
}
diff --git a/core/io/dtls_server.h b/core/io/dtls_server.h
new file mode 100644
index 0000000000..7b08138f7f
--- /dev/null
+++ b/core/io/dtls_server.h
@@ -0,0 +1,57 @@
+/*************************************************************************/
+/* dtls_server.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 DTLS_SERVER_H
+#define DTLS_SERVER_H
+
+#include "core/io/net_socket.h"
+#include "core/io/packet_peer_dtls.h"
+
+class DTLSServer : public Reference {
+ GDCLASS(DTLSServer, Reference);
+
+protected:
+ static DTLSServer *(*_create)();
+ static void _bind_methods();
+
+ static bool available;
+
+public:
+ static bool is_available();
+ static DTLSServer *create();
+
+ virtual Error setup(Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain = Ref<X509Certificate>()) = 0;
+ virtual void stop() = 0;
+ virtual Ref<PacketPeerDTLS> take_connection(Ref<PacketPeerUDP> p_peer) = 0;
+
+ DTLSServer();
+};
+
+#endif // DTLS_SERVER_H
diff --git a/core/io/file_access_buffered.cpp b/core/io/file_access_buffered.cpp
index 6ac065a19b..ab0fb3943c 100644
--- a/core/io/file_access_buffered.cpp
+++ b/core/io/file_access_buffered.cpp
@@ -113,7 +113,7 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
int size = (cache.buffer.size() - (file.offset - cache.offset));
size = size - (size % 4);
- //PoolVector<uint8_t>::Read read = cache.buffer.read();
+ //const uint8_t* read = cache.buffer.ptr();
//memcpy(p_dest, read.ptr() + (file.offset - cache.offset), size);
memcpy(p_dest, cache.buffer.ptr() + (file.offset - cache.offset), size);
p_dest += size;
@@ -145,7 +145,7 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
}
int r = MIN(left, to_read);
- //PoolVector<uint8_t>::Read read = cache.buffer.read();
+ //const uint8_t* read = cache.buffer.ptr();
//memcpy(p_dest+total_read, &read.ptr()[file.offset - cache.offset], r);
memcpy(p_dest + total_read, cache.buffer.ptr() + (file.offset - cache.offset), r);
diff --git a/core/io/file_access_buffered.h b/core/io/file_access_buffered.h
index 5e2939c1a2..a6177c20be 100644
--- a/core/io/file_access_buffered.h
+++ b/core/io/file_access_buffered.h
@@ -32,7 +32,7 @@
#define FILE_ACCESS_BUFFERED_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 c17652080c..6ec77d503b 100644
--- a/core/io/file_access_buffered_fa.h
+++ b/core/io/file_access_buffered_fa.h
@@ -54,8 +54,8 @@ class FileAccessBufferedFA : public FileAccessBuffered {
cache.offset = p_offset;
cache.buffer.resize(p_size);
- // on PoolVector
- //PoolVector<uint8_t>::Write write = cache.buffer.write();
+ // on Vector
+ //uint8_t* write = cache.buffer.ptrw();
//f.get_buffer(write.ptrw(), p_size);
// on vector
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index 202eb89dbd..370dd8f982 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -42,14 +42,14 @@
void FileAccessNetworkClient::lock_mutex() {
- mutex->lock();
+ mutex.lock();
lockcount++;
}
void FileAccessNetworkClient::unlock_mutex() {
lockcount--;
- mutex->unlock();
+ mutex.unlock();
}
void FileAccessNetworkClient::put_32(int p_32) {
@@ -88,24 +88,23 @@ void FileAccessNetworkClient::_thread_func() {
while (!quit) {
DEBUG_PRINT("SEM WAIT - " + itos(sem->get()));
- Error err = sem->wait();
- if (err != OK)
- ERR_PRINT("sem->wait() failed");
+ sem.wait();
DEBUG_TIME("sem_unlock");
//DEBUG_PRINT("semwait returned "+itos(werr));
DEBUG_PRINT("MUTEX LOCK " + itos(lockcount));
lock_mutex();
DEBUG_PRINT("MUTEX PASS");
- blockrequest_mutex->lock();
- while (block_requests.size()) {
- put_32(block_requests.front()->get().id);
- put_32(FileAccessNetwork::COMMAND_READ_BLOCK);
- put_64(block_requests.front()->get().offset);
- put_32(block_requests.front()->get().size);
- block_requests.pop_front();
+ {
+ MutexLock lock(blockrequest_mutex);
+ while (block_requests.size()) {
+ put_32(block_requests.front()->get().id);
+ put_32(FileAccessNetwork::COMMAND_READ_BLOCK);
+ put_64(block_requests.front()->get().offset);
+ put_32(block_requests.front()->get().size);
+ block_requests.pop_front();
+ }
}
- blockrequest_mutex->unlock();
DEBUG_PRINT("THREAD ITER");
@@ -140,7 +139,7 @@ void FileAccessNetworkClient::_thread_func() {
fa->_respond(len, Error(status));
}
- fa->sem->post();
+ fa->sem.post();
} break;
case FileAccessNetwork::RESPONSE_DATA: {
@@ -160,14 +159,14 @@ void FileAccessNetworkClient::_thread_func() {
int status = get_32();
fa->exists_modtime = status != 0;
- fa->sem->post();
+ fa->sem.post();
} break;
case FileAccessNetwork::RESPONSE_GET_MODTIME: {
uint64_t status = get_64();
fa->exists_modtime = status;
- fa->sem->post();
+ fa->sem.post();
} break;
}
@@ -225,13 +224,10 @@ FileAccessNetworkClient *FileAccessNetworkClient::singleton = NULL;
FileAccessNetworkClient::FileAccessNetworkClient() {
thread = NULL;
- mutex = Mutex::create();
- blockrequest_mutex = Mutex::create();
quit = false;
singleton = this;
last_id = 0;
client.instance();
- sem = SemaphoreOld::create();
lockcount = 0;
}
@@ -239,14 +235,10 @@ FileAccessNetworkClient::~FileAccessNetworkClient() {
if (thread) {
quit = true;
- sem->post();
+ sem.post();
Thread::wait_to_finish(thread);
memdelete(thread);
}
-
- memdelete(blockrequest_mutex);
- memdelete(mutex);
- memdelete(sem);
}
void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block) {
@@ -259,14 +251,15 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block)
ERR_FAIL_COND((p_block.size() != (int)(total_size % page_size)));
}
- buffer_mutex->lock();
- pages.write[page].buffer = p_block;
- pages.write[page].queued = false;
- buffer_mutex->unlock();
+ {
+ MutexLock lock(buffer_mutex);
+ pages.write[page].buffer = p_block;
+ pages.write[page].queued = false;
+ }
if (waiting_on_page == page) {
waiting_on_page = -1;
- page_sem->post();
+ page_sem.post();
}
}
@@ -308,9 +301,9 @@ Error FileAccessNetwork::_open(const String &p_path, int p_mode_flags) {
nc->unlock_mutex();
DEBUG_PRINT("OPEN POST");
DEBUG_TIME("open_post");
- nc->sem->post(); //awaiting answer
+ nc->sem.post(); //awaiting answer
DEBUG_PRINT("WAIT...");
- sem->wait();
+ sem.wait();
DEBUG_TIME("open_end");
DEBUG_PRINT("WAIT ENDED...");
@@ -384,17 +377,18 @@ void FileAccessNetwork::_queue_page(int p_page) const {
if (pages[p_page].buffer.empty() && !pages[p_page].queued) {
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
-
- nc->blockrequest_mutex->lock();
- FileAccessNetworkClient::BlockRequest br;
- br.id = id;
- br.offset = size_t(p_page) * page_size;
- br.size = page_size;
- nc->block_requests.push_back(br);
- pages.write[p_page].queued = true;
- nc->blockrequest_mutex->unlock();
+ {
+ MutexLock lock(nc->blockrequest_mutex);
+
+ FileAccessNetworkClient::BlockRequest br;
+ br.id = id;
+ br.offset = size_t(p_page) * page_size;
+ br.size = page_size;
+ nc->block_requests.push_back(br);
+ pages.write[p_page].queued = true;
+ }
DEBUG_PRINT("QUEUE PAGE POST");
- nc->sem->post();
+ nc->sem.post();
DEBUG_PRINT("queued " + itos(p_page));
}
}
@@ -418,16 +412,16 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
int page = pos / page_size;
if (page != last_page) {
- buffer_mutex->lock();
+ buffer_mutex.lock();
if (pages[page].buffer.empty()) {
waiting_on_page = page;
for (int j = 0; j < read_ahead; j++) {
_queue_page(page + j);
}
- buffer_mutex->unlock();
+ buffer_mutex.unlock();
DEBUG_PRINT("wait");
- page_sem->wait();
+ page_sem.wait();
DEBUG_PRINT("done");
} else {
@@ -436,7 +430,7 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
_queue_page(page + j);
}
//queue pages
- buffer_mutex->unlock();
+ buffer_mutex.unlock();
}
buff = pages.write[page].buffer.ptrw();
@@ -476,8 +470,8 @@ bool FileAccessNetwork::file_exists(const String &p_path) {
nc->client->put_data((const uint8_t *)cs.ptr(), cs.length());
nc->unlock_mutex();
DEBUG_PRINT("FILE EXISTS POST");
- nc->sem->post();
- sem->wait();
+ nc->sem.post();
+ sem.wait();
return exists_modtime != 0;
}
@@ -493,8 +487,8 @@ uint64_t FileAccessNetwork::_get_modified_time(const String &p_file) {
nc->client->put_data((const uint8_t *)cs.ptr(), cs.length());
nc->unlock_mutex();
DEBUG_PRINT("MODTIME POST");
- nc->sem->post();
- sem->wait();
+ nc->sem.post();
+ sem.wait();
return exists_modtime;
}
@@ -522,9 +516,6 @@ FileAccessNetwork::FileAccessNetwork() {
eof_flag = false;
opened = false;
pos = 0;
- sem = SemaphoreOld::create();
- page_sem = SemaphoreOld::create();
- buffer_mutex = Mutex::create();
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
id = nc->last_id++;
@@ -540,9 +531,6 @@ FileAccessNetwork::FileAccessNetwork() {
FileAccessNetwork::~FileAccessNetwork() {
close();
- memdelete(sem);
- memdelete(page_sem);
- memdelete(buffer_mutex);
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h
index f329abf7c5..7f664b46f7 100644
--- a/core/io/file_access_network.h
+++ b/core/io/file_access_network.h
@@ -49,11 +49,11 @@ class FileAccessNetworkClient {
List<BlockRequest> block_requests;
- SemaphoreOld *sem;
+ Semaphore sem;
Thread *thread;
bool quit;
- Mutex *mutex;
- Mutex *blockrequest_mutex;
+ Mutex mutex;
+ Mutex blockrequest_mutex;
Map<int, FileAccessNetwork *> accesses;
Ref<StreamPeerTCP> client;
int last_id;
@@ -85,9 +85,9 @@ public:
class FileAccessNetwork : public FileAccess {
- SemaphoreOld *sem;
- SemaphoreOld *page_sem;
- Mutex *buffer_mutex;
+ Semaphore sem;
+ Semaphore page_sem;
+ Mutex buffer_mutex;
bool opened;
size_t total_size;
mutable size_t pos;
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index 83ce03418a..055ce816ad 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -454,7 +454,7 @@ Error DirAccessPack::change_dir(String p_dir) {
return OK;
}
-String DirAccessPack::get_current_dir() {
+String DirAccessPack::get_current_dir(bool p_include_drive) {
PackedData::PackedDir *pd = current;
String p = current->name;
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index b6ea9c158f..e1f35aabdd 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -216,7 +216,7 @@ public:
virtual String get_drive(int p_drive);
virtual Error change_dir(String p_dir);
- virtual String get_current_dir();
+ virtual String get_current_dir(bool p_include_drive = true);
virtual bool file_exists(String p_file);
virtual bool dir_exists(String p_dir);
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index 541bd3a7c8..ce7025de35 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -110,7 +110,7 @@ Ref<StreamPeer> HTTPClient::get_connection() const {
return connection;
}
-Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const PoolVector<uint8_t> &p_body) {
+Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body) {
ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER);
@@ -152,10 +152,10 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector
request += "\r\n";
CharString cs = request.utf8();
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
data.resize(cs.length());
{
- PoolVector<uint8_t>::Write data_write = data.write();
+ uint8_t *data_write = data.ptrw();
for (int i = 0; i < cs.length(); i++) {
data_write[i] = cs[i];
}
@@ -163,7 +163,7 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector
data.append_array(p_body);
- PoolVector<uint8_t>::Read r = data.read();
+ const uint8_t *r = data.ptr();
Error err = connection->put_data(&r[0], data.size());
if (err) {
@@ -517,11 +517,11 @@ int HTTPClient::get_response_body_length() const {
return body_size;
}
-PoolByteArray HTTPClient::read_response_body_chunk() {
+PackedByteArray HTTPClient::read_response_body_chunk() {
- ERR_FAIL_COND_V(status != STATUS_BODY, PoolByteArray());
+ ERR_FAIL_COND_V(status != STATUS_BODY, PackedByteArray());
- PoolByteArray ret;
+ PackedByteArray ret;
Error err = OK;
if (chunked) {
@@ -622,8 +622,8 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
}
ret.resize(chunk.size() - 2);
- PoolByteArray::Write w = ret.write();
- copymem(w.ptr(), chunk.ptr(), chunk.size() - 2);
+ uint8_t *w = ret.ptrw();
+ copymem(w, chunk.ptr(), chunk.size() - 2);
chunk.clear();
}
@@ -639,8 +639,8 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
while (to_read > 0) {
int rec = 0;
{
- PoolByteArray::Write w = ret.write();
- err = _get_http_data(w.ptr() + _offset, to_read, rec);
+ uint8_t *w = ret.ptrw();
+ err = _get_http_data(w + _offset, to_read, rec);
}
if (rec <= 0) { // Ended up reading less
ret.resize(_offset);
@@ -801,11 +801,11 @@ Dictionary HTTPClient::_get_response_headers_as_dictionary() {
return ret;
}
-PoolStringArray HTTPClient::_get_response_headers() {
+PackedStringArray HTTPClient::_get_response_headers() {
List<String> rh;
get_response_headers(&rh);
- PoolStringArray ret;
+ PackedStringArray ret;
ret.resize(rh.size());
int idx = 0;
for (const List<String>::Element *E = rh.front(); E; E = E->next()) {
diff --git a/core/io/http_client.h b/core/io/http_client.h
index 3796eb992c..03ba20f8dd 100644
--- a/core/io/http_client.h
+++ b/core/io/http_client.h
@@ -191,7 +191,7 @@ private:
#include "platform/javascript/http_client.h.inc"
#endif
- PoolStringArray _get_response_headers();
+ PackedStringArray _get_response_headers();
Dictionary _get_response_headers_as_dictionary();
static void _bind_methods();
@@ -202,7 +202,7 @@ public:
void set_connection(const Ref<StreamPeer> &p_connection);
Ref<StreamPeer> get_connection() const;
- Error request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const PoolVector<uint8_t> &p_body);
+ Error request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body);
Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body = String());
void close();
@@ -215,7 +215,7 @@ public:
Error get_response_headers(List<String> *r_response);
int get_response_body_length() const;
- PoolByteArray read_response_body_chunk(); // Can't get body as partial text because of most encodings UTF8, gzip, etc.
+ PackedByteArray read_response_body_chunk(); // Can't get body as partial text because of most encodings UTF8, gzip, etc.
void set_blocking_mode(bool p_enable); // Useful mostly if running in a thread
bool is_blocking_mode_enabled() const;
diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp
index 720f25f91b..99ac5bcdd9 100644
--- a/core/io/image_loader.cpp
+++ b/core/io/image_loader.cpp
@@ -129,7 +129,7 @@ void ImageLoader::cleanup() {
/////////////////
-RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
diff --git a/core/io/image_loader.h b/core/io/image_loader.h
index d6dfd261ca..3ba028b99c 100644
--- a/core/io/image_loader.h
+++ b/core/io/image_loader.h
@@ -73,7 +73,7 @@ public:
class ResourceFormatLoaderImage : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index 7d18117711..2143b84d15 100644
--- a/core/io/ip.cpp
+++ b/core/io/ip.cpp
@@ -70,8 +70,8 @@ struct _IP_ResolverPrivate {
return IP::RESOLVER_INVALID_ID;
}
- Mutex *mutex;
- SemaphoreOld *sem;
+ Mutex mutex;
+ Semaphore sem;
Thread *thread;
//Semaphore* semaphore;
@@ -98,11 +98,10 @@ struct _IP_ResolverPrivate {
while (!ipr->thread_abort) {
- ipr->sem->wait();
+ ipr->sem.wait();
- ipr->mutex->lock();
+ MutexLock lock(ipr->mutex);
ipr->resolve_queues();
- ipr->mutex->unlock();
}
}
@@ -115,30 +114,27 @@ struct _IP_ResolverPrivate {
IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
- resolver->mutex->lock();
+ MutexLock lock(resolver->mutex);
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
if (resolver->cache.has(key) && resolver->cache[key].is_valid()) {
IP_Address res = resolver->cache[key];
- resolver->mutex->unlock();
return res;
}
IP_Address res = _resolve_hostname(p_hostname, p_type);
resolver->cache[key] = res;
- resolver->mutex->unlock();
return res;
}
IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Type p_type) {
- resolver->mutex->lock();
+ MutexLock lock(resolver->mutex);
ResolverID id = resolver->find_empty_id();
if (id == RESOLVER_INVALID_ID) {
WARN_PRINT("Out of resolver queries");
- resolver->mutex->unlock();
return id;
}
@@ -152,12 +148,11 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ
resolver->queue[id].response = IP_Address();
resolver->queue[id].status = IP::RESOLVER_STATUS_WAITING;
if (resolver->thread)
- resolver->sem->post();
+ resolver->sem.post();
else
resolver->resolve_queues();
}
- resolver->mutex->unlock();
return id;
}
@@ -165,50 +160,43 @@ IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const {
ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP::RESOLVER_STATUS_NONE);
- resolver->mutex->lock();
+ MutexLock lock(resolver->mutex);
+
if (resolver->queue[p_id].status == IP::RESOLVER_STATUS_NONE) {
ERR_PRINT("Condition status == IP::RESOLVER_STATUS_NONE");
- resolver->mutex->unlock();
+ resolver->mutex.unlock();
return IP::RESOLVER_STATUS_NONE;
}
- IP::ResolverStatus res = resolver->queue[p_id].status;
-
- resolver->mutex->unlock();
- return res;
+ return resolver->queue[p_id].status;
}
IP_Address IP::get_resolve_item_address(ResolverID p_id) const {
ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP_Address());
- resolver->mutex->lock();
+ MutexLock lock(resolver->mutex);
if (resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE) {
ERR_PRINT("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet.");
- resolver->mutex->unlock();
+ resolver->mutex.unlock();
return IP_Address();
}
- IP_Address res = resolver->queue[p_id].response;
-
- resolver->mutex->unlock();
- return res;
+ return resolver->queue[p_id].response;
}
void IP::erase_resolve_item(ResolverID p_id) {
ERR_FAIL_INDEX(p_id, IP::RESOLVER_MAX_QUERIES);
- resolver->mutex->lock();
+ MutexLock lock(resolver->mutex);
resolver->queue[p_id].status = IP::RESOLVER_STATUS_NONE;
-
- resolver->mutex->unlock();
}
void IP::clear_cache(const String &p_hostname) {
- resolver->mutex->lock();
+ MutexLock lock(resolver->mutex);
if (p_hostname.empty()) {
resolver->cache.clear();
@@ -218,8 +206,6 @@ void IP::clear_cache(const String &p_hostname) {
resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_IPV6));
resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_ANY));
}
-
- resolver->mutex->unlock();
}
Array IP::_get_local_addresses() const {
@@ -314,24 +300,13 @@ IP::IP() {
singleton = this;
resolver = memnew(_IP_ResolverPrivate);
- resolver->sem = NULL;
- resolver->mutex = Mutex::create();
#ifndef NO_THREADS
- resolver->sem = SemaphoreOld::create();
- if (resolver->sem) {
- resolver->thread_abort = false;
-
- resolver->thread = Thread::create(_IP_ResolverPrivate::_thread_function, resolver);
+ resolver->thread_abort = false;
- if (!resolver->thread)
- memdelete(resolver->sem); //wtf
- } else {
- resolver->thread = NULL;
- }
+ resolver->thread = Thread::create(_IP_ResolverPrivate::_thread_function, resolver);
#else
- resolver->sem = NULL;
resolver->thread = NULL;
#endif
}
@@ -341,14 +316,12 @@ IP::~IP() {
#ifndef NO_THREADS
if (resolver->thread) {
resolver->thread_abort = true;
- resolver->sem->post();
+ resolver->sem.post();
Thread::wait_to_finish(resolver->thread);
memdelete(resolver->thread);
- memdelete(resolver->sem);
}
#endif
- memdelete(resolver->mutex);
memdelete(resolver);
}
diff --git a/core/io/json.cpp b/core/io/json.cpp
index 144e4bdc3b..3a0edceb81 100644
--- a/core/io/json.cpp
+++ b/core/io/json.cpp
@@ -70,10 +70,12 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_
case Variant::NIL: return "null";
case Variant::BOOL: return p_var.operator bool() ? "true" : "false";
case Variant::INT: return itos(p_var);
- case Variant::REAL: return rtos(p_var);
- case Variant::POOL_INT_ARRAY:
- case Variant::POOL_REAL_ARRAY:
- case Variant::POOL_STRING_ARRAY:
+ case Variant::FLOAT: return rtos(p_var);
+ case Variant::PACKED_INT32_ARRAY:
+ case Variant::PACKED_INT64_ARRAY:
+ case Variant::PACKED_FLOAT32_ARRAY:
+ case Variant::PACKED_FLOAT64_ARRAY:
+ case Variant::PACKED_STRING_ARRAY:
case Variant::ARRAY: {
String s = "[";
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index 17edc4982c..fbcaa582b7 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -147,7 +147,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
}
} break;
- case Variant::REAL: {
+ case Variant::FLOAT: {
if (type & ENCODE_FLAG_64) {
ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
@@ -186,7 +186,19 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
if (r_len)
(*r_len) += 4 * 2;
- } break; // 5
+ } break;
+ case Variant::VECTOR2I: {
+
+ ERR_FAIL_COND_V(len < 4 * 2, ERR_INVALID_DATA);
+ Vector2i val;
+ val.x = decode_uint32(&buf[0]);
+ val.y = decode_uint32(&buf[4]);
+ r_variant = val;
+
+ if (r_len)
+ (*r_len) += 4 * 2;
+
+ } break;
case Variant::RECT2: {
ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA);
@@ -201,6 +213,20 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
(*r_len) += 4 * 4;
} break;
+ case Variant::RECT2I: {
+
+ ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA);
+ Rect2i val;
+ val.position.x = decode_uint32(&buf[0]);
+ val.position.y = decode_uint32(&buf[4]);
+ val.size.x = decode_uint32(&buf[8]);
+ val.size.y = decode_uint32(&buf[12]);
+ r_variant = val;
+
+ if (r_len)
+ (*r_len) += 4 * 4;
+
+ } break;
case Variant::VECTOR3: {
ERR_FAIL_COND_V(len < 4 * 3, ERR_INVALID_DATA);
@@ -214,6 +240,19 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
(*r_len) += 4 * 3;
} break;
+ case Variant::VECTOR3I: {
+
+ ERR_FAIL_COND_V(len < 4 * 3, ERR_INVALID_DATA);
+ Vector3i val;
+ val.x = decode_uint32(&buf[0]);
+ val.y = decode_uint32(&buf[4]);
+ val.z = decode_uint32(&buf[8]);
+ r_variant = val;
+
+ if (r_len)
+ (*r_len) += 4 * 3;
+
+ } break;
case Variant::TRANSFORM2D: {
ERR_FAIL_COND_V(len < 4 * 6, ERR_INVALID_DATA);
@@ -328,6 +367,16 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
(*r_len) += 4 * 4;
} break;
+ case Variant::STRING_NAME: {
+
+ String str;
+ Error err = _decode_string(buf, len, r_len, str);
+ if (err)
+ return err;
+ r_variant = StringName(str);
+
+ } break;
+
case Variant::NODE_PATH: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
@@ -455,6 +504,15 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
}
} break;
+ case Variant::CALLABLE: {
+
+ r_variant = Callable();
+ } break;
+ case Variant::SIGNAL: {
+
+ r_variant = Signal();
+ } break;
+
case Variant::DICTIONARY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
@@ -535,7 +593,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
// arrays
- case Variant::POOL_BYTE_ARRAY: {
+ case Variant::PACKED_BYTE_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
@@ -543,11 +601,11 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
len -= 4;
ERR_FAIL_COND_V(count < 0 || count > len, ERR_INVALID_DATA);
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
if (count) {
data.resize(count);
- PoolVector<uint8_t>::Write w = data.write();
+ uint8_t *w = data.ptrw();
for (int32_t i = 0; i < count; i++) {
w[i] = buf[i];
@@ -563,7 +621,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
}
} break;
- case Variant::POOL_INT_ARRAY: {
+ case Variant::PACKED_INT32_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
@@ -572,12 +630,12 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
ERR_FAIL_MUL_OF(count, 4, ERR_INVALID_DATA);
ERR_FAIL_COND_V(count < 0 || count * 4 > len, ERR_INVALID_DATA);
- PoolVector<int> data;
+ Vector<int32_t> data;
if (count) {
//const int*rbuf=(const int*)buf;
data.resize(count);
- PoolVector<int>::Write w = data.write();
+ int32_t *w = data.ptrw();
for (int32_t i = 0; i < count; i++) {
w[i] = decode_uint32(&buf[i * 4]);
@@ -585,11 +643,37 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
}
r_variant = Variant(data);
if (r_len) {
- (*r_len) += 4 + count * sizeof(int);
+ (*r_len) += 4 + count * sizeof(int32_t);
}
} break;
- case Variant::POOL_REAL_ARRAY: {
+ case Variant::PACKED_INT64_ARRAY: {
+
+ ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
+ int64_t count = decode_uint64(buf);
+ buf += 4;
+ len -= 4;
+ ERR_FAIL_MUL_OF(count, 8, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(count < 0 || count * 8 > len, ERR_INVALID_DATA);
+
+ Vector<int64_t> data;
+
+ if (count) {
+ //const int*rbuf=(const int*)buf;
+ data.resize(count);
+ int64_t *w = data.ptrw();
+ for (int64_t i = 0; i < count; i++) {
+
+ w[i] = decode_uint64(&buf[i * 8]);
+ }
+ }
+ r_variant = Variant(data);
+ if (r_len) {
+ (*r_len) += 4 + count * sizeof(int64_t);
+ }
+
+ } break;
+ case Variant::PACKED_FLOAT32_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
@@ -598,12 +682,12 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
ERR_FAIL_MUL_OF(count, 4, ERR_INVALID_DATA);
ERR_FAIL_COND_V(count < 0 || count * 4 > len, ERR_INVALID_DATA);
- PoolVector<float> data;
+ Vector<float> data;
if (count) {
//const float*rbuf=(const float*)buf;
data.resize(count);
- PoolVector<float>::Write w = data.write();
+ float *w = data.ptrw();
for (int32_t i = 0; i < count; i++) {
w[i] = decode_float(&buf[i * 4]);
@@ -616,12 +700,39 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
}
} break;
- case Variant::POOL_STRING_ARRAY: {
+ case Variant::PACKED_FLOAT64_ARRAY: {
+
+ ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
+ int64_t count = decode_uint64(buf);
+ buf += 4;
+ len -= 4;
+ ERR_FAIL_MUL_OF(count, 8, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(count < 0 || count * 8 > len, ERR_INVALID_DATA);
+
+ Vector<double> data;
+
+ if (count) {
+ //const double*rbuf=(const double*)buf;
+ data.resize(count);
+ double *w = data.ptrw();
+ for (int64_t i = 0; i < count; i++) {
+
+ w[i] = decode_double(&buf[i * 8]);
+ }
+ }
+ r_variant = data;
+
+ if (r_len) {
+ (*r_len) += 4 + count * sizeof(double);
+ }
+
+ } break;
+ case Variant::PACKED_STRING_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
- PoolVector<String> strings;
+ Vector<String> strings;
buf += 4;
len -= 4;
@@ -642,7 +753,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
r_variant = strings;
} break;
- case Variant::POOL_VECTOR2_ARRAY: {
+ case Variant::PACKED_VECTOR2_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
@@ -651,7 +762,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
ERR_FAIL_MUL_OF(count, 4 * 2, ERR_INVALID_DATA);
ERR_FAIL_COND_V(count < 0 || count * 4 * 2 > len, ERR_INVALID_DATA);
- PoolVector<Vector2> varray;
+ Vector<Vector2> varray;
if (r_len) {
(*r_len) += 4;
@@ -659,7 +770,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
if (count) {
varray.resize(count);
- PoolVector<Vector2>::Write w = varray.write();
+ Vector2 *w = varray.ptrw();
for (int32_t i = 0; i < count; i++) {
@@ -676,7 +787,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
r_variant = varray;
} break;
- case Variant::POOL_VECTOR3_ARRAY: {
+ case Variant::PACKED_VECTOR3_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
@@ -686,7 +797,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
ERR_FAIL_MUL_OF(count, 4 * 3, ERR_INVALID_DATA);
ERR_FAIL_COND_V(count < 0 || count * 4 * 3 > len, ERR_INVALID_DATA);
- PoolVector<Vector3> varray;
+ Vector<Vector3> varray;
if (r_len) {
(*r_len) += 4;
@@ -694,7 +805,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
if (count) {
varray.resize(count);
- PoolVector<Vector3>::Write w = varray.write();
+ Vector3 *w = varray.ptrw();
for (int32_t i = 0; i < count; i++) {
@@ -712,7 +823,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
r_variant = varray;
} break;
- case Variant::POOL_COLOR_ARRAY: {
+ case Variant::PACKED_COLOR_ARRAY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
@@ -722,7 +833,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
ERR_FAIL_MUL_OF(count, 4 * 4, ERR_INVALID_DATA);
ERR_FAIL_COND_V(count < 0 || count * 4 * 4 > len, ERR_INVALID_DATA);
- PoolVector<Color> carray;
+ Vector<Color> carray;
if (r_len) {
(*r_len) += 4;
@@ -730,7 +841,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
if (count) {
carray.resize(count);
- PoolVector<Color>::Write w = carray.write();
+ Color *w = carray.ptrw();
for (int32_t i = 0; i < count; i++) {
@@ -793,7 +904,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
flags |= ENCODE_FLAG_64;
}
} break;
- case Variant::REAL: {
+ case Variant::FLOAT: {
double d = p_variant;
float f = d;
@@ -860,7 +971,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4;
}
} break;
- case Variant::REAL: {
+ case Variant::FLOAT: {
if (flags & ENCODE_FLAG_64) {
if (buf) {
@@ -930,6 +1041,11 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
_encode_string(p_variant, buf, r_len);
} break;
+ case Variant::STRING_NAME: {
+
+ _encode_string(p_variant, buf, r_len);
+
+ } break;
// math types
case Variant::VECTOR2: {
@@ -942,7 +1058,18 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 2 * 4;
- } break; // 5
+ } break;
+ case Variant::VECTOR2I: {
+
+ if (buf) {
+ Vector2i v2 = p_variant;
+ encode_uint32(v2.x, &buf[0]);
+ encode_uint32(v2.y, &buf[4]);
+ }
+
+ r_len += 2 * 4;
+
+ } break;
case Variant::RECT2: {
if (buf) {
@@ -955,6 +1082,18 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4 * 4;
} break;
+ case Variant::RECT2I: {
+
+ if (buf) {
+ Rect2i r2 = p_variant;
+ encode_uint32(r2.position.x, &buf[0]);
+ encode_uint32(r2.position.y, &buf[4]);
+ encode_uint32(r2.size.x, &buf[8]);
+ encode_uint32(r2.size.y, &buf[12]);
+ }
+ r_len += 4 * 4;
+
+ } break;
case Variant::VECTOR3: {
if (buf) {
@@ -967,6 +1106,18 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 3 * 4;
} break;
+ case Variant::VECTOR3I: {
+
+ if (buf) {
+ Vector3i v3 = p_variant;
+ encode_uint32(v3.x, &buf[0]);
+ encode_uint32(v3.y, &buf[4]);
+ encode_uint32(v3.z, &buf[8]);
+ }
+
+ r_len += 3 * 4;
+
+ } break;
case Variant::TRANSFORM2D: {
if (buf) {
@@ -1075,6 +1226,12 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
case Variant::_RID: {
} break;
+ case Variant::CALLABLE: {
+
+ } break;
+ case Variant::SIGNAL: {
+
+ } break;
case Variant::OBJECT: {
if (p_full_objects) {
@@ -1207,16 +1364,16 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
// arrays
- case Variant::POOL_BYTE_ARRAY: {
+ case Variant::PACKED_BYTE_ARRAY: {
- PoolVector<uint8_t> data = p_variant;
+ Vector<uint8_t> data = p_variant;
int datalen = data.size();
int datasize = sizeof(uint8_t);
if (buf) {
encode_uint32(datalen, buf);
buf += 4;
- PoolVector<uint8_t>::Read r = data.read();
+ const uint8_t *r = data.ptr();
copymem(buf, &r[0], datalen * datasize);
buf += datalen * datasize;
}
@@ -1229,33 +1386,50 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
}
} break;
- case Variant::POOL_INT_ARRAY: {
+ case Variant::PACKED_INT32_ARRAY: {
- PoolVector<int> data = p_variant;
+ Vector<int32_t> data = p_variant;
int datalen = data.size();
int datasize = sizeof(int32_t);
if (buf) {
encode_uint32(datalen, buf);
buf += 4;
- PoolVector<int>::Read r = data.read();
- for (int i = 0; i < datalen; i++)
+ const int32_t *r = data.ptr();
+ for (int32_t i = 0; i < datalen; i++)
encode_uint32(r[i], &buf[i * datasize]);
}
r_len += 4 + datalen * datasize;
} break;
- case Variant::POOL_REAL_ARRAY: {
+ case Variant::PACKED_INT64_ARRAY: {
- PoolVector<real_t> data = p_variant;
+ Vector<int64_t> data = p_variant;
int datalen = data.size();
- int datasize = sizeof(real_t);
+ int datasize = sizeof(int64_t);
+
+ if (buf) {
+ encode_uint64(datalen, buf);
+ buf += 4;
+ const int64_t *r = data.ptr();
+ for (int64_t i = 0; i < datalen; i++)
+ encode_uint64(r[i], &buf[i * datasize]);
+ }
+
+ r_len += 4 + datalen * datasize;
+
+ } break;
+ case Variant::PACKED_FLOAT32_ARRAY: {
+
+ Vector<float> data = p_variant;
+ int datalen = data.size();
+ int datasize = sizeof(float);
if (buf) {
encode_uint32(datalen, buf);
buf += 4;
- PoolVector<real_t>::Read r = data.read();
+ const float *r = data.ptr();
for (int i = 0; i < datalen; i++)
encode_float(r[i], &buf[i * datasize]);
}
@@ -1263,9 +1437,26 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4 + datalen * datasize;
} break;
- case Variant::POOL_STRING_ARRAY: {
+ case Variant::PACKED_FLOAT64_ARRAY: {
+
+ Vector<double> data = p_variant;
+ int datalen = data.size();
+ int datasize = sizeof(double);
+
+ if (buf) {
+ encode_uint32(datalen, buf);
+ buf += 4;
+ const double *r = data.ptr();
+ for (int i = 0; i < datalen; i++)
+ encode_double(r[i], &buf[i * datasize]);
+ }
+
+ r_len += 4 + datalen * datasize;
+
+ } break;
+ case Variant::PACKED_STRING_ARRAY: {
- PoolVector<String> data = p_variant;
+ Vector<String> data = p_variant;
int len = data.size();
if (buf) {
@@ -1295,9 +1486,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
}
} break;
- case Variant::POOL_VECTOR2_ARRAY: {
+ case Variant::PACKED_VECTOR2_ARRAY: {
- PoolVector<Vector2> data = p_variant;
+ Vector<Vector2> data = p_variant;
int len = data.size();
if (buf) {
@@ -1322,9 +1513,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4 * 2 * len;
} break;
- case Variant::POOL_VECTOR3_ARRAY: {
+ case Variant::PACKED_VECTOR3_ARRAY: {
- PoolVector<Vector3> data = p_variant;
+ Vector<Vector3> data = p_variant;
int len = data.size();
if (buf) {
@@ -1350,9 +1541,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4 * 3 * len;
} break;
- case Variant::POOL_COLOR_ARRAY: {
+ case Variant::PACKED_COLOR_ARRAY: {
- PoolVector<Color> data = p_variant;
+ Vector<Color> data = p_variant;
int len = data.size();
if (buf) {
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index 3f66e00021..d7c82fddd9 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -34,6 +34,10 @@
#include "scene/main/node.h"
#include <stdint.h>
+#define NODE_ID_COMPRESSION_SHIFT 3
+#define NAME_ID_COMPRESSION_SHIFT 5
+#define BYTE_ONLY_OR_NO_ARGS_SHIFT 6
+
#ifdef DEBUG_ENABLED
#include "core/os/os.h"
#endif
@@ -51,7 +55,7 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas
case MultiplayerAPI::RPC_MODE_MASTERSYNC: {
if (is_master)
r_skip_rpc = true; // I am the master, so skip remote call.
- FALLTHROUGH;
+ [[fallthrough]];
}
case MultiplayerAPI::RPC_MODE_REMOTESYNC:
case MultiplayerAPI::RPC_MODE_PUPPETSYNC: {
@@ -145,22 +149,22 @@ void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_pee
"Supplied NetworkedMultiplayerPeer must be connecting or connected.");
if (network_peer.is_valid()) {
- network_peer->disconnect("peer_connected", this, "_add_peer");
- network_peer->disconnect("peer_disconnected", this, "_del_peer");
- network_peer->disconnect("connection_succeeded", this, "_connected_to_server");
- network_peer->disconnect("connection_failed", this, "_connection_failed");
- network_peer->disconnect("server_disconnected", this, "_server_disconnected");
+ network_peer->disconnect("peer_connected", callable_mp(this, &MultiplayerAPI::_add_peer));
+ network_peer->disconnect("peer_disconnected", callable_mp(this, &MultiplayerAPI::_del_peer));
+ network_peer->disconnect("connection_succeeded", callable_mp(this, &MultiplayerAPI::_connected_to_server));
+ network_peer->disconnect("connection_failed", callable_mp(this, &MultiplayerAPI::_connection_failed));
+ network_peer->disconnect("server_disconnected", callable_mp(this, &MultiplayerAPI::_server_disconnected));
clear();
}
network_peer = p_peer;
if (network_peer.is_valid()) {
- network_peer->connect("peer_connected", this, "_add_peer");
- network_peer->connect("peer_disconnected", this, "_del_peer");
- network_peer->connect("connection_succeeded", this, "_connected_to_server");
- network_peer->connect("connection_failed", this, "_connection_failed");
- network_peer->connect("server_disconnected", this, "_server_disconnected");
+ network_peer->connect("peer_connected", callable_mp(this, &MultiplayerAPI::_add_peer));
+ network_peer->connect("peer_disconnected", callable_mp(this, &MultiplayerAPI::_del_peer));
+ network_peer->connect("connection_succeeded", callable_mp(this, &MultiplayerAPI::_connected_to_server));
+ network_peer->connect("connection_failed", callable_mp(this, &MultiplayerAPI::_connection_failed));
+ network_peer->connect("server_disconnected", callable_mp(this, &MultiplayerAPI::_server_disconnected));
}
}
@@ -168,6 +172,16 @@ Ref<NetworkedMultiplayerPeer> MultiplayerAPI::get_network_peer() const {
return network_peer;
}
+// Returns the packet size stripping the node path added when the node is not yet cached.
+int get_packet_len(uint32_t p_node_target, int p_packet_len) {
+ if (p_node_target & 0x80000000) {
+ int ofs = p_node_target & 0x7FFFFFFF;
+ return p_packet_len - (p_packet_len - ofs);
+ } else {
+ return p_packet_len;
+ }
+}
+
void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_packet_len) {
ERR_FAIL_COND_MSG(root_node == NULL, "Multiplayer root node was not initialized. If you are using custom multiplayer, remember to set the root node via MultiplayerAPI.set_root_node before using it.");
@@ -204,8 +218,8 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
int name_id_offset = 1;
ERR_FAIL_COND_MSG(p_packet_len < packet_min_size, "Invalid packet received. Size too small.");
// Compute the meta size, which depends on the compression level.
- int node_id_compression = (p_packet[0] & 24) >> 3;
- int name_id_compression = (p_packet[0] & 32) >> 5;
+ int node_id_compression = (p_packet[0] & 24) >> NODE_ID_COMPRESSION_SHIFT;
+ int name_id_compression = (p_packet[0] & 32) >> NAME_ID_COMPRESSION_SHIFT;
switch (node_id_compression) {
case NETWORK_NODE_ID_COMPRESSION_8:
@@ -250,6 +264,7 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
// Unreachable, checked before.
CRASH_NOW();
}
+
Node *node = _process_get_node(p_from, p_packet, node_target, p_packet_len);
ERR_FAIL_COND_MSG(node == NULL, "Invalid packet received. Requested node was not found.");
@@ -266,13 +281,14 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
CRASH_NOW();
}
+ const int packet_len = get_packet_len(node_target, p_packet_len);
if (packet_type == NETWORK_COMMAND_REMOTE_CALL) {
- _process_rpc(node, name_id, p_from, p_packet, p_packet_len, packet_min_size);
+ _process_rpc(node, name_id, p_from, p_packet, packet_len, packet_min_size);
} else {
- _process_rset(node, name_id, p_from, p_packet, p_packet_len, packet_min_size);
+ _process_rset(node, name_id, p_from, p_packet, packet_len, packet_min_size);
}
} break;
@@ -326,7 +342,7 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, uin
void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
- ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
+ ERR_FAIL_COND_MSG(p_offset > p_packet_len, "Invalid packet received. Size too small.");
// Check that remote can call the RPC on this node.
StringName name = p_node->get_node_rpc_method(p_rpc_method_id);
@@ -340,14 +356,30 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id,
bool can_call = _can_call_mode(p_node, rpc_mode, p_from);
ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
- int argc = p_packet[p_offset];
+ int argc = 0;
+ bool byte_only = false;
+
+ const bool byte_only_or_no_args = ((p_packet[0] & 64) >> BYTE_ONLY_OR_NO_ARGS_SHIFT) == 1;
+ if (byte_only_or_no_args) {
+ if (p_offset < p_packet_len) {
+ // This packet contains only bytes.
+ argc = 1;
+ byte_only = true;
+ } else {
+ // This rpc calls a method without parameters.
+ }
+ } else {
+ // Normal variant, takes the argument count from the packet.
+ ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
+ argc = p_packet[p_offset];
+ p_offset += 1;
+ }
+
Vector<Variant> args;
Vector<const Variant *> argp;
args.resize(argc);
argp.resize(argc);
- p_offset++;
-
#ifdef DEBUG_ENABLED
if (profiling) {
ObjectID id = p_node->get_instance_id();
@@ -356,22 +388,32 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id,
}
#endif
- for (int i = 0; i < argc; i++) {
+ if (byte_only) {
+ Vector<uint8_t> pure_data;
+ const int len = p_packet_len - p_offset;
+ pure_data.resize(len);
+ memcpy(pure_data.ptrw(), &p_packet[p_offset], len);
+ args.write[0] = pure_data;
+ argp.write[0] = &args[0];
+ p_offset += len;
+ } else {
+ for (int i = 0; i < argc; i++) {
- ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
+ ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
- int vlen;
- Error err = _decode_and_decompress_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen);
- ERR_FAIL_COND_MSG(err != OK, "Invalid packet received. Unable to decode RPC argument.");
+ int vlen;
+ Error err = _decode_and_decompress_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen);
+ ERR_FAIL_COND_MSG(err != OK, "Invalid packet received. Unable to decode RPC argument.");
- argp.write[i] = &args[i];
- p_offset += vlen;
+ argp.write[i] = &args[i];
+ p_offset += vlen;
+ }
}
- Variant::CallError ce;
+ Callable::CallError ce;
p_node->call(name, (const Variant **)argp.ptr(), argc, ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
String error = Variant::get_call_error_text(p_node, name, (const Variant **)argp.ptr(), argc, ce);
error = "RPC - " + error;
ERR_PRINT(error);
@@ -742,10 +784,12 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
// - `NetworkCommands` in the first three bits.
// - `NetworkNodeIdCompression` in the next 2 bits.
// - `NetworkNameIdCompression` in the next 1 bit.
- // - So we still have the last two bits free!
+ // - `byte_only_or_no_args` in the next 1 bit.
+ // - So we still have the last bit free!
uint8_t command_type = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL;
uint8_t node_id_compression = UINT8_MAX;
uint8_t name_id_compression = UINT8_MAX;
+ bool byte_only_or_no_args = false;
MAKE_ROOM(1);
// The meta is composed along the way, so just set 0 for now.
@@ -835,17 +879,28 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
ofs += 2;
}
- // Call arguments.
- MAKE_ROOM(ofs + 1);
- packet_cache.write[ofs] = p_argcount;
- ofs += 1;
- for (int i = 0; i < p_argcount; i++) {
- int len(0);
- Error err = _encode_and_compress_variant(*p_arg[i], NULL, len);
- ERR_FAIL_COND_MSG(err != OK, "Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!");
- MAKE_ROOM(ofs + len);
- _encode_and_compress_variant(*p_arg[i], &(packet_cache.write[ofs]), len);
- ofs += len;
+ if (p_argcount == 0) {
+ byte_only_or_no_args = true;
+ } else if (p_argcount == 1 && p_arg[0]->get_type() == Variant::PACKED_BYTE_ARRAY) {
+ byte_only_or_no_args = true;
+ // Special optimization when only the byte vector is sent.
+ const Vector<uint8_t> data = *p_arg[0];
+ MAKE_ROOM(ofs + data.size());
+ copymem(&(packet_cache.write[ofs]), data.ptr(), sizeof(uint8_t) * data.size());
+ ofs += data.size();
+ } else {
+ // Arguments
+ MAKE_ROOM(ofs + 1);
+ packet_cache.write[ofs] = p_argcount;
+ ofs += 1;
+ for (int i = 0; i < p_argcount; i++) {
+ int len(0);
+ Error err = _encode_and_compress_variant(*p_arg[i], NULL, len);
+ ERR_FAIL_COND_MSG(err != OK, "Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!");
+ MAKE_ROOM(ofs + len);
+ _encode_and_compress_variant(*p_arg[i], &(packet_cache.write[ofs]), len);
+ ofs += len;
+ }
}
}
@@ -854,7 +909,7 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
ERR_FAIL_COND(name_id_compression > 1);
// We can now set the meta
- packet_cache.write[0] = command_type + (node_id_compression << 3) + (name_id_compression << 5);
+ packet_cache.write[0] = command_type + (node_id_compression << NODE_ID_COMPRESSION_SHIFT) + (name_id_compression << NAME_ID_COMPRESSION_SHIFT) + ((byte_only_or_no_args ? 1 : 0) << BYTE_ONLY_OR_NO_ARGS_SHIFT);
#ifdef DEBUG_ENABLED
if (profiling) {
@@ -989,10 +1044,10 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
if (call_local_native) {
int temp_id = rpc_sender_id;
rpc_sender_id = get_network_unique_id();
- Variant::CallError ce;
+ Callable::CallError ce;
p_node->call(p_method, p_arg, p_argcount, ce);
rpc_sender_id = temp_id;
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce);
error = "rpc() aborted in local call: - " + error + ".";
ERR_PRINT(error);
@@ -1003,11 +1058,11 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
if (call_local_script) {
int temp_id = rpc_sender_id;
rpc_sender_id = get_network_unique_id();
- Variant::CallError ce;
- ce.error = Variant::CallError::CALL_OK;
+ Callable::CallError ce;
+ ce.error = Callable::CallError::CALL_OK;
p_node->get_script_instance()->call(p_method, p_arg, p_argcount, ce);
rpc_sender_id = temp_id;
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce);
error = "rpc() aborted in script local call: - " + error + ".";
ERR_PRINT(error);
@@ -1087,14 +1142,14 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
_send_rpc(p_node, p_peer_id, p_unreliable, true, p_property, &vptr, 1);
}
-Error MultiplayerAPI::send_bytes(PoolVector<uint8_t> p_data, int p_to, NetworkedMultiplayerPeer::TransferMode p_mode) {
+Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, NetworkedMultiplayerPeer::TransferMode p_mode) {
ERR_FAIL_COND_V_MSG(p_data.size() < 1, ERR_INVALID_DATA, "Trying to send an empty raw packet.");
ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), ERR_UNCONFIGURED, "Trying to send a raw packet while no network peer is active.");
ERR_FAIL_COND_V_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED, "Trying to send a raw packet via a network peer which is not connected.");
MAKE_ROOM(p_data.size() + 1);
- PoolVector<uint8_t>::Read r = p_data.read();
+ const uint8_t *r = p_data.ptr();
packet_cache.write[0] = NETWORK_COMMAND_RAW;
memcpy(&packet_cache.write[1], &r[0], p_data.size());
@@ -1108,11 +1163,11 @@ void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_pac
ERR_FAIL_COND_MSG(p_packet_len < 2, "Invalid packet received. Size too small.");
- PoolVector<uint8_t> out;
+ Vector<uint8_t> out;
int len = p_packet_len - 1;
out.resize(len);
{
- PoolVector<uint8_t>::Write w = out.write();
+ uint8_t *w = out.ptrw();
memcpy(&w[0], &p_packet[1], len);
}
emit_signal("network_peer_packet", p_from, out);
@@ -1262,15 +1317,10 @@ void MultiplayerAPI::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_network_unique_id"), &MultiplayerAPI::get_network_unique_id);
ClassDB::bind_method(D_METHOD("is_network_server"), &MultiplayerAPI::is_network_server);
ClassDB::bind_method(D_METHOD("get_rpc_sender_id"), &MultiplayerAPI::get_rpc_sender_id);
- ClassDB::bind_method(D_METHOD("_add_peer", "id"), &MultiplayerAPI::_add_peer);
- ClassDB::bind_method(D_METHOD("_del_peer", "id"), &MultiplayerAPI::_del_peer);
ClassDB::bind_method(D_METHOD("set_network_peer", "peer"), &MultiplayerAPI::set_network_peer);
ClassDB::bind_method(D_METHOD("poll"), &MultiplayerAPI::poll);
ClassDB::bind_method(D_METHOD("clear"), &MultiplayerAPI::clear);
- ClassDB::bind_method(D_METHOD("_connected_to_server"), &MultiplayerAPI::_connected_to_server);
- ClassDB::bind_method(D_METHOD("_connection_failed"), &MultiplayerAPI::_connection_failed);
- ClassDB::bind_method(D_METHOD("_server_disconnected"), &MultiplayerAPI::_server_disconnected);
ClassDB::bind_method(D_METHOD("get_network_connected_peers"), &MultiplayerAPI::get_network_connected_peers);
ClassDB::bind_method(D_METHOD("set_refuse_new_network_connections", "refuse"), &MultiplayerAPI::set_refuse_new_network_connections);
ClassDB::bind_method(D_METHOD("is_refusing_new_network_connections"), &MultiplayerAPI::is_refusing_new_network_connections);
@@ -1284,7 +1334,7 @@ void MultiplayerAPI::_bind_methods() {
ADD_SIGNAL(MethodInfo("network_peer_connected", PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("network_peer_disconnected", PropertyInfo(Variant::INT, "id")));
- ADD_SIGNAL(MethodInfo("network_peer_packet", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::POOL_BYTE_ARRAY, "packet")));
+ ADD_SIGNAL(MethodInfo("network_peer_packet", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::PACKED_BYTE_ARRAY, "packet")));
ADD_SIGNAL(MethodInfo("connected_to_server"));
ADD_SIGNAL(MethodInfo("connection_failed"));
ADD_SIGNAL(MethodInfo("server_disconnected"));
diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h
index 8748dba03c..a706a0e450 100644
--- a/core/io/multiplayer_api.h
+++ b/core/io/multiplayer_api.h
@@ -145,7 +145,7 @@ public:
void set_root_node(Node *p_node);
void set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_peer);
Ref<NetworkedMultiplayerPeer> get_network_peer() const;
- Error send_bytes(PoolVector<uint8_t> p_data, int p_to = NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST, NetworkedMultiplayerPeer::TransferMode p_mode = NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
+ Error send_bytes(Vector<uint8_t> p_data, int p_to = NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST, NetworkedMultiplayerPeer::TransferMode p_mode = NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
// Called by Node.rpc
void rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount);
diff --git a/core/io/net_socket.h b/core/io/net_socket.h
index 710df2dd78..376fd87a27 100644
--- a/core/io/net_socket.h
+++ b/core/io/net_socket.h
@@ -61,7 +61,7 @@ public:
virtual Error connect_to_host(IP_Address p_addr, uint16_t p_port) = 0;
virtual Error poll(PollType p_type, int timeout) const = 0;
virtual Error recv(uint8_t *p_buffer, int p_len, int &r_read) = 0;
- virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) = 0;
+ virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port, bool p_peek = false) = 0;
virtual Error send(const uint8_t *p_buffer, int p_len, int &r_sent) = 0;
virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) = 0;
virtual Ref<NetSocket> accept(IP_Address &r_ip, uint16_t &r_port) = 0;
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index 81d7b86161..2f5c493c2c 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -53,7 +53,7 @@ int PacketPeer::get_encode_buffer_max_size() const {
return encode_buffer_max_size;
}
-Error PacketPeer::get_packet_buffer(PoolVector<uint8_t> &r_buffer) {
+Error PacketPeer::get_packet_buffer(Vector<uint8_t> &r_buffer) {
const uint8_t *buffer;
int buffer_size;
@@ -65,20 +65,20 @@ Error PacketPeer::get_packet_buffer(PoolVector<uint8_t> &r_buffer) {
if (buffer_size == 0)
return OK;
- PoolVector<uint8_t>::Write w = r_buffer.write();
+ uint8_t *w = r_buffer.ptrw();
for (int i = 0; i < buffer_size; i++)
w[i] = buffer[i];
return OK;
}
-Error PacketPeer::put_packet_buffer(const PoolVector<uint8_t> &p_buffer) {
+Error PacketPeer::put_packet_buffer(const Vector<uint8_t> &p_buffer) {
int len = p_buffer.size();
if (len == 0)
return OK;
- PoolVector<uint8_t>::Read r = p_buffer.read();
+ const uint8_t *r = p_buffer.ptr();
return put_packet(&r[0], len);
}
@@ -110,11 +110,11 @@ Error PacketPeer::put_var(const Variant &p_packet, bool p_full_objects) {
encode_buffer.resize(next_power_of_2(len));
}
- PoolVector<uint8_t>::Write w = encode_buffer.write();
- err = encode_variant(p_packet, w.ptr(), len, p_full_objects);
+ uint8_t *w = encode_buffer.ptrw();
+ err = encode_variant(p_packet, w, len, p_full_objects);
ERR_FAIL_COND_V_MSG(err != OK, err, "Error when trying to encode Variant.");
- return put_packet(w.ptr(), len);
+ return put_packet(w, len);
}
Variant PacketPeer::_bnd_get_var(bool p_allow_objects) {
@@ -125,12 +125,12 @@ Variant PacketPeer::_bnd_get_var(bool p_allow_objects) {
return var;
}
-Error PacketPeer::_put_packet(const PoolVector<uint8_t> &p_buffer) {
+Error PacketPeer::_put_packet(const Vector<uint8_t> &p_buffer) {
return put_packet_buffer(p_buffer);
}
-PoolVector<uint8_t> PacketPeer::_get_packet() {
+Vector<uint8_t> PacketPeer::_get_packet() {
- PoolVector<uint8_t> raw;
+ Vector<uint8_t> raw;
last_get_error = get_packet_buffer(raw);
return raw;
}
diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h
index bee69f5ca9..62144259cc 100644
--- a/core/io/packet_peer.h
+++ b/core/io/packet_peer.h
@@ -43,14 +43,14 @@ class PacketPeer : public Reference {
static void _bind_methods();
- Error _put_packet(const PoolVector<uint8_t> &p_buffer);
- PoolVector<uint8_t> _get_packet();
+ Error _put_packet(const Vector<uint8_t> &p_buffer);
+ Vector<uint8_t> _get_packet();
Error _get_packet_error() const;
mutable Error last_get_error;
int encode_buffer_max_size;
- PoolVector<uint8_t> encode_buffer;
+ Vector<uint8_t> encode_buffer;
public:
virtual int get_available_packet_count() const = 0;
@@ -61,8 +61,8 @@ public:
/* helpers / binders */
- virtual Error get_packet_buffer(PoolVector<uint8_t> &r_buffer);
- virtual Error put_packet_buffer(const PoolVector<uint8_t> &p_buffer);
+ virtual Error get_packet_buffer(Vector<uint8_t> &r_buffer);
+ virtual Error put_packet_buffer(const Vector<uint8_t> &p_buffer);
virtual Error get_var(Variant &r_variant, bool p_allow_objects = false);
virtual Error put_var(const Variant &p_packet, bool p_full_objects = false);
diff --git a/core/io/packet_peer_dtls.cpp b/core/io/packet_peer_dtls.cpp
new file mode 100644
index 0000000000..01218a6881
--- /dev/null
+++ b/core/io/packet_peer_dtls.cpp
@@ -0,0 +1,62 @@
+/*************************************************************************/
+/* packet_peer_dtls.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 "packet_peer_dtls.h"
+#include "core/os/file_access.h"
+#include "core/project_settings.h"
+
+PacketPeerDTLS *(*PacketPeerDTLS::_create)() = NULL;
+bool PacketPeerDTLS::available = false;
+
+PacketPeerDTLS *PacketPeerDTLS::create() {
+
+ return _create();
+}
+
+bool PacketPeerDTLS::is_available() {
+ return available;
+}
+
+void PacketPeerDTLS::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("poll"), &PacketPeerDTLS::poll);
+ ClassDB::bind_method(D_METHOD("connect_to_peer", "packet_peer", "validate_certs", "for_hostname", "valid_certificate"), &PacketPeerDTLS::connect_to_peer, DEFVAL(true), DEFVAL(String()), DEFVAL(Ref<X509Certificate>()));
+ ClassDB::bind_method(D_METHOD("get_status"), &PacketPeerDTLS::get_status);
+ ClassDB::bind_method(D_METHOD("disconnect_from_peer"), &PacketPeerDTLS::disconnect_from_peer);
+
+ BIND_ENUM_CONSTANT(STATUS_DISCONNECTED);
+ BIND_ENUM_CONSTANT(STATUS_HANDSHAKING);
+ BIND_ENUM_CONSTANT(STATUS_CONNECTED);
+ BIND_ENUM_CONSTANT(STATUS_ERROR);
+ BIND_ENUM_CONSTANT(STATUS_ERROR_HOSTNAME_MISMATCH);
+}
+
+PacketPeerDTLS::PacketPeerDTLS() {
+}
diff --git a/core/io/packet_peer_dtls.h b/core/io/packet_peer_dtls.h
new file mode 100644
index 0000000000..4f9f4535bc
--- /dev/null
+++ b/core/io/packet_peer_dtls.h
@@ -0,0 +1,68 @@
+/*************************************************************************/
+/* packet_peer_dtls.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 PACKET_PEER_DTLS_H
+#define PACKET_PEER_DTLS_H
+
+#include "core/crypto/crypto.h"
+#include "core/io/packet_peer_udp.h"
+
+class PacketPeerDTLS : public PacketPeer {
+ GDCLASS(PacketPeerDTLS, PacketPeer);
+
+protected:
+ static PacketPeerDTLS *(*_create)();
+ static void _bind_methods();
+
+ static bool available;
+
+public:
+ enum Status {
+ STATUS_DISCONNECTED,
+ STATUS_HANDSHAKING,
+ STATUS_CONNECTED,
+ STATUS_ERROR,
+ STATUS_ERROR_HOSTNAME_MISMATCH
+ };
+
+ virtual void poll() = 0;
+ virtual Error connect_to_peer(Ref<PacketPeerUDP> p_base, bool p_validate_certs = true, const String &p_for_hostname = String(), Ref<X509Certificate> p_ca_certs = Ref<X509Certificate>()) = 0;
+ virtual void disconnect_from_peer() = 0;
+ virtual Status get_status() const = 0;
+
+ static PacketPeerDTLS *create();
+ static bool is_available();
+
+ PacketPeerDTLS();
+};
+
+VARIANT_ENUM_CAST(PacketPeerDTLS::Status);
+
+#endif // PACKET_PEER_DTLS_H
diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp
index a8cfd741bb..f800ffc3db 100644
--- a/core/io/packet_peer_udp.cpp
+++ b/core/io/packet_peer_udp.cpp
@@ -133,7 +133,11 @@ Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
}
do {
- err = _sock->sendto(p_buffer, p_buffer_size, sent, peer_addr, peer_port);
+ if (connected) {
+ err = _sock->send(p_buffer, p_buffer_size, sent);
+ } else {
+ err = _sock->sendto(p_buffer, p_buffer_size, sent, peer_addr, peer_port);
+ }
if (err != OK) {
if (err != ERR_BUSY)
return FAILED;
@@ -184,12 +188,69 @@ Error PacketPeerUDP::listen(int p_port, const IP_Address &p_bind_address, int p_
return OK;
}
+Error PacketPeerUDP::connect_socket(Ref<NetSocket> p_sock) {
+ Error err;
+ int read = 0;
+ uint16_t r_port;
+ IP_Address r_ip;
+
+ err = p_sock->recvfrom(recv_buffer, sizeof(recv_buffer), read, r_ip, r_port, true);
+ ERR_FAIL_COND_V(err != OK, err);
+ err = p_sock->connect_to_host(r_ip, r_port);
+ ERR_FAIL_COND_V(err != OK, err);
+ _sock = p_sock;
+ peer_addr = r_ip;
+ peer_port = r_port;
+ packet_ip = peer_addr;
+ packet_port = peer_port;
+ connected = true;
+ return OK;
+}
+
+Error PacketPeerUDP::connect_to_host(const IP_Address &p_host, int p_port) {
+ ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(!p_host.is_valid(), ERR_INVALID_PARAMETER);
+
+ Error err;
+
+ if (!_sock->is_open()) {
+ IP::Type ip_type = p_host.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
+ err = _sock->open(NetSocket::TYPE_UDP, ip_type);
+ ERR_FAIL_COND_V(err != OK, ERR_CANT_OPEN);
+ _sock->set_blocking_enabled(false);
+ }
+
+ err = _sock->connect_to_host(p_host, p_port);
+
+ // I see no reason why we should get ERR_BUSY (wouldblock/eagain) here.
+ // This is UDP, so connect is only used to tell the OS to which socket
+ // it shuold deliver packets when multiple are bound on the same address/port.
+ if (err != OK) {
+ close();
+ ERR_FAIL_V_MSG(FAILED, "Unable to connect");
+ }
+
+ connected = true;
+
+ peer_addr = p_host;
+ peer_port = p_port;
+
+ // Flush any packet we might still have in queue.
+ rb.clear();
+ return OK;
+}
+
+bool PacketPeerUDP::is_connected_to_host() const {
+ return connected;
+}
+
void PacketPeerUDP::close() {
if (_sock.is_valid())
_sock->close();
rb.resize(16);
queue_count = 0;
+ connected = false;
}
Error PacketPeerUDP::wait() {
@@ -212,7 +273,13 @@ Error PacketPeerUDP::_poll() {
uint16_t port;
while (true) {
- err = _sock->recvfrom(recv_buffer, sizeof(recv_buffer), read, ip, port);
+ if (connected) {
+ err = _sock->recv(recv_buffer, sizeof(recv_buffer), read);
+ ip = peer_addr;
+ port = peer_port;
+ } else {
+ err = _sock->recvfrom(recv_buffer, sizeof(recv_buffer), read, ip, port);
+ }
if (err != OK) {
if (err == ERR_BUSY)
@@ -254,6 +321,7 @@ int PacketPeerUDP::get_packet_port() const {
void PacketPeerUDP::set_dest_address(const IP_Address &p_address, int p_port) {
+ ERR_FAIL_COND_MSG(connected, "Destination address cannot be set for connected sockets");
peer_addr = p_address;
peer_port = p_port;
}
@@ -264,6 +332,8 @@ void PacketPeerUDP::_bind_methods() {
ClassDB::bind_method(D_METHOD("close"), &PacketPeerUDP::close);
ClassDB::bind_method(D_METHOD("wait"), &PacketPeerUDP::wait);
ClassDB::bind_method(D_METHOD("is_listening"), &PacketPeerUDP::is_listening);
+ ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port"), &PacketPeerUDP::connect_to_host);
+ ClassDB::bind_method(D_METHOD("is_connected_to_host"), &PacketPeerUDP::is_connected_to_host);
ClassDB::bind_method(D_METHOD("get_packet_ip"), &PacketPeerUDP::_get_packet_ip);
ClassDB::bind_method(D_METHOD("get_packet_port"), &PacketPeerUDP::get_packet_port);
ClassDB::bind_method(D_METHOD("set_dest_address", "host", "port"), &PacketPeerUDP::_set_dest_address);
@@ -276,6 +346,7 @@ PacketPeerUDP::PacketPeerUDP() :
packet_port(0),
queue_count(0),
peer_port(0),
+ connected(false),
blocking(true),
broadcast(false),
_sock(Ref<NetSocket>(NetSocket::create())) {
diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h
index 15b4d00c37..b5a9fc9ec3 100644
--- a/core/io/packet_peer_udp.h
+++ b/core/io/packet_peer_udp.h
@@ -52,6 +52,7 @@ protected:
IP_Address peer_addr;
int peer_port;
+ bool connected;
bool blocking;
bool broadcast;
Ref<NetSocket> _sock;
@@ -70,6 +71,11 @@ public:
void close();
Error wait();
bool is_listening() const;
+
+ Error connect_socket(Ref<NetSocket> p_sock); // Used by UDPServer
+ Error connect_to_host(const IP_Address &p_host, int p_port);
+ bool is_connected_to_host() const;
+
IP_Address get_packet_address() const;
int get_packet_port() const;
void set_dest_address(const IP_Address &p_address, int p_port);
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 02ae5788fc..efd452191a 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -46,7 +46,7 @@ enum {
VARIANT_NIL = 1,
VARIANT_BOOL = 2,
VARIANT_INT = 3,
- VARIANT_REAL = 4,
+ VARIANT_FLOAT = 4,
VARIANT_STRING = 5,
VARIANT_VECTOR2 = 10,
VARIANT_RECT2 = 11,
@@ -65,14 +65,22 @@ enum {
VARIANT_DICTIONARY = 26,
VARIANT_ARRAY = 30,
VARIANT_RAW_ARRAY = 31,
- VARIANT_INT_ARRAY = 32,
- VARIANT_REAL_ARRAY = 33,
+ VARIANT_INT32_ARRAY = 32,
+ VARIANT_FLOAT32_ARRAY = 33,
VARIANT_STRING_ARRAY = 34,
VARIANT_VECTOR3_ARRAY = 35,
VARIANT_COLOR_ARRAY = 36,
VARIANT_VECTOR2_ARRAY = 37,
VARIANT_INT64 = 40,
VARIANT_DOUBLE = 41,
+ VARIANT_CALLABLE = 42,
+ VARIANT_SIGNAL = 43,
+ VARIANT_STRING_NAME = 44,
+ VARIANT_VECTOR2I = 45,
+ VARIANT_RECT2I = 46,
+ VARIANT_VECTOR3I = 47,
+ VARIANT_INT64_ARRAY = 48,
+ VARIANT_FLOAT64_ARRAY = 49,
OBJECT_EMPTY = 0,
OBJECT_EXTERNAL_RESOURCE = 1,
OBJECT_INTERNAL_RESOURCE = 2,
@@ -85,7 +93,7 @@ enum {
};
-void ResourceInteractiveLoaderBinary::_advance_padding(uint32_t p_len) {
+void ResourceLoaderBinary::_advance_padding(uint32_t p_len) {
uint32_t extra = 4 - (p_len % 4);
if (extra < 4) {
@@ -94,7 +102,7 @@ void ResourceInteractiveLoaderBinary::_advance_padding(uint32_t p_len) {
}
}
-StringName ResourceInteractiveLoaderBinary::_get_string() {
+StringName ResourceLoaderBinary::_get_string() {
uint32_t id = f->get_32();
if (id & 0x80000000) {
@@ -113,7 +121,7 @@ StringName ResourceInteractiveLoaderBinary::_get_string() {
return string_map[id];
}
-Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
+Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
uint32_t type = f->get_32();
print_bl("find property of type: " + itos(type));
@@ -136,7 +144,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
r_v = int64_t(f->get_64());
} break;
- case VARIANT_REAL: {
+ case VARIANT_FLOAT: {
r_v = f->get_real();
} break;
@@ -156,6 +164,14 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
r_v = v;
} break;
+ case VARIANT_VECTOR2I: {
+
+ Vector2i v;
+ v.x = f->get_32();
+ v.y = f->get_32();
+ r_v = v;
+
+ } break;
case VARIANT_RECT2: {
Rect2 v;
@@ -166,6 +182,16 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
r_v = v;
} break;
+ case VARIANT_RECT2I: {
+
+ Rect2i v;
+ v.position.x = f->get_32();
+ v.position.y = f->get_32();
+ v.size.x = f->get_32();
+ v.size.y = f->get_32();
+ r_v = v;
+
+ } break;
case VARIANT_VECTOR3: {
Vector3 v;
@@ -174,6 +200,14 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
v.z = f->get_real();
r_v = v;
} break;
+ case VARIANT_VECTOR3I: {
+
+ Vector3i v;
+ v.x = f->get_32();
+ v.y = f->get_32();
+ v.z = f->get_32();
+ r_v = v;
+ } break;
case VARIANT_PLANE: {
Plane v;
@@ -258,6 +292,10 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
r_v = v;
} break;
+ case VARIANT_STRING_NAME: {
+
+ r_v = StringName(get_unicode_string());
+ } break;
case VARIANT_NODE_PATH: {
@@ -339,20 +377,26 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
r_v = Variant();
} else {
- String exttype = external_resources[erindex].type;
- String path = external_resources[erindex].path;
+ if (external_resources[erindex].cache.is_null()) {
+ //cache not here yet, wait for it?
+ if (use_sub_threads) {
+ Error err;
+ external_resources.write[erindex].cache = ResourceLoader::load_threaded_get(external_resources[erindex].path, &err);
- if (path.find("://") == -1 && path.is_rel_path()) {
- // path is relative to file being loaded, so convert to a resource path
- path = ProjectSettings::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
- }
+ if (err != OK || external_resources[erindex].cache.is_null()) {
+ if (!ResourceLoader::get_abort_on_missing_resources()) {
- RES res = ResourceLoader::load(path, exttype);
+ ResourceLoader::notify_dependency_error(local_path, external_resources[erindex].path, external_resources[erindex].type);
+ } else {
- if (res.is_null()) {
- WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
+ error = ERR_FILE_MISSING_DEPENDENCIES;
+ ERR_FAIL_V_MSG(error, "Can't load dependency: " + external_resources[erindex].path + ".");
+ }
+ }
+ }
}
- r_v = res;
+
+ r_v = external_resources[erindex].cache;
}
} break;
@@ -363,6 +407,15 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
}
} break;
+ case VARIANT_CALLABLE: {
+
+ r_v = Callable();
+ } break;
+ case VARIANT_SIGNAL: {
+
+ r_v = Signal();
+ } break;
+
case VARIANT_DICTIONARY: {
uint32_t len = f->get_32();
@@ -398,23 +451,23 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
uint32_t len = f->get_32();
- PoolVector<uint8_t> array;
+ Vector<uint8_t> array;
array.resize(len);
- PoolVector<uint8_t>::Write w = array.write();
- f->get_buffer(w.ptr(), len);
+ uint8_t *w = array.ptrw();
+ f->get_buffer(w, len);
_advance_padding(len);
- w.release();
+
r_v = array;
} break;
- case VARIANT_INT_ARRAY: {
+ case VARIANT_INT32_ARRAY: {
uint32_t len = f->get_32();
- PoolVector<int> array;
+ Vector<int32_t> array;
array.resize(len);
- PoolVector<int>::Write w = array.write();
- f->get_buffer((uint8_t *)w.ptr(), len * 4);
+ int32_t *w = array.ptrw();
+ f->get_buffer((uint8_t *)w, len * sizeof(int32_t));
#ifdef BIG_ENDIAN_ENABLED
{
uint32_t *ptr = (uint32_t *)w.ptr();
@@ -425,17 +478,38 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
}
#endif
- w.release();
+
+ r_v = array;
+ } break;
+ case VARIANT_INT64_ARRAY: {
+
+ uint32_t len = f->get_32();
+
+ Vector<int64_t> array;
+ array.resize(len);
+ int64_t *w = array.ptrw();
+ f->get_buffer((uint8_t *)w, len * sizeof(int64_t));
+#ifdef BIG_ENDIAN_ENABLED
+ {
+ uint64_t *ptr = (uint64_t *)w.ptr();
+ for (int i = 0; i < len; i++) {
+
+ ptr[i] = BSWAP64(ptr[i]);
+ }
+ }
+
+#endif
+
r_v = array;
} break;
- case VARIANT_REAL_ARRAY: {
+ case VARIANT_FLOAT32_ARRAY: {
uint32_t len = f->get_32();
- PoolVector<real_t> array;
+ Vector<float> array;
array.resize(len);
- PoolVector<real_t>::Write w = array.write();
- f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t));
+ float *w = array.ptrw();
+ f->get_buffer((uint8_t *)w, len * sizeof(float));
#ifdef BIG_ENDIAN_ENABLED
{
uint32_t *ptr = (uint32_t *)w.ptr();
@@ -447,18 +521,38 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
#endif
- w.release();
+ r_v = array;
+ } break;
+ case VARIANT_FLOAT64_ARRAY: {
+
+ uint32_t len = f->get_32();
+
+ Vector<double> array;
+ array.resize(len);
+ double *w = array.ptrw();
+ f->get_buffer((uint8_t *)w, len * sizeof(double));
+#ifdef BIG_ENDIAN_ENABLED
+ {
+ uint64_t *ptr = (uint64_t *)w.ptr();
+ for (int i = 0; i < len; i++) {
+
+ ptr[i] = BSWAP64(ptr[i]);
+ }
+ }
+
+#endif
+
r_v = array;
} break;
case VARIANT_STRING_ARRAY: {
uint32_t len = f->get_32();
- PoolVector<String> array;
+ Vector<String> array;
array.resize(len);
- PoolVector<String>::Write w = array.write();
+ String *w = array.ptrw();
for (uint32_t i = 0; i < len; i++)
w[i] = get_unicode_string();
- w.release();
+
r_v = array;
} break;
@@ -466,11 +560,11 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
uint32_t len = f->get_32();
- PoolVector<Vector2> array;
+ Vector<Vector2> array;
array.resize(len);
- PoolVector<Vector2>::Write w = array.write();
+ Vector2 *w = array.ptrw();
if (sizeof(Vector2) == 8) {
- f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t) * 2);
+ f->get_buffer((uint8_t *)w, len * sizeof(real_t) * 2);
#ifdef BIG_ENDIAN_ENABLED
{
uint32_t *ptr = (uint32_t *)w.ptr();
@@ -485,7 +579,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
} else {
ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Vector2 size is NOT 8!");
}
- w.release();
+
r_v = array;
} break;
@@ -493,11 +587,11 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
uint32_t len = f->get_32();
- PoolVector<Vector3> array;
+ Vector<Vector3> array;
array.resize(len);
- PoolVector<Vector3>::Write w = array.write();
+ Vector3 *w = array.ptrw();
if (sizeof(Vector3) == 12) {
- f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t) * 3);
+ f->get_buffer((uint8_t *)w, len * sizeof(real_t) * 3);
#ifdef BIG_ENDIAN_ENABLED
{
uint32_t *ptr = (uint32_t *)w.ptr();
@@ -512,7 +606,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
} else {
ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Vector3 size is NOT 12!");
}
- w.release();
+
r_v = array;
} break;
@@ -520,11 +614,11 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
uint32_t len = f->get_32();
- PoolVector<Color> array;
+ Vector<Color> array;
array.resize(len);
- PoolVector<Color>::Write w = array.write();
+ Color *w = array.ptrw();
if (sizeof(Color) == 16) {
- f->get_buffer((uint8_t *)w.ptr(), len * sizeof(real_t) * 4);
+ f->get_buffer((uint8_t *)w, len * sizeof(real_t) * 4);
#ifdef BIG_ENDIAN_ENABLED
{
uint32_t *ptr = (uint32_t *)w.ptr();
@@ -539,7 +633,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
} else {
ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Color size is NOT 16!");
}
- w.release();
+
r_v = array;
} break;
default: {
@@ -550,160 +644,168 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
return OK; //never reach anyway
}
-void ResourceInteractiveLoaderBinary::set_local_path(const String &p_local_path) {
+void ResourceLoaderBinary::set_local_path(const String &p_local_path) {
res_path = p_local_path;
}
-Ref<Resource> ResourceInteractiveLoaderBinary::get_resource() {
+Ref<Resource> ResourceLoaderBinary::get_resource() {
return resource;
}
-Error ResourceInteractiveLoaderBinary::poll() {
+Error ResourceLoaderBinary::load() {
if (error != OK)
return error;
- int s = stage;
+ int stage = 0;
- if (s < external_resources.size()) {
+ for (int i = 0; i < external_resources.size(); i++) {
- String path = external_resources[s].path;
+ String path = external_resources[i].path;
if (remaps.has(path)) {
path = remaps[path];
}
- RES res = ResourceLoader::load(path, external_resources[s].type);
- if (res.is_null()) {
- if (!ResourceLoader::get_abort_on_missing_resources()) {
+ if (path.find("://") == -1 && path.is_rel_path()) {
+ // path is relative to file being loaded, so convert to a resource path
+ path = ProjectSettings::get_singleton()->localize_path(path.get_base_dir().plus_file(external_resources[i].path));
+ }
- ResourceLoader::notify_dependency_error(local_path, path, external_resources[s].type);
- } else {
+ external_resources.write[i].path = path; //remap happens here, not on load because on load it can actually be used for filesystem dock resource remap
+
+ if (!use_sub_threads) {
+ external_resources.write[i].cache = ResourceLoader::load(path, external_resources[i].type);
- error = ERR_FILE_MISSING_DEPENDENCIES;
- ERR_FAIL_V_MSG(error, "Can't load dependency: " + path + ".");
+ if (external_resources[i].cache.is_null()) {
+ if (!ResourceLoader::get_abort_on_missing_resources()) {
+
+ ResourceLoader::notify_dependency_error(local_path, path, external_resources[i].type);
+ } else {
+
+ error = ERR_FILE_MISSING_DEPENDENCIES;
+ ERR_FAIL_V_MSG(error, "Can't load dependency: " + path + ".");
+ }
}
} else {
- resource_cache.push_back(res);
+ Error err = ResourceLoader::load_threaded_request(path, external_resources[i].type, use_sub_threads, local_path);
+ if (err != OK) {
+ if (!ResourceLoader::get_abort_on_missing_resources()) {
+
+ ResourceLoader::notify_dependency_error(local_path, path, external_resources[i].type);
+ } else {
+
+ error = ERR_FILE_MISSING_DEPENDENCIES;
+ ERR_FAIL_V_MSG(error, "Can't load dependency: " + path + ".");
+ }
+ }
}
stage++;
- return error;
}
- s -= external_resources.size();
-
- if (s >= internal_resources.size()) {
+ for (int i = 0; i < internal_resources.size(); i++) {
- error = ERR_BUG;
- ERR_FAIL_COND_V(s >= internal_resources.size(), error);
- }
+ bool main = i == (internal_resources.size() - 1);
- bool main = s == (internal_resources.size() - 1);
+ //maybe it is loaded already
+ String path;
+ int subindex = 0;
- //maybe it is loaded already
- String path;
- int subindex = 0;
+ if (!main) {
- if (!main) {
+ path = internal_resources[i].path;
+ if (path.begins_with("local://")) {
+ path = path.replace_first("local://", "");
+ subindex = path.to_int();
+ path = res_path + "::" + path;
+ }
- path = internal_resources[s].path;
- if (path.begins_with("local://")) {
- path = path.replace_first("local://", "");
- subindex = path.to_int();
- path = res_path + "::" + path;
- }
+ if (ResourceCache::has(path)) {
+ //already loaded, don't do anything
+ stage++;
+ error = OK;
+ continue;
+ }
+ } else {
- if (ResourceCache::has(path)) {
- //already loaded, don't do anything
- stage++;
- error = OK;
- return error;
+ if (!ResourceCache::has(res_path))
+ path = res_path;
}
- } else {
- if (!ResourceCache::has(res_path))
- path = res_path;
- }
-
- uint64_t offset = internal_resources[s].offset;
+ uint64_t offset = internal_resources[i].offset;
- f->seek(offset);
+ f->seek(offset);
- String t = get_unicode_string();
+ String t = get_unicode_string();
- Object *obj = ClassDB::instance(t);
- if (!obj) {
- error = ERR_FILE_CORRUPT;
- ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource of unrecognized type in file: " + t + ".");
- }
+ Object *obj = ClassDB::instance(t);
+ if (!obj) {
+ error = ERR_FILE_CORRUPT;
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource of unrecognized type in file: " + t + ".");
+ }
- Resource *r = Object::cast_to<Resource>(obj);
- if (!r) {
- String obj_class = obj->get_class();
- error = ERR_FILE_CORRUPT;
- memdelete(obj); //bye
- ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource type in resource field not a resource, type is: " + obj_class + ".");
- }
+ Resource *r = Object::cast_to<Resource>(obj);
+ if (!r) {
+ String obj_class = obj->get_class();
+ error = ERR_FILE_CORRUPT;
+ memdelete(obj); //bye
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource type in resource field not a resource, type is: " + obj_class + ".");
+ }
- RES res = RES(r);
+ RES res = RES(r);
- r->set_path(path);
- r->set_subindex(subindex);
+ r->set_path(path);
+ r->set_subindex(subindex);
- int pc = f->get_32();
+ int pc = f->get_32();
- //set properties
+ //set properties
- for (int i = 0; i < pc; i++) {
+ for (int j = 0; j < pc; j++) {
- StringName name = _get_string();
+ StringName name = _get_string();
- if (name == StringName()) {
- error = ERR_FILE_CORRUPT;
- ERR_FAIL_V(ERR_FILE_CORRUPT);
- }
+ if (name == StringName()) {
+ error = ERR_FILE_CORRUPT;
+ ERR_FAIL_V(ERR_FILE_CORRUPT);
+ }
- Variant value;
+ Variant value;
- error = parse_variant(value);
- if (error)
- return error;
+ error = parse_variant(value);
+ if (error)
+ return error;
- res->set(name, value);
- }
+ res->set(name, value);
+ }
#ifdef TOOLS_ENABLED
- res->set_edited(false);
+ res->set_edited(false);
#endif
- stage++;
+ stage++;
- resource_cache.push_back(res);
+ if (progress) {
+ *progress = (i + 1) / float(internal_resources.size());
+ }
- if (main) {
+ resource_cache.push_back(res);
- f->close();
- resource = res;
- resource->set_as_translation_remapped(translation_remapped);
- error = ERR_FILE_EOF;
+ if (main) {
- } else {
- error = OK;
+ f->close();
+ resource = res;
+ resource->set_as_translation_remapped(translation_remapped);
+ error = OK;
+ return OK;
+ }
}
- return OK;
+ return ERR_FILE_EOF;
}
-int ResourceInteractiveLoaderBinary::get_stage() const {
- return stage;
-}
-int ResourceInteractiveLoaderBinary::get_stage_count() const {
-
- return external_resources.size() + internal_resources.size();
-}
-
-void ResourceInteractiveLoaderBinary::set_translation_remapped(bool p_remapped) {
+void ResourceLoaderBinary::set_translation_remapped(bool p_remapped) {
translation_remapped = p_remapped;
}
@@ -726,7 +828,7 @@ static String get_ustring(FileAccess *f) {
return s;
}
-String ResourceInteractiveLoaderBinary::get_unicode_string() {
+String ResourceLoaderBinary::get_unicode_string() {
int len = f->get_32();
if (len > str_buf.size()) {
@@ -740,7 +842,7 @@ String ResourceInteractiveLoaderBinary::get_unicode_string() {
return s;
}
-void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) {
+void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) {
open(p_f);
if (error)
@@ -758,7 +860,7 @@ void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f, List<Str
}
}
-void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
+void ResourceLoaderBinary::open(FileAccess *p_f) {
error = OK;
@@ -859,7 +961,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
}
}
-String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) {
+String ResourceLoaderBinary::recognize(FileAccess *p_f) {
error = OK;
@@ -904,20 +1006,24 @@ String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) {
return type;
}
-ResourceInteractiveLoaderBinary::ResourceInteractiveLoaderBinary() :
+ResourceLoaderBinary::ResourceLoaderBinary() :
translation_remapped(false),
+ ver_format(0),
f(NULL),
- error(OK),
- stage(0) {
+ importmd_ofs(0),
+ error(OK) {
+
+ progress = nullptr;
+ use_sub_threads = false;
}
-ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() {
+ResourceLoaderBinary::~ResourceLoaderBinary() {
if (f)
memdelete(f);
}
-Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
if (r_error)
*r_error = ERR_FILE_CANT_OPEN;
@@ -925,16 +1031,27 @@ Ref<ResourceInteractiveLoader> ResourceFormatLoaderBinary::load_interactive(cons
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
- ERR_FAIL_COND_V_MSG(err != OK, Ref<ResourceInteractiveLoader>(), "Cannot open file '" + p_path + "'.");
+ ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'.");
- Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary);
+ ResourceLoaderBinary loader;
+ loader.use_sub_threads = p_use_sub_threads;
+ loader.progress = r_progress;
String path = p_original_path != "" ? p_original_path : p_path;
- ria->local_path = ProjectSettings::get_singleton()->localize_path(path);
- ria->res_path = ria->local_path;
- //ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
- ria->open(f);
+ loader.local_path = ProjectSettings::get_singleton()->localize_path(path);
+ loader.res_path = loader.local_path;
+ //loader.set_local_path( Globals::get_singleton()->localize_path(p_path) );
+ loader.open(f);
+
+ err = loader.load();
+
+ if (r_error) {
+ *r_error = err;
+ }
- return ria;
+ if (err) {
+ return RES();
+ }
+ return loader.resource;
}
void ResourceFormatLoaderBinary::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
@@ -976,11 +1093,11 @@ void ResourceFormatLoaderBinary::get_dependencies(const String &p_path, List<Str
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_MSG(!f, "Cannot open file '" + p_path + "'.");
- Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary);
- ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
- ria->res_path = ria->local_path;
- //ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
- ria->get_dependencies(f, p_dependencies, p_add_types);
+ ResourceLoaderBinary loader;
+ loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ loader.res_path = loader.local_path;
+ //loader.set_local_path( Globals::get_singleton()->localize_path(p_path) );
+ loader.get_dependencies(f, p_dependencies, p_add_types);
}
Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {
@@ -1065,21 +1182,17 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_OPEN, "Cannot open file '" + p_path + "'.");
- Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary);
- ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
- ria->res_path = ria->local_path;
- ria->remaps = p_map;
- //ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
- ria->open(f);
+ ResourceLoaderBinary loader;
+ loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ loader.res_path = loader.local_path;
+ loader.remaps = p_map;
+ //loader.set_local_path( Globals::get_singleton()->localize_path(p_path) );
+ loader.open(f);
- err = ria->poll();
-
- while (err == OK) {
- err = ria->poll();
- }
+ err = loader.load();
ERR_FAIL_COND_V(err != ERR_FILE_EOF, ERR_FILE_CORRUPT);
- RES res = ria->get_resource();
+ RES res = loader.get_resource();
ERR_FAIL_COND_V(!res.is_valid(), ERR_FILE_CORRUPT);
return ResourceFormatSaverBinary::singleton->save(p_path, res);
@@ -1195,11 +1308,11 @@ String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const
return ""; //could not rwead
}
- Ref<ResourceInteractiveLoaderBinary> ria = memnew(ResourceInteractiveLoaderBinary);
- ria->local_path = ProjectSettings::get_singleton()->localize_path(p_path);
- ria->res_path = ria->local_path;
- //ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
- String r = ria->recognize(f);
+ ResourceLoaderBinary loader;
+ loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ loader.res_path = loader.local_path;
+ //loader.set_local_path( Globals::get_singleton()->localize_path(p_path) );
+ String r = loader.recognize(f);
return ClassDB::get_compatibility_remapped_class(r);
}
@@ -1249,7 +1362,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
}
} break;
- case Variant::REAL: {
+ case Variant::FLOAT: {
double d = p_property;
float fl = d;
@@ -1258,7 +1371,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
f->store_double(d);
} else {
- f->store_32(VARIANT_REAL);
+ f->store_32(VARIANT_FLOAT);
f->store_real(fl);
}
@@ -1278,6 +1391,14 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
f->store_real(val.y);
} break;
+ case Variant::VECTOR2I: {
+
+ f->store_32(VARIANT_VECTOR2I);
+ Vector2i val = p_property;
+ f->store_32(val.x);
+ f->store_32(val.y);
+
+ } break;
case Variant::RECT2: {
f->store_32(VARIANT_RECT2);
@@ -1288,6 +1409,16 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
f->store_real(val.size.y);
} break;
+ case Variant::RECT2I: {
+
+ f->store_32(VARIANT_RECT2I);
+ Rect2i val = p_property;
+ f->store_32(val.position.x);
+ f->store_32(val.position.y);
+ f->store_32(val.size.x);
+ f->store_32(val.size.y);
+
+ } break;
case Variant::VECTOR3: {
f->store_32(VARIANT_VECTOR3);
@@ -1297,6 +1428,15 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
f->store_real(val.z);
} break;
+ case Variant::VECTOR3I: {
+
+ f->store_32(VARIANT_VECTOR3I);
+ Vector3i val = p_property;
+ f->store_32(val.x);
+ f->store_32(val.y);
+ f->store_32(val.z);
+
+ } break;
case Variant::PLANE: {
f->store_32(VARIANT_PLANE);
@@ -1384,6 +1524,13 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
f->store_real(val.a);
} break;
+ case Variant::STRING_NAME: {
+
+ f->store_32(VARIANT_STRING_NAME);
+ String val = p_property;
+ save_unicode_string(f, val);
+
+ } break;
case Variant::NODE_PATH: {
f->store_32(VARIANT_NODE_PATH);
@@ -1441,6 +1588,17 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
}
} break;
+ case Variant::CALLABLE: {
+
+ f->store_32(VARIANT_CALLABLE);
+ WARN_PRINT("Can't save Callables.");
+ } break;
+ case Variant::SIGNAL: {
+
+ f->store_32(VARIANT_SIGNAL);
+ WARN_PRINT("Can't save Signals.");
+ } break;
+
case Variant::DICTIONARY: {
f->store_32(VARIANT_DICTIONARY);
@@ -1473,59 +1631,82 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
}
} break;
- case Variant::POOL_BYTE_ARRAY: {
+ case Variant::PACKED_BYTE_ARRAY: {
f->store_32(VARIANT_RAW_ARRAY);
- PoolVector<uint8_t> arr = p_property;
+ Vector<uint8_t> arr = p_property;
int len = arr.size();
f->store_32(len);
- PoolVector<uint8_t>::Read r = arr.read();
- f->store_buffer(r.ptr(), len);
+ const uint8_t *r = arr.ptr();
+ f->store_buffer(r, len);
_pad_buffer(f, len);
} break;
- case Variant::POOL_INT_ARRAY: {
+ case Variant::PACKED_INT32_ARRAY: {
- f->store_32(VARIANT_INT_ARRAY);
- PoolVector<int> arr = p_property;
+ f->store_32(VARIANT_INT32_ARRAY);
+ Vector<int32_t> arr = p_property;
int len = arr.size();
f->store_32(len);
- PoolVector<int>::Read r = arr.read();
+ const int32_t *r = arr.ptr();
for (int i = 0; i < len; i++)
f->store_32(r[i]);
} break;
- case Variant::POOL_REAL_ARRAY: {
+ case Variant::PACKED_INT64_ARRAY: {
+
+ f->store_32(VARIANT_INT64_ARRAY);
+ Vector<int64_t> arr = p_property;
+ int len = arr.size();
+ f->store_32(len);
+ const int64_t *r = arr.ptr();
+ for (int i = 0; i < len; i++)
+ f->store_64(r[i]);
+
+ } break;
+ case Variant::PACKED_FLOAT32_ARRAY: {
- f->store_32(VARIANT_REAL_ARRAY);
- PoolVector<real_t> arr = p_property;
+ f->store_32(VARIANT_FLOAT32_ARRAY);
+ Vector<float> arr = p_property;
int len = arr.size();
f->store_32(len);
- PoolVector<real_t>::Read r = arr.read();
+ const float *r = arr.ptr();
for (int i = 0; i < len; i++) {
f->store_real(r[i]);
}
} break;
- case Variant::POOL_STRING_ARRAY: {
+ case Variant::PACKED_FLOAT64_ARRAY: {
+
+ f->store_32(VARIANT_FLOAT64_ARRAY);
+ Vector<double> arr = p_property;
+ int len = arr.size();
+ f->store_32(len);
+ const double *r = arr.ptr();
+ for (int i = 0; i < len; i++) {
+ f->store_double(r[i]);
+ }
+
+ } break;
+ case Variant::PACKED_STRING_ARRAY: {
f->store_32(VARIANT_STRING_ARRAY);
- PoolVector<String> arr = p_property;
+ Vector<String> arr = p_property;
int len = arr.size();
f->store_32(len);
- PoolVector<String>::Read r = arr.read();
+ const String *r = arr.ptr();
for (int i = 0; i < len; i++) {
save_unicode_string(f, r[i]);
}
} break;
- case Variant::POOL_VECTOR3_ARRAY: {
+ case Variant::PACKED_VECTOR3_ARRAY: {
f->store_32(VARIANT_VECTOR3_ARRAY);
- PoolVector<Vector3> arr = p_property;
+ Vector<Vector3> arr = p_property;
int len = arr.size();
f->store_32(len);
- PoolVector<Vector3>::Read r = arr.read();
+ const Vector3 *r = arr.ptr();
for (int i = 0; i < len; i++) {
f->store_real(r[i].x);
f->store_real(r[i].y);
@@ -1533,26 +1714,26 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
}
} break;
- case Variant::POOL_VECTOR2_ARRAY: {
+ case Variant::PACKED_VECTOR2_ARRAY: {
f->store_32(VARIANT_VECTOR2_ARRAY);
- PoolVector<Vector2> arr = p_property;
+ Vector<Vector2> arr = p_property;
int len = arr.size();
f->store_32(len);
- PoolVector<Vector2>::Read r = arr.read();
+ const Vector2 *r = arr.ptr();
for (int i = 0; i < len; i++) {
f->store_real(r[i].x);
f->store_real(r[i].y);
}
} break;
- case Variant::POOL_COLOR_ARRAY: {
+ case Variant::PACKED_COLOR_ARRAY: {
f->store_32(VARIANT_COLOR_ARRAY);
- PoolVector<Color> arr = p_property;
+ Vector<Color> arr = p_property;
int len = arr.size();
f->store_32(len);
- PoolVector<Color>::Read r = arr.read();
+ const Color *r = arr.ptr();
for (int i = 0; i < len; i++) {
f->store_real(r[i].r);
f->store_real(r[i].g);
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index f02dbaa0c2..0ffa2c3626 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -35,7 +35,7 @@
#include "core/io/resource_saver.h"
#include "core/os/file_access.h"
-class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
+class ResourceLoaderBinary {
bool translation_remapped;
String local_path;
@@ -58,8 +58,11 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
struct ExtResource {
String path;
String type;
+ RES cache;
};
+ bool use_sub_threads;
+ float *progress;
Vector<ExtResource> external_resources;
struct IntResource {
@@ -75,32 +78,30 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
Map<String, String> remaps;
Error error;
- int stage;
-
friend class ResourceFormatLoaderBinary;
Error parse_variant(Variant &r_v);
+ Map<String, RES> dependency_cache;
+
public:
- virtual void set_local_path(const String &p_local_path);
- virtual Ref<Resource> get_resource();
- virtual Error poll();
- virtual int get_stage() const;
- virtual int get_stage_count() const;
- virtual void set_translation_remapped(bool p_remapped);
+ void set_local_path(const String &p_local_path);
+ Ref<Resource> get_resource();
+ Error load();
+ void set_translation_remapped(bool p_remapped);
void set_remaps(const Map<String, String> &p_remaps) { remaps = p_remaps; }
void open(FileAccess *p_f);
String recognize(FileAccess *p_f);
void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
- ResourceInteractiveLoaderBinary();
- ~ResourceInteractiveLoaderBinary();
+ ResourceLoaderBinary();
+ ~ResourceLoaderBinary();
};
class ResourceFormatLoaderBinary : public ResourceFormatLoader {
public:
- virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp
index f147170ff7..efaf958949 100644
--- a/core/io/resource_importer.cpp
+++ b/core/io/resource_importer.cpp
@@ -117,7 +117,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
return OK;
}
-RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
PathAndType pat;
Error err = _get_path_and_type(p_path, pat);
@@ -130,7 +130,7 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_
return RES();
}
- RES res = ResourceLoader::_load(pat.path, p_path, pat.type, false, r_error);
+ RES res = ResourceLoader::_load(pat.path, p_path, pat.type, false, r_error, p_use_sub_threads, r_progress);
#ifdef TOOLS_ENABLED
if (res.is_valid()) {
diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h
index 4eb04586e6..65c148f2ac 100644
--- a/core/io/resource_importer.h
+++ b/core/io/resource_importer.h
@@ -58,7 +58,7 @@ class ResourceFormatImporter : public ResourceFormatLoader {
public:
static ResourceFormatImporter *get_singleton() { return singleton; }
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const;
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 6877f816e1..5dca8b3b89 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -39,26 +39,16 @@
#include "core/translation.h"
#include "core/variant_parser.h"
+#ifdef DEBUG_LOAD_THREADED
+#define print_lt(m_text) print_line(m_text)
+#else
+#define print_lt(m_text)
+#endif
+
Ref<ResourceFormatLoader> ResourceLoader::loader[ResourceLoader::MAX_LOADERS];
int ResourceLoader::loader_count = 0;
-Error ResourceInteractiveLoader::wait() {
-
- Error err = poll();
- while (err == OK) {
- err = poll();
- }
-
- return err;
-}
-
-ResourceInteractiveLoader::~ResourceInteractiveLoader() {
- if (path_loading != String()) {
- ResourceLoader::_remove_from_loading_map_and_thread(path_loading, path_loading_thread);
- }
-}
-
bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_for_type) const {
String extension = p_path.get_extension();
@@ -111,45 +101,6 @@ void ResourceLoader::get_recognized_extensions_for_type(const String &p_type, Li
}
}
-void ResourceInteractiveLoader::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("get_resource"), &ResourceInteractiveLoader::get_resource);
- ClassDB::bind_method(D_METHOD("poll"), &ResourceInteractiveLoader::poll);
- ClassDB::bind_method(D_METHOD("wait"), &ResourceInteractiveLoader::wait);
- ClassDB::bind_method(D_METHOD("get_stage"), &ResourceInteractiveLoader::get_stage);
- ClassDB::bind_method(D_METHOD("get_stage_count"), &ResourceInteractiveLoader::get_stage_count);
-}
-
-class ResourceInteractiveLoaderDefault : public ResourceInteractiveLoader {
-
- GDCLASS(ResourceInteractiveLoaderDefault, ResourceInteractiveLoader);
-
-public:
- Ref<Resource> resource;
-
- virtual void set_local_path(const String &p_local_path) { /*scene->set_filename(p_local_path);*/
- }
- virtual Ref<Resource> get_resource() { return resource; }
- virtual Error poll() { return ERR_FILE_EOF; }
- virtual int get_stage() const { return 1; }
- virtual int get_stage_count() const { return 1; }
- virtual void set_translation_remapped(bool p_remapped) { resource->set_as_translation_remapped(p_remapped); }
-
- ResourceInteractiveLoaderDefault() {}
-};
-
-Ref<ResourceInteractiveLoader> ResourceFormatLoader::load_interactive(const String &p_path, const String &p_original_path, Error *r_error) {
-
- //either this
- Ref<Resource> res = load(p_path, p_original_path, r_error);
- if (res.is_null())
- return Ref<ResourceInteractiveLoader>();
-
- Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault));
- ril->resource = res;
- return ril;
-}
-
bool ResourceFormatLoader::exists(const String &p_path) const {
return FileAccess::exists(p_path); //by default just check file
}
@@ -157,10 +108,10 @@ bool ResourceFormatLoader::exists(const String &p_path) const {
void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions) const {
if (get_script_instance() && get_script_instance()->has_method("get_recognized_extensions")) {
- PoolStringArray exts = get_script_instance()->call("get_recognized_extensions");
+ PackedStringArray exts = get_script_instance()->call("get_recognized_extensions");
{
- PoolStringArray::Read r = exts.read();
+ const String *r = exts.ptr();
for (int i = 0; i < exts.size(); ++i) {
p_extensions->push_back(r[i]);
}
@@ -168,10 +119,10 @@ void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions)
}
}
-RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
if (get_script_instance() && get_script_instance()->has_method("load")) {
- Variant res = get_script_instance()->call("load", p_path, p_original_path);
+ Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads);
if (res.get_type() == Variant::INT) {
@@ -184,38 +135,20 @@ RES ResourceFormatLoader::load(const String &p_path, const String &p_original_pa
*r_error = OK;
return res;
}
- }
-
- //or this must be implemented
- Ref<ResourceInteractiveLoader> ril = load_interactive(p_path, p_original_path, r_error);
- if (!ril.is_valid())
- return RES();
- ril->set_local_path(p_original_path);
-
- while (true) {
-
- Error err = ril->poll();
-
- if (err == ERR_FILE_EOF) {
- if (r_error)
- *r_error = OK;
- return ril->get_resource();
- }
- if (r_error)
- *r_error = err;
-
- ERR_FAIL_COND_V_MSG(err != OK, RES(), "Failed to load resource '" + p_path + "'.");
+ return res;
}
+
+ ERR_FAIL_V_MSG(RES(), "Failed to load resource '" + p_path + "', ResourceFormatLoader::load was not implemented for this resource type.");
}
void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
if (get_script_instance() && get_script_instance()->has_method("get_dependencies")) {
- PoolStringArray deps = get_script_instance()->call("get_dependencies", p_path, p_add_types);
+ PackedStringArray deps = get_script_instance()->call("get_dependencies", p_path, p_add_types);
{
- PoolStringArray::Read r = deps.read();
+ const String *r = deps.ptr();
for (int i = 0; i < deps.size(); ++i) {
p_dependencies->push_back(r[i]);
}
@@ -247,8 +180,8 @@ void ResourceFormatLoader::_bind_methods() {
ClassDB::add_virtual_method(get_class_static(), info);
}
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::POOL_STRING_ARRAY, "get_recognized_extensions"));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "handles_type", PropertyInfo(Variant::STRING, "typename")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::PACKED_STRING_ARRAY, "get_recognized_extensions"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "handles_type", PropertyInfo(Variant::STRING_NAME, "typename")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_resource_type", PropertyInfo(Variant::STRING, "path")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo("get_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "add_types")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "rename_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "renames")));
@@ -256,7 +189,7 @@ void ResourceFormatLoader::_bind_methods() {
///////////////////////////////////
-RES ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
+RES ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error, bool p_use_sub_threads, float *r_progress) {
bool found = false;
@@ -267,7 +200,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c
continue;
}
found = true;
- RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error);
+ RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress);
if (res.is_null()) {
continue;
}
@@ -285,61 +218,302 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c
ERR_FAIL_V_MSG(RES(), "No loader found for resource: " + p_path + ".");
}
-bool ResourceLoader::_add_to_loading_map(const String &p_path) {
+void ResourceLoader::_thread_load_function(void *p_userdata) {
- bool success;
- if (loading_map_mutex) {
- loading_map_mutex->lock();
+ ThreadLoadTask &load_task = *(ThreadLoadTask *)p_userdata;
+ load_task.loader_id = Thread::get_caller_id();
+
+ if (load_task.semaphore) {
+ //this is an actual thread, so wait for Ok fom semaphore
+ thread_load_semaphore->wait(); //wait until its ok to start loading
}
+ load_task.resource = _load(load_task.remapped_path, load_task.remapped_path != load_task.local_path ? load_task.local_path : String(), load_task.type_hint, false, &load_task.error, load_task.use_sub_threads, &load_task.progress);
- LoadingMapKey key;
- key.path = p_path;
- key.thread = Thread::get_caller_id();
+ load_task.progress = 1.0; //it was fully loaded at this point, so force progress to 1.0
- if (loading_map.has(key)) {
- success = false;
+ thread_load_mutex->lock();
+ if (load_task.error != OK) {
+ load_task.status = THREAD_LOAD_FAILED;
} else {
- loading_map[key] = true;
- success = true;
+ load_task.status = THREAD_LOAD_LOADED;
+ }
+ if (load_task.semaphore) {
+
+ if (load_task.start_next && thread_waiting_count > 0) {
+ thread_waiting_count--;
+ //thread loading count remains constant, this ends but another one begins
+ thread_load_semaphore->post();
+ } else {
+ thread_loading_count--; //no threads waiting, just reduce loading count
+ }
+
+ print_lt("END: load count: " + itos(thread_loading_count) + " / wait count: " + itos(thread_waiting_count) + " / suspended count: " + itos(thread_suspended_count) + " / active: " + itos(thread_loading_count - thread_suspended_count));
+
+ for (int i = 0; i < load_task.poll_requests; i++) {
+ load_task.semaphore->post();
+ }
+ memdelete(load_task.semaphore);
+ load_task.semaphore = nullptr;
}
- if (loading_map_mutex) {
- loading_map_mutex->unlock();
+ if (load_task.resource.is_valid()) {
+ load_task.resource->set_path(load_task.local_path);
+
+ if (load_task.xl_remapped)
+ load_task.resource->set_as_translation_remapped(true);
+
+#ifdef TOOLS_ENABLED
+
+ load_task.resource->set_edited(false);
+ if (timestamp_on_load) {
+ uint64_t mt = FileAccess::get_modified_time(load_task.remapped_path);
+ //printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt);
+ load_task.resource->set_last_modified_time(mt);
+ }
+#endif
+
+ if (_loaded_callback) {
+ _loaded_callback(load_task.resource, load_task.local_path);
+ }
}
- return success;
+ thread_load_mutex->unlock();
}
+Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, const String &p_source_resource) {
-void ResourceLoader::_remove_from_loading_map(const String &p_path) {
- if (loading_map_mutex) {
- loading_map_mutex->lock();
+ String local_path;
+ if (p_path.is_rel_path())
+ local_path = "res://" + p_path;
+ else
+ local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+
+ thread_load_mutex->lock();
+
+ if (p_source_resource != String()) {
+ //must be loading from this resource
+ if (!thread_load_tasks.has(p_source_resource)) {
+ thread_load_mutex->unlock();
+ ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "There is no thread loading source resource '" + p_source_resource + "'.");
+ }
+ //must be loading from this thread
+ if (thread_load_tasks[p_source_resource].loader_id != Thread::get_caller_id()) {
+ thread_load_mutex->unlock();
+ ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Threading loading resource'" + local_path + " failed: Source specified: '" + p_source_resource + "' but was not called by it.");
+ }
+
+ //must not be already added as s sub tasks
+ if (thread_load_tasks[p_source_resource].sub_tasks.has(local_path)) {
+ thread_load_mutex->unlock();
+ ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Thread loading source resource '" + p_source_resource + "' already is loading '" + local_path + "'.");
+ }
+ }
+
+ if (thread_load_tasks.has(local_path)) {
+ thread_load_tasks[local_path].requests++;
+ if (p_source_resource != String()) {
+ thread_load_tasks[p_source_resource].sub_tasks.insert(local_path);
+ }
+ thread_load_mutex->unlock();
+ return OK;
}
- LoadingMapKey key;
- key.path = p_path;
- key.thread = Thread::get_caller_id();
+ {
+ //create load task
+
+ ThreadLoadTask load_task;
+
+ load_task.requests = 1;
+ load_task.remapped_path = _path_remap(local_path, &load_task.xl_remapped);
+ load_task.local_path = local_path;
+ load_task.type_hint = p_type_hint;
+ load_task.use_sub_threads = p_use_sub_threads;
+
+ { //must check if resource is already loaded before attempting to load it in a thread
+
+ if (load_task.loader_id == Thread::get_caller_id()) {
+ thread_load_mutex->unlock();
+ ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Attempted to load a resource already being loaded from this thread, cyclic reference?");
+ }
+ //lock first if possible
+ if (ResourceCache::lock) {
+ ResourceCache::lock->read_lock();
+ }
+
+ //get ptr
+ Resource **rptr = ResourceCache::resources.getptr(local_path);
+
+ if (rptr) {
+ RES res(*rptr);
+ //it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached
+ if (res.is_valid()) {
+ //referencing is fine
+ load_task.resource = res;
+ load_task.status = THREAD_LOAD_LOADED;
+ load_task.progress = 1.0;
+ }
+ }
+ if (ResourceCache::lock) {
+ ResourceCache::lock->read_unlock();
+ }
+ }
- loading_map.erase(key);
+ if (p_source_resource != String()) {
+ thread_load_tasks[p_source_resource].sub_tasks.insert(local_path);
+ }
- if (loading_map_mutex) {
- loading_map_mutex->unlock();
+ thread_load_tasks[local_path] = load_task;
}
+
+ ThreadLoadTask &load_task = thread_load_tasks[local_path];
+
+ if (load_task.resource.is_null()) { //needs to be loaded in thread
+
+ load_task.semaphore = memnew(Semaphore);
+ if (thread_loading_count < thread_load_max) {
+ thread_loading_count++;
+ thread_load_semaphore->post(); //we have free threads, so allow one
+ } else {
+ thread_waiting_count++;
+ }
+
+ print_lt("REQUEST: load count: " + itos(thread_loading_count) + " / wait count: " + itos(thread_waiting_count) + " / suspended count: " + itos(thread_suspended_count) + " / active: " + itos(thread_loading_count - thread_suspended_count));
+
+ load_task.thread = Thread::create(_thread_load_function, &thread_load_tasks[local_path]);
+ load_task.loader_id = load_task.thread->get_id();
+ }
+
+ thread_load_mutex->unlock();
+
+ return OK;
}
-void ResourceLoader::_remove_from_loading_map_and_thread(const String &p_path, Thread::ID p_thread) {
- if (loading_map_mutex) {
- loading_map_mutex->lock();
+float ResourceLoader::_dependency_get_progress(const String &p_path) {
+
+ if (thread_load_tasks.has(p_path)) {
+ ThreadLoadTask &load_task = thread_load_tasks[p_path];
+ int dep_count = load_task.sub_tasks.size();
+ if (dep_count > 0) {
+ float dep_progress = 0;
+ for (Set<String>::Element *E = load_task.sub_tasks.front(); E; E = E->next()) {
+ dep_progress += _dependency_get_progress(E->get());
+ }
+ dep_progress /= float(dep_count);
+ dep_progress *= 0.5;
+ dep_progress += load_task.progress * 0.5;
+ return dep_progress;
+ } else {
+ return load_task.progress;
+ }
+
+ } else {
+ return 1.0; //assume finished loading it so it no longer exists
}
+}
- LoadingMapKey key;
- key.path = p_path;
- key.thread = p_thread;
+ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const String &p_path, float *r_progress) {
- loading_map.erase(key);
+ String local_path;
+ if (p_path.is_rel_path())
+ local_path = "res://" + p_path;
+ else
+ local_path = ProjectSettings::get_singleton()->localize_path(p_path);
- if (loading_map_mutex) {
- loading_map_mutex->unlock();
+ thread_load_mutex->lock();
+ if (!thread_load_tasks.has(local_path)) {
+ thread_load_mutex->unlock();
+ return THREAD_LOAD_INVALID_RESOURCE;
+ }
+ ThreadLoadTask &load_task = thread_load_tasks[local_path];
+ ThreadLoadStatus status;
+ status = load_task.status;
+ if (r_progress) {
+ *r_progress = _dependency_get_progress(local_path);
}
+
+ thread_load_mutex->unlock();
+
+ return status;
+}
+RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) {
+
+ String local_path;
+ if (p_path.is_rel_path())
+ local_path = "res://" + p_path;
+ else
+ local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+
+ thread_load_mutex->lock();
+ if (!thread_load_tasks.has(local_path)) {
+ thread_load_mutex->unlock();
+ if (r_error) {
+ *r_error = ERR_INVALID_PARAMETER;
+ }
+ return RES();
+ }
+
+ ThreadLoadTask &load_task = thread_load_tasks[local_path];
+
+ //semaphore still exists, meaning its still loading, request poll
+ Semaphore *semaphore = load_task.semaphore;
+ if (semaphore) {
+ load_task.poll_requests++;
+
+ {
+ // As we got a semaphore, this means we are going to have to wait
+ // until the sub-resource is done loading
+ //
+ // As this thread will become 'blocked' we should "echange" its
+ // active status with a waiting one, to ensure load continues.
+ //
+ // This ensures loading is never blocked and that is also within
+ // the maximum number of active threads.
+
+ if (thread_waiting_count > 0) {
+ thread_waiting_count--;
+ thread_loading_count++;
+ thread_load_semaphore->post();
+
+ load_task.start_next = false; //do not start next since we are doing it here
+ }
+
+ thread_suspended_count++;
+
+ print_lt("GET: load count: " + itos(thread_loading_count) + " / wait count: " + itos(thread_waiting_count) + " / suspended count: " + itos(thread_suspended_count) + " / active: " + itos(thread_loading_count - thread_suspended_count));
+ }
+
+ thread_load_mutex->unlock();
+ semaphore->wait();
+ thread_load_mutex->lock();
+
+ thread_suspended_count--;
+
+ if (!thread_load_tasks.has(local_path)) { //may have been erased during unlock and this was always an invalid call
+ thread_load_mutex->unlock();
+ if (r_error) {
+ *r_error = ERR_INVALID_PARAMETER;
+ }
+ return RES();
+ }
+ }
+
+ RES resource = load_task.resource;
+ if (r_error) {
+ *r_error = load_task.error;
+ }
+
+ load_task.requests--;
+
+ if (load_task.requests == 0) {
+ if (load_task.thread) { //thread may not have been used
+ Thread::wait_to_finish(load_task.thread);
+ memdelete(load_task.thread);
+ }
+ thread_load_tasks.erase(local_path);
+ }
+
+ thread_load_mutex->unlock();
+
+ return resource;
}
RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
@@ -355,83 +529,102 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
if (!p_no_cache) {
- {
- bool success = _add_to_loading_map(local_path);
- ERR_FAIL_COND_V_MSG(!success, RES(), "Resource: '" + local_path + "' is already being loaded. Cyclic reference?");
+ thread_load_mutex->lock();
+
+ //Is it already being loaded? poll until done
+ if (thread_load_tasks.has(local_path)) {
+ Error err = load_threaded_request(p_path, p_type_hint);
+ if (err != OK) {
+ if (r_error) {
+ *r_error = err;
+ }
+ thread_load_mutex->unlock();
+ return RES();
+ }
+ thread_load_mutex->unlock();
+
+ return load_threaded_get(p_path, r_error);
}
- //lock first if possible
+ //Is it cached?
if (ResourceCache::lock) {
ResourceCache::lock->read_lock();
}
- //get ptr
Resource **rptr = ResourceCache::resources.getptr(local_path);
if (rptr) {
RES res(*rptr);
+
//it is possible this resource was just freed in a thread. If so, this referencing will not work and resource is considered not cached
if (res.is_valid()) {
- //referencing is fine
- if (r_error)
- *r_error = OK;
if (ResourceCache::lock) {
ResourceCache::lock->read_unlock();
}
- _remove_from_loading_map(local_path);
- return res;
+ thread_load_mutex->unlock();
+
+ if (r_error) {
+ *r_error = OK;
+ }
+
+ return res; //use cached
}
}
+
if (ResourceCache::lock) {
ResourceCache::lock->read_unlock();
}
- }
- bool xl_remapped = false;
- String path = _path_remap(local_path, &xl_remapped);
+ //load using task (but this thread)
+ ThreadLoadTask load_task;
+
+ load_task.requests = 1;
+ load_task.local_path = local_path;
+ load_task.remapped_path = _path_remap(local_path, &load_task.xl_remapped);
+ load_task.type_hint = p_type_hint;
+ load_task.loader_id = Thread::get_caller_id();
- if (path == "") {
- if (!p_no_cache) {
- _remove_from_loading_map(local_path);
+ thread_load_tasks[local_path] = load_task;
+
+ thread_load_mutex->unlock();
+
+ _thread_load_function(&thread_load_tasks[local_path]);
+
+ return load_threaded_get(p_path, r_error);
+
+ } else {
+
+ bool xl_remapped = false;
+ String path = _path_remap(local_path, &xl_remapped);
+
+ if (path == "") {
+ ERR_FAIL_V_MSG(RES(), "Remapping '" + local_path + "' failed.");
}
- ERR_FAIL_V_MSG(RES(), "Remapping '" + local_path + "' failed.");
- }
- print_verbose("Loading resource: " + path);
- RES res = _load(path, local_path, p_type_hint, p_no_cache, r_error);
+ print_verbose("Loading resource: " + path);
+ float p;
+ RES res = _load(path, local_path, p_type_hint, p_no_cache, r_error, false, &p);
- if (res.is_null()) {
- if (!p_no_cache) {
- _remove_from_loading_map(local_path);
+ if (res.is_null()) {
+ print_verbose("Failed loading resource: " + path);
+ return RES();
}
- print_verbose("Failed loading resource: " + path);
- return RES();
- }
- if (!p_no_cache)
- res->set_path(local_path);
- if (xl_remapped)
- res->set_as_translation_remapped(true);
+ if (xl_remapped)
+ res->set_as_translation_remapped(true);
#ifdef TOOLS_ENABLED
- res->set_edited(false);
- if (timestamp_on_load) {
- uint64_t mt = FileAccess::get_modified_time(path);
- //printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt);
- res->set_last_modified_time(mt);
- }
+ res->set_edited(false);
+ if (timestamp_on_load) {
+ uint64_t mt = FileAccess::get_modified_time(path);
+ //printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt);
+ res->set_last_modified_time(mt);
+ }
#endif
- if (!p_no_cache) {
- _remove_from_loading_map(local_path);
- }
-
- if (_loaded_callback) {
- _loaded_callback(res, p_path);
+ return res;
}
-
- return res;
}
bool ResourceLoader::exists(const String &p_path, const String &p_type_hint) {
@@ -464,76 +657,6 @@ bool ResourceLoader::exists(const String &p_path, const String &p_type_hint) {
return false;
}
-Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
-
- if (r_error)
- *r_error = ERR_CANT_OPEN;
-
- String local_path;
- if (p_path.is_rel_path())
- local_path = "res://" + p_path;
- else
- local_path = ProjectSettings::get_singleton()->localize_path(p_path);
-
- if (!p_no_cache) {
-
- bool success = _add_to_loading_map(local_path);
- ERR_FAIL_COND_V_MSG(!success, RES(), "Resource: '" + local_path + "' is already being loaded. Cyclic reference?");
-
- if (ResourceCache::has(local_path)) {
-
- print_verbose("Loading resource: " + local_path + " (cached)");
- Ref<Resource> res_cached = ResourceCache::get(local_path);
- Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault));
-
- ril->resource = res_cached;
- ril->path_loading = local_path;
- ril->path_loading_thread = Thread::get_caller_id();
- return ril;
- }
- }
-
- bool xl_remapped = false;
- String path = _path_remap(local_path, &xl_remapped);
- if (path == "") {
- if (!p_no_cache) {
- _remove_from_loading_map(local_path);
- }
- ERR_FAIL_V_MSG(RES(), "Remapping '" + local_path + "' failed.");
- }
-
- print_verbose("Loading resource: " + path);
-
- bool found = false;
- for (int i = 0; i < loader_count; i++) {
-
- if (!loader[i]->recognize_path(path, p_type_hint))
- continue;
- found = true;
- Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, local_path, r_error);
- if (ril.is_null())
- continue;
- 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)
- ril->set_translation_remapped(true);
-
- return ril;
- }
-
- if (!p_no_cache) {
- _remove_from_loading_map(local_path);
- }
-
- ERR_FAIL_COND_V_MSG(found, Ref<ResourceInteractiveLoader>(), "Failed loading resource: " + path + ".");
-
- ERR_FAIL_V_MSG(Ref<ResourceInteractiveLoader>(), "No loader found for resource: " + path + ".");
-}
-
void ResourceLoader::add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front) {
ERR_FAIL_COND(p_format_loader.is_null());
@@ -743,7 +866,7 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
if (translation_remaps.has(p_path)) {
// translation_remaps has the following format:
- // { "res://path.png": PoolStringArray( "res://path-ru.png:ru", "res://path-de.png:de" ) }
+ // { "res://path.png": PackedStringArray( "res://path-ru.png:ru", "res://path-de.png:de" ) }
// To find the path of the remapped resource, we extract the locale name after
// the last ':' to match the project locale.
@@ -905,10 +1028,10 @@ void ResourceLoader::load_path_remaps() {
if (!ProjectSettings::get_singleton()->has_setting("path_remap/remapped_paths"))
return;
- PoolVector<String> remaps = ProjectSettings::get_singleton()->get("path_remap/remapped_paths");
+ Vector<String> remaps = ProjectSettings::get_singleton()->get("path_remap/remapped_paths");
int rc = remaps.size();
ERR_FAIL_COND(rc & 1); //must be even
- PoolVector<String>::Read r = remaps.read();
+ const String *r = remaps.ptr();
for (int i = 0; i < rc; i += 2) {
@@ -1002,25 +1125,19 @@ void ResourceLoader::remove_custom_loaders() {
}
}
-Mutex *ResourceLoader::loading_map_mutex = NULL;
-HashMap<ResourceLoader::LoadingMapKey, int, ResourceLoader::LoadingMapKeyHasher> ResourceLoader::loading_map;
-
void ResourceLoader::initialize() {
-#ifndef NO_THREADS
- loading_map_mutex = Mutex::create();
-#endif
+ thread_load_mutex = memnew(Mutex);
+ thread_load_max = OS::get_singleton()->get_processor_count();
+ thread_loading_count = 0;
+ thread_waiting_count = 0;
+ thread_suspended_count = 0;
+ thread_load_semaphore = memnew(Semaphore);
}
void ResourceLoader::finalize() {
-#ifndef NO_THREADS
- const LoadingMapKey *K = NULL;
- while ((K = loading_map.next(K))) {
- ERR_PRINT("Exited while resource is being loaded: " + K->path);
- }
- loading_map.clear();
- memdelete(loading_map_mutex);
- loading_map_mutex = NULL;
-#endif
+
+ memdelete(thread_load_mutex);
+ memdelete(thread_load_semaphore);
}
ResourceLoadErrorNotify ResourceLoader::err_notify = NULL;
@@ -1032,6 +1149,15 @@ void *ResourceLoader::dep_err_notify_ud = NULL;
bool ResourceLoader::abort_on_missing_resource = true;
bool ResourceLoader::timestamp_on_load = false;
+Mutex *ResourceLoader::thread_load_mutex = nullptr;
+HashMap<String, ResourceLoader::ThreadLoadTask> ResourceLoader::thread_load_tasks;
+Semaphore *ResourceLoader::thread_load_semaphore = nullptr;
+
+int ResourceLoader::thread_loading_count = 0;
+int ResourceLoader::thread_waiting_count = 0;
+int ResourceLoader::thread_suspended_count = 0;
+int ResourceLoader::thread_load_max = 0;
+
SelfList<Resource>::List ResourceLoader::remapped_list;
HashMap<String, Vector<String> > ResourceLoader::translation_remaps;
HashMap<String, String> ResourceLoader::path_remaps;
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 4e83427fae..ea89917a5f 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -31,32 +31,10 @@
#ifndef RESOURCE_LOADER_H
#define RESOURCE_LOADER_H
+#include "core/os/semaphore.h"
#include "core/os/thread.h"
#include "core/resource.h"
-class ResourceInteractiveLoader : public Reference {
-
- GDCLASS(ResourceInteractiveLoader, Reference);
- friend class ResourceLoader;
- String path_loading;
- Thread::ID path_loading_thread;
-
-protected:
- static void _bind_methods();
-
-public:
- virtual void set_local_path(const String &p_local_path) = 0;
- virtual Ref<Resource> get_resource() = 0;
- virtual Error poll() = 0;
- virtual int get_stage() const = 0;
- virtual int get_stage_count() const = 0;
- virtual void set_translation_remapped(bool p_remapped) = 0;
- virtual Error wait();
-
- ResourceInteractiveLoader() {}
- ~ResourceInteractiveLoader();
-};
-
class ResourceFormatLoader : public Reference {
GDCLASS(ResourceFormatLoader, Reference);
@@ -65,8 +43,7 @@ protected:
static void _bind_methods();
public:
- virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr);
virtual bool exists(const String &p_path) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
@@ -95,6 +72,15 @@ class ResourceLoader {
MAX_LOADERS = 64
};
+public:
+ enum ThreadLoadStatus {
+ THREAD_LOAD_INVALID_RESOURCE,
+ THREAD_LOAD_IN_PROGRESS,
+ THREAD_LOAD_FAILED,
+ THREAD_LOAD_LOADED
+ };
+
+private:
static Ref<ResourceFormatLoader> loader[MAX_LOADERS];
static int loader_count;
static bool timestamp_on_load;
@@ -115,34 +101,47 @@ class ResourceLoader {
friend class ResourceFormatImporter;
friend class ResourceInteractiveLoader;
//internal load function
- static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error);
+ static RES _load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error, bool p_use_sub_threads, float *r_progress);
static ResourceLoadedCallback _loaded_callback;
static Ref<ResourceFormatLoader> _find_custom_resource_format_loader(String path);
- static Mutex *loading_map_mutex;
-
- //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); }
+ struct ThreadLoadTask {
+ Thread *thread = nullptr;
+ Thread::ID loader_id = 0;
+ Semaphore *semaphore = nullptr;
+ String local_path;
+ String remapped_path;
+ String type_hint;
+ float progress = 0.0;
+ ThreadLoadStatus status = THREAD_LOAD_IN_PROGRESS;
+ Error error = OK;
+ RES resource;
+ bool xl_remapped = false;
+ bool use_sub_threads = false;
+ bool start_next = true;
+ int requests = 0;
+ int poll_requests = 0;
+ Set<String> sub_tasks;
};
- static HashMap<LoadingMapKey, int, LoadingMapKeyHasher> loading_map;
+ static void _thread_load_function(void *p_userdata);
+ static Mutex *thread_load_mutex;
+ static HashMap<String, ThreadLoadTask> thread_load_tasks;
+ static Semaphore *thread_load_semaphore;
+ static int thread_waiting_count;
+ static int thread_loading_count;
+ static int thread_suspended_count;
+ static int thread_load_max;
- 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);
+ static float _dependency_get_progress(const String &p_path);
public:
- static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
+ static Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false, const String &p_source_resource = String());
+ static ThreadLoadStatus load_threaded_get_status(const String &p_path, float *r_progress = nullptr);
+ static RES load_threaded_get(const String &p_path, Error *r_error = NULL);
+
static RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL);
static bool exists(const String &p_path, const String &p_type_hint = "");
diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp
index 685d21107f..740aaf5cfa 100644
--- a/core/io/resource_saver.cpp
+++ b/core/io/resource_saver.cpp
@@ -61,10 +61,10 @@ bool ResourceFormatSaver::recognize(const RES &p_resource) const {
void ResourceFormatSaver::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
if (get_script_instance() && get_script_instance()->has_method("get_recognized_extensions")) {
- PoolStringArray exts = get_script_instance()->call("get_recognized_extensions", p_resource);
+ PackedStringArray exts = get_script_instance()->call("get_recognized_extensions", p_resource);
{
- PoolStringArray::Read r = exts.read();
+ const String *r = exts.ptr();
for (int i = 0; i < exts.size(); ++i) {
p_extensions->push_back(r[i]);
}
@@ -81,7 +81,7 @@ void ResourceFormatSaver::_bind_methods() {
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "save", arg0, arg1, arg2));
}
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::POOL_STRING_ARRAY, "get_recognized_extensions", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::PACKED_STRING_ARRAY, "get_recognized_extensions", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "recognize", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
}
diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp
index dee82de691..3c695c18fc 100644
--- a/core/io/stream_peer.cpp
+++ b/core/io/stream_peer.cpp
@@ -32,16 +32,16 @@
#include "core/io/marshalls.h"
-Error StreamPeer::_put_data(const PoolVector<uint8_t> &p_data) {
+Error StreamPeer::_put_data(const Vector<uint8_t> &p_data) {
int len = p_data.size();
if (len == 0)
return OK;
- PoolVector<uint8_t>::Read r = p_data.read();
+ const uint8_t *r = p_data.ptr();
return put_data(&r[0], len);
}
-Array StreamPeer::_put_partial_data(const PoolVector<uint8_t> &p_data) {
+Array StreamPeer::_put_partial_data(const Vector<uint8_t> &p_data) {
Array ret;
@@ -52,7 +52,7 @@ Array StreamPeer::_put_partial_data(const PoolVector<uint8_t> &p_data) {
return ret;
}
- PoolVector<uint8_t>::Read r = p_data.read();
+ const uint8_t *r = p_data.ptr();
int sent;
Error err = put_partial_data(&r[0], len, sent);
@@ -68,18 +68,18 @@ Array StreamPeer::_get_data(int p_bytes) {
Array ret;
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
data.resize(p_bytes);
if (data.size() != p_bytes) {
ret.push_back(ERR_OUT_OF_MEMORY);
- ret.push_back(PoolVector<uint8_t>());
+ ret.push_back(Vector<uint8_t>());
return ret;
}
- PoolVector<uint8_t>::Write w = data.write();
+ uint8_t *w = data.ptrw();
Error err = get_data(&w[0], p_bytes);
- w.release();
+
ret.push_back(err);
ret.push_back(data);
return ret;
@@ -89,19 +89,18 @@ Array StreamPeer::_get_partial_data(int p_bytes) {
Array ret;
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
data.resize(p_bytes);
if (data.size() != p_bytes) {
ret.push_back(ERR_OUT_OF_MEMORY);
- ret.push_back(PoolVector<uint8_t>());
+ ret.push_back(Vector<uint8_t>());
return ret;
}
- PoolVector<uint8_t>::Write w = data.write();
+ uint8_t *w = data.ptrw();
int received;
Error err = get_partial_data(&w[0], p_bytes, received);
- w.release();
if (err != OK) {
data.resize(0);
@@ -431,7 +430,7 @@ void StreamPeerBuffer::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear"), &StreamPeerBuffer::clear);
ClassDB::bind_method(D_METHOD("duplicate"), &StreamPeerBuffer::duplicate);
- ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "data_array"), "set_data_array", "get_data_array");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data_array"), "set_data_array", "get_data_array");
}
Error StreamPeerBuffer::put_data(const uint8_t *p_data, int p_bytes) {
@@ -443,7 +442,7 @@ Error StreamPeerBuffer::put_data(const uint8_t *p_data, int p_bytes) {
data.resize(pointer + p_bytes);
}
- PoolVector<uint8_t>::Write w = data.write();
+ uint8_t *w = data.ptrw();
copymem(&w[pointer], p_data, p_bytes);
pointer += p_bytes;
@@ -478,8 +477,8 @@ Error StreamPeerBuffer::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_
r_received = p_bytes;
}
- PoolVector<uint8_t>::Read r = data.read();
- copymem(p_buffer, r.ptr() + pointer, r_received);
+ const uint8_t *r = data.ptr();
+ copymem(p_buffer, r + pointer, r_received);
pointer += r_received;
// FIXME: return what? OK or ERR_*
@@ -513,13 +512,13 @@ void StreamPeerBuffer::resize(int p_size) {
data.resize(p_size);
}
-void StreamPeerBuffer::set_data_array(const PoolVector<uint8_t> &p_data) {
+void StreamPeerBuffer::set_data_array(const Vector<uint8_t> &p_data) {
data = p_data;
pointer = 0;
}
-PoolVector<uint8_t> StreamPeerBuffer::get_data_array() const {
+Vector<uint8_t> StreamPeerBuffer::get_data_array() const {
return data;
}
diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h
index d6ce7ddc16..9358a2c07c 100644
--- a/core/io/stream_peer.h
+++ b/core/io/stream_peer.h
@@ -41,8 +41,8 @@ protected:
static void _bind_methods();
//bind helpers
- Error _put_data(const PoolVector<uint8_t> &p_data);
- Array _put_partial_data(const PoolVector<uint8_t> &p_data);
+ Error _put_data(const Vector<uint8_t> &p_data);
+ Array _put_partial_data(const Vector<uint8_t> &p_data);
Array _get_data(int p_bytes);
Array _get_partial_data(int p_bytes);
@@ -96,7 +96,7 @@ class StreamPeerBuffer : public StreamPeer {
GDCLASS(StreamPeerBuffer, StreamPeer);
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
int pointer;
protected:
@@ -116,8 +116,8 @@ public:
int get_position() const;
void resize(int p_size);
- void set_data_array(const PoolVector<uint8_t> &p_data);
- PoolVector<uint8_t> get_data_array() const;
+ void set_data_array(const Vector<uint8_t> &p_data);
+ Vector<uint8_t> get_data_array() const;
void clear();
diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp
index 4f7eeddc43..4051bf2947 100644
--- a/core/io/translation_loader_po.cpp
+++ b/core/io/translation_loader_po.cpp
@@ -176,7 +176,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error, const S
return translation;
}
-RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error) {
+RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
if (r_error)
*r_error = ERR_CANT_OPEN;
diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h
index 47e64276ca..fe3a75e5eb 100644
--- a/core/io/translation_loader_po.h
+++ b/core/io/translation_loader_po.h
@@ -38,7 +38,7 @@
class TranslationLoaderPO : public ResourceFormatLoader {
public:
static RES load_translation(FileAccess *f, Error *r_error, const String &p_path = String());
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/core/io/udp_server.cpp b/core/io/udp_server.cpp
new file mode 100644
index 0000000000..16b7863cdd
--- /dev/null
+++ b/core/io/udp_server.cpp
@@ -0,0 +1,119 @@
+/*************************************************************************/
+/* udp_server.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 "udp_server.h"
+
+void UDPServer::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("listen", "port", "bind_address"), &UDPServer::listen, DEFVAL("*"));
+ ClassDB::bind_method(D_METHOD("is_connection_available"), &UDPServer::is_connection_available);
+ ClassDB::bind_method(D_METHOD("is_listening"), &UDPServer::is_listening);
+ ClassDB::bind_method(D_METHOD("take_connection"), &UDPServer::take_connection);
+ ClassDB::bind_method(D_METHOD("stop"), &UDPServer::stop);
+}
+
+Error UDPServer::listen(uint16_t p_port, const IP_Address &p_bind_address) {
+
+ ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE);
+ ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);
+
+ Error err;
+ IP::Type ip_type = IP::TYPE_ANY;
+
+ if (p_bind_address.is_valid())
+ ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
+
+ err = _sock->open(NetSocket::TYPE_UDP, ip_type);
+
+ if (err != OK)
+ return ERR_CANT_CREATE;
+
+ _sock->set_blocking_enabled(false);
+ _sock->set_reuse_address_enabled(true);
+ err = _sock->bind(p_bind_address, p_port);
+
+ if (err != OK) {
+ stop();
+ return err;
+ }
+ bind_address = p_bind_address;
+ bind_port = p_port;
+ return OK;
+}
+
+bool UDPServer::is_listening() const {
+ ERR_FAIL_COND_V(!_sock.is_valid(), false);
+
+ return _sock->is_open();
+}
+
+bool UDPServer::is_connection_available() const {
+
+ ERR_FAIL_COND_V(!_sock.is_valid(), false);
+
+ if (!_sock->is_open())
+ return false;
+
+ Error err = _sock->poll(NetSocket::POLL_TYPE_IN, 0);
+ return (err == OK);
+}
+
+Ref<PacketPeerUDP> UDPServer::take_connection() {
+
+ Ref<PacketPeerUDP> conn;
+ if (!is_connection_available()) {
+ return conn;
+ }
+
+ conn = Ref<PacketPeerUDP>(memnew(PacketPeerUDP));
+ conn->connect_socket(_sock);
+ _sock = Ref<NetSocket>(NetSocket::create());
+ listen(bind_port, bind_address);
+ return conn;
+}
+
+void UDPServer::stop() {
+
+ if (_sock.is_valid()) {
+ _sock->close();
+ }
+ bind_port = 0;
+ bind_address = IP_Address();
+}
+
+UDPServer::UDPServer() :
+ _sock(Ref<NetSocket>(NetSocket::create())) {
+}
+
+UDPServer::~UDPServer() {
+
+ stop();
+}
diff --git a/core/os/thread_safe.cpp b/core/io/udp_server.h
index d8d783ae16..90bb82b62b 100644
--- a/core/os/thread_safe.cpp
+++ b/core/io/udp_server.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* thread_safe.cpp */
+/* udp_server.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,22 +28,31 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "thread_safe.h"
+#ifndef UDP_SERVER_H
+#define UDP_SERVER_H
-#include "core/error_macros.h"
-#include "core/os/memory.h"
+#include "core/io/net_socket.h"
+#include "core/io/packet_peer_udp.h"
-ThreadSafe::ThreadSafe() {
+class UDPServer : public Reference {
+ GDCLASS(UDPServer, Reference);
- mutex = Mutex::create();
- if (!mutex) {
+protected:
+ static void _bind_methods();
+ int bind_port;
+ IP_Address bind_address;
+ Ref<NetSocket> _sock;
- WARN_PRINT("THREAD_SAFE defined, but no default mutex type");
- }
-}
+public:
+ Error listen(uint16_t p_port, const IP_Address &p_bind_address = IP_Address("*"));
+ bool is_listening() const;
+ bool is_connection_available() const;
+ Ref<PacketPeerUDP> take_connection();
-ThreadSafe::~ThreadSafe() {
+ void stop();
- if (mutex)
- memdelete(mutex);
-}
+ UDPServer();
+ ~UDPServer();
+};
+
+#endif // UDP_SERVER_H
diff --git a/core/make_binders.py b/core/make_binders.py
index 11cfbf6e79..c42b91fbe5 100644
--- a/core/make_binders.py
+++ b/core/make_binders.py
@@ -32,22 +32,22 @@ public:
return T::get_class_static();
}
- virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) {
+ virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Callable::CallError& r_error) {
T *instance=Object::cast_to<T>(p_object);
- r_error.error=Variant::CallError::CALL_OK;
+ r_error.error=Callable::CallError::CALL_OK;
#ifdef DEBUG_METHODS_ENABLED
ERR_FAIL_COND_V(!instance,Variant());
if (p_arg_count>get_argument_count()) {
- r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.error=Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument=get_argument_count();
return Variant();
}
if (p_arg_count<(get_argument_count()-get_default_argument_count())) {
- r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error=Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument=get_argument_count()-get_default_argument_count();
return Variant();
}
@@ -126,23 +126,23 @@ public:
return type_name;
}
- virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) {
+ virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Callable::CallError& r_error) {
__UnexistingClass *instance = (__UnexistingClass*)p_object;
- r_error.error=Variant::CallError::CALL_OK;
+ r_error.error=Callable::CallError::CALL_OK;
#ifdef DEBUG_METHODS_ENABLED
ERR_FAIL_COND_V(!instance,Variant());
if (p_arg_count>get_argument_count()) {
- r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.error=Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument=get_argument_count();
return Variant();
}
if (p_arg_count<(get_argument_count()-get_default_argument_count())) {
- r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error=Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument=get_argument_count()-get_default_argument_count();
return Variant();
}
@@ -223,22 +223,22 @@ public:
return T::get_class_static();
}
- virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) {
+ virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Callable::CallError& r_error) {
T *instance=Object::cast_to<T>(p_object);
- r_error.error=Variant::CallError::CALL_OK;
+ r_error.error=Callable::CallError::CALL_OK;
#ifdef DEBUG_METHODS_ENABLED
ERR_FAIL_COND_V(!instance,Variant());
if (p_arg_count>get_argument_count()) {
- r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.error=Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument=get_argument_count();
return Variant();
}
if (p_arg_count<(get_argument_count()-get_default_argument_count())) {
- r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error=Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument=get_argument_count()-get_default_argument_count();
return Variant();
}
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index 73f190a330..847d4d8681 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -235,13 +235,13 @@ Array AStar::get_points() {
return point_list;
}
-PoolVector<int> AStar::get_point_connections(int p_id) {
+Vector<int> AStar::get_point_connections(int p_id) {
Point *p;
bool p_exists = points.lookup(p_id, p);
- ERR_FAIL_COND_V(!p_exists, PoolVector<int>());
+ ERR_FAIL_COND_V(!p_exists, Vector<int>());
- PoolVector<int> point_list;
+ Vector<int> point_list;
for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
point_list.push_back((*it.key));
@@ -431,18 +431,18 @@ float AStar::_compute_cost(int p_from_id, int p_to_id) {
return from_point->pos.distance_to(to_point->pos);
}
-PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
+Vector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
Point *a;
bool from_exists = points.lookup(p_from_id, a);
- ERR_FAIL_COND_V(!from_exists, PoolVector<Vector3>());
+ ERR_FAIL_COND_V(!from_exists, Vector<Vector3>());
Point *b;
bool to_exists = points.lookup(p_to_id, b);
- ERR_FAIL_COND_V(!to_exists, PoolVector<Vector3>());
+ ERR_FAIL_COND_V(!to_exists, Vector<Vector3>());
if (a == b) {
- PoolVector<Vector3> ret;
+ Vector<Vector3> ret;
ret.push_back(a->pos);
return ret;
}
@@ -451,7 +451,7 @@ PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
- if (!found_route) return PoolVector<Vector3>();
+ if (!found_route) return Vector<Vector3>();
Point *p = end_point;
int pc = 1; // Begin point
@@ -460,11 +460,11 @@ PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
p = p->prev_point;
}
- PoolVector<Vector3> path;
+ Vector<Vector3> path;
path.resize(pc);
{
- PoolVector<Vector3>::Write w = path.write();
+ Vector3 *w = path.ptrw();
Point *p2 = end_point;
int idx = pc - 1;
@@ -479,18 +479,18 @@ PoolVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
return path;
}
-PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
+Vector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
Point *a;
bool from_exists = points.lookup(p_from_id, a);
- ERR_FAIL_COND_V(!from_exists, PoolVector<int>());
+ ERR_FAIL_COND_V(!from_exists, Vector<int>());
Point *b;
bool to_exists = points.lookup(p_to_id, b);
- ERR_FAIL_COND_V(!to_exists, PoolVector<int>());
+ ERR_FAIL_COND_V(!to_exists, Vector<int>());
if (a == b) {
- PoolVector<int> ret;
+ Vector<int> ret;
ret.push_back(a->id);
return ret;
}
@@ -499,7 +499,7 @@ PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
- if (!found_route) return PoolVector<int>();
+ if (!found_route) return Vector<int>();
Point *p = end_point;
int pc = 1; // Begin point
@@ -508,11 +508,11 @@ PoolVector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
p = p->prev_point;
}
- PoolVector<int> path;
+ Vector<int> path;
path.resize(pc);
{
- PoolVector<int>::Write w = path.write();
+ int *w = path.ptrw();
p = end_point;
int idx = pc - 1;
@@ -576,8 +576,8 @@ void AStar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id"), &AStar::get_point_path);
ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id"), &AStar::get_id_path);
- BIND_VMETHOD(MethodInfo(Variant::REAL, "_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
- BIND_VMETHOD(MethodInfo(Variant::REAL, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
+ BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
+ BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
}
AStar::AStar() {
@@ -624,7 +624,7 @@ bool AStar2D::has_point(int p_id) const {
return astar.has_point(p_id);
}
-PoolVector<int> AStar2D::get_point_connections(int p_id) {
+Vector<int> AStar2D::get_point_connections(int p_id) {
return astar.get_point_connections(p_id);
}
@@ -677,15 +677,15 @@ Vector2 AStar2D::get_closest_position_in_segment(const Vector2 &p_point) const {
return Vector2(p.x, p.y);
}
-PoolVector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
+Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
- PoolVector3Array pv = astar.get_point_path(p_from_id, p_to_id);
+ PackedVector3Array pv = astar.get_point_path(p_from_id, p_to_id);
int size = pv.size();
- PoolVector2Array path;
+ PackedVector2Array path;
path.resize(size);
{
- PoolVector<Vector3>::Read r = pv.read();
- PoolVector<Vector2>::Write w = path.write();
+ const Vector3 *r = pv.ptr();
+ Vector2 *w = path.ptrw();
for (int i = 0; i < size; i++) {
Vector3 p = r[i];
w[i] = Vector2(p.x, p.y);
@@ -694,7 +694,7 @@ PoolVector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
return path;
}
-PoolVector<int> AStar2D::get_id_path(int p_from_id, int p_to_id) {
+Vector<int> AStar2D::get_id_path(int p_from_id, int p_to_id) {
return astar.get_id_path(p_from_id, p_to_id);
}
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 0b10976932..bfcf0c09d3 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -137,7 +137,7 @@ public:
void set_point_weight_scale(int p_id, real_t p_weight_scale);
void remove_point(int p_id);
bool has_point(int p_id) const;
- PoolVector<int> get_point_connections(int p_id);
+ Vector<int> get_point_connections(int p_id);
Array get_points();
void set_point_disabled(int p_id, bool p_disabled = true);
@@ -155,8 +155,8 @@ public:
int get_closest_point(const Vector3 &p_point, bool p_include_disabled = false) const;
Vector3 get_closest_position_in_segment(const Vector3 &p_point) const;
- PoolVector<Vector3> get_point_path(int p_from_id, int p_to_id);
- PoolVector<int> get_id_path(int p_from_id, int p_to_id);
+ Vector<Vector3> get_point_path(int p_from_id, int p_to_id);
+ Vector<int> get_id_path(int p_from_id, int p_to_id);
AStar();
~AStar();
@@ -179,7 +179,7 @@ public:
void set_point_weight_scale(int p_id, real_t p_weight_scale);
void remove_point(int p_id);
bool has_point(int p_id) const;
- PoolVector<int> get_point_connections(int p_id);
+ Vector<int> get_point_connections(int p_id);
Array get_points();
void set_point_disabled(int p_id, bool p_disabled = true);
@@ -197,8 +197,8 @@ public:
int get_closest_point(const Vector2 &p_point, bool p_include_disabled = false) const;
Vector2 get_closest_position_in_segment(const Vector2 &p_point) const;
- PoolVector<Vector2> get_point_path(int p_from_id, int p_to_id);
- PoolVector<int> get_id_path(int p_from_id, int p_to_id);
+ Vector<Vector2> get_point_path(int p_from_id, int p_to_id);
+ Vector<int> get_id_path(int p_from_id, int p_to_id);
AStar2D();
~AStar2D();
diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp
deleted file mode 100644
index 7ad907db97..0000000000
--- a/core/math/bsp_tree.cpp
+++ /dev/null
@@ -1,581 +0,0 @@
-/*************************************************************************/
-/* bsp_tree.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 "bsp_tree.h"
-
-#include "core/error_macros.h"
-#include "core/print_string.h"
-
-void BSP_Tree::from_aabb(const AABB &p_aabb) {
-
- planes.clear();
-
- for (int i = 0; i < 3; i++) {
-
- Vector3 n;
- n[i] = 1;
- planes.push_back(Plane(n, p_aabb.position[i] + p_aabb.size[i]));
- planes.push_back(Plane(-n, -p_aabb.position[i]));
- }
-
- nodes.clear();
-
- for (int i = 0; i < 6; i++) {
-
- Node n;
- n.plane = i;
- n.under = (i == 0) ? UNDER_LEAF : i - 1;
- n.over = OVER_LEAF;
- nodes.push_back(n);
- }
-
- aabb = p_aabb;
- error_radius = 0;
-}
-
-Vector<BSP_Tree::Node> BSP_Tree::get_nodes() const {
-
- return nodes;
-}
-Vector<Plane> BSP_Tree::get_planes() const {
-
- return planes;
-}
-
-AABB BSP_Tree::get_aabb() const {
-
- return aabb;
-}
-
-int BSP_Tree::_get_points_inside(int p_node, const Vector3 *p_points, int *p_indices, const Vector3 &p_center, const Vector3 &p_half_extents, int p_indices_count) const {
-
- const Node *node = &nodes[p_node];
- const Plane &p = planes[node->plane];
-
- Vector3 min(
- (p.normal.x > 0) ? -p_half_extents.x : p_half_extents.x,
- (p.normal.y > 0) ? -p_half_extents.y : p_half_extents.y,
- (p.normal.z > 0) ? -p_half_extents.z : p_half_extents.z);
- Vector3 max = -min;
- max += p_center;
- min += p_center;
-
- real_t dist_min = p.distance_to(min);
- real_t dist_max = p.distance_to(max);
-
- if ((dist_min * dist_max) < CMP_EPSILON) { //intersection, test point by point
-
- int under_count = 0;
-
- //sort points, so the are under first, over last
- for (int i = 0; i < p_indices_count; i++) {
-
- int index = p_indices[i];
-
- if (p.is_point_over(p_points[index])) {
-
- // kind of slow (but cache friendly), should try something else,
- // but this is a corner case most of the time
-
- for (int j = index; j < p_indices_count - 1; j++)
- p_indices[j] = p_indices[j + 1];
-
- p_indices[p_indices_count - 1] = index;
-
- } else {
- under_count++;
- }
- }
-
- int total = 0;
-
- if (under_count > 0) {
- if (node->under == UNDER_LEAF) {
- total += under_count;
- } else {
- total += _get_points_inside(node->under, p_points, p_indices, p_center, p_half_extents, under_count);
- }
- }
-
- if (under_count != p_indices_count) {
- if (node->over == OVER_LEAF) {
- //total+=0 //if they are over an OVER_LEAF, they are outside the model
- } else {
- total += _get_points_inside(node->over, p_points, &p_indices[under_count], p_center, p_half_extents, p_indices_count - under_count);
- }
- }
-
- return total;
-
- } else if (dist_min > 0) { //all points over plane
-
- if (node->over == OVER_LEAF) {
-
- return 0; // all these points are not visible
- }
-
- return _get_points_inside(node->over, p_points, p_indices, p_center, p_half_extents, p_indices_count);
- } else { //all points behind plane
-
- if (node->under == UNDER_LEAF) {
-
- return p_indices_count; // all these points are visible
- }
- return _get_points_inside(node->under, p_points, p_indices, p_center, p_half_extents, p_indices_count);
- }
-}
-
-int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) const {
-
- if (nodes.size() == 0)
- return 0;
-
-#if 1
- //this version is easier to debug, and and MUCH faster in real world cases
-
- int pass_count = 0;
- const Node *nodesptr = &nodes[0];
- const Plane *planesptr = &planes[0];
- int node_count = nodes.size();
-
- if (node_count == 0) // no nodes!
- return 0;
-
- for (int i = 0; i < p_point_count; i++) {
-
- const Vector3 &point = p_points[i];
- if (!aabb.has_point(point)) {
- continue;
- }
-
- int idx = node_count - 1;
-
- bool pass = false;
-
- while (true) {
-
- if (idx == OVER_LEAF) {
- pass = false;
- break;
- } else if (idx == UNDER_LEAF) {
- pass = true;
- break;
- }
-
-#ifdef DEBUG_ENABLED
- int plane_count = planes.size();
- uint16_t plane = nodesptr[idx].plane;
- ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, 0);
-#endif
-
- idx = planesptr[nodesptr[idx].plane].is_point_over(point) ? nodes[idx].over : nodes[idx].under;
-
-#ifdef DEBUG_ENABLED
-
- ERR_FAIL_COND_V(idx < MAX_NODES && idx >= node_count, 0);
-#endif
- }
-
- if (pass)
- pass_count++;
- }
-
- return pass_count;
-
-#else
- //this version scales better but it's slower for real world cases
-
- int *indices = (int *)alloca(p_point_count * sizeof(int));
- AABB bounds;
-
- for (int i = 0; i < p_point_count; i++) {
-
- indices[i] = i;
- if (i == 0)
- bounds.pos = p_points[i];
- else
- bounds.expand_to(p_points[i]);
- }
-
- Vector3 half_extents = bounds.size / 2.0;
- return _get_points_inside(nodes.size() + 1, p_points, indices, bounds.pos + half_extents, half_extents, p_point_count);
-#endif
-}
-
-bool BSP_Tree::point_is_inside(const Vector3 &p_point) const {
-
- if (!aabb.has_point(p_point)) {
- return false;
- }
-
- int node_count = nodes.size();
-
- if (node_count == 0) // no nodes!
- return false;
-
- const Node *nodesptr = &nodes[0];
- const Plane *planesptr = &planes[0];
-
- int idx = node_count - 1;
-
- while (true) {
-
- if (idx == OVER_LEAF) {
- return false;
- }
- if (idx == UNDER_LEAF) {
-
- return true;
- }
-
-#ifdef DEBUG_ENABLED
- int plane_count = planes.size();
- uint16_t plane = nodesptr[idx].plane;
- ERR_FAIL_UNSIGNED_INDEX_V(plane, plane_count, false);
-#endif
-
- bool over = planesptr[nodesptr[idx].plane].is_point_over(p_point);
-
- idx = over ? nodes[idx].over : nodes[idx].under;
-
-#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_V(idx < MAX_NODES && idx >= node_count, false);
-#endif
- }
-}
-
-static int _bsp_find_best_half_plane(const Face3 *p_faces, const Vector<int> &p_indices, real_t p_tolerance) {
-
- int ic = p_indices.size();
- const int *indices = p_indices.ptr();
-
- int best_plane = -1;
- real_t best_plane_cost = 1e20;
-
- // Loop to find the polygon that best divides the set.
-
- for (int i = 0; i < ic; i++) {
-
- const Face3 &f = p_faces[indices[i]];
- Plane p = f.get_plane();
-
- int num_over = 0, num_under = 0, num_spanning = 0;
-
- for (int j = 0; j < ic; j++) {
-
- if (i == j)
- continue;
-
- const Face3 &g = p_faces[indices[j]];
- int over = 0, under = 0;
-
- for (int k = 0; k < 3; k++) {
-
- real_t d = p.distance_to(g.vertex[j]);
-
- if (Math::abs(d) > p_tolerance) {
-
- if (d > 0)
- over++;
- else
- under++;
- }
- }
-
- if (over && under)
- num_spanning++;
- else if (over)
- num_over++;
- else
- num_under++;
- }
-
- //real_t split_cost = num_spanning / (real_t) face_count;
- real_t relation = Math::abs(num_over - num_under) / (real_t)ic;
-
- // being honest, i never found a way to add split cost to the mix in a meaninguful way
- // in this engine, also, will likely be ignored anyway
-
- real_t plane_cost = /*split_cost +*/ relation;
-
- //printf("plane %i, %i over, %i under, %i spanning, cost is %g\n",i,num_over,num_under,num_spanning,plane_cost);
- if (plane_cost < best_plane_cost) {
-
- best_plane = i;
- best_plane_cost = plane_cost;
- }
- }
-
- return best_plane;
-}
-
-static int _bsp_create_node(const Face3 *p_faces, const Vector<int> &p_indices, Vector<Plane> &p_planes, Vector<BSP_Tree::Node> &p_nodes, real_t p_tolerance) {
-
- ERR_FAIL_COND_V(p_nodes.size() == BSP_Tree::MAX_NODES, -1);
-
- // should not reach here
- ERR_FAIL_COND_V(p_indices.size() == 0, -1);
-
- int ic = p_indices.size();
- const int *indices = p_indices.ptr();
-
- int divisor_idx = _bsp_find_best_half_plane(p_faces, p_indices, p_tolerance);
-
- // returned error
- ERR_FAIL_COND_V(divisor_idx < 0, -1);
-
- Vector<int> faces_over;
- Vector<int> faces_under;
-
- Plane divisor_plane = p_faces[indices[divisor_idx]].get_plane();
-
- for (int i = 0; i < ic; i++) {
-
- if (i == divisor_idx)
- continue;
-
- const Face3 &f = p_faces[indices[i]];
-
- /*
- if (f.get_plane().is_equal_approx(divisor_plane))
- continue;
- */
-
- int over_count = 0;
- int under_count = 0;
-
- for (int j = 0; j < 3; j++) {
-
- real_t d = divisor_plane.distance_to(f.vertex[j]);
- if (Math::abs(d) > p_tolerance) {
-
- if (d > 0)
- over_count++;
- else
- under_count++;
- }
- }
-
- if (over_count)
- faces_over.push_back(indices[i]);
- if (under_count)
- faces_under.push_back(indices[i]);
- }
-
- uint16_t over_idx = BSP_Tree::OVER_LEAF, under_idx = BSP_Tree::UNDER_LEAF;
-
- if (faces_over.size() > 0) { //have facess above?
-
- int idx = _bsp_create_node(p_faces, faces_over, p_planes, p_nodes, p_tolerance);
- if (idx >= 0)
- over_idx = idx;
- }
-
- if (faces_under.size() > 0) { //have facess above?
-
- int idx = _bsp_create_node(p_faces, faces_under, p_planes, p_nodes, p_tolerance);
- if (idx >= 0)
- under_idx = idx;
- }
-
- /* Create the node */
-
- // find existing divisor plane
- int divisor_plane_idx = -1;
-
- for (int i = 0; i < p_planes.size(); i++) {
-
- if (p_planes[i].is_equal_approx(divisor_plane)) {
- divisor_plane_idx = i;
- break;
- }
- }
-
- if (divisor_plane_idx == -1) {
-
- ERR_FAIL_COND_V(p_planes.size() == BSP_Tree::MAX_PLANES, -1);
- divisor_plane_idx = p_planes.size();
- p_planes.push_back(divisor_plane);
- }
-
- BSP_Tree::Node node;
- node.plane = divisor_plane_idx;
- node.under = under_idx;
- node.over = over_idx;
-
- p_nodes.push_back(node);
-
- return p_nodes.size() - 1;
-}
-
-BSP_Tree::operator Variant() const {
-
- Dictionary d;
- d["error_radius"] = error_radius;
-
- Vector<real_t> plane_values;
- plane_values.resize(planes.size() * 4);
-
- for (int i = 0; i < planes.size(); i++) {
-
- plane_values.write[i * 4 + 0] = planes[i].normal.x;
- plane_values.write[i * 4 + 1] = planes[i].normal.y;
- plane_values.write[i * 4 + 2] = planes[i].normal.z;
- plane_values.write[i * 4 + 3] = planes[i].d;
- }
-
- d["planes"] = plane_values;
-
- PoolVector<int> dst_nodes;
- dst_nodes.resize(nodes.size() * 3);
-
- for (int i = 0; i < nodes.size(); i++) {
-
- dst_nodes.set(i * 3 + 0, nodes[i].over);
- dst_nodes.set(i * 3 + 1, nodes[i].under);
- dst_nodes.set(i * 3 + 2, nodes[i].plane);
- }
-
- d["nodes"] = dst_nodes;
- d["aabb"] = aabb;
-
- return Variant(d);
-}
-
-BSP_Tree::BSP_Tree() {
-}
-
-BSP_Tree::BSP_Tree(const Variant &p_variant) {
-
- Dictionary d = p_variant;
- ERR_FAIL_COND(!d.has("nodes"));
- ERR_FAIL_COND(!d.has("planes"));
- ERR_FAIL_COND(!d.has("aabb"));
- ERR_FAIL_COND(!d.has("error_radius"));
-
- PoolVector<int> src_nodes = d["nodes"];
- ERR_FAIL_COND(src_nodes.size() % 3);
-
- if (d["planes"].get_type() == Variant::POOL_REAL_ARRAY) {
-
- PoolVector<real_t> src_planes = d["planes"];
- int plane_count = src_planes.size();
- ERR_FAIL_COND(plane_count % 4);
- planes.resize(plane_count / 4);
-
- if (plane_count) {
- PoolVector<real_t>::Read r = src_planes.read();
- for (int i = 0; i < plane_count / 4; i++) {
-
- planes.write[i].normal.x = r[i * 4 + 0];
- planes.write[i].normal.y = r[i * 4 + 1];
- planes.write[i].normal.z = r[i * 4 + 2];
- planes.write[i].d = r[i * 4 + 3];
- }
- }
-
- } else {
-
- planes = d["planes"];
- }
-
- error_radius = d["error"];
- aabb = d["aabb"];
-
- //int node_count = src_nodes.size();
- nodes.resize(src_nodes.size() / 3);
-
- PoolVector<int>::Read r = src_nodes.read();
-
- for (int i = 0; i < nodes.size(); i++) {
-
- nodes.write[i].over = r[i * 3 + 0];
- nodes.write[i].under = r[i * 3 + 1];
- nodes.write[i].plane = r[i * 3 + 2];
- }
-}
-
-BSP_Tree::BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius) {
-
- // compute aabb
-
- int face_count = p_faces.size();
- PoolVector<Face3>::Read faces_r = p_faces.read();
- const Face3 *facesptr = faces_r.ptr();
-
- bool first = true;
-
- Vector<int> indices;
-
- for (int i = 0; i < face_count; i++) {
-
- const Face3 &f = facesptr[i];
-
- if (f.is_degenerate())
- continue;
-
- for (int j = 0; j < 3; j++) {
-
- if (first) {
-
- aabb.position = f.vertex[0];
- first = false;
- } else {
-
- aabb.expand_to(f.vertex[j]);
- }
- }
-
- indices.push_back(i);
- }
-
- ERR_FAIL_COND(aabb.has_no_area());
-
- int top = _bsp_create_node(faces_r.ptr(), indices, planes, nodes, aabb.get_longest_axis_size() * 0.0001);
-
- if (top < 0) {
-
- nodes.clear();
- planes.clear();
- ERR_FAIL_COND(top < 0);
- }
-
- error_radius = p_error_radius;
-}
-
-BSP_Tree::BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB &p_aabb, real_t p_error_radius) :
- nodes(p_nodes),
- planes(p_planes),
- aabb(p_aabb),
- error_radius(p_error_radius) {
-}
-
-BSP_Tree::~BSP_Tree() {
-}
diff --git a/core/math/bsp_tree.h b/core/math/bsp_tree.h
deleted file mode 100644
index 1c8ea380ff..0000000000
--- a/core/math/bsp_tree.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*************************************************************************/
-/* bsp_tree.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 BSP_TREE_H
-#define BSP_TREE_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"
-
-class BSP_Tree {
-public:
- enum {
-
- UNDER_LEAF = 0xFFFF,
- OVER_LEAF = 0xFFFE,
- MAX_NODES = 0xFFFE,
- MAX_PLANES = (1 << 16)
- };
-
- struct Node {
-
- uint16_t plane;
- uint16_t under;
- uint16_t over;
- };
-
-private:
- // thanks to the properties of Vector,
- // this class can be assigned and passed around between threads
- // with no cost.
-
- Vector<Node> nodes;
- Vector<Plane> planes;
- AABB aabb;
- real_t error_radius;
-
- int _get_points_inside(int p_node, const Vector3 *p_points, int *p_indices, const Vector3 &p_center, const Vector3 &p_half_extents, int p_indices_count) const;
-
- template <class T>
- bool _test_convex(const Node *p_nodes, const Plane *p_planes, int p_current, const T &p_convex) const;
-
-public:
- bool is_empty() const { return nodes.size() == 0; }
- Vector<Node> get_nodes() const;
- Vector<Plane> get_planes() const;
- AABB get_aabb() const;
-
- bool point_is_inside(const Vector3 &p_point) const;
- int get_points_inside(const Vector3 *p_points, int p_point_count) const;
- template <class T>
- bool convex_is_inside(const T &p_convex) const;
-
- operator Variant() const;
-
- void from_aabb(const AABB &p_aabb);
-
- BSP_Tree();
- BSP_Tree(const Variant &p_variant);
- BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius = 0);
- BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB &p_aabb, real_t p_error_radius = 0);
- ~BSP_Tree();
-};
-
-template <class T>
-bool BSP_Tree::_test_convex(const Node *p_nodes, const Plane *p_planes, int p_current, const T &p_convex) const {
-
- if (p_current == UNDER_LEAF)
- return true;
- else if (p_current == OVER_LEAF)
- return false;
-
- bool collided = false;
- const Node &n = p_nodes[p_current];
-
- const Plane &p = p_planes[n.plane];
-
- real_t min, max;
- p_convex.project_range(p.normal, min, max);
-
- bool go_under = min < p.d;
- bool go_over = max >= p.d;
-
- if (go_under && _test_convex(p_nodes, p_planes, n.under, p_convex))
- collided = true;
- if (go_over && _test_convex(p_nodes, p_planes, n.over, p_convex))
- collided = true;
-
- return collided;
-}
-
-template <class T>
-bool BSP_Tree::convex_is_inside(const T &p_convex) const {
-
- int node_count = nodes.size();
- if (node_count == 0)
- return false;
- const Node *nodes = &this->nodes[0];
- const Plane *planes = &this->planes[0];
-
- return _test_convex(nodes, planes, node_count - 1, p_convex);
-}
-
-#ifdef PTRCALL_ENABLED
-
-template <>
-struct PtrToArg<BSP_Tree> {
- _FORCE_INLINE_ static BSP_Tree convert(const void *p_ptr) {
- BSP_Tree s(Variant(*reinterpret_cast<const Dictionary *>(p_ptr)));
- return s;
- }
- _FORCE_INLINE_ static void encode(BSP_Tree p_val, void *p_ptr) {
- Dictionary *d = reinterpret_cast<Dictionary *>(p_ptr);
- *d = Variant(p_val);
- }
-};
-
-template <>
-struct PtrToArg<const BSP_Tree &> {
- _FORCE_INLINE_ static BSP_Tree convert(const void *p_ptr) {
- BSP_Tree s(Variant(*reinterpret_cast<const Dictionary *>(p_ptr)));
- return s;
- }
-};
-
-#endif
-
-#endif
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 2fda7a27d5..058673b681 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -208,16 +208,16 @@ int Expression::get_func_argument_count(BuiltinFunc p_func) {
return 0;
}
-#define VALIDATE_ARG_NUM(m_arg) \
- if (!p_inputs[m_arg]->is_num()) { \
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; \
- r_error.argument = m_arg; \
- r_error.expected = Variant::REAL; \
- return; \
+#define VALIDATE_ARG_NUM(m_arg) \
+ if (!p_inputs[m_arg]->is_num()) { \
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; \
+ r_error.argument = m_arg; \
+ r_error.expected = Variant::FLOAT; \
+ return; \
}
-void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Variant::CallError &r_error, String &r_error_str) {
- r_error.error = Variant::CallError::CALL_OK;
+void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str) {
+ r_error.error = Callable::CallError::CALL_OK;
switch (p_func) {
case MATH_SIN: {
@@ -314,15 +314,15 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
int64_t i = *p_inputs[0];
*r_return = ABS(i);
- } else if (p_inputs[0]->get_type() == Variant::REAL) {
+ } else if (p_inputs[0]->get_type() == Variant::FLOAT) {
real_t r = *p_inputs[0];
*r_return = Math::abs(r);
} else {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::REAL;
+ r_error.expected = Variant::FLOAT;
}
} break;
case MATH_SIGN: {
@@ -331,15 +331,15 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
int64_t i = *p_inputs[0];
*r_return = i < 0 ? -1 : (i > 0 ? +1 : 0);
- } else if (p_inputs[0]->get_type() == Variant::REAL) {
+ } else if (p_inputs[0]->get_type() == Variant::FLOAT) {
real_t r = *p_inputs[0];
*r_return = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0);
} else {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::REAL;
+ r_error.expected = Variant::FLOAT;
}
} break;
case MATH_POW: {
@@ -580,7 +580,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
if (p_inputs[0]->get_type() != Variant::OBJECT) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -614,7 +614,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
if (p_inputs[0]->get_type() != Variant::OBJECT) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -622,7 +622,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
}
if (p_inputs[1]->get_type() != Variant::STRING && p_inputs[1]->get_type() != Variant::NODE_PATH) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING;
@@ -644,7 +644,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
if (type < 0 || type >= Variant::VARIANT_MAX) {
r_error_str = RTR("Invalid type argument to convert(), use TYPE_* constants.");
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::INT;
return;
@@ -675,7 +675,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
if (p_inputs[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
@@ -687,7 +687,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
if (str.length() != 1) {
r_error_str = RTR("Expected a string of length 1 (a character).");
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
@@ -732,7 +732,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
case STR_TO_VAR: {
if (p_inputs[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
@@ -747,7 +747,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
Error err = VariantParser::parse(&ss, *r_return, errs, line);
if (err != OK) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
*r_return = "Parse error at line " + itos(line) + ": " + errs;
@@ -757,12 +757,12 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
} break;
case VAR_TO_BYTES: {
- PoolByteArray barr;
+ PackedByteArray barr;
bool full_objects = *p_inputs[1];
int len;
Error err = encode_variant(*p_inputs[0], NULL, len, full_objects);
if (err) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::NIL;
r_error_str = "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID).";
@@ -771,32 +771,32 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
barr.resize(len);
{
- PoolByteArray::Write w = barr.write();
- encode_variant(*p_inputs[0], w.ptr(), len, full_objects);
+ uint8_t *w = barr.ptrw();
+ encode_variant(*p_inputs[0], w, len, full_objects);
}
*r_return = barr;
} break;
case BYTES_TO_VAR: {
- if (p_inputs[0]->get_type() != Variant::POOL_BYTE_ARRAY) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ if (p_inputs[0]->get_type() != Variant::PACKED_BYTE_ARRAY) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::POOL_BYTE_ARRAY;
+ r_error.expected = Variant::PACKED_BYTE_ARRAY;
return;
}
- PoolByteArray varr = *p_inputs[0];
+ PackedByteArray varr = *p_inputs[0];
bool allow_objects = *p_inputs[1];
Variant ret;
{
- PoolByteArray::Read r = varr.read();
- Error err = decode_variant(ret, r.ptr(), varr.size(), NULL, allow_objects);
+ const uint8_t *r = varr.ptr();
+ Error err = decode_variant(ret, r, varr.size(), NULL, allow_objects);
if (err != OK) {
r_error_str = RTR("Not enough bytes for decoding bytes, or invalid format.");
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::POOL_BYTE_ARRAY;
+ r_error.expected = Variant::PACKED_BYTE_ARRAY;
return;
}
}
@@ -1161,7 +1161,7 @@ Error Expression::_get_token(Token &r_token) {
if (is_float)
r_token.value = num.to_double();
else
- r_token.value = num.to_int();
+ r_token.value = num.to_int64();
return OK;
} else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') {
@@ -2071,10 +2071,10 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
argp.write[i] = &arr[i];
}
- Variant::CallError ce;
+ Callable::CallError ce;
r_ret = Variant::construct(constructor->data_type, (const Variant **)argp.ptr(), argp.size(), ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = vformat(RTR("Invalid arguments to construct '%s'"), Variant::get_type_name(constructor->data_type));
return true;
}
@@ -2099,10 +2099,10 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
argp.write[i] = &arr[i];
}
- Variant::CallError ce;
+ Callable::CallError ce;
exec_func(bifunc->func, (const Variant **)argp.ptr(), &r_ret, ce, r_error_str);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = "Builtin Call Failed. " + r_error_str;
return true;
}
@@ -2134,10 +2134,10 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
argp.write[i] = &arr[i];
}
- Variant::CallError ce;
+ Callable::CallError ce;
r_ret = base.call(call->method, (const Variant **)argp.ptr(), argp.size(), ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = vformat(RTR("On call to '%s':"), String(call->method));
return true;
}
diff --git a/core/math/expression.h b/core/math/expression.h
index 1cd1415dcf..bbf946bb0a 100644
--- a/core/math/expression.h
+++ b/core/math/expression.h
@@ -111,7 +111,7 @@ public:
static int get_func_argument_count(BuiltinFunc p_func);
static String get_func_name(BuiltinFunc p_func);
- static void exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Variant::CallError &r_error, String &r_error_str);
+ static void exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str);
static BuiltinFunc find_function(const String &p_string);
private:
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index 7eb48290a8..69c7abfd30 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -214,23 +214,19 @@ static bool _group_face(_FaceClassify *p_faces, int len, int p_index, int p_grou
return true;
}
-PoolVector<PoolVector<Face3> > Geometry::separate_objects(PoolVector<Face3> p_array) {
+Vector<Vector<Face3> > Geometry::separate_objects(Vector<Face3> p_array) {
- PoolVector<PoolVector<Face3> > objects;
+ Vector<Vector<Face3> > objects;
int len = p_array.size();
- PoolVector<Face3>::Read r = p_array.read();
+ const Face3 *arrayptr = p_array.ptr();
- const Face3 *arrayptr = r.ptr();
-
- PoolVector<_FaceClassify> fc;
+ Vector<_FaceClassify> fc;
fc.resize(len);
- PoolVector<_FaceClassify>::Write fcw = fc.write();
-
- _FaceClassify *_fcptr = fcw.ptr();
+ _FaceClassify *_fcptr = fc.ptrw();
for (int i = 0; i < len; i++) {
@@ -239,7 +235,7 @@ PoolVector<PoolVector<Face3> > Geometry::separate_objects(PoolVector<Face3> p_ar
bool error = _connect_faces(_fcptr, len, -1);
- ERR_FAIL_COND_V_MSG(error, PoolVector<PoolVector<Face3> >(), "Invalid geometry.");
+ ERR_FAIL_COND_V_MSG(error, Vector<Vector<Face3> >(), "Invalid geometry.");
// Group connected faces in separate objects.
@@ -263,8 +259,7 @@ PoolVector<PoolVector<Face3> > Geometry::separate_objects(PoolVector<Face3> p_ar
if (group >= 0) {
objects.resize(group);
- PoolVector<PoolVector<Face3> >::Write obw = objects.write();
- PoolVector<Face3> *group_faces = obw.ptr();
+ Vector<Face3> *group_faces = objects.ptrw();
for (int i = 0; i < len; i++) {
if (!_fcptr[i].valid)
@@ -470,7 +465,7 @@ static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z,
}
}
-static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z, PoolVector<Face3> &p_faces) {
+static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z, Vector<Face3> &p_faces) {
ERR_FAIL_INDEX(x, len_x);
ERR_FAIL_INDEX(y, len_y);
@@ -530,14 +525,13 @@ static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, i
}
}
-PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_error) {
+Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
#define _MIN_SIZE 1.0
#define _MAX_LENGTH 20
int face_count = p_array.size();
- PoolVector<Face3>::Read facesr = p_array.read();
- const Face3 *faces = facesr.ptr();
+ const Face3 *faces = p_array.ptr();
AABB global_aabb;
@@ -638,7 +632,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
// Build faces for the inside-outside cell divisors.
- PoolVector<Face3> wrapped_faces;
+ Vector<Face3> wrapped_faces;
for (int i = 0; i < div_x; i++) {
@@ -654,8 +648,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
// Transform face vertices to global coords.
int wrapped_faces_count = wrapped_faces.size();
- PoolVector<Face3>::Write wrapped_facesw = wrapped_faces.write();
- Face3 *wrapped_faces_ptr = wrapped_facesw.ptr();
+ Face3 *wrapped_faces_ptr = wrapped_faces.ptrw();
for (int i = 0; i < wrapped_faces_count; i++) {
@@ -720,7 +713,7 @@ Vector<Vector<Vector2> > Geometry::decompose_polygon_in_convex(Vector<Point2> po
return decomp;
}
-Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<Plane> &p_planes) {
+Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
MeshData mesh;
@@ -859,9 +852,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<Plane> &p_planes
return mesh;
}
-PoolVector<Plane> Geometry::build_box_planes(const Vector3 &p_extents) {
+Vector<Plane> Geometry::build_box_planes(const Vector3 &p_extents) {
- PoolVector<Plane> planes;
+ Vector<Plane> planes;
planes.push_back(Plane(Vector3(1, 0, 0), p_extents.x));
planes.push_back(Plane(Vector3(-1, 0, 0), p_extents.x));
@@ -873,9 +866,9 @@ PoolVector<Plane> Geometry::build_box_planes(const Vector3 &p_extents) {
return planes;
}
-PoolVector<Plane> Geometry::build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis) {
+Vector<Plane> Geometry::build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis) {
- PoolVector<Plane> planes;
+ Vector<Plane> planes;
for (int i = 0; i < p_sides; i++) {
@@ -895,9 +888,9 @@ PoolVector<Plane> Geometry::build_cylinder_planes(real_t p_radius, real_t p_heig
return planes;
}
-PoolVector<Plane> Geometry::build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis) {
+Vector<Plane> Geometry::build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis) {
- PoolVector<Plane> planes;
+ Vector<Plane> planes;
Vector3 axis;
axis[p_axis] = 1.0;
@@ -928,9 +921,9 @@ PoolVector<Plane> Geometry::build_sphere_planes(real_t p_radius, int p_lats, int
return planes;
}
-PoolVector<Plane> Geometry::build_capsule_planes(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
+Vector<Plane> Geometry::build_capsule_planes(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
- PoolVector<Plane> planes;
+ Vector<Plane> planes;
Vector3 axis;
axis[p_axis] = 1.0;
diff --git a/core/math/geometry.h b/core/math/geometry.h
index b9193242bc..a94d00bf77 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -37,7 +37,7 @@
#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"
@@ -899,10 +899,10 @@ public:
return (intersections & 1);
}
- static PoolVector<PoolVector<Face3> > separate_objects(PoolVector<Face3> p_array);
+ static Vector<Vector<Face3> > separate_objects(Vector<Face3> p_array);
// Create a "wrap" that encloses the given geometry.
- static PoolVector<Face3> wrap_geometry(PoolVector<Face3> p_array, real_t *p_error = NULL);
+ static Vector<Face3> wrap_geometry(Vector<Face3> p_array, real_t *p_error = NULL);
struct MeshData {
@@ -1006,11 +1006,11 @@ public:
}
static Vector<Vector<Vector2> > decompose_polygon_in_convex(Vector<Point2> polygon);
- static MeshData build_convex_mesh(const PoolVector<Plane> &p_planes);
- static PoolVector<Plane> build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis = Vector3::AXIS_Z);
- static PoolVector<Plane> build_box_planes(const Vector3 &p_extents);
- static PoolVector<Plane> build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z);
- static PoolVector<Plane> build_capsule_planes(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis = Vector3::AXIS_Z);
+ static MeshData build_convex_mesh(const Vector<Plane> &p_planes);
+ static Vector<Plane> build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis = Vector3::AXIS_Z);
+ static Vector<Plane> build_box_planes(const Vector3 &p_extents);
+ static Vector<Plane> build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z);
+ static Vector<Plane> build_capsule_planes(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis = Vector3::AXIS_Z);
static void make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_result, Size2i &r_size);
diff --git a/core/math/rect2.h b/core/math/rect2.h
index 0d2e7eb6e5..3b9660e2f0 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -47,28 +47,26 @@ struct Rect2 {
real_t get_area() const { return size.width * size.height; }
- inline bool intersects(const Rect2 &p_rect) const {
- if (position.x >= (p_rect.position.x + p_rect.size.width))
- return false;
- if ((position.x + size.width) <= p_rect.position.x)
- return false;
- if (position.y >= (p_rect.position.y + p_rect.size.height))
- return false;
- if ((position.y + size.height) <= p_rect.position.y)
- return false;
-
- return true;
- }
-
- inline bool intersects_touch(const Rect2 &p_rect) const {
- if (position.x > (p_rect.position.x + p_rect.size.width))
- return false;
- if ((position.x + size.width) < p_rect.position.x)
- return false;
- if (position.y > (p_rect.position.y + p_rect.size.height))
- return false;
- if ((position.y + size.height) < p_rect.position.y)
- return false;
+ inline bool intersects(const Rect2 &p_rect, const bool p_include_borders = false) const {
+ if (p_include_borders) {
+ if (position.x > (p_rect.position.x + p_rect.size.width))
+ return false;
+ if ((position.x + size.width) < p_rect.position.x)
+ return false;
+ if (position.y > (p_rect.position.y + p_rect.size.height))
+ return false;
+ if ((position.y + size.height) < p_rect.position.y)
+ return false;
+ } else {
+ if (position.x >= (p_rect.position.x + p_rect.size.width))
+ return false;
+ if ((position.x + size.width) <= p_rect.position.x)
+ return false;
+ if (position.y >= (p_rect.position.y + p_rect.size.height))
+ return false;
+ if ((position.y + size.height) <= p_rect.position.y)
+ return false;
+ }
return true;
}
@@ -387,6 +385,11 @@ struct Rect2i {
size = end - begin;
}
+ _FORCE_INLINE_ Rect2i abs() const {
+
+ return Rect2i(Point2i(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs());
+ }
+
operator String() const { return String(position) + ", " + String(size); }
operator Rect2() const { return Rect2(position, size); }
diff --git a/core/math/transform.h b/core/math/transform.h
index ad397d9c09..c6e3be4c70 100644
--- a/core/math/transform.h
+++ b/core/math/transform.h
@@ -34,7 +34,6 @@
#include "core/math/aabb.h"
#include "core/math/basis.h"
#include "core/math/plane.h"
-#include "core/pool_vector.h"
class Transform {
public:
@@ -84,8 +83,8 @@ public:
_FORCE_INLINE_ AABB xform(const AABB &p_aabb) const;
_FORCE_INLINE_ AABB xform_inv(const AABB &p_aabb) const;
- _FORCE_INLINE_ PoolVector<Vector3> xform(const PoolVector<Vector3> &p_array) const;
- _FORCE_INLINE_ PoolVector<Vector3> xform_inv(const PoolVector<Vector3> &p_array) const;
+ _FORCE_INLINE_ Vector<Vector3> xform(const Vector<Vector3> &p_array) const;
+ _FORCE_INLINE_ Vector<Vector3> xform_inv(const Vector<Vector3> &p_array) const;
void operator*=(const Transform &p_transform);
Transform operator*(const Transform &p_transform) const;
@@ -210,13 +209,13 @@ _FORCE_INLINE_ AABB Transform::xform_inv(const AABB &p_aabb) const {
return ret;
}
-PoolVector<Vector3> Transform::xform(const PoolVector<Vector3> &p_array) const {
+Vector<Vector3> Transform::xform(const Vector<Vector3> &p_array) const {
- PoolVector<Vector3> array;
+ Vector<Vector3> array;
array.resize(p_array.size());
- PoolVector<Vector3>::Read r = p_array.read();
- PoolVector<Vector3>::Write w = array.write();
+ const Vector3 *r = p_array.ptr();
+ Vector3 *w = array.ptrw();
for (int i = 0; i < p_array.size(); ++i) {
w[i] = xform(r[i]);
@@ -224,13 +223,13 @@ PoolVector<Vector3> Transform::xform(const PoolVector<Vector3> &p_array) const {
return array;
}
-PoolVector<Vector3> Transform::xform_inv(const PoolVector<Vector3> &p_array) const {
+Vector<Vector3> Transform::xform_inv(const Vector<Vector3> &p_array) const {
- PoolVector<Vector3> array;
+ Vector<Vector3> array;
array.resize(p_array.size());
- PoolVector<Vector3>::Read r = p_array.read();
- PoolVector<Vector3>::Write w = array.write();
+ const Vector3 *r = p_array.ptr();
+ Vector3 *w = array.ptrw();
for (int i = 0; i < p_array.size(); ++i) {
w[i] = xform_inv(r[i]);
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index 367f697ccf..fa43762aa4 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -32,7 +32,6 @@
#define TRANSFORM_2D_H
#include "core/math/rect2.h" // also includes vector2, math_funcs, and ustring
-#include "core/pool_vector.h"
struct Transform2D {
// Warning #1: basis of Transform2D is stored differently from Basis. In terms of elements array, the basis matrix looks like "on paper":
@@ -112,8 +111,8 @@ struct Transform2D {
_FORCE_INLINE_ Vector2 xform_inv(const Vector2 &p_vec) const;
_FORCE_INLINE_ Rect2 xform(const Rect2 &p_rect) const;
_FORCE_INLINE_ Rect2 xform_inv(const Rect2 &p_rect) const;
- _FORCE_INLINE_ PoolVector<Vector2> xform(const PoolVector<Vector2> &p_array) const;
- _FORCE_INLINE_ PoolVector<Vector2> xform_inv(const PoolVector<Vector2> &p_array) const;
+ _FORCE_INLINE_ Vector<Vector2> xform(const Vector<Vector2> &p_array) const;
+ _FORCE_INLINE_ Vector<Vector2> xform_inv(const Vector<Vector2> &p_array) const;
operator String() const;
@@ -203,13 +202,13 @@ Rect2 Transform2D::xform_inv(const Rect2 &p_rect) const {
return new_rect;
}
-PoolVector<Vector2> Transform2D::xform(const PoolVector<Vector2> &p_array) const {
+Vector<Vector2> Transform2D::xform(const Vector<Vector2> &p_array) const {
- PoolVector<Vector2> array;
+ Vector<Vector2> array;
array.resize(p_array.size());
- PoolVector<Vector2>::Read r = p_array.read();
- PoolVector<Vector2>::Write w = array.write();
+ const Vector2 *r = p_array.ptr();
+ Vector2 *w = array.ptrw();
for (int i = 0; i < p_array.size(); ++i) {
w[i] = xform(r[i]);
@@ -217,13 +216,13 @@ PoolVector<Vector2> Transform2D::xform(const PoolVector<Vector2> &p_array) const
return array;
}
-PoolVector<Vector2> Transform2D::xform_inv(const PoolVector<Vector2> &p_array) const {
+Vector<Vector2> Transform2D::xform_inv(const Vector<Vector2> &p_array) const {
- PoolVector<Vector2> array;
+ Vector<Vector2> array;
array.resize(p_array.size());
- PoolVector<Vector2>::Read r = p_array.read();
- PoolVector<Vector2>::Write w = array.write();
+ const Vector2 *r = p_array.ptr();
+ Vector2 *w = array.ptrw();
for (int i = 0; i < p_array.size(); ++i) {
w[i] = xform_inv(r[i]);
diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp
index 53d4ea0a96..01d38cf24e 100644
--- a/core/math/triangle_mesh.cpp
+++ b/core/math/triangle_mesh.cpp
@@ -89,7 +89,7 @@ int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, in
return index;
}
-void TriangleMesh::get_indices(PoolVector<int> *r_triangles_indices) const {
+void TriangleMesh::get_indices(Vector<int> *r_triangles_indices) const {
if (!valid)
return;
@@ -97,10 +97,10 @@ void TriangleMesh::get_indices(PoolVector<int> *r_triangles_indices) const {
const int triangles_num = triangles.size();
// Parse vertices indices
- PoolVector<Triangle>::Read triangles_read = triangles.read();
+ const Triangle *triangles_read = triangles.ptr();
r_triangles_indices->resize(triangles_num * 3);
- PoolVector<int>::Write r_indices_write = r_triangles_indices->write();
+ int *r_indices_write = r_triangles_indices->ptrw();
for (int i = 0; i < triangles_num; ++i) {
r_indices_write[3 * i + 0] = triangles_read[i].indices[0];
@@ -109,7 +109,7 @@ void TriangleMesh::get_indices(PoolVector<int> *r_triangles_indices) const {
}
}
-void TriangleMesh::create(const PoolVector<Vector3> &p_faces) {
+void TriangleMesh::create(const Vector<Vector3> &p_faces) {
valid = false;
@@ -119,7 +119,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) {
triangles.resize(fc);
bvh.resize(fc * 3); //will never be larger than this (todo make better)
- PoolVector<BVH>::Write bw = bvh.write();
+ BVH *bw = bvh.ptrw();
{
@@ -127,8 +127,8 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) {
//except for the Set for repeated triangles, everything
//goes in-place.
- PoolVector<Vector3>::Read r = p_faces.read();
- PoolVector<Triangle>::Write w = triangles.write();
+ const Vector3 *r = p_faces.ptr();
+ Triangle *w = triangles.ptrw();
Map<Vector3, int> db;
for (int i = 0; i < fc; i++) {
@@ -164,15 +164,15 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) {
}
vertices.resize(db.size());
- PoolVector<Vector3>::Write vw = vertices.write();
+ Vector3 *vw = vertices.ptrw();
for (Map<Vector3, int>::Element *E = db.front(); E; E = E->next()) {
vw[E->get()] = E->key();
}
}
- PoolVector<BVH *> bwptrs;
+ Vector<BVH *> bwptrs;
bwptrs.resize(fc);
- PoolVector<BVH *>::Write bwp = bwptrs.write();
+ BVH **bwp = bwptrs.ptrw();
for (int i = 0; i < fc; i++) {
bwp[i] = &bw[i];
@@ -180,9 +180,8 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) {
max_depth = 0;
int max_alloc = fc;
- _create_bvh(bw.ptr(), bwp.ptr(), 0, fc, 1, max_depth, max_alloc);
+ _create_bvh(bw, bwp, 0, fc, 1, max_depth, max_alloc);
- bw.release(); //clearup
bvh.resize(max_alloc); //resize back
valid = true;
@@ -208,13 +207,11 @@ Vector3 TriangleMesh::get_area_normal(const AABB &p_aabb) const {
int level = 0;
- PoolVector<Triangle>::Read trianglesr = triangles.read();
- PoolVector<Vector3>::Read verticesr = vertices.read();
- PoolVector<BVH>::Read bvhr = bvh.read();
+ const Triangle *triangleptr = triangles.ptr();
+ // const Vector3 *verticesr = vertices.ptr();
+ const BVH *bvhptr = bvh.ptr();
- const Triangle *triangleptr = trianglesr.ptr();
int pos = bvh.size() - 1;
- const BVH *bvhptr = bvhr.ptr();
stack[0] = pos;
while (true) {
@@ -304,14 +301,11 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en
int level = 0;
- PoolVector<Triangle>::Read trianglesr = triangles.read();
- PoolVector<Vector3>::Read verticesr = vertices.read();
- PoolVector<BVH>::Read bvhr = bvh.read();
+ const Triangle *triangleptr = triangles.ptr();
+ const Vector3 *vertexptr = vertices.ptr();
+ const BVH *bvhptr = bvh.ptr();
- const Triangle *triangleptr = trianglesr.ptr();
- const Vector3 *vertexptr = verticesr.ptr();
int pos = bvh.size() - 1;
- const BVH *bvhptr = bvhr.ptr();
stack[0] = pos;
while (true) {
@@ -419,14 +413,11 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V
int level = 0;
- PoolVector<Triangle>::Read trianglesr = triangles.read();
- PoolVector<Vector3>::Read verticesr = vertices.read();
- PoolVector<BVH>::Read bvhr = bvh.read();
+ const Triangle *triangleptr = triangles.ptr();
+ const Vector3 *vertexptr = vertices.ptr();
+ const BVH *bvhptr = bvh.ptr();
- const Triangle *triangleptr = trianglesr.ptr();
- const Vector3 *vertexptr = verticesr.ptr();
int pos = bvh.size() - 1;
- const BVH *bvhptr = bvhr.ptr();
stack[0] = pos;
while (true) {
@@ -529,14 +520,11 @@ bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_cou
int level = 0;
- PoolVector<Triangle>::Read trianglesr = triangles.read();
- PoolVector<Vector3>::Read verticesr = vertices.read();
- PoolVector<BVH>::Read bvhr = bvh.read();
+ const Triangle *triangleptr = triangles.ptr();
+ const Vector3 *vertexptr = vertices.ptr();
+ const BVH *bvhptr = bvh.ptr();
- const Triangle *triangleptr = trianglesr.ptr();
- const Vector3 *vertexptr = verticesr.ptr();
int pos = bvh.size() - 1;
- const BVH *bvhptr = bvhr.ptr();
stack[0] = pos;
while (true) {
@@ -645,16 +633,13 @@ bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count,
int level = 0;
- PoolVector<Triangle>::Read trianglesr = triangles.read();
- PoolVector<Vector3>::Read verticesr = vertices.read();
- PoolVector<BVH>::Read bvhr = bvh.read();
+ const Triangle *triangleptr = triangles.ptr();
+ const Vector3 *vertexptr = vertices.ptr();
+ const BVH *bvhptr = bvh.ptr();
Transform scale(Basis().scaled(p_scale));
- const Triangle *triangleptr = trianglesr.ptr();
- const Vector3 *vertexptr = verticesr.ptr();
int pos = bvh.size() - 1;
- const BVH *bvhptr = bvhr.ptr();
stack[0] = pos;
while (true) {
@@ -732,18 +717,18 @@ bool TriangleMesh::is_valid() const {
return valid;
}
-PoolVector<Face3> TriangleMesh::get_faces() const {
+Vector<Face3> TriangleMesh::get_faces() const {
if (!valid)
- return PoolVector<Face3>();
+ return Vector<Face3>();
- PoolVector<Face3> faces;
+ Vector<Face3> faces;
int ts = triangles.size();
faces.resize(triangles.size());
- PoolVector<Face3>::Write w = faces.write();
- PoolVector<Triangle>::Read r = triangles.read();
- PoolVector<Vector3>::Read rv = vertices.read();
+ Face3 *w = faces.ptrw();
+ const Triangle *r = triangles.ptr();
+ const Vector3 *rv = vertices.ptr();
for (int i = 0; i < ts; i++) {
for (int j = 0; j < 3; j++) {
@@ -751,7 +736,6 @@ PoolVector<Face3> TriangleMesh::get_faces() const {
}
}
- w.release();
return faces;
}
diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h
index 575a78b0b5..fdbfb90465 100644
--- a/core/math/triangle_mesh.h
+++ b/core/math/triangle_mesh.h
@@ -44,8 +44,8 @@ class TriangleMesh : public Reference {
int indices[3];
};
- PoolVector<Triangle> triangles;
- PoolVector<Vector3> vertices;
+ Vector<Triangle> triangles;
+ Vector<Vector3> vertices;
struct BVH {
@@ -82,7 +82,7 @@ class TriangleMesh : public Reference {
int _create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc);
- PoolVector<BVH> bvh;
+ Vector<BVH> bvh;
int max_depth;
bool valid;
@@ -93,13 +93,13 @@ public:
bool intersect_convex_shape(const Plane *p_planes, int p_plane_count) const;
bool inside_convex_shape(const Plane *p_planes, int p_plane_count, Vector3 p_scale = Vector3(1, 1, 1)) const;
Vector3 get_area_normal(const AABB &p_aabb) const;
- PoolVector<Face3> get_faces() const;
+ Vector<Face3> get_faces() const;
- PoolVector<Triangle> get_triangles() const { return triangles; }
- PoolVector<Vector3> get_vertices() const { return vertices; }
- void get_indices(PoolVector<int> *r_triangles_indices) const;
+ Vector<Triangle> get_triangles() const { return triangles; }
+ Vector<Vector3> get_vertices() const { return vertices; }
+ void get_indices(Vector<int> *r_triangles_indices) const;
- void create(const PoolVector<Vector3> &p_faces);
+ void create(const Vector<Vector3> &p_faces);
TriangleMesh();
};
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 1dec830821..ba5558102f 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -311,10 +311,15 @@ struct Vector2i {
bool operator<(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
bool operator>(const Vector2i &p_vec2) const { return (x == p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); }
+ bool operator<=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y <= p_vec2.y) : (x < p_vec2.x); }
+ bool operator>=(const Vector2i &p_vec2) const { return x == p_vec2.x ? (y >= p_vec2.y) : (x > p_vec2.x); }
+
bool operator==(const Vector2i &p_vec2) const;
bool operator!=(const Vector2i &p_vec2) const;
- real_t get_aspect() const { return width / (real_t)height; }
+ real_t aspect() const { return width / (real_t)height; }
+ Vector2i sign() const { return Vector2i(SGN(x), SGN(y)); }
+ Vector2i abs() const { return Vector2i(ABS(x), ABS(y)); }
operator String() const { return String::num(x) + ", " + String::num(y); }
diff --git a/core/message_queue.cpp b/core/message_queue.cpp
index 42390935d4..37207483fe 100644
--- a/core/message_queue.cpp
+++ b/core/message_queue.cpp
@@ -30,6 +30,7 @@
#include "message_queue.h"
+#include "core/core_string_names.h"
#include "core/project_settings.h"
#include "core/script_language.h"
@@ -42,37 +43,7 @@ MessageQueue *MessageQueue::get_singleton() {
Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, const Variant **p_args, int p_argcount, bool p_show_error) {
- _THREAD_SAFE_METHOD_
-
- int room_needed = sizeof(Message) + sizeof(Variant) * p_argcount;
-
- if ((buffer_end + room_needed) >= buffer_size) {
- String type;
- if (ObjectDB::get_instance(p_id))
- type = ObjectDB::get_instance(p_id)->get_class();
- print_line("Failed method: " + type + ":" + p_method + " target ID: " + itos(p_id));
- statistics();
- ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings.");
- }
-
- Message *msg = memnew_placement(&buffer[buffer_end], Message);
- msg->args = p_argcount;
- msg->instance_id = p_id;
- msg->target = p_method;
- msg->type = TYPE_CALL;
- if (p_show_error)
- msg->type |= FLAG_SHOW_ERROR;
-
- buffer_end += sizeof(Message);
-
- for (int i = 0; i < p_argcount; i++) {
-
- Variant *v = memnew_placement(&buffer[buffer_end], Variant);
- buffer_end += sizeof(Variant);
- *v = *p_args[i];
- }
-
- return OK;
+ return push_callable(Callable(p_id, p_method), p_args, p_argcount, p_show_error);
}
Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, VARIANT_ARG_DECLARE) {
@@ -107,8 +78,7 @@ Error MessageQueue::push_set(ObjectID p_id, const StringName &p_prop, const Vari
Message *msg = memnew_placement(&buffer[buffer_end], Message);
msg->args = 1;
- msg->instance_id = p_id;
- msg->target = p_prop;
+ msg->callable = Callable(p_id, p_prop);
msg->type = TYPE_SET;
buffer_end += sizeof(Message);
@@ -137,7 +107,7 @@ Error MessageQueue::push_notification(ObjectID p_id, int p_notification) {
Message *msg = memnew_placement(&buffer[buffer_end], Message);
msg->type = TYPE_NOTIFICATION;
- msg->instance_id = p_id;
+ msg->callable = Callable(p_id, CoreStringNames::get_singleton()->notification); //name is meaningless but callable needs it
//msg->target;
msg->notification = p_notification;
@@ -160,18 +130,49 @@ Error MessageQueue::push_set(Object *p_object, const StringName &p_prop, const V
return push_set(p_object->get_instance_id(), p_prop, p_value);
}
+Error MessageQueue::push_callable(const Callable &p_callable, const Variant **p_args, int p_argcount, bool p_show_error) {
+
+ _THREAD_SAFE_METHOD_
+
+ int room_needed = sizeof(Message) + sizeof(Variant) * p_argcount;
+
+ if ((buffer_end + room_needed) >= buffer_size) {
+ print_line("Failed method: " + p_callable);
+ statistics();
+ ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings.");
+ }
+
+ Message *msg = memnew_placement(&buffer[buffer_end], Message);
+ msg->args = p_argcount;
+ msg->callable = p_callable;
+ msg->type = TYPE_CALL;
+ if (p_show_error)
+ msg->type |= FLAG_SHOW_ERROR;
+
+ buffer_end += sizeof(Message);
+
+ for (int i = 0; i < p_argcount; i++) {
+
+ Variant *v = memnew_placement(&buffer[buffer_end], Variant);
+ buffer_end += sizeof(Variant);
+ *v = *p_args[i];
+ }
+
+ return OK;
+}
+
void MessageQueue::statistics() {
Map<StringName, int> set_count;
Map<int, int> notify_count;
- Map<StringName, int> call_count;
+ Map<Callable, int> call_count;
int null_count = 0;
uint32_t read_pos = 0;
while (read_pos < buffer_end) {
Message *message = (Message *)&buffer[read_pos];
- Object *target = ObjectDB::get_instance(message->instance_id);
+ Object *target = message->callable.get_object();
if (target != NULL) {
@@ -179,10 +180,10 @@ void MessageQueue::statistics() {
case TYPE_CALL: {
- if (!call_count.has(message->target))
- call_count[message->target] = 0;
+ if (!call_count.has(message->callable))
+ call_count[message->callable] = 0;
- call_count[message->target]++;
+ call_count[message->callable]++;
} break;
case TYPE_NOTIFICATION: {
@@ -195,10 +196,11 @@ void MessageQueue::statistics() {
} break;
case TYPE_SET: {
- if (!set_count.has(message->target))
- set_count[message->target] = 0;
+ StringName t = message->callable.get_method();
+ if (!set_count.has(t))
+ set_count[t] = 0;
- set_count[message->target]++;
+ set_count[t]++;
} break;
}
@@ -222,7 +224,7 @@ void MessageQueue::statistics() {
print_line("SET " + E->key() + ": " + itos(E->get()));
}
- for (Map<StringName, int>::Element *E = call_count.front(); E; E = E->next()) {
+ for (Map<Callable, int>::Element *E = call_count.front(); E; E = E->next()) {
print_line("CALL " + E->key() + ": " + itos(E->get()));
}
@@ -236,7 +238,7 @@ int MessageQueue::get_max_buffer_usage() const {
return buffer_max_used;
}
-void MessageQueue::_call_function(Object *p_target, const StringName &p_func, const Variant *p_args, int p_argcount, bool p_show_error) {
+void MessageQueue::_call_function(const Callable &p_callable, const Variant *p_args, int p_argcount, bool p_show_error) {
const Variant **argptrs = NULL;
if (p_argcount) {
@@ -246,11 +248,12 @@ void MessageQueue::_call_function(Object *p_target, const StringName &p_func, co
}
}
- Variant::CallError ce;
- p_target->call(p_func, argptrs, p_argcount, ce);
- if (p_show_error && ce.error != Variant::CallError::CALL_OK) {
+ Callable::CallError ce;
+ Variant ret;
+ p_callable.call(argptrs, p_argcount, ret, ce);
+ if (p_show_error && ce.error != Callable::CallError::CALL_OK) {
- ERR_PRINT("Error calling deferred method: " + Variant::get_call_error_text(p_target, p_func, argptrs, p_argcount, ce) + ".");
+ ERR_PRINT("Error calling deferred method: " + Variant::get_callable_error_text(p_callable, argptrs, p_argcount, ce) + ".");
}
}
@@ -265,7 +268,10 @@ void MessageQueue::flush() {
//using reverse locking strategy
_THREAD_SAFE_LOCK_
- ERR_FAIL_COND(flushing); //already flushing, you did something odd
+ if (flushing) {
+ _THREAD_SAFE_UNLOCK_
+ ERR_FAIL_COND(flushing); //already flushing, you did something odd
+ }
flushing = true;
while (read_pos < buffer_end) {
@@ -283,7 +289,7 @@ void MessageQueue::flush() {
_THREAD_SAFE_UNLOCK_
- Object *target = ObjectDB::get_instance(message->instance_id);
+ Object *target = message->callable.get_object();
if (target != NULL) {
@@ -294,7 +300,7 @@ void MessageQueue::flush() {
// messages don't expect a return value
- _call_function(target, message->target, args, message->args, message->type & FLAG_SHOW_ERROR);
+ _call_function(message->callable, args, message->args, message->type & FLAG_SHOW_ERROR);
} break;
case TYPE_NOTIFICATION: {
@@ -307,7 +313,7 @@ void MessageQueue::flush() {
Variant *arg = (Variant *)(message + 1);
// messages don't expect a return value
- target->set(message->target, *arg);
+ target->set(message->callable.get_method(), *arg);
} break;
}
diff --git a/core/message_queue.h b/core/message_queue.h
index e9a92ff5b7..9ba748bb42 100644
--- a/core/message_queue.h
+++ b/core/message_queue.h
@@ -54,8 +54,7 @@ class MessageQueue {
struct Message {
- ObjectID instance_id;
- StringName target;
+ Callable callable;
int16_t type;
union {
int16_t notification;
@@ -68,7 +67,7 @@ class MessageQueue {
uint32_t buffer_max_used;
uint32_t buffer_size;
- void _call_function(Object *p_target, const StringName &p_func, const Variant *p_args, int p_argcount, bool p_show_error);
+ void _call_function(const Callable &p_callable, const Variant *p_args, int p_argcount, bool p_show_error);
static MessageQueue *singleton;
@@ -81,6 +80,7 @@ public:
Error push_call(ObjectID p_id, const StringName &p_method, VARIANT_ARG_LIST);
Error push_notification(ObjectID p_id, int p_notification);
Error push_set(ObjectID p_id, const StringName &p_prop, const Variant &p_value);
+ Error push_callable(const Callable &p_callable, const Variant **p_args, int p_argcount, bool p_show_error = false);
Error push_call(Object *p_object, const StringName &p_method, VARIANT_ARG_LIST);
Error push_notification(Object *p_object, int p_notification);
diff --git a/core/method_bind.h b/core/method_bind.h
index 1860d227f7..726ce512f8 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -31,19 +31,18 @@
#ifndef METHOD_BIND_H
#define METHOD_BIND_H
+#ifdef DEBUG_ENABLED
+#define DEBUG_METHODS_ENABLED
+#endif
+
#include "core/list.h"
#include "core/method_ptrcall.h"
#include "core/object.h"
+#include "core/type_info.h"
#include "core/variant.h"
#include <stdio.h>
-#ifdef DEBUG_ENABLED
-#define DEBUG_METHODS_ENABLED
-#endif
-
-#include "core/type_info.h"
-
enum MethodFlags {
METHOD_FLAG_NORMAL = 1,
@@ -155,7 +154,7 @@ struct VariantObjectClassChecker<Control *> {
Variant::Type argtype = get_argument_type(m_arg - 1); \
if (!Variant::can_convert_strict(p_args[m_arg - 1]->get_type(), argtype) || \
!VariantObjectClassChecker<P##m_arg>::check(*p_args[m_arg - 1])) { \
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; \
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; \
r_error.argument = m_arg - 1; \
r_error.expected = argtype; \
return Variant(); \
@@ -278,7 +277,7 @@ public:
_FORCE_INLINE_ int get_argument_count() const { return argument_count; };
- virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Variant::CallError &r_error) = 0;
+ virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) = 0;
#ifdef PTRCALL_ENABLED
virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) = 0;
@@ -300,7 +299,7 @@ public:
template <class T>
class MethodBindVarArg : public MethodBind {
public:
- typedef Variant (T::*NativeCall)(const Variant **, int, Variant::CallError &);
+ typedef Variant (T::*NativeCall)(const Variant **, int, Callable::CallError &);
protected:
NativeCall call_method;
@@ -338,7 +337,7 @@ public:
}
#endif
- virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Variant::CallError &r_error) {
+ virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
T *instance = static_cast<T *>(p_object);
return (instance->*call_method)(p_args, p_arg_count, r_error);
@@ -389,7 +388,7 @@ public:
};
template <class T>
-MethodBind *create_vararg_method_bind(Variant (T::*p_method)(const Variant **, int, Variant::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
+MethodBind *create_vararg_method_bind(Variant (T::*p_method)(const Variant **, int, Callable::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
MethodBindVarArg<T> *a = memnew((MethodBindVarArg<T>));
a->set_method(p_method);
diff --git a/core/method_ptrcall.h b/core/method_ptrcall.h
index 118970de80..3db186ca69 100644
--- a/core/method_ptrcall.h
+++ b/core/method_ptrcall.h
@@ -125,17 +125,22 @@ MAKE_PTRARG_BY_REFERENCE(AABB);
MAKE_PTRARG_BY_REFERENCE(Basis);
MAKE_PTRARG_BY_REFERENCE(Transform);
MAKE_PTRARG_BY_REFERENCE(Color);
+MAKE_PTRARG(StringName);
MAKE_PTRARG(NodePath);
MAKE_PTRARG(RID);
MAKE_PTRARG(Dictionary);
+MAKE_PTRARG(Callable);
+MAKE_PTRARG(Signal);
MAKE_PTRARG(Array);
-MAKE_PTRARG(PoolByteArray);
-MAKE_PTRARG(PoolIntArray);
-MAKE_PTRARG(PoolRealArray);
-MAKE_PTRARG(PoolStringArray);
-MAKE_PTRARG(PoolVector2Array);
-MAKE_PTRARG(PoolVector3Array);
-MAKE_PTRARG(PoolColorArray);
+MAKE_PTRARG(PackedByteArray);
+MAKE_PTRARG(PackedInt32Array);
+MAKE_PTRARG(PackedInt64Array);
+MAKE_PTRARG(PackedFloat32Array);
+MAKE_PTRARG(PackedFloat64Array);
+MAKE_PTRARG(PackedStringArray);
+MAKE_PTRARG(PackedVector2Array);
+MAKE_PTRARG(PackedVector3Array);
+MAKE_PTRARG(PackedColorArray);
MAKE_PTRARG_BY_REFERENCE(Variant);
//this is for Object
@@ -185,95 +190,96 @@ struct PtrToArg<ObjectID> {
//this is for the special cases used by Variant
-#define MAKE_VECARG(m_type) \
- template <> \
- struct PtrToArg<Vector<m_type> > { \
- _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
- const PoolVector<m_type> *dvs = reinterpret_cast<const PoolVector<m_type> *>(p_ptr); \
- Vector<m_type> ret; \
- int len = dvs->size(); \
- ret.resize(len); \
- { \
- PoolVector<m_type>::Read r = dvs->read(); \
- for (int i = 0; i < len; i++) { \
- ret.write[i] = r[i]; \
- } \
- } \
- return ret; \
- } \
- _FORCE_INLINE_ static void encode(Vector<m_type> p_vec, void *p_ptr) { \
- PoolVector<m_type> *dv = reinterpret_cast<PoolVector<m_type> *>(p_ptr); \
- int len = p_vec.size(); \
- dv->resize(len); \
- { \
- PoolVector<m_type>::Write w = dv->write(); \
- for (int i = 0; i < len; i++) { \
- w[i] = p_vec[i]; \
- } \
- } \
- } \
- }; \
- template <> \
- struct PtrToArg<const Vector<m_type> &> { \
- _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
- const PoolVector<m_type> *dvs = reinterpret_cast<const PoolVector<m_type> *>(p_ptr); \
- Vector<m_type> ret; \
- int len = dvs->size(); \
- ret.resize(len); \
- { \
- PoolVector<m_type>::Read r = dvs->read(); \
- for (int i = 0; i < len; i++) { \
- ret.write[i] = r[i]; \
- } \
- } \
- return ret; \
- } \
+#define MAKE_VECARG(m_type) \
+ template <> \
+ struct PtrToArg<Vector<m_type> > { \
+ _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
+ const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \
+ Vector<m_type> ret; \
+ int len = dvs->size(); \
+ ret.resize(len); \
+ { \
+ const m_type *r = dvs->ptr(); \
+ for (int i = 0; i < len; i++) { \
+ ret.write[i] = r[i]; \
+ } \
+ } \
+ return ret; \
+ } \
+ _FORCE_INLINE_ static void encode(Vector<m_type> p_vec, void *p_ptr) { \
+ Vector<m_type> *dv = reinterpret_cast<Vector<m_type> *>(p_ptr); \
+ int len = p_vec.size(); \
+ dv->resize(len); \
+ { \
+ m_type *w = dv->ptrw(); \
+ for (int i = 0; i < len; i++) { \
+ w[i] = p_vec[i]; \
+ } \
+ } \
+ } \
+ }; \
+ template <> \
+ struct PtrToArg<const Vector<m_type> &> { \
+ _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
+ const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \
+ Vector<m_type> ret; \
+ int len = dvs->size(); \
+ ret.resize(len); \
+ { \
+ const m_type *r = dvs->ptr(); \
+ for (int i = 0; i < len; i++) { \
+ ret.write[i] = r[i]; \
+ } \
+ } \
+ return ret; \
+ } \
}
-#define MAKE_VECARG_ALT(m_type, m_type_alt) \
- template <> \
- struct PtrToArg<Vector<m_type_alt> > { \
- _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \
- const PoolVector<m_type> *dvs = reinterpret_cast<const PoolVector<m_type> *>(p_ptr); \
- Vector<m_type_alt> ret; \
- int len = dvs->size(); \
- ret.resize(len); \
- { \
- PoolVector<m_type>::Read r = dvs->read(); \
- for (int i = 0; i < len; i++) { \
- ret.write[i] = r[i]; \
- } \
- } \
- return ret; \
- } \
- _FORCE_INLINE_ static void encode(Vector<m_type_alt> p_vec, void *p_ptr) { \
- PoolVector<m_type> *dv = reinterpret_cast<PoolVector<m_type> *>(p_ptr); \
- int len = p_vec.size(); \
- dv->resize(len); \
- { \
- PoolVector<m_type>::Write w = dv->write(); \
- for (int i = 0; i < len; i++) { \
- w[i] = p_vec[i]; \
- } \
- } \
- } \
- }; \
- template <> \
- struct PtrToArg<const Vector<m_type_alt> &> { \
- _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \
- const PoolVector<m_type> *dvs = reinterpret_cast<const PoolVector<m_type> *>(p_ptr); \
- Vector<m_type_alt> ret; \
- int len = dvs->size(); \
- ret.resize(len); \
- { \
- PoolVector<m_type>::Read r = dvs->read(); \
- for (int i = 0; i < len; i++) { \
- ret.write[i] = r[i]; \
- } \
- } \
- return ret; \
- } \
+#define MAKE_VECARG_ALT(m_type, m_type_alt) \
+ template <> \
+ struct PtrToArg<Vector<m_type_alt> > { \
+ _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \
+ const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \
+ Vector<m_type_alt> ret; \
+ int len = dvs->size(); \
+ ret.resize(len); \
+ { \
+ const m_type *r = dvs->ptr(); \
+ for (int i = 0; i < len; i++) { \
+ ret.write[i] = r[i]; \
+ } \
+ } \
+ return ret; \
+ } \
+ _FORCE_INLINE_ static void encode(Vector<m_type_alt> p_vec, void *p_ptr) { \
+ Vector<m_type> *dv = reinterpret_cast<Vector<m_type> *>(p_ptr); \
+ int len = p_vec.size(); \
+ dv->resize(len); \
+ { \
+ m_type *w = dv->ptrw(); \
+ for (int i = 0; i < len; i++) { \
+ w[i] = p_vec[i]; \
+ } \
+ } \
+ } \
+ }; \
+ template <> \
+ struct PtrToArg<const Vector<m_type_alt> &> { \
+ _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \
+ const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \
+ Vector<m_type_alt> ret; \
+ int len = dvs->size(); \
+ ret.resize(len); \
+ { \
+ const m_type *r = dvs->ptr(); \
+ for (int i = 0; i < len; i++) { \
+ ret.write[i] = r[i]; \
+ } \
+ } \
+ return ret; \
+ } \
}
+/*
MAKE_VECARG(String);
MAKE_VECARG(uint8_t);
MAKE_VECARG(int);
@@ -281,6 +287,7 @@ MAKE_VECARG(float);
MAKE_VECARG(Vector2);
MAKE_VECARG(Vector3);
MAKE_VECARG(Color);
+*/
MAKE_VECARG_ALT(String, StringName);
//for stuff that gets converted to Array vectors
@@ -324,74 +331,52 @@ MAKE_VECARR(Variant);
MAKE_VECARR(RID);
MAKE_VECARR(Plane);
-#define MAKE_DVECARR(m_type) \
- template <> \
- struct PtrToArg<PoolVector<m_type> > { \
- _FORCE_INLINE_ static PoolVector<m_type> convert(const void *p_ptr) { \
- const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
- PoolVector<m_type> ret; \
- int len = arr->size(); \
- ret.resize(len); \
- { \
- PoolVector<m_type>::Write w = ret.write(); \
- for (int i = 0; i < len; i++) { \
- w[i] = (*arr)[i]; \
- } \
- } \
- return ret; \
- } \
- _FORCE_INLINE_ static void encode(PoolVector<m_type> p_vec, void *p_ptr) { \
- Array *arr = reinterpret_cast<Array *>(p_ptr); \
- int len = p_vec.size(); \
- arr->resize(len); \
- { \
- PoolVector<m_type>::Read r = p_vec.read(); \
- for (int i = 0; i < len; i++) { \
- (*arr)[i] = r[i]; \
- } \
- } \
- } \
- }; \
- template <> \
- struct PtrToArg<const PoolVector<m_type> &> { \
- _FORCE_INLINE_ static PoolVector<m_type> convert(const void *p_ptr) { \
- const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
- PoolVector<m_type> ret; \
- int len = arr->size(); \
- ret.resize(len); \
- { \
- PoolVector<m_type>::Write w = ret.write(); \
- for (int i = 0; i < len; i++) { \
- w[i] = (*arr)[i]; \
- } \
- } \
- return ret; \
- } \
+#define MAKE_DVECARR(m_type) \
+ template <> \
+ struct PtrToArg<Vector<m_type> > { \
+ _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
+ const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
+ Vector<m_type> ret; \
+ int len = arr->size(); \
+ ret.resize(len); \
+ { \
+ m_type *w = ret.ptrw(); \
+ for (int i = 0; i < len; i++) { \
+ w[i] = (*arr)[i]; \
+ } \
+ } \
+ return ret; \
+ } \
+ _FORCE_INLINE_ static void encode(Vector<m_type> p_vec, void *p_ptr) { \
+ Array *arr = reinterpret_cast<Array *>(p_ptr); \
+ int len = p_vec.size(); \
+ arr->resize(len); \
+ { \
+ const m_type *r = p_vec.ptr(); \
+ for (int i = 0; i < len; i++) { \
+ (*arr)[i] = r[i]; \
+ } \
+ } \
+ } \
+ }; \
+ template <> \
+ struct PtrToArg<const Vector<m_type> &> { \
+ _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
+ const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
+ Vector<m_type> ret; \
+ int len = arr->size(); \
+ ret.resize(len); \
+ { \
+ m_type *w = ret.ptrw(); \
+ for (int i = 0; i < len; i++) { \
+ w[i] = (*arr)[i]; \
+ } \
+ } \
+ return ret; \
+ } \
}
-MAKE_DVECARR(Plane);
-//for special case StringName
-
-#define MAKE_STRINGCONV(m_type) \
- template <> \
- struct PtrToArg<m_type> { \
- _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
- m_type s = *reinterpret_cast<const String *>(p_ptr); \
- return s; \
- } \
- _FORCE_INLINE_ static void encode(m_type p_vec, void *p_ptr) { \
- String *arr = reinterpret_cast<String *>(p_ptr); \
- *arr = p_vec; \
- } \
- }; \
- \
- template <> \
- struct PtrToArg<const m_type &> { \
- _FORCE_INLINE_ static m_type convert(const void *p_ptr) { \
- m_type s = *reinterpret_cast<const String *>(p_ptr); \
- return s; \
- } \
- }
+// Special case for IP_Address.
#define MAKE_STRINGCONV_BY_REFERENCE(m_type) \
template <> \
@@ -414,19 +399,18 @@ MAKE_DVECARR(Plane);
} \
}
-MAKE_STRINGCONV(StringName);
MAKE_STRINGCONV_BY_REFERENCE(IP_Address);
template <>
-struct PtrToArg<PoolVector<Face3> > {
- _FORCE_INLINE_ static PoolVector<Face3> convert(const void *p_ptr) {
- const PoolVector<Vector3> *dvs = reinterpret_cast<const PoolVector<Vector3> *>(p_ptr);
- PoolVector<Face3> ret;
+struct PtrToArg<Vector<Face3> > {
+ _FORCE_INLINE_ static Vector<Face3> convert(const void *p_ptr) {
+ const Vector<Vector3> *dvs = reinterpret_cast<const Vector<Vector3> *>(p_ptr);
+ Vector<Face3> ret;
int len = dvs->size() / 3;
ret.resize(len);
{
- PoolVector<Vector3>::Read r = dvs->read();
- PoolVector<Face3>::Write w = ret.write();
+ const Vector3 *r = dvs->ptr();
+ Face3 *w = ret.ptrw();
for (int i = 0; i < len; i++) {
w[i].vertex[0] = r[i * 3 + 0];
w[i].vertex[1] = r[i * 3 + 1];
@@ -435,13 +419,13 @@ struct PtrToArg<PoolVector<Face3> > {
}
return ret;
}
- _FORCE_INLINE_ static void encode(PoolVector<Face3> p_vec, void *p_ptr) {
- PoolVector<Vector3> *arr = reinterpret_cast<PoolVector<Vector3> *>(p_ptr);
+ _FORCE_INLINE_ static void encode(Vector<Face3> p_vec, void *p_ptr) {
+ Vector<Vector3> *arr = reinterpret_cast<Vector<Vector3> *>(p_ptr);
int len = p_vec.size();
arr->resize(len * 3);
{
- PoolVector<Face3>::Read r = p_vec.read();
- PoolVector<Vector3>::Write w = arr->write();
+ const Face3 *r = p_vec.ptr();
+ Vector3 *w = arr->ptrw();
for (int i = 0; i < len; i++) {
w[i * 3 + 0] = r[i].vertex[0];
w[i * 3 + 1] = r[i].vertex[1];
@@ -451,15 +435,15 @@ struct PtrToArg<PoolVector<Face3> > {
}
};
template <>
-struct PtrToArg<const PoolVector<Face3> &> {
- _FORCE_INLINE_ static PoolVector<Face3> convert(const void *p_ptr) {
- const PoolVector<Vector3> *dvs = reinterpret_cast<const PoolVector<Vector3> *>(p_ptr);
- PoolVector<Face3> ret;
+struct PtrToArg<const Vector<Face3> &> {
+ _FORCE_INLINE_ static Vector<Face3> convert(const void *p_ptr) {
+ const Vector<Vector3> *dvs = reinterpret_cast<const Vector<Vector3> *>(p_ptr);
+ Vector<Face3> ret;
int len = dvs->size() / 3;
ret.resize(len);
{
- PoolVector<Vector3>::Read r = dvs->read();
- PoolVector<Face3>::Write w = ret.write();
+ const Vector3 *r = dvs->ptr();
+ Face3 *w = ret.ptrw();
for (int i = 0; i < len; i++) {
w[i].vertex[0] = r[i * 3 + 0];
w[i].vertex[1] = r[i * 3 + 1];
diff --git a/core/node_path.h b/core/node_path.h
index 5439658910..05b6d844ff 100644
--- a/core/node_path.h
+++ b/core/node_path.h
@@ -54,15 +54,6 @@ class NodePath {
void _update_hash_cache() const;
public:
- _FORCE_INLINE_ StringName get_sname() const {
-
- if (data && data->path.size() == 1 && data->subpath.empty()) {
- return data->path[0];
- } else {
- return operator String();
- }
- }
-
bool is_absolute() const;
int get_name_count() const;
StringName get_name(int p_idx) const;
diff --git a/core/object.cpp b/core/object.cpp
index 9a5cfe5c22..140ee811fe 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -335,10 +335,8 @@ MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const Pr
Object::Connection::operator Variant() const {
Dictionary d;
- d["source"] = source;
d["signal"] = signal;
- d["target"] = target;
- d["method"] = method;
+ d["callable"] = callable;
d["flags"] = flags;
d["binds"] = binds;
return d;
@@ -346,34 +344,19 @@ Object::Connection::operator Variant() const {
bool Object::Connection::operator<(const Connection &p_conn) const {
- if (source == p_conn.source) {
-
- if (signal == p_conn.signal) {
-
- if (target == p_conn.target) {
-
- return method < p_conn.method;
- } else {
-
- return target < p_conn.target;
- }
- } else
- return signal < p_conn.signal;
+ if (signal == p_conn.signal) {
+ return callable < p_conn.callable;
} else {
- return source < p_conn.source;
+ return signal < p_conn.signal;
}
}
Object::Connection::Connection(const Variant &p_variant) {
Dictionary d = p_variant;
- if (d.has("source"))
- source = d["source"];
if (d.has("signal"))
signal = d["signal"];
- if (d.has("target"))
- target = d["target"];
- if (d.has("method"))
- method = d["method"];
+ if (d.has("callable"))
+ callable = d["callable"];
if (d.has("flags"))
flags = d["flags"];
if (d.has("binds"))
@@ -655,18 +638,18 @@ void Object::get_method_list(List<MethodInfo> *p_list) const {
}
}
-Variant Object::_call_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant Object::_call_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (p_argcount < 1) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
return Variant();
}
- if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ if (p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::STRING;
+ r_error.expected = Variant::STRING_NAME;
return Variant();
}
@@ -675,22 +658,22 @@ Variant Object::_call_bind(const Variant **p_args, int p_argcount, Variant::Call
return call(method, &p_args[1], p_argcount - 1, r_error);
}
-Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (p_argcount < 1) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
return Variant();
}
- if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ if (p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::STRING;
+ r_error.expected = Variant::STRING_NAME;
return Variant();
}
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
StringName method = *p_args[0];
@@ -700,29 +683,29 @@ Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Vari
}
#ifdef DEBUG_ENABLED
-static void _test_call_error(const StringName &p_func, const Variant::CallError &error) {
+static void _test_call_error(const StringName &p_func, const Callable::CallError &error) {
switch (error.error) {
- case Variant::CallError::CALL_OK:
- case Variant::CallError::CALL_ERROR_INVALID_METHOD:
+ case Callable::CallError::CALL_OK:
+ case Callable::CallError::CALL_ERROR_INVALID_METHOD:
break;
- case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT: {
+ case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
- ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Invalid type for argument " + itos(error.argument) + ", expected " + Variant::get_type_name(error.expected) + ".");
+ ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Invalid type for argument " + itos(error.argument) + ", expected " + Variant::get_type_name(Variant::Type(error.expected)) + ".");
break;
}
- case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
+ case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Too many arguments, expected " + itos(error.argument) + ".");
break;
}
- case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
+ case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Too few arguments, expected " + itos(error.argument) + ".");
break;
}
- case Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL:
+ case Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL:
break;
}
}
@@ -749,7 +732,7 @@ void Object::call_multilevel(const StringName &p_method, const Variant **p_args,
//Variant ret;
OBJ_DEBUG_LOCK
- Variant::CallError error;
+ Callable::CallError error;
if (script_instance) {
script_instance->call_multilevel(p_method, p_args, p_argcount);
@@ -769,7 +752,7 @@ void Object::call_multilevel_reversed(const StringName &p_method, const Variant
MethodBind *method = ClassDB::get_method(get_class_name(), p_method);
- Variant::CallError error;
+ Callable::CallError error;
OBJ_DEBUG_LOCK
if (method) {
@@ -823,9 +806,9 @@ Variant Object::callv(const StringName &p_method, const Array &p_args) {
}
}
- Variant::CallError ce;
+ Callable::CallError ce;
Variant ret = call(p_method, argptrs, p_args.size(), ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
ERR_FAIL_V_MSG(Variant(), "Error calling method from 'callv': " + Variant::get_call_error_text(this, p_method, argptrs, p_args.size(), ce) + ".");
}
return ret;
@@ -842,7 +825,7 @@ Variant Object::call(const StringName &p_name, VARIANT_ARG_DECLARE) {
argc++;
}
- Variant::CallError error;
+ Callable::CallError error;
Variant ret = call(p_name, argptr, argc, error);
return ret;
@@ -859,38 +842,38 @@ void Object::call_multilevel(const StringName &p_name, VARIANT_ARG_DECLARE) {
argc++;
}
- //Variant::CallError error;
+ //Callable::CallError error;
call_multilevel(p_name, argptr, argc);
}
-Variant Object::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant Object::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
if (p_method == CoreStringNames::get_singleton()->_free) {
//free must be here, before anything, always ready
#ifdef DEBUG_ENABLED
if (p_argcount != 0) {
r_error.argument = 0;
- r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
return Variant();
}
if (Object::cast_to<Reference>(this)) {
r_error.argument = 0;
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
ERR_FAIL_V_MSG(Variant(), "Can't 'free' a reference.");
}
if (_lock_index.get() > 1) {
r_error.argument = 0;
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
ERR_FAIL_V_MSG(Variant(), "Object is locked and can't be freed.");
}
#endif
//must be here, must be before everything,
memdelete(this);
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
return Variant();
}
@@ -901,15 +884,15 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a
//force jumptable
switch (r_error.error) {
- case Variant::CallError::CALL_OK:
+ case Callable::CallError::CALL_OK:
return ret;
- case Variant::CallError::CALL_ERROR_INVALID_METHOD:
+ case Callable::CallError::CALL_ERROR_INVALID_METHOD:
break;
- case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT:
- case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS:
- case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS:
+ case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT:
+ case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS:
+ case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS:
return ret;
- case Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL: {
+ case Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL: {
}
}
}
@@ -917,10 +900,9 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a
MethodBind *method = ClassDB::get_method(get_class_name(), p_method);
if (method) {
-
ret = method->call(this, p_args, p_argcount, r_error);
} else {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
}
return ret;
@@ -1075,9 +1057,9 @@ Array Object::_get_method_list_bind() const {
return ret;
}
-PoolVector<String> Object::_get_meta_list_bind() const {
+Vector<String> Object::_get_meta_list_bind() const {
- PoolVector<String> _metaret;
+ Vector<String> _metaret;
List<Variant> keys;
metadata.get_key_list(&keys);
@@ -1103,7 +1085,7 @@ void Object::add_user_signal(const MethodInfo &p_signal) {
ERR_FAIL_COND_MSG(p_signal.name == "", "Signal name cannot be empty.");
ERR_FAIL_COND_MSG(ClassDB::has_signal(get_class_name(), p_signal.name), "User signal's name conflicts with a built-in signal of '" + get_class_name() + "'.");
ERR_FAIL_COND_MSG(signal_map.has(p_signal.name), "Trying to add already existing signal '" + p_signal.name + "'.");
- Signal s;
+ SignalData s;
s.user = p_signal;
signal_map[p_signal.name] = s;
}
@@ -1118,23 +1100,22 @@ bool Object::_has_user_signal(const StringName &p_name) const {
struct _ObjectSignalDisconnectData {
StringName signal;
- Object *target;
- StringName method;
+ Callable callable;
};
-Variant Object::_emit_signal(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant Object::_emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
ERR_FAIL_COND_V(p_argcount < 1, Variant());
- if (p_args[0]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ if (p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
- r_error.expected = Variant::STRING;
- ERR_FAIL_COND_V(p_args[0]->get_type() != Variant::STRING, Variant());
+ r_error.expected = Variant::STRING_NAME;
+ ERR_FAIL_COND_V(p_args[0]->get_type() != Variant::STRING_NAME && p_args[0]->get_type() != Variant::STRING, Variant());
}
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
StringName signal = *p_args[0];
@@ -1155,7 +1136,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
if (_block_signals)
return ERR_CANT_ACQUIRE_RESOURCE; //no emit, signals blocked
- Signal *s = signal_map.getptr(p_name);
+ SignalData *s = signal_map.getptr(p_name);
if (!s) {
#ifdef DEBUG_ENABLED
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_name);
@@ -1171,7 +1152,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
//copy on write will ensure that disconnecting the signal or even deleting the object will not affect the signal calling.
//this happens automatically and will not change the performance of calling.
//awesome, isn't it?
- VMap<Signal::Target, Signal::Slot> slot_map = s->slot_map;
+ VMap<Callable, SignalData::Slot> slot_map = s->slot_map;
int ssize = slot_map.size();
@@ -1185,7 +1166,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
const Connection &c = slot_map.getv(i).conn;
- Object *target = ObjectDB::get_instance(slot_map.getk(i)._id);
+ Object *target = c.callable.get_object();
if (!target) {
// Target might have been deleted during signal callback, this is expected and OK.
continue;
@@ -1210,22 +1191,23 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
}
if (c.flags & CONNECT_DEFERRED) {
- MessageQueue::get_singleton()->push_call(target->get_instance_id(), c.method, args, argc, true);
+ MessageQueue::get_singleton()->push_callable(c.callable, args, argc, true);
} else {
- Variant::CallError ce;
+ Callable::CallError ce;
_emitting = true;
- target->call(c.method, args, argc, ce);
+ Variant ret;
+ c.callable.call(args, argc, ret, ce);
_emitting = false;
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
#ifdef DEBUG_ENABLED
if (c.flags & CONNECT_PERSIST && Engine::get_singleton()->is_editor_hint() && (script.is_null() || !Ref<Script>(script)->is_tool()))
continue;
#endif
- if (ce.error == Variant::CallError::CALL_ERROR_INVALID_METHOD && !ClassDB::class_exists(target->get_class_name())) {
+ if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD && !ClassDB::class_exists(target->get_class_name())) {
//most likely object is not initialized yet, do not throw error.
} else {
- ERR_PRINT("Error calling method from signal '" + String(p_name) + "': " + Variant::get_call_error_text(target, c.method, args, argc, ce) + ".");
+ ERR_PRINT("Error calling from signal '" + String(p_name) + "' to callable: " + Variant::get_callable_error_text(c.callable, args, argc, ce) + ".");
err = ERR_METHOD_NOT_FOUND;
}
}
@@ -1242,8 +1224,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
_ObjectSignalDisconnectData dd;
dd.signal = p_name;
- dd.target = target;
- dd.method = c.method;
+ dd.callable = c.callable;
disconnect_data.push_back(dd);
}
}
@@ -1251,7 +1232,8 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
while (!disconnect_data.empty()) {
const _ObjectSignalDisconnectData &dd = disconnect_data.front()->get();
- disconnect(dd.signal, dd.target, dd.method);
+
+ _disconnect(dd.signal, dd.callable);
disconnect_data.pop_front();
}
@@ -1323,15 +1305,8 @@ Array Object::_get_signal_connection_list(const String &p_signal) const {
for (List<Connection>::Element *E = conns.front(); E; E = E->next()) {
Connection &c = E->get();
- if (c.signal == p_signal) {
- Dictionary rc;
- rc["signal"] = c.signal;
- rc["method"] = c.method;
- rc["source"] = c.source;
- rc["target"] = c.target;
- rc["binds"] = c.binds;
- rc["flags"] = c.flags;
- ret.push_back(rc);
+ if (c.signal.get_name() == p_signal) {
+ ret.push_back(c);
}
}
@@ -1343,11 +1318,7 @@ Array Object::_get_incoming_connections() const {
Array ret;
int connections_amount = connections.size();
for (int idx_conn = 0; idx_conn < connections_amount; idx_conn++) {
- Dictionary conn_data;
- conn_data["source"] = connections[idx_conn].source;
- conn_data["signal_name"] = connections[idx_conn].signal;
- conn_data["method_name"] = connections[idx_conn].method;
- ret.push_back(conn_data);
+ ret.push_back(connections[idx_conn]);
}
return ret;
@@ -1381,7 +1352,7 @@ void Object::get_all_signal_connections(List<Connection> *p_connections) const {
while ((S = signal_map.next(S))) {
- const Signal *s = &signal_map[*S];
+ const SignalData *s = &signal_map[*S];
for (int i = 0; i < s->slot_map.size(); i++) {
@@ -1392,7 +1363,7 @@ void Object::get_all_signal_connections(List<Connection> *p_connections) const {
void Object::get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const {
- const Signal *s = signal_map.getptr(p_signal);
+ const SignalData *s = signal_map.getptr(p_signal);
if (!s)
return; //nothing
@@ -1407,7 +1378,7 @@ int Object::get_persistent_signal_connection_count() const {
while ((S = signal_map.next(S))) {
- const Signal *s = &signal_map[*S];
+ const SignalData *s = &signal_map[*S];
for (int i = 0; i < s->slot_map.size(); i++) {
if (s->slot_map.getv(i).conn.flags & CONNECT_PERSIST) {
@@ -1426,11 +1397,18 @@ void Object::get_signals_connected_to_this(List<Connection> *p_connections) cons
}
}
-Error Object::connect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds, uint32_t p_flags) {
+Error Object::connect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds, uint32_t p_flags) {
+
+ return connect(p_signal, Callable(p_to_object, p_to_method), p_binds, p_flags);
+}
+Error Object::connect(const StringName &p_signal, const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) {
+
+ ERR_FAIL_COND_V(p_callable.is_null(), ERR_INVALID_PARAMETER);
- ERR_FAIL_NULL_V(p_to_object, ERR_INVALID_PARAMETER);
+ Object *target_object = p_callable.get_object();
+ ERR_FAIL_COND_V(!target_object, ERR_INVALID_PARAMETER);
- Signal *s = signal_map.getptr(p_signal);
+ SignalData *s = signal_map.getptr(p_signal);
if (!s) {
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal);
//check in script
@@ -1449,33 +1427,32 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str
#endif
}
- ERR_FAIL_COND_V_MSG(!signal_is_valid, ERR_INVALID_PARAMETER, "In Object of type '" + String(get_class()) + "': Attempt to connect nonexistent signal '" + p_signal + "' to method '" + p_to_object->get_class() + "." + p_to_method + "'.");
+ ERR_FAIL_COND_V_MSG(!signal_is_valid, ERR_INVALID_PARAMETER, "In Object of type '" + String(get_class()) + "': Attempt to connect nonexistent signal '" + p_signal + "' to callable '" + p_callable + "'.");
- signal_map[p_signal] = Signal();
+ signal_map[p_signal] = SignalData();
s = &signal_map[p_signal];
}
- Signal::Target target(p_to_object->get_instance_id(), p_to_method);
+ Callable target = p_callable;
+
if (s->slot_map.has(target)) {
if (p_flags & CONNECT_REFERENCE_COUNTED) {
s->slot_map[target].reference_count++;
return OK;
} else {
- ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Signal '" + p_signal + "' is already connected to given method '" + p_to_method + "' in that object.");
+ ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Signal '" + p_signal + "' is already connected to given callable '" + p_callable + "' in that object.");
}
}
- Signal::Slot slot;
+ SignalData::Slot slot;
Connection conn;
- conn.source = this;
- conn.target = p_to_object;
- conn.method = p_to_method;
- conn.signal = p_signal;
+ conn.callable = target;
+ conn.signal = ::Signal(this, p_signal);
conn.flags = p_flags;
conn.binds = p_binds;
slot.conn = conn;
- slot.cE = p_to_object->connections.push_back(conn);
+ slot.cE = target_object->connections.push_back(conn);
if (p_flags & CONNECT_REFERENCE_COUNTED) {
slot.reference_count = 1;
}
@@ -1485,10 +1462,15 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str
return OK;
}
-bool Object::is_connected(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const {
+bool Object::is_connected_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const {
+
+ return is_connected(p_signal, Callable(p_to_object, p_to_method));
+}
- ERR_FAIL_NULL_V(p_to_object, false);
- const Signal *s = signal_map.getptr(p_signal);
+bool Object::is_connected(const StringName &p_signal, const Callable &p_callable) const {
+
+ ERR_FAIL_COND_V(p_callable.is_null(), false);
+ const SignalData *s = signal_map.getptr(p_signal);
if (!s) {
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal);
if (signal_is_valid)
@@ -1500,28 +1482,35 @@ bool Object::is_connected(const StringName &p_signal, Object *p_to_object, const
ERR_FAIL_V_MSG(false, "Nonexistent signal: " + p_signal + ".");
}
- Signal::Target target(p_to_object->get_instance_id(), p_to_method);
+ Callable target = p_callable;
return s->slot_map.has(target);
//const Map<Signal::Target,Signal::Slot>::Element *E = s->slot_map.find(target);
//return (E!=NULL);
}
-void Object::disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) {
+void Object::disconnect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) {
- _disconnect(p_signal, p_to_object, p_to_method);
+ _disconnect(p_signal, Callable(p_to_object, p_to_method));
}
-void Object::_disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, bool p_force) {
- ERR_FAIL_NULL(p_to_object);
- Signal *s = signal_map.getptr(p_signal);
- ERR_FAIL_COND_MSG(!s, vformat("Nonexistent signal '%s' in %s.", p_signal, to_string()));
+void Object::disconnect(const StringName &p_signal, const Callable &p_callable) {
+ _disconnect(p_signal, p_callable);
+}
+
+void Object::_disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force) {
+
+ ERR_FAIL_COND(p_callable.is_null());
- Signal::Target target(p_to_object->get_instance_id(), p_to_method);
+ Object *target_object = p_callable.get_object();
+ ERR_FAIL_COND(!target_object);
+
+ SignalData *s = signal_map.getptr(p_signal);
+ ERR_FAIL_COND_MSG(!s, vformat("Nonexistent signal '%s' in %s.", p_signal, to_string()));
- ERR_FAIL_COND_MSG(!s->slot_map.has(target), "Disconnecting nonexistent signal '" + p_signal + "', slot: " + itos(target._id) + ":" + target.method + ".");
+ ERR_FAIL_COND_MSG(!s->slot_map.has(p_callable), "Disconnecting nonexistent signal '" + p_signal + "', callable: " + p_callable + ".");
- Signal::Slot *slot = &s->slot_map[target];
+ SignalData::Slot *slot = &s->slot_map[p_callable];
if (!p_force) {
slot->reference_count--; // by default is zero, if it was not referenced it will go below it
@@ -1530,8 +1519,8 @@ void Object::_disconnect(const StringName &p_signal, Object *p_to_object, const
}
}
- p_to_object->connections.erase(slot->cE);
- s->slot_map.erase(target);
+ target_object->connections.erase(slot->cE);
+ s->slot_map.erase(p_callable);
if (s->slot_map.empty() && ClassDB::has_signal(get_class_name(), p_signal)) {
//not user signal, delete
@@ -1680,7 +1669,7 @@ void Object::_bind_methods() {
{
MethodInfo mi;
mi.name = "emit_signal";
- mi.arguments.push_back(PropertyInfo(Variant::STRING, "signal"));
+ mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "signal"));
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "emit_signal", &Object::_emit_signal, mi, varray(), false);
}
@@ -1688,7 +1677,7 @@ void Object::_bind_methods() {
{
MethodInfo mi;
mi.name = "call";
- mi.arguments.push_back(PropertyInfo(Variant::STRING, "method"));
+ mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method"));
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call", &Object::_call_bind, mi);
}
@@ -1696,7 +1685,7 @@ void Object::_bind_methods() {
{
MethodInfo mi;
mi.name = "call_deferred";
- mi.arguments.push_back(PropertyInfo(Variant::STRING, "method"));
+ mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method"));
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call_deferred", &Object::_call_deferred_bind, mi, varray(), false);
}
@@ -1711,9 +1700,9 @@ void Object::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_signal_connection_list", "signal"), &Object::_get_signal_connection_list);
ClassDB::bind_method(D_METHOD("get_incoming_connections"), &Object::_get_incoming_connections);
- ClassDB::bind_method(D_METHOD("connect", "signal", "target", "method", "binds", "flags"), &Object::connect, DEFVAL(Array()), DEFVAL(0));
- ClassDB::bind_method(D_METHOD("disconnect", "signal", "target", "method"), &Object::disconnect);
- ClassDB::bind_method(D_METHOD("is_connected", "signal", "target", "method"), &Object::is_connected);
+ ClassDB::bind_method(D_METHOD("connect", "signal", "callable", "binds", "flags"), &Object::connect, DEFVAL(Array()), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("disconnect", "signal", "callable"), &Object::disconnect);
+ ClassDB::bind_method(D_METHOD("is_connected", "signal", "callable"), &Object::is_connected);
ClassDB::bind_method(D_METHOD("set_block_signals", "enable"), &Object::set_block_signals);
ClassDB::bind_method(D_METHOD("is_blocking_signals"), &Object::is_blocking_signals);
@@ -1730,9 +1719,9 @@ void Object::_bind_methods() {
ADD_SIGNAL(MethodInfo("script_changed"));
BIND_VMETHOD(MethodInfo("_notification", PropertyInfo(Variant::INT, "what")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::NIL, "value")));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value")));
#ifdef TOOLS_ENABLED
- MethodInfo miget("_get", PropertyInfo(Variant::STRING, "property"));
+ MethodInfo miget("_get", PropertyInfo(Variant::STRING_NAME, "property"));
miget.return_val.name = "Variant";
miget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
BIND_VMETHOD(miget);
@@ -1830,7 +1819,7 @@ Variant::Type Object::get_static_property_type_indexed(const Vector<StringName>
return Variant::NIL;
}
- Variant::CallError ce;
+ Callable::CallError ce;
Variant check = Variant::construct(t, NULL, 0, ce);
for (int i = 1; i < p_path.size(); i++) {
@@ -1957,15 +1946,15 @@ Object::~Object() {
while ((S = signal_map.next(NULL))) {
- Signal *s = &signal_map[*S];
+ SignalData *s = &signal_map[*S];
//brute force disconnect for performance
int slot_count = s->slot_map.size();
- const VMap<Signal::Target, Signal::Slot>::Pair *slot_list = s->slot_map.get_array();
+ const VMap<Callable, SignalData::Slot>::Pair *slot_list = s->slot_map.get_array();
for (int i = 0; i < slot_count; i++) {
- slot_list[i].value.conn.target->connections.erase(slot_list[i].value.cE);
+ slot_list[i].value.conn.callable.get_object()->connections.erase(slot_list[i].value.cE);
}
signal_map.erase(*S);
@@ -1975,7 +1964,7 @@ Object::~Object() {
while (connections.size()) {
Connection c = connections.front()->get();
- c.source->_disconnect(c.signal, c.target, c.method, true);
+ c.signal.get_object()->_disconnect(c.signal.get_name(), c.callable, true);
}
ObjectDB::remove_instance(this);
diff --git a/core/object.h b/core/object.h
index 6a229afaea..59d3f06cfe 100644
--- a/core/object.h
+++ b/core/object.h
@@ -126,6 +126,7 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT = 1 << 23,
PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT = 1 << 24,
PROPERTY_USAGE_KEYING_INCREMENTS = 1 << 25, // Used in inspector to increment property when keyed in animation player
+ PROPERTY_USAGE_DEFERRED_SET_RESOURCE = 1 << 26, // when loading, the resource for this property can be set at the end of loading
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,
@@ -413,18 +414,15 @@ public:
struct Connection {
- Object *source;
- StringName signal;
- Object *target;
- StringName method;
+ ::Signal signal;
+ Callable callable;
+
uint32_t flags;
Vector<Variant> binds;
bool operator<(const Connection &p_conn) const;
operator Variant() const;
Connection() {
- source = NULL;
- target = NULL;
flags = 0;
}
Connection(const Variant &p_variant);
@@ -441,21 +439,7 @@ private:
friend bool predelete_handler(Object *);
friend void postinitialize_handler(Object *);
- struct Signal {
-
- struct Target {
-
- ObjectID _id;
- StringName method;
-
- _FORCE_INLINE_ bool operator<(const Target &p_target) const { return (_id == p_target._id) ? (method < p_target.method) : (_id < p_target._id); }
-
- Target(const ObjectID &p_id, const StringName &p_method) :
- _id(p_id),
- method(p_method) {
- }
- Target() { _id = ObjectID(); }
- };
+ struct SignalData {
struct Slot {
@@ -466,11 +450,11 @@ private:
};
MethodInfo user;
- VMap<Target, Slot> slot_map;
- Signal() {}
+ VMap<Callable, Slot> slot_map;
+ SignalData() {}
};
- HashMap<StringName, Signal> signal_map;
+ HashMap<StringName, SignalData> signal_map;
List<Connection> connections;
#ifdef DEBUG_ENABLED
SafeRefCount _lock_index;
@@ -496,7 +480,7 @@ private:
void _add_user_signal(const String &p_name, const Array &p_args = Array());
bool _has_user_signal(const StringName &p_name) const;
- Variant _emit_signal(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ Variant _emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
Array _get_signal_list() const;
Array _get_signal_connection_list(const String &p_signal) const;
Array _get_incoming_connections() const;
@@ -554,8 +538,8 @@ protected:
//Variant _call_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant());
//void _call_deferred_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant());
- Variant _call_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
- Variant _call_deferred_bind(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ Variant _call_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
+ Variant _call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
virtual const StringName *_get_class_namev() const {
if (!_class_name)
@@ -563,7 +547,7 @@ protected:
return &_class_name;
}
- PoolVector<String> _get_meta_list_bind() const;
+ Vector<String> _get_meta_list_bind() const;
Array _get_property_list_bind() const;
Array _get_method_list_bind() const;
@@ -572,7 +556,7 @@ protected:
friend class ClassDB;
virtual void _validate_property(PropertyInfo &property) const;
- void _disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, bool p_force = false);
+ void _disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force = false);
public: //should be protected, but bug in clang++
static void initialize_class();
@@ -670,7 +654,7 @@ public:
bool has_method(const StringName &p_method) const;
void get_method_list(List<MethodInfo> *p_list) const;
Variant callv(const StringName &p_method, const Array &p_args);
- virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount);
Variant call(const StringName &p_name, VARIANT_ARG_LIST); // C++ helper
@@ -716,9 +700,13 @@ public:
int get_persistent_signal_connection_count() const;
void get_signals_connected_to_this(List<Connection> *p_connections) const;
- Error connect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds = Vector<Variant>(), uint32_t p_flags = 0);
- void disconnect(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method);
- bool is_connected(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const;
+ Error connect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds = Vector<Variant>(), uint32_t p_flags = 0);
+ void disconnect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method);
+ bool is_connected_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const;
+
+ Error connect(const StringName &p_signal, const Callable &p_callable, const Vector<Variant> &p_binds = Vector<Variant>(), uint32_t p_flags = 0);
+ void disconnect(const StringName &p_signal, const Callable &p_callable);
+ bool is_connected(const StringName &p_signal, const Callable &p_callable) const;
void call_deferred(const StringName &p_method, VARIANT_ARG_LIST);
void set_deferred(const StringName &p_property, const Variant &p_value);
diff --git a/core/object_id.h b/core/object_id.h
index 6ab1a3031a..63b0c27af8 100644
--- a/core/object_id.h
+++ b/core/object_id.h
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* object_id.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 OBJECT_ID_H
#define OBJECT_ID_H
diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp
index f65fc00077..642c86be2f 100644
--- a/core/os/dir_access.cpp
+++ b/core/os/dir_access.cpp
@@ -66,6 +66,11 @@ int DirAccess::get_current_drive() {
return 0;
}
+bool DirAccess::drives_are_shortcuts() {
+
+ return false;
+}
+
static Error _erase_recursive(DirAccess *da) {
List<String> dirs;
diff --git a/core/os/dir_access.h b/core/os/dir_access.h
index 55a6d53f72..aac6c67f0a 100644
--- a/core/os/dir_access.h
+++ b/core/os/dir_access.h
@@ -76,9 +76,10 @@ public:
virtual int get_drive_count() = 0;
virtual String get_drive(int p_drive) = 0;
virtual int get_current_drive();
+ virtual bool drives_are_shortcuts();
virtual Error change_dir(String p_dir) = 0; ///< can be relative or absolute, return false on success
- virtual String get_current_dir() = 0; ///< return current dir location
+ virtual String get_current_dir(bool p_include_drive = true) = 0; ///< return current dir location
virtual Error make_dir(String p_dir) = 0;
virtual Error make_dir_recursive(String p_dir);
virtual Error erase_contents_recursive(); //super dangerous, use with care!
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 2917351a2f..30cfaa7617 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -408,17 +408,17 @@ int FileAccess::get_buffer(uint8_t *p_dst, int p_length) const {
}
String FileAccess::get_as_utf8_string() const {
- PoolVector<uint8_t> sourcef;
+ Vector<uint8_t> sourcef;
int len = get_len();
sourcef.resize(len + 1);
- PoolVector<uint8_t>::Write w = sourcef.write();
- int r = get_buffer(w.ptr(), len);
+ uint8_t *w = sourcef.ptrw();
+ int r = get_buffer(w, len);
ERR_FAIL_COND_V(r != len, String());
w[len] = 0;
String s;
- if (s.parse_utf8((const char *)w.ptr())) {
+ if (s.parse_utf8((const char *)w)) {
return String();
}
return s;
diff --git a/core/os/input.cpp b/core/os/input.cpp
index 6f0392fec9..1768b851df 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -57,7 +57,7 @@ Input::MouseMode Input::get_mouse_mode() const {
void Input::_bind_methods() {
- ClassDB::bind_method(D_METHOD("is_key_pressed", "scancode"), &Input::is_key_pressed);
+ ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &Input::is_key_pressed);
ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &Input::is_mouse_button_pressed);
ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &Input::is_joy_button_pressed);
ClassDB::bind_method(D_METHOD("is_action_pressed", "action"), &Input::is_action_pressed);
diff --git a/core/os/input.h b/core/os/input.h
index 8df3b1c5a9..55e0511080 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -79,7 +79,7 @@ public:
static Input *get_singleton();
- virtual bool is_key_pressed(int p_scancode) const = 0;
+ virtual bool is_key_pressed(int p_keycode) const = 0;
virtual bool is_mouse_button_pressed(int p_button) const = 0;
virtual bool is_joy_button_pressed(int p_device, int p_button) const = 0;
virtual bool is_action_pressed(const StringName &p_action) const = 0;
diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp
index 2e863c9c76..204a36bf56 100644
--- a/core/os/input_event.cpp
+++ b/core/os/input_event.cpp
@@ -237,19 +237,31 @@ bool InputEventKey::is_pressed() const {
return pressed;
}
-void InputEventKey::set_scancode(uint32_t p_scancode) {
+void InputEventKey::set_keycode(uint32_t p_keycode) {
- scancode = p_scancode;
+ keycode = p_keycode;
}
-uint32_t InputEventKey::get_scancode() const {
- return scancode;
+uint32_t InputEventKey::get_keycode() const {
+
+ return keycode;
+}
+
+void InputEventKey::set_physical_keycode(uint32_t p_keycode) {
+
+ physical_keycode = p_keycode;
+}
+
+uint32_t InputEventKey::get_physical_keycode() const {
+
+ return physical_keycode;
}
void InputEventKey::set_unicode(uint32_t p_unicode) {
unicode = p_unicode;
}
+
uint32_t InputEventKey::get_unicode() const {
return unicode;
@@ -259,14 +271,30 @@ void InputEventKey::set_echo(bool p_enable) {
echo = p_enable;
}
+
bool InputEventKey::is_echo() const {
return echo;
}
-uint32_t InputEventKey::get_scancode_with_modifiers() const {
+uint32_t InputEventKey::get_keycode_with_modifiers() const {
- uint32_t sc = scancode;
+ uint32_t sc = keycode;
+ if (get_control())
+ sc |= KEY_MASK_CTRL;
+ if (get_alt())
+ sc |= KEY_MASK_ALT;
+ if (get_shift())
+ sc |= KEY_MASK_SHIFT;
+ if (get_metakey())
+ sc |= KEY_MASK_META;
+
+ return sc;
+}
+
+uint32_t InputEventKey::get_physical_keycode_with_modifiers() const {
+
+ uint32_t sc = physical_keycode;
if (get_control())
sc |= KEY_MASK_CTRL;
if (get_alt())
@@ -281,7 +309,7 @@ uint32_t InputEventKey::get_scancode_with_modifiers() const {
String InputEventKey::as_text() const {
- String kc = keycode_get_string(scancode);
+ String kc = keycode_get_string(keycode);
if (kc == String())
return kc;
@@ -306,10 +334,18 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed
if (key.is_null())
return false;
- uint32_t code = get_scancode_with_modifiers();
- uint32_t event_code = key->get_scancode_with_modifiers();
+ bool match = false;
+ if (get_keycode() == 0) {
+ uint32_t code = get_physical_keycode_with_modifiers();
+ uint32_t event_code = key->get_physical_keycode_with_modifiers();
- bool match = get_scancode() == key->get_scancode() && (!key->is_pressed() || (code & event_code) == code);
+ match = get_physical_keycode() == key->get_physical_keycode() && (!key->is_pressed() || (code & event_code) == code);
+ } else {
+ uint32_t code = get_keycode_with_modifiers();
+ uint32_t event_code = key->get_keycode_with_modifiers();
+
+ match = get_keycode() == key->get_keycode() && (!key->is_pressed() || (code & event_code) == code);
+ }
if (match) {
if (p_pressed != NULL)
*p_pressed = key->is_pressed();
@@ -325,8 +361,8 @@ bool InputEventKey::shortcut_match(const Ref<InputEvent> &p_event) const {
if (key.is_null())
return false;
- uint32_t code = get_scancode_with_modifiers();
- uint32_t event_code = key->get_scancode_with_modifiers();
+ uint32_t code = get_keycode_with_modifiers();
+ uint32_t event_code = key->get_keycode_with_modifiers();
return code == event_code;
}
@@ -335,26 +371,32 @@ void InputEventKey::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventKey::set_pressed);
- ClassDB::bind_method(D_METHOD("set_scancode", "scancode"), &InputEventKey::set_scancode);
- ClassDB::bind_method(D_METHOD("get_scancode"), &InputEventKey::get_scancode);
+ ClassDB::bind_method(D_METHOD("set_keycode", "keycode"), &InputEventKey::set_keycode);
+ ClassDB::bind_method(D_METHOD("get_keycode"), &InputEventKey::get_keycode);
+
+ ClassDB::bind_method(D_METHOD("set_physical_keycode", "physical_keycode"), &InputEventKey::set_physical_keycode);
+ ClassDB::bind_method(D_METHOD("get_physical_keycode"), &InputEventKey::get_physical_keycode);
ClassDB::bind_method(D_METHOD("set_unicode", "unicode"), &InputEventKey::set_unicode);
ClassDB::bind_method(D_METHOD("get_unicode"), &InputEventKey::get_unicode);
ClassDB::bind_method(D_METHOD("set_echo", "echo"), &InputEventKey::set_echo);
- ClassDB::bind_method(D_METHOD("get_scancode_with_modifiers"), &InputEventKey::get_scancode_with_modifiers);
+ ClassDB::bind_method(D_METHOD("get_keycode_with_modifiers"), &InputEventKey::get_keycode_with_modifiers);
+ ClassDB::bind_method(D_METHOD("get_physical_keycode_with_modifiers"), &InputEventKey::get_physical_keycode_with_modifiers);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "scancode"), "set_scancode", "get_scancode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "keycode"), "set_keycode", "get_keycode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "physical_keycode"), "set_physical_keycode", "get_physical_keycode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "unicode"), "set_unicode", "get_unicode");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "echo"), "set_echo", "is_echo");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "echo"), "set_echo", "is_echo");
}
InputEventKey::InputEventKey() {
pressed = false;
- scancode = 0;
+ keycode = 0;
+ physical_keycode = 0;
unicode = 0; ///unicode
echo = false;
}
@@ -541,7 +583,7 @@ void InputEventMouseButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_doubleclick", "doubleclick"), &InputEventMouseButton::set_doubleclick);
ClassDB::bind_method(D_METHOD("is_doubleclick"), &InputEventMouseButton::is_doubleclick);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "factor"), "set_factor", "get_factor");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "factor"), "set_factor", "get_factor");
ADD_PROPERTY(PropertyInfo(Variant::INT, "button_index"), "set_button_index", "get_button_index");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "doubleclick"), "set_doubleclick", "is_doubleclick");
@@ -702,7 +744,7 @@ void InputEventMouseMotion::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_speed"), &InputEventMouseMotion::get_speed);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "pressure"), "set_pressure", "get_pressure");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure"), "set_pressure", "get_pressure");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed");
}
@@ -780,7 +822,7 @@ void InputEventJoypadMotion::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_axis_value"), &InputEventJoypadMotion::get_axis_value);
ADD_PROPERTY(PropertyInfo(Variant::INT, "axis"), "set_axis", "get_axis");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "axis_value"), "set_axis_value", "get_axis_value");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "axis_value"), "set_axis_value", "get_axis_value");
}
InputEventJoypadMotion::InputEventJoypadMotion() {
@@ -861,7 +903,7 @@ void InputEventJoypadButton::_bind_methods() {
// ClassDB::bind_method(D_METHOD("is_pressed"), &InputEventJoypadButton::is_pressed);
ADD_PROPERTY(PropertyInfo(Variant::INT, "button_index"), "set_button_index", "get_button_index");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "pressure"), "set_pressure", "get_pressure");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure"), "set_pressure", "get_pressure");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
}
@@ -1098,9 +1140,9 @@ void InputEventAction::_bind_methods() {
// ClassDB::bind_method(D_METHOD("is_action", "name"), &InputEventAction::is_action);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "action"), "set_action", "get_action");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "action"), "set_action", "get_action");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_strength", "get_strength");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_strength", "get_strength");
}
InputEventAction::InputEventAction() {
@@ -1162,7 +1204,7 @@ void InputEventMagnifyGesture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_factor", "factor"), &InputEventMagnifyGesture::set_factor);
ClassDB::bind_method(D_METHOD("get_factor"), &InputEventMagnifyGesture::get_factor);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "factor"), "set_factor", "get_factor");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "factor"), "set_factor", "get_factor");
}
InputEventMagnifyGesture::InputEventMagnifyGesture() {
diff --git a/core/os/input_event.h b/core/os/input_event.h
index c6b04bcfa5..c105fcd1c1 100644
--- a/core/os/input_event.h
+++ b/core/os/input_event.h
@@ -256,7 +256,8 @@ class InputEventKey : public InputEventWithModifiers {
bool pressed; /// otherwise release
- uint32_t scancode; ///< check keyboard.h , KeyCode enum, without modifier masks
+ uint32_t keycode; ///< check keyboard.h , KeyCode enum, without modifier masks
+ uint32_t physical_keycode;
uint32_t unicode; ///unicode
bool echo; /// true if this is an echo key
@@ -268,8 +269,11 @@ public:
void set_pressed(bool p_pressed);
virtual bool is_pressed() const;
- void set_scancode(uint32_t p_scancode);
- uint32_t get_scancode() const;
+ void set_keycode(uint32_t p_keycode);
+ uint32_t get_keycode() const;
+
+ void set_physical_keycode(uint32_t p_keycode);
+ uint32_t get_physical_keycode() const;
void set_unicode(uint32_t p_unicode);
uint32_t get_unicode() const;
@@ -277,7 +281,8 @@ public:
void set_echo(bool p_enable);
virtual bool is_echo() const;
- uint32_t get_scancode_with_modifiers() const;
+ uint32_t get_keycode_with_modifiers() const;
+ uint32_t get_physical_keycode_with_modifiers() 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;
diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp
index 6020c4b219..ab43ce4af7 100644
--- a/core/os/main_loop.cpp
+++ b/core/os/main_loop.cpp
@@ -44,9 +44,9 @@ void MainLoop::_bind_methods() {
BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
BIND_VMETHOD(MethodInfo("_input_text", PropertyInfo(Variant::STRING, "text")));
BIND_VMETHOD(MethodInfo("_initialize"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_iteration", PropertyInfo(Variant::REAL, "delta")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_idle", PropertyInfo(Variant::REAL, "delta")));
- BIND_VMETHOD(MethodInfo("_drop_files", PropertyInfo(Variant::POOL_STRING_ARRAY, "files"), PropertyInfo(Variant::INT, "from_screen")));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "_iteration", PropertyInfo(Variant::FLOAT, "delta")));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "_idle", PropertyInfo(Variant::FLOAT, "delta")));
+ BIND_VMETHOD(MethodInfo("_drop_files", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files"), PropertyInfo(Variant::INT, "from_screen")));
BIND_VMETHOD(MethodInfo("_finalize"));
BIND_VMETHOD(MethodInfo("_global_menu_action", PropertyInfo(Variant::NIL, "id"), PropertyInfo(Variant::NIL, "meta")));
diff --git a/core/os/memory.h b/core/os/memory.h
index e45f97e0c8..207149b57e 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -143,7 +143,7 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
if (p_elements == 0)
return 0;
/** overloading operator new[] cannot be done , because it may not return the real allocated address (it may pad the 'element count' before the actual array). Because of that, it must be done by hand. This is the
- same strategy used by std::vector, and the PoolVector class, so it should be safe.*/
+ same strategy used by std::vector, and the Vector class, so it should be safe.*/
size_t len = sizeof(T) * p_elements;
uint64_t *mem = (uint64_t *)Memory::alloc_static(len, true);
diff --git a/core/os/midi_driver.cpp b/core/os/midi_driver.cpp
index 3e020a1585..6ebec50ff0 100644
--- a/core/os/midi_driver.cpp
+++ b/core/os/midi_driver.cpp
@@ -121,9 +121,9 @@ void MIDIDriver::receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_
id->parse_input_event(event);
}
-PoolStringArray MIDIDriver::get_connected_inputs() {
+PackedStringArray MIDIDriver::get_connected_inputs() {
- PoolStringArray list;
+ PackedStringArray list;
return list;
}
diff --git a/core/os/midi_driver.h b/core/os/midi_driver.h
index 26dbdce151..4f53feb43e 100644
--- a/core/os/midi_driver.h
+++ b/core/os/midi_driver.h
@@ -50,7 +50,7 @@ public:
virtual Error open() = 0;
virtual void close() = 0;
- virtual PoolStringArray get_connected_inputs();
+ virtual PackedStringArray get_connected_inputs();
static void receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_t length);
diff --git a/core/os/mutex.cpp b/core/os/mutex.cpp
index f099b4319a..74c308f646 100644
--- a/core/os/mutex.cpp
+++ b/core/os/mutex.cpp
@@ -30,31 +30,17 @@
#include "mutex.h"
-#include "core/error_macros.h"
-
-#include <stddef.h>
-
-Mutex *(*Mutex::create_func)(bool) = 0;
-
-Mutex *Mutex::create(bool p_recursive) {
-
- ERR_FAIL_COND_V(!create_func, 0);
-
- return create_func(p_recursive);
-}
-
-Mutex::~Mutex() {
-}
-
-Mutex *_global_mutex = NULL;
+static Mutex _global_mutex;
void _global_lock() {
-
- if (_global_mutex)
- _global_mutex->lock();
+ _global_mutex.lock();
}
-void _global_unlock() {
- if (_global_mutex)
- _global_mutex->unlock();
+void _global_unlock() {
+ _global_mutex.unlock();
}
+
+template class MutexImpl<std::recursive_mutex>;
+template class MutexImpl<std::mutex>;
+template class MutexLock<MutexImpl<std::recursive_mutex> >;
+template class MutexLock<MutexImpl<std::mutex> >;
diff --git a/core/os/mutex.h b/core/os/mutex.h
index db82eb64f5..8d7b378d60 100644
--- a/core/os/mutex.h
+++ b/core/os/mutex.h
@@ -32,42 +32,69 @@
#define MUTEX_H
#include "core/error_list.h"
+#include "core/typedefs.h"
-/**
- * @class Mutex
- * @author Juan Linietsky
- * Portable Mutex (thread-safe locking) implementation.
- * Mutexes are always recursive ( they don't self-lock in a single thread ).
- * Mutexes can be used with a Lockp object like this, to avoid having to worry about unlocking:
- * Lockp( mutex );
- */
+#if !defined(NO_THREADS)
-class Mutex {
-protected:
- static Mutex *(*create_func)(bool);
+#include <mutex>
+
+template <class StdMutexT>
+class MutexImpl {
+ mutable StdMutexT mutex;
public:
- virtual void lock() = 0; ///< Lock the mutex, block if locked by someone else
- virtual void unlock() = 0; ///< Unlock the mutex, let other threads continue
- virtual Error try_lock() = 0; ///< Attempt to lock the mutex, OK on success, ERROR means it can't lock.
+ _ALWAYS_INLINE_ void lock() const {
+ mutex.lock();
+ }
- static Mutex *create(bool p_recursive = true); ///< Create a mutex
+ _ALWAYS_INLINE_ void unlock() const {
+ mutex.unlock();
+ }
- virtual ~Mutex();
+ _ALWAYS_INLINE_ Error try_lock() const {
+ return mutex.try_lock() ? OK : ERR_BUSY;
+ }
};
+template <class MutexT>
class MutexLock {
-
- Mutex *mutex;
+ const MutexT &mutex;
public:
- MutexLock(Mutex *p_mutex) {
- mutex = p_mutex;
- if (mutex) mutex->lock();
+ _ALWAYS_INLINE_ explicit MutexLock(const MutexT &p_mutex) :
+ mutex(p_mutex) {
+ mutex.lock();
}
- ~MutexLock() {
- if (mutex) mutex->unlock();
+
+ _ALWAYS_INLINE_ ~MutexLock() {
+ mutex.unlock();
}
};
+#else
+
+template <class StdMutexType>
+class MutexImpl {
+public:
+ _ALWAYS_INLINE_ void lock() const {}
+ _ALWAYS_INLINE_ void unlock() const {}
+ _ALWAYS_INLINE_ Error try_lock() const { return OK; }
+};
+
+template <class MutexT>
+class MutexLock {
+public:
+ explicit MutexLock(const MutexT &p_mutex) {}
+};
+
+#endif // !NO_THREADS
+
+using Mutex = MutexImpl<std::recursive_mutex>; // Recursive, for general use
+using BinaryMutex = MutexImpl<std::mutex>; // Non-recursive, handle with care
+
+extern template class MutexImpl<std::recursive_mutex>;
+extern template class MutexImpl<std::mutex>;
+extern template class MutexLock<MutexImpl<std::recursive_mutex> >;
+extern template class MutexLock<MutexImpl<std::mutex> >;
+
#endif
diff --git a/core/os/os.cpp b/core/os/os.cpp
index d1b6ccab54..9a65d537ac 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -416,10 +416,6 @@ uint64_t OS::get_static_memory_usage() const {
return Memory::get_mem_usage();
}
-uint64_t OS::get_dynamic_memory_usage() const {
-
- return MemoryPool::total_memory;
-}
uint64_t OS::get_static_memory_peak_usage() const {
@@ -712,12 +708,12 @@ List<String> OS::get_restart_on_exit_arguments() const {
return restart_commandline;
}
-PoolStringArray OS::get_connected_midi_inputs() {
+PackedStringArray OS::get_connected_midi_inputs() {
if (MIDIDriver::get_singleton())
return MIDIDriver::get_singleton()->get_connected_inputs();
- PoolStringArray list;
+ PackedStringArray list;
return list;
}
diff --git a/core/os/os.h b/core/os/os.h
index e4661e4583..1d3619b1e6 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -41,8 +41,6 @@
#include <stdarg.h>
-class Mutex;
-
class OS {
static OS *singleton;
@@ -185,7 +183,7 @@ public:
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
- virtual PoolStringArray get_connected_midi_inputs();
+ virtual PackedStringArray get_connected_midi_inputs();
virtual void open_midi_inputs();
virtual void close_midi_inputs();
@@ -390,7 +388,6 @@ public:
virtual uint64_t get_static_memory_usage() const;
virtual uint64_t get_static_memory_peak_usage() const;
- virtual uint64_t get_dynamic_memory_usage() const;
virtual uint64_t get_free_static_memory() const;
RenderThreadMode get_render_thread_mode() const { return _render_thread_mode; }
diff --git a/core/os/semaphore.cpp b/core/os/semaphore.cpp
index 2c20f234d0..93f1e2dff4 100644
--- a/core/os/semaphore.cpp
+++ b/core/os/semaphore.cpp
@@ -29,17 +29,3 @@
/*************************************************************************/
#include "semaphore.h"
-
-#include "core/error_macros.h"
-
-SemaphoreOld *(*SemaphoreOld::create_func)() = 0;
-
-SemaphoreOld *SemaphoreOld::create() {
-
- ERR_FAIL_COND_V(!create_func, 0);
-
- return create_func();
-}
-
-SemaphoreOld::~SemaphoreOld() {
-}
diff --git a/core/os/semaphore.h b/core/os/semaphore.h
index f16a15a6db..6f194d4887 100644
--- a/core/os/semaphore.h
+++ b/core/os/semaphore.h
@@ -34,30 +34,32 @@
#include "core/error_list.h"
#include "core/typedefs.h"
+#if !defined(NO_THREADS)
+
#include <condition_variable>
#include <mutex>
class Semaphore {
private:
- std::mutex mutex_;
- std::condition_variable condition_;
- unsigned long count_ = 0; // Initialized as locked.
+ mutable std::mutex mutex_;
+ mutable std::condition_variable condition_;
+ mutable unsigned long count_ = 0; // Initialized as locked.
public:
- _ALWAYS_INLINE_ void post() {
+ _ALWAYS_INLINE_ void post() const {
std::lock_guard<decltype(mutex_)> lock(mutex_);
++count_;
condition_.notify_one();
}
- _ALWAYS_INLINE_ void wait() {
+ _ALWAYS_INLINE_ void wait() const {
std::unique_lock<decltype(mutex_)> lock(mutex_);
while (!count_) // Handle spurious wake-ups.
condition_.wait(lock);
--count_;
}
- _ALWAYS_INLINE_ bool try_wait() {
+ _ALWAYS_INLINE_ bool try_wait() const {
std::lock_guard<decltype(mutex_)> lock(mutex_);
if (count_) {
--count_;
@@ -67,18 +69,15 @@ public:
}
};
-class SemaphoreOld {
-protected:
- static SemaphoreOld *(*create_func)();
+#else
+class Semaphore {
public:
- virtual Error wait() = 0; ///< wait until semaphore has positive value, then decrement and pass
- virtual Error post() = 0; ///< unlock the semaphore, incrementing the value
- virtual int get() const = 0; ///< get semaphore value
-
- static SemaphoreOld *create(); ///< Create a mutex
-
- virtual ~SemaphoreOld();
+ _ALWAYS_INLINE_ void post() const {}
+ _ALWAYS_INLINE_ void wait() const {}
+ _ALWAYS_INLINE_ bool try_wait() const { return true; }
};
#endif
+
+#endif
diff --git a/core/os/thread_dummy.cpp b/core/os/thread_dummy.cpp
index 916aeeda30..9dcddcae11 100644
--- a/core/os/thread_dummy.cpp
+++ b/core/os/thread_dummy.cpp
@@ -40,22 +40,6 @@ void ThreadDummy::make_default() {
Thread::create_func = &ThreadDummy::create;
};
-Mutex *MutexDummy::create(bool p_recursive) {
- return memnew(MutexDummy);
-};
-
-void MutexDummy::make_default() {
- Mutex::create_func = &MutexDummy::create;
-};
-
-SemaphoreOld *SemaphoreDummy::create() {
- return memnew(SemaphoreDummy);
-};
-
-void SemaphoreDummy::make_default() {
- SemaphoreOld::create_func = &SemaphoreDummy::create;
-};
-
RWLock *RWLockDummy::create() {
return memnew(RWLockDummy);
};
diff --git a/core/os/thread_dummy.h b/core/os/thread_dummy.h
index 9329cdaa32..da8188f983 100644
--- a/core/os/thread_dummy.h
+++ b/core/os/thread_dummy.h
@@ -31,7 +31,6 @@
#ifndef THREAD_DUMMY_H
#define THREAD_DUMMY_H
-#include "core/os/mutex.h"
#include "core/os/rw_lock.h"
#include "core/os/semaphore.h"
#include "core/os/thread.h"
@@ -46,30 +45,6 @@ public:
static void make_default();
};
-class MutexDummy : public Mutex {
-
- static Mutex *create(bool p_recursive);
-
-public:
- virtual void lock(){};
- virtual void unlock(){};
- virtual Error try_lock() { return OK; };
-
- static void make_default();
-};
-
-class SemaphoreDummy : public SemaphoreOld {
-
- static SemaphoreOld *create();
-
-public:
- virtual Error wait() { return OK; };
- virtual Error post() { return OK; };
- virtual int get() const { return 0; }; ///< get semaphore value
-
- static void make_default();
-};
-
class RWLockDummy : public RWLock {
static RWLock *create();
diff --git a/core/os/thread_safe.h b/core/os/thread_safe.h
index a4238a9225..0221edf491 100644
--- a/core/os/thread_safe.h
+++ b/core/os/thread_safe.h
@@ -33,50 +33,9 @@
#include "core/os/mutex.h"
-class ThreadSafe {
-
- Mutex *mutex;
-
-public:
- inline void lock() const {
- if (mutex) mutex->lock();
- }
- inline void unlock() const {
- if (mutex) mutex->unlock();
- }
-
- ThreadSafe();
- ~ThreadSafe();
-};
-
-class ThreadSafeMethod {
-
- const ThreadSafe *_ts;
-
-public:
- ThreadSafeMethod(const ThreadSafe *p_ts) {
-
- _ts = p_ts;
- _ts->lock();
- }
-
- ~ThreadSafeMethod() { _ts->unlock(); }
-};
-
-#ifndef NO_THREADS
-
-#define _THREAD_SAFE_CLASS_ ThreadSafe __thread__safe__;
-#define _THREAD_SAFE_METHOD_ ThreadSafeMethod __thread_safe_method__(&__thread__safe__);
-#define _THREAD_SAFE_LOCK_ __thread__safe__.lock();
-#define _THREAD_SAFE_UNLOCK_ __thread__safe__.unlock();
-
-#else
-
-#define _THREAD_SAFE_CLASS_
-#define _THREAD_SAFE_METHOD_
-#define _THREAD_SAFE_LOCK_
-#define _THREAD_SAFE_UNLOCK_
-
-#endif
+#define _THREAD_SAFE_CLASS_ mutable Mutex _thread_safe_;
+#define _THREAD_SAFE_METHOD_ MutexLock _thread_safe_method_(_thread_safe_);
+#define _THREAD_SAFE_LOCK_ _thread_safe_.lock();
+#define _THREAD_SAFE_UNLOCK_ _thread_safe_.unlock();
#endif
diff --git a/core/packed_data_container.cpp b/core/packed_data_container.cpp
index f8f51c4c75..b82a366ef2 100644
--- a/core/packed_data_container.cpp
+++ b/core/packed_data_container.cpp
@@ -80,20 +80,20 @@ Variant PackedDataContainer::_iter_get_ofs(const Variant &p_iter, uint32_t p_off
if (pos < 0 || pos >= size)
return Variant();
- PoolVector<uint8_t>::Read rd = data.read();
+ const uint8_t *rd = data.ptr();
const uint8_t *r = &rd[p_offset];
uint32_t type = decode_uint32(r);
bool err = false;
if (type == TYPE_ARRAY) {
- uint32_t vpos = decode_uint32(rd.ptr() + p_offset + 8 + pos * 4);
- return _get_at_ofs(vpos, rd.ptr(), err);
+ uint32_t vpos = decode_uint32(rd + p_offset + 8 + pos * 4);
+ return _get_at_ofs(vpos, rd, err);
} else if (type == TYPE_DICT) {
- uint32_t vpos = decode_uint32(rd.ptr() + p_offset + 8 + pos * 12 + 4);
- return _get_at_ofs(vpos, rd.ptr(), err);
+ uint32_t vpos = decode_uint32(rd + p_offset + 8 + pos * 12 + 4);
+ return _get_at_ofs(vpos, rd, err);
} else {
ERR_FAIL_V(Variant());
}
@@ -127,7 +127,7 @@ Variant PackedDataContainer::_get_at_ofs(uint32_t p_ofs, const uint8_t *p_buf, b
uint32_t PackedDataContainer::_type_at_ofs(uint32_t p_ofs) const {
- PoolVector<uint8_t>::Read rd = data.read();
+ const uint8_t *rd = data.ptr();
const uint8_t *r = &rd[p_ofs];
uint32_t type = decode_uint32(r);
@@ -136,8 +136,8 @@ uint32_t PackedDataContainer::_type_at_ofs(uint32_t p_ofs) const {
int PackedDataContainer::_size(uint32_t p_ofs) const {
- PoolVector<uint8_t>::Read rd = data.read();
- ERR_FAIL_COND_V(!rd.ptr(), 0);
+ const uint8_t *rd = data.ptr();
+ ERR_FAIL_COND_V(!rd, 0);
const uint8_t *r = &rd[p_ofs];
uint32_t type = decode_uint32(r);
@@ -157,7 +157,7 @@ int PackedDataContainer::_size(uint32_t p_ofs) const {
Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, bool &err) const {
- PoolVector<uint8_t>::Read rd = data.read();
+ const uint8_t *rd = data.ptr();
const uint8_t *r = &rd[p_ofs];
uint32_t type = decode_uint32(r);
@@ -172,7 +172,7 @@ Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, b
return Variant();
}
uint32_t ofs = decode_uint32(r + 8 + 4 * idx);
- return _get_at_ofs(ofs, rd.ptr(), err);
+ return _get_at_ofs(ofs, rd, err);
} else {
err = true;
@@ -188,12 +188,12 @@ Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, b
for (uint32_t i = 0; i < len; i++) {
uint32_t khash = decode_uint32(r + 8 + i * 12 + 0);
if (khash == hash) {
- Variant key = _get_at_ofs(decode_uint32(r + 8 + i * 12 + 4), rd.ptr(), err);
+ Variant key = _get_at_ofs(decode_uint32(r + 8 + i * 12 + 4), rd, err);
if (err)
return Variant();
if (key == p_key) {
//key matches, return value
- return _get_at_ofs(decode_uint32(r + 8 + i * 12 + 8), rd.ptr(), err);
+ return _get_at_ofs(decode_uint32(r + 8 + i * 12 + 8), rd, err);
}
found = true;
} else {
@@ -225,12 +225,12 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
string_cache[s] = tmpdata.size();
- FALLTHROUGH;
- };
+ [[fallthrough]];
+ }
case Variant::NIL:
case Variant::BOOL:
case Variant::INT:
- case Variant::REAL:
+ case Variant::FLOAT:
case Variant::VECTOR2:
case Variant::RECT2:
case Variant::VECTOR3:
@@ -240,13 +240,16 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
case Variant::AABB:
case Variant::BASIS:
case Variant::TRANSFORM:
- case Variant::POOL_BYTE_ARRAY:
- case Variant::POOL_INT_ARRAY:
- case Variant::POOL_REAL_ARRAY:
- case Variant::POOL_STRING_ARRAY:
- case Variant::POOL_VECTOR2_ARRAY:
- case Variant::POOL_VECTOR3_ARRAY:
- case Variant::POOL_COLOR_ARRAY:
+ case Variant::PACKED_BYTE_ARRAY:
+ case Variant::PACKED_INT32_ARRAY:
+ case Variant::PACKED_INT64_ARRAY:
+ case Variant::PACKED_FLOAT32_ARRAY:
+ case Variant::PACKED_FLOAT64_ARRAY:
+ case Variant::PACKED_STRING_ARRAY:
+ case Variant::PACKED_VECTOR2_ARRAY:
+ case Variant::PACKED_VECTOR3_ARRAY:
+ case Variant::PACKED_COLOR_ARRAY:
+ case Variant::STRING_NAME:
case Variant::NODE_PATH: {
uint32_t pos = tmpdata.size();
@@ -335,19 +338,19 @@ Error PackedDataContainer::pack(const Variant &p_data) {
_pack(p_data, tmpdata, string_cache);
datalen = tmpdata.size();
data.resize(tmpdata.size());
- PoolVector<uint8_t>::Write w = data.write();
- copymem(w.ptr(), tmpdata.ptr(), tmpdata.size());
+ uint8_t *w = data.ptrw();
+ copymem(w, tmpdata.ptr(), tmpdata.size());
return OK;
}
-void PackedDataContainer::_set_data(const PoolVector<uint8_t> &p_data) {
+void PackedDataContainer::_set_data(const Vector<uint8_t> &p_data) {
data = p_data;
datalen = data.size();
}
-PoolVector<uint8_t> PackedDataContainer::_get_data() const {
+Vector<uint8_t> PackedDataContainer::_get_data() const {
return data;
}
@@ -375,7 +378,7 @@ void PackedDataContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("pack", "value"), &PackedDataContainer::pack);
ClassDB::bind_method(D_METHOD("size"), &PackedDataContainer::size);
- ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "__data__"), "_set_data", "_get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "__data__"), "_set_data", "_get_data");
}
PackedDataContainer::PackedDataContainer() {
diff --git a/core/packed_data_container.h b/core/packed_data_container.h
index b534169077..852fdcd0d3 100644
--- a/core/packed_data_container.h
+++ b/core/packed_data_container.h
@@ -48,7 +48,7 @@ class PackedDataContainer : public Resource {
bool operator<(const DictKey &p_key) const { return hash < p_key.hash; }
};
- PoolVector<uint8_t> data;
+ Vector<uint8_t> data;
int datalen;
uint32_t _pack(const Variant &p_data, Vector<uint8_t> &tmpdata, Map<String, uint32_t> &string_cache);
@@ -68,8 +68,8 @@ class PackedDataContainer : public Resource {
int _size(uint32_t p_ofs) const;
protected:
- void _set_data(const PoolVector<uint8_t> &p_data);
- PoolVector<uint8_t> _get_data() const;
+ void _set_data(const Vector<uint8_t> &p_data);
+ Vector<uint8_t> _get_data() const;
static void _bind_methods();
public:
diff --git a/core/pool_vector.h b/core/pool_vector.h
deleted file mode 100644
index 01c40a237d..0000000000
--- a/core/pool_vector.h
+++ /dev/null
@@ -1,648 +0,0 @@
-/*************************************************************************/
-/* pool_vector.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 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 POOL_VECTOR_H
-#define POOL_VECTOR_H
-
-#include "core/os/copymem.h"
-#include "core/os/memory.h"
-#include "core/os/rw_lock.h"
-#include "core/pool_allocator.h"
-#include "core/safe_refcount.h"
-#include "core/ustring.h"
-
-struct MemoryPool {
-
- //avoid accessing these directly, must be public for template access
-
- static PoolAllocator *memory_pool;
- static uint8_t *pool_memory;
- static size_t *pool_size;
-
- struct Alloc {
-
- SafeRefCount refcount;
- uint32_t lock;
- void *mem;
- PoolAllocator::ID pool_id;
- size_t size;
-
- Alloc *free_list;
-
- Alloc() :
- lock(0),
- mem(NULL),
- pool_id(POOL_ALLOCATOR_INVALID_ID),
- size(0),
- free_list(NULL) {
- }
- };
-
- static Alloc *allocs;
- static Alloc *free_list;
- static uint32_t alloc_count;
- static uint32_t allocs_used;
- static Mutex *alloc_mutex;
- static size_t total_memory;
- static size_t max_memory;
-
- static void setup(uint32_t p_max_allocs = (1 << 16));
- static void cleanup();
-};
-
-template <class T>
-class PoolVector {
-
- MemoryPool::Alloc *alloc;
-
- void _copy_on_write() {
-
- if (!alloc)
- return;
-
- // ERR_FAIL_COND(alloc->lock>0); should not be illegal to lock this for copy on write, as it's a copy on write after all
-
- // Refcount should not be zero, otherwise it's a misuse of COW
- if (alloc->refcount.get() == 1)
- return; //nothing to do
-
- //must allocate something
-
- MemoryPool::alloc_mutex->lock();
- if (MemoryPool::allocs_used == MemoryPool::alloc_count) {
- MemoryPool::alloc_mutex->unlock();
- ERR_FAIL_MSG("All memory pool allocations are in use, can't COW.");
- }
-
- MemoryPool::Alloc *old_alloc = alloc;
-
- //take one from the free list
- alloc = MemoryPool::free_list;
- MemoryPool::free_list = alloc->free_list;
- //increment the used counter
- MemoryPool::allocs_used++;
-
- //copy the alloc data
- alloc->size = old_alloc->size;
- alloc->refcount.init();
- alloc->pool_id = POOL_ALLOCATOR_INVALID_ID;
- alloc->lock = 0;
-
-#ifdef DEBUG_ENABLED
- MemoryPool::total_memory += alloc->size;
- if (MemoryPool::total_memory > MemoryPool::max_memory) {
- MemoryPool::max_memory = MemoryPool::total_memory;
- }
-#endif
-
- MemoryPool::alloc_mutex->unlock();
-
- if (MemoryPool::memory_pool) {
-
- } else {
- alloc->mem = memalloc(alloc->size);
- }
-
- {
- Write w;
- w._ref(alloc);
- Read r;
- r._ref(old_alloc);
-
- int cur_elements = alloc->size / sizeof(T);
- T *dst = (T *)w.ptr();
- const T *src = (const T *)r.ptr();
- for (int i = 0; i < cur_elements; i++) {
- memnew_placement(&dst[i], T(src[i]));
- }
- }
-
- if (old_alloc->refcount.unref()) {
- //this should never happen but..
-
-#ifdef DEBUG_ENABLED
- MemoryPool::alloc_mutex->lock();
- MemoryPool::total_memory -= old_alloc->size;
- MemoryPool::alloc_mutex->unlock();
-#endif
-
- {
- Write w;
- w._ref(old_alloc);
-
- int cur_elements = old_alloc->size / sizeof(T);
- T *elems = (T *)w.ptr();
- for (int i = 0; i < cur_elements; i++) {
- elems[i].~T();
- }
- }
-
- if (MemoryPool::memory_pool) {
- //resize memory pool
- //if none, create
- //if some resize
- } else {
-
- memfree(old_alloc->mem);
- old_alloc->mem = NULL;
- old_alloc->size = 0;
-
- MemoryPool::alloc_mutex->lock();
- old_alloc->free_list = MemoryPool::free_list;
- MemoryPool::free_list = old_alloc;
- MemoryPool::allocs_used--;
- MemoryPool::alloc_mutex->unlock();
- }
- }
- }
-
- void _reference(const PoolVector &p_pool_vector) {
-
- if (alloc == p_pool_vector.alloc)
- return;
-
- _unreference();
-
- if (!p_pool_vector.alloc) {
- return;
- }
-
- if (p_pool_vector.alloc->refcount.ref()) {
- alloc = p_pool_vector.alloc;
- }
- }
-
- void _unreference() {
-
- if (!alloc)
- return;
-
- if (!alloc->refcount.unref()) {
- alloc = NULL;
- return;
- }
-
- //must be disposed!
-
- {
- int cur_elements = alloc->size / sizeof(T);
-
- // Don't use write() here because it could otherwise provoke COW,
- // which is not desirable here because we are destroying the last reference anyways
- Write w;
- // Reference to still prevent other threads from touching the alloc
- w._ref(alloc);
-
- for (int i = 0; i < cur_elements; i++) {
-
- w[i].~T();
- }
- }
-
-#ifdef DEBUG_ENABLED
- MemoryPool::alloc_mutex->lock();
- MemoryPool::total_memory -= alloc->size;
- MemoryPool::alloc_mutex->unlock();
-#endif
-
- if (MemoryPool::memory_pool) {
- //resize memory pool
- //if none, create
- //if some resize
- } else {
-
- memfree(alloc->mem);
- alloc->mem = NULL;
- alloc->size = 0;
-
- MemoryPool::alloc_mutex->lock();
- alloc->free_list = MemoryPool::free_list;
- MemoryPool::free_list = alloc;
- MemoryPool::allocs_used--;
- MemoryPool::alloc_mutex->unlock();
- }
-
- alloc = NULL;
- }
-
-public:
- class Access {
- friend class PoolVector;
-
- protected:
- MemoryPool::Alloc *alloc;
- T *mem;
-
- _FORCE_INLINE_ void _ref(MemoryPool::Alloc *p_alloc) {
- alloc = p_alloc;
- if (alloc) {
- if (atomic_increment(&alloc->lock) == 1) {
- if (MemoryPool::memory_pool) {
- //lock it and get mem
- }
- }
-
- mem = (T *)alloc->mem;
- }
- }
-
- _FORCE_INLINE_ void _unref() {
-
- if (alloc) {
- if (atomic_decrement(&alloc->lock) == 0) {
- if (MemoryPool::memory_pool) {
- //put mem back
- }
- }
-
- mem = NULL;
- alloc = NULL;
- }
- }
-
- Access() {
- alloc = NULL;
- mem = NULL;
- }
-
- public:
- virtual ~Access() {
- _unref();
- }
-
- void release() {
- _unref();
- }
- };
-
- class Read : public Access {
- public:
- _FORCE_INLINE_ const T &operator[](int p_index) const { return this->mem[p_index]; }
- _FORCE_INLINE_ const T *ptr() const { return this->mem; }
-
- void operator=(const Read &p_read) {
- if (this->alloc == p_read.alloc)
- return;
- this->_unref();
- this->_ref(p_read.alloc);
- }
-
- Read(const Read &p_read) {
- this->_ref(p_read.alloc);
- }
-
- Read() {}
- };
-
- class Write : public Access {
- public:
- _FORCE_INLINE_ T &operator[](int p_index) const { return this->mem[p_index]; }
- _FORCE_INLINE_ T *ptr() const { return this->mem; }
-
- void operator=(const Write &p_read) {
- if (this->alloc == p_read.alloc)
- return;
- this->_unref();
- this->_ref(p_read.alloc);
- }
-
- Write(const Write &p_read) {
- this->_ref(p_read.alloc);
- }
-
- Write() {}
- };
-
- Read read() const {
-
- Read r;
- if (alloc) {
- r._ref(alloc);
- }
- return r;
- }
- Write write() {
-
- Write w;
- if (alloc) {
- _copy_on_write(); //make sure there is only one being acessed
- w._ref(alloc);
- }
- return w;
- }
-
- template <class MC>
- void fill_with(const MC &p_mc) {
-
- int c = p_mc.size();
- resize(c);
- Write w = write();
- int idx = 0;
- for (const typename MC::Element *E = p_mc.front(); E; E = E->next()) {
-
- w[idx++] = E->get();
- }
- }
-
- void remove(int p_index) {
-
- int s = size();
- ERR_FAIL_INDEX(p_index, s);
- Write w = write();
- for (int i = p_index; i < s - 1; i++) {
-
- w[i] = w[i + 1];
- };
- w = Write();
- resize(s - 1);
- }
-
- inline int size() const;
- inline bool empty() const;
- T get(int p_index) const;
- void set(int p_index, const T &p_val);
- void push_back(const T &p_val);
- void append(const T &p_val) { push_back(p_val); }
- void append_array(const PoolVector<T> &p_arr) {
- int ds = p_arr.size();
- if (ds == 0)
- return;
- int bs = size();
- resize(bs + ds);
- Write w = write();
- Read r = p_arr.read();
- for (int i = 0; i < ds; i++)
- w[bs + i] = r[i];
- }
-
- PoolVector<T> subarray(int p_from, int p_to) {
-
- if (p_from < 0) {
- p_from = size() + p_from;
- }
- if (p_to < 0) {
- p_to = size() + p_to;
- }
-
- ERR_FAIL_INDEX_V(p_from, size(), PoolVector<T>());
- ERR_FAIL_INDEX_V(p_to, size(), PoolVector<T>());
-
- PoolVector<T> slice;
- int span = 1 + p_to - p_from;
- slice.resize(span);
- Read r = read();
- Write w = slice.write();
- for (int i = 0; i < span; ++i) {
- w[i] = r[p_from + i];
- }
-
- return slice;
- }
-
- Error insert(int p_pos, const T &p_val) {
-
- int s = size();
- ERR_FAIL_INDEX_V(p_pos, s + 1, ERR_INVALID_PARAMETER);
- resize(s + 1);
- {
- Write w = write();
- for (int i = s; i > p_pos; i--)
- w[i] = w[i - 1];
- w[p_pos] = p_val;
- }
-
- return OK;
- }
-
- String join(String delimiter) {
- String rs = "";
- int s = size();
- Read r = read();
- for (int i = 0; i < s; i++) {
- rs += r[i] + delimiter;
- }
- rs.erase(rs.length() - delimiter.length(), delimiter.length());
- return rs;
- }
-
- bool is_locked() const { return alloc && alloc->lock > 0; }
-
- inline T operator[](int p_index) const;
-
- Error resize(int p_size);
-
- void invert();
-
- void operator=(const PoolVector &p_pool_vector) { _reference(p_pool_vector); }
- PoolVector() { alloc = NULL; }
- PoolVector(const PoolVector &p_pool_vector) {
- alloc = NULL;
- _reference(p_pool_vector);
- }
- ~PoolVector() { _unreference(); }
-};
-
-template <class T>
-int PoolVector<T>::size() const {
-
- return alloc ? alloc->size / sizeof(T) : 0;
-}
-
-template <class T>
-bool PoolVector<T>::empty() const {
-
- return alloc ? alloc->size == 0 : true;
-}
-
-template <class T>
-T PoolVector<T>::get(int p_index) const {
-
- return operator[](p_index);
-}
-
-template <class T>
-void PoolVector<T>::set(int p_index, const T &p_val) {
-
- ERR_FAIL_INDEX(p_index, size());
-
- Write w = write();
- w[p_index] = p_val;
-}
-
-template <class T>
-void PoolVector<T>::push_back(const T &p_val) {
-
- resize(size() + 1);
- set(size() - 1, p_val);
-}
-
-template <class T>
-T PoolVector<T>::operator[](int p_index) const {
-
- CRASH_BAD_INDEX(p_index, size());
-
- Read r = read();
- return r[p_index];
-}
-
-template <class T>
-Error PoolVector<T>::resize(int p_size) {
-
- ERR_FAIL_COND_V_MSG(p_size < 0, ERR_INVALID_PARAMETER, "Size of PoolVector cannot be negative.");
-
- if (alloc == NULL) {
-
- if (p_size == 0)
- return OK; //nothing to do here
-
- //must allocate something
- MemoryPool::alloc_mutex->lock();
- if (MemoryPool::allocs_used == MemoryPool::alloc_count) {
- MemoryPool::alloc_mutex->unlock();
- ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "All memory pool allocations are in use.");
- }
-
- //take one from the free list
- alloc = MemoryPool::free_list;
- MemoryPool::free_list = alloc->free_list;
- //increment the used counter
- MemoryPool::allocs_used++;
-
- //cleanup the alloc
- alloc->size = 0;
- alloc->refcount.init();
- alloc->pool_id = POOL_ALLOCATOR_INVALID_ID;
- MemoryPool::alloc_mutex->unlock();
-
- } else {
-
- ERR_FAIL_COND_V_MSG(alloc->lock > 0, ERR_LOCKED, "Can't resize PoolVector if locked."); //can't resize if locked!
- }
-
- size_t new_size = sizeof(T) * p_size;
-
- if (alloc->size == new_size)
- return OK; //nothing to do
-
- if (p_size == 0) {
- _unreference();
- return OK;
- }
-
- _copy_on_write(); // make it unique
-
-#ifdef DEBUG_ENABLED
- MemoryPool::alloc_mutex->lock();
- MemoryPool::total_memory -= alloc->size;
- MemoryPool::total_memory += new_size;
- if (MemoryPool::total_memory > MemoryPool::max_memory) {
- MemoryPool::max_memory = MemoryPool::total_memory;
- }
- MemoryPool::alloc_mutex->unlock();
-#endif
-
- int cur_elements = alloc->size / sizeof(T);
-
- if (p_size > cur_elements) {
-
- if (MemoryPool::memory_pool) {
- //resize memory pool
- //if none, create
- //if some resize
- } else {
-
- if (alloc->size == 0) {
- alloc->mem = memalloc(new_size);
- } else {
- alloc->mem = memrealloc(alloc->mem, new_size);
- }
- }
-
- alloc->size = new_size;
-
- Write w = write();
-
- for (int i = cur_elements; i < p_size; i++) {
-
- memnew_placement(&w[i], T);
- }
-
- } else {
-
- {
- Write w = write();
- for (int i = p_size; i < cur_elements; i++) {
-
- w[i].~T();
- }
- }
-
- if (MemoryPool::memory_pool) {
- //resize memory pool
- //if none, create
- //if some resize
- } else {
-
- if (new_size == 0) {
- memfree(alloc->mem);
- alloc->mem = NULL;
- alloc->size = 0;
-
- MemoryPool::alloc_mutex->lock();
- alloc->free_list = MemoryPool::free_list;
- MemoryPool::free_list = alloc;
- MemoryPool::allocs_used--;
- MemoryPool::alloc_mutex->unlock();
-
- } else {
- alloc->mem = memrealloc(alloc->mem, new_size);
- alloc->size = new_size;
- }
- }
- }
-
- return OK;
-}
-
-template <class T>
-void PoolVector<T>::invert() {
- T temp;
- Write w = write();
- int s = size();
- int half_s = s / 2;
-
- for (int i = 0; i < half_s; i++) {
- temp = w[i];
- w[i] = w[s - i - 1];
- w[s - i - 1] = temp;
- }
-}
-
-#endif // POOL_VECTOR_H
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index 59d7e82850..3a21610331 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -1023,14 +1023,14 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF("audio/default_bus_layout", "res://default_bus_layout.tres");
custom_prop_info["audio/default_bus_layout"] = PropertyInfo(Variant::STRING, "audio/default_bus_layout", PROPERTY_HINT_FILE, "*.tres");
- PoolStringArray extensions = PoolStringArray();
+ PackedStringArray extensions = PackedStringArray();
extensions.push_back("gd");
if (Engine::get_singleton()->has_singleton("GodotSharp"))
extensions.push_back("cs");
extensions.push_back("shader");
GLOBAL_DEF("editor/search_in_file_extensions", extensions);
- custom_prop_info["editor/search_in_file_extensions"] = PropertyInfo(Variant::POOL_STRING_ARRAY, "editor/search_in_file_extensions");
+ custom_prop_info["editor/search_in_file_extensions"] = PropertyInfo(Variant::PACKED_STRING_ARRAY, "editor/search_in_file_extensions");
GLOBAL_DEF("editor/script_templates_search_path", "res://script_templates");
custom_prop_info["editor/script_templates_search_path"] = PropertyInfo(Variant::STRING, "editor/script_templates_search_path", PROPERTY_HINT_DIR);
@@ -1039,13 +1039,13 @@ ProjectSettings::ProjectSettings() {
action["deadzone"] = Variant(0.5f);
events = Array();
key.instance();
- key->set_scancode(KEY_ENTER);
+ key->set_keycode(KEY_ENTER);
events.push_back(key);
key.instance();
- key->set_scancode(KEY_KP_ENTER);
+ key->set_keycode(KEY_KP_ENTER);
events.push_back(key);
key.instance();
- key->set_scancode(KEY_SPACE);
+ key->set_keycode(KEY_SPACE);
events.push_back(key);
joyb.instance();
joyb->set_button_index(JOY_BUTTON_0);
@@ -1058,7 +1058,7 @@ ProjectSettings::ProjectSettings() {
action["deadzone"] = Variant(0.5f);
events = Array();
key.instance();
- key->set_scancode(KEY_SPACE);
+ key->set_keycode(KEY_SPACE);
events.push_back(key);
joyb.instance();
joyb->set_button_index(JOY_BUTTON_3);
@@ -1071,7 +1071,7 @@ ProjectSettings::ProjectSettings() {
action["deadzone"] = Variant(0.5f);
events = Array();
key.instance();
- key->set_scancode(KEY_ESCAPE);
+ key->set_keycode(KEY_ESCAPE);
events.push_back(key);
joyb.instance();
joyb->set_button_index(JOY_BUTTON_1);
@@ -1084,7 +1084,7 @@ ProjectSettings::ProjectSettings() {
action["deadzone"] = Variant(0.5f);
events = Array();
key.instance();
- key->set_scancode(KEY_TAB);
+ key->set_keycode(KEY_TAB);
events.push_back(key);
action["events"] = events;
GLOBAL_DEF("input/ui_focus_next", action);
@@ -1094,7 +1094,7 @@ ProjectSettings::ProjectSettings() {
action["deadzone"] = Variant(0.5f);
events = Array();
key.instance();
- key->set_scancode(KEY_TAB);
+ key->set_keycode(KEY_TAB);
key->set_shift(true);
events.push_back(key);
action["events"] = events;
@@ -1105,7 +1105,7 @@ ProjectSettings::ProjectSettings() {
action["deadzone"] = Variant(0.5f);
events = Array();
key.instance();
- key->set_scancode(KEY_LEFT);
+ key->set_keycode(KEY_LEFT);
events.push_back(key);
joyb.instance();
joyb->set_button_index(JOY_DPAD_LEFT);
@@ -1118,7 +1118,7 @@ ProjectSettings::ProjectSettings() {
action["deadzone"] = Variant(0.5f);
events = Array();
key.instance();
- key->set_scancode(KEY_RIGHT);
+ key->set_keycode(KEY_RIGHT);
events.push_back(key);
joyb.instance();
joyb->set_button_index(JOY_DPAD_RIGHT);
@@ -1131,7 +1131,7 @@ ProjectSettings::ProjectSettings() {
action["deadzone"] = Variant(0.5f);
events = Array();
key.instance();
- key->set_scancode(KEY_UP);
+ key->set_keycode(KEY_UP);
events.push_back(key);
joyb.instance();
joyb->set_button_index(JOY_DPAD_UP);
@@ -1144,7 +1144,7 @@ ProjectSettings::ProjectSettings() {
action["deadzone"] = Variant(0.5f);
events = Array();
key.instance();
- key->set_scancode(KEY_DOWN);
+ key->set_keycode(KEY_DOWN);
events.push_back(key);
joyb.instance();
joyb->set_button_index(JOY_DPAD_DOWN);
@@ -1157,7 +1157,7 @@ ProjectSettings::ProjectSettings() {
action["deadzone"] = Variant(0.5f);
events = Array();
key.instance();
- key->set_scancode(KEY_PAGEUP);
+ key->set_keycode(KEY_PAGEUP);
events.push_back(key);
action["events"] = events;
GLOBAL_DEF("input/ui_page_up", action);
@@ -1167,7 +1167,7 @@ ProjectSettings::ProjectSettings() {
action["deadzone"] = Variant(0.5f);
events = Array();
key.instance();
- key->set_scancode(KEY_PAGEDOWN);
+ key->set_keycode(KEY_PAGEDOWN);
events.push_back(key);
action["events"] = events;
GLOBAL_DEF("input/ui_page_down", action);
@@ -1177,7 +1177,7 @@ ProjectSettings::ProjectSettings() {
action["deadzone"] = Variant(0.5f);
events = Array();
key.instance();
- key->set_scancode(KEY_HOME);
+ key->set_keycode(KEY_HOME);
events.push_back(key);
action["events"] = events;
GLOBAL_DEF("input/ui_home", action);
@@ -1187,7 +1187,7 @@ ProjectSettings::ProjectSettings() {
action["deadzone"] = Variant(0.5f);
events = Array();
key.instance();
- key->set_scancode(KEY_END);
+ key->set_keycode(KEY_END);
events.push_back(key);
action["events"] = events;
GLOBAL_DEF("input/ui_end", action);
@@ -1215,9 +1215,6 @@ ProjectSettings::ProjectSettings() {
Compression::gzip_level = GLOBAL_DEF("compression/formats/gzip/compression_level", Z_DEFAULT_COMPRESSION);
custom_prop_info["compression/formats/gzip/compression_level"] = PropertyInfo(Variant::INT, "compression/formats/gzip/compression_level", PROPERTY_HINT_RANGE, "-1,9,1");
- // Would ideally be defined in an Android-specific file, but then it doesn't appear in the docs
- GLOBAL_DEF("android/modules", "");
-
using_datapack = false;
}
diff --git a/core/reference.h b/core/reference.h
index b01e0035a7..fd42c4e537 100644
--- a/core/reference.h
+++ b/core/reference.h
@@ -38,7 +38,6 @@
class Reference : public Object {
GDCLASS(Reference, Object);
- friend class RefBase;
SafeRefCount refcount;
SafeRefCount refcount_init;
@@ -170,9 +169,9 @@ public:
return;
}
- Reference *r = Object::cast_to<Reference>(object);
+ T *r = Object::cast_to<T>(object);
if (r && r->reference()) {
- reference = static_cast<T *>(r);
+ reference = r;
}
}
@@ -226,9 +225,9 @@ public:
return;
}
- Reference *r = Object::cast_to<Reference>(object);
+ T *r = Object::cast_to<T>(object);
if (r && r->reference()) {
- reference = static_cast<T *>(r);
+ reference = r;
} else {
reference = nullptr;
}
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index 91d9289563..b0ba8ed194 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -40,12 +40,14 @@
#include "core/func_ref.h"
#include "core/input_map.h"
#include "core/io/config_file.h"
+#include "core/io/dtls_server.h"
#include "core/io/http_client.h"
#include "core/io/image_loader.h"
#include "core/io/marshalls.h"
#include "core/io/multiplayer_api.h"
#include "core/io/networked_multiplayer_peer.h"
#include "core/io/packet_peer.h"
+#include "core/io/packet_peer_dtls.h"
#include "core/io/packet_peer_udp.h"
#include "core/io/pck_packer.h"
#include "core/io/resource_format_binary.h"
@@ -53,6 +55,7 @@
#include "core/io/stream_peer_ssl.h"
#include "core/io/tcp_server.h"
#include "core/io/translation_loader_po.h"
+#include "core/io/udp_server.h"
#include "core/io/xml_parser.h"
#include "core/math/a_star.h"
#include "core/math/expression.h"
@@ -87,7 +90,7 @@ static IP *ip = NULL;
static _Geometry *_geometry = NULL;
-extern Mutex *_global_mutex;
+extern Mutex _global_mutex;
extern void register_global_constants();
extern void unregister_global_constants();
@@ -96,11 +99,11 @@ extern void unregister_variant_methods();
void register_core_types() {
+ //consistency check
+ static_assert(sizeof(Callable) <= 16);
+
ObjectDB::setup();
ResourceCache::setup();
- MemoryPool::setup();
-
- _global_mutex = Mutex::create();
StringName::setup();
ResourceLoader::initialize();
@@ -155,6 +158,9 @@ void register_core_types() {
ClassDB::register_class<StreamPeerTCP>();
ClassDB::register_class<TCP_Server>();
ClassDB::register_class<PacketPeerUDP>();
+ ClassDB::register_class<UDPServer>();
+ ClassDB::register_custom_instance_class<PacketPeerDTLS>();
+ ClassDB::register_custom_instance_class<DTLSServer>();
// Crypto
ClassDB::register_class<HashingContext>();
@@ -180,8 +186,6 @@ void register_core_types() {
ClassDB::register_class<HTTPClient>();
ClassDB::register_class<TriangleMesh>();
- ClassDB::register_virtual_class<ResourceInteractiveLoader>();
-
ClassDB::register_class<ResourceFormatLoader>();
ClassDB::register_class<ResourceFormatSaver>();
@@ -311,11 +315,4 @@ void unregister_core_types() {
ResourceCache::clear();
CoreStringNames::free();
StringName::cleanup();
-
- if (_global_mutex) {
- memdelete(_global_mutex);
- _global_mutex = NULL; //still needed at a few places
- };
-
- MemoryPool::cleanup();
}
diff --git a/core/resource.cpp b/core/resource.cpp
index 30e09716aa..2afc9e4042 100644
--- a/core/resource.cpp
+++ b/core/resource.cpp
@@ -423,7 +423,7 @@ void Resource::_bind_methods() {
ADD_GROUP("Resource", "resource_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resource_local_to_scene"), "set_local_to_scene", "is_local_to_scene");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "resource_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_path", "get_path");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "resource_name"), "set_name", "get_name");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "resource_name"), "set_name", "get_name");
BIND_VMETHOD(MethodInfo("_setup_local_to_scene"));
}
diff --git a/core/rid_owner.h b/core/rid_owner.h
index bd01eba17d..5c8c48a4cb 100644
--- a/core/rid_owner.h
+++ b/core/rid_owner.h
@@ -298,7 +298,11 @@ public:
if (description) {
print_error("ERROR: " + itos(alloc_count) + " RID allocations of type '" + description + "' were leaked at exit.");
} else {
+#ifdef NO_SAFE_CAST
+ print_error("ERROR: " + itos(alloc_count) + " RID allocations of type 'unknown' were leaked at exit.");
+#else
print_error("ERROR: " + itos(alloc_count) + " RID allocations of type '" + typeid(T).name() + "' were leaked at exit.");
+#endif
}
for (size_t i = 0; i < max_alloc; i++) {
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
new file mode 100644
index 0000000000..67375da6e2
--- /dev/null
+++ b/core/script_debugger_remote.cpp
@@ -0,0 +1,1143 @@
+/*************************************************************************/
+/* script_debugger_remote.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 "script_debugger_remote.h"
+
+#include "core/engine.h"
+#include "core/io/ip.h"
+#include "core/io/marshalls.h"
+#include "core/os/input.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
+#include "servers/visual_server.h"
+
+#define CHECK_SIZE(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() < (uint32_t)(expected), false, String("Malformed ") + what + " message from script debugger, message too short. Exptected size: " + itos(expected) + ", actual size: " + itos(arr.size()))
+#define CHECK_END(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() > (uint32_t)expected, false, String("Malformed ") + what + " message from script debugger, message too short. Exptected size: " + itos(expected) + ", actual size: " + itos(arr.size()))
+
+Array ScriptDebuggerRemote::ScriptStackDump::serialize() {
+ Array arr;
+ arr.push_back(frames.size() * 3);
+ for (int i = 0; i < frames.size(); i++) {
+ arr.push_back(frames[i].file);
+ arr.push_back(frames[i].line);
+ arr.push_back(frames[i].func);
+ }
+ return arr;
+}
+
+bool ScriptDebuggerRemote::ScriptStackDump::deserialize(const Array &p_arr) {
+ CHECK_SIZE(p_arr, 1, "ScriptStackDump");
+ uint32_t size = p_arr[0];
+ CHECK_SIZE(p_arr, size, "ScriptStackDump");
+ int idx = 1;
+ for (uint32_t i = 0; i < size / 3; i++) {
+ ScriptLanguage::StackInfo sf;
+ sf.file = p_arr[idx];
+ sf.line = p_arr[idx + 1];
+ sf.func = p_arr[idx + 2];
+ frames.push_back(sf);
+ idx += 3;
+ }
+ CHECK_END(p_arr, idx, "ScriptStackDump");
+ return true;
+}
+
+Array ScriptDebuggerRemote::ScriptStackVariable::serialize(int max_size) {
+ Array arr;
+ arr.push_back(name);
+ arr.push_back(type);
+
+ Variant var = value;
+ if (value.get_type() == Variant::OBJECT && value.get_validated_object() == nullptr) {
+ var = Variant();
+ }
+
+ int len = 0;
+ Error err = encode_variant(var, NULL, len, true);
+ if (err != OK)
+ ERR_PRINT("Failed to encode variant.");
+
+ if (len > max_size) {
+ arr.push_back(Variant());
+ } else {
+ arr.push_back(var);
+ }
+ return arr;
+}
+
+bool ScriptDebuggerRemote::ScriptStackVariable::deserialize(const Array &p_arr) {
+ CHECK_SIZE(p_arr, 3, "ScriptStackVariable");
+ name = p_arr[0];
+ type = p_arr[1];
+ value = p_arr[2];
+ CHECK_END(p_arr, 3, "ScriptStackVariable");
+ return true;
+}
+
+Array ScriptDebuggerRemote::OutputError::serialize() {
+ Array arr;
+ arr.push_back(hr);
+ arr.push_back(min);
+ arr.push_back(sec);
+ arr.push_back(msec);
+ arr.push_back(source_file);
+ arr.push_back(source_func);
+ arr.push_back(source_line);
+ arr.push_back(error);
+ arr.push_back(error_descr);
+ arr.push_back(warning);
+ unsigned int size = callstack.size();
+ const ScriptLanguage::StackInfo *r = callstack.ptr();
+ arr.push_back(size * 3);
+ for (int i = 0; i < callstack.size(); i++) {
+ arr.push_back(r[i].file);
+ arr.push_back(r[i].func);
+ arr.push_back(r[i].line);
+ }
+ return arr;
+}
+
+bool ScriptDebuggerRemote::OutputError::deserialize(const Array &p_arr) {
+ CHECK_SIZE(p_arr, 11, "OutputError");
+ hr = p_arr[0];
+ min = p_arr[1];
+ sec = p_arr[2];
+ msec = p_arr[3];
+ source_file = p_arr[4];
+ source_func = p_arr[5];
+ source_line = p_arr[6];
+ error = p_arr[7];
+ error_descr = p_arr[8];
+ warning = p_arr[9];
+ unsigned int stack_size = p_arr[10];
+ CHECK_SIZE(p_arr, stack_size, "OutputError");
+ int idx = 11;
+ callstack.resize(stack_size / 3);
+ ScriptLanguage::StackInfo *w = callstack.ptrw();
+ for (unsigned int i = 0; i < stack_size / 3; i++) {
+ w[i].file = p_arr[idx];
+ w[i].func = p_arr[idx + 1];
+ w[i].line = p_arr[idx + 2];
+ idx += 3;
+ }
+ CHECK_END(p_arr, idx, "OutputError");
+ return true;
+}
+
+Array ScriptDebuggerRemote::ResourceUsage::serialize() {
+ infos.sort();
+
+ Array arr;
+ arr.push_back(infos.size() * 4);
+ for (List<ResourceInfo>::Element *E = infos.front(); E; E = E->next()) {
+ arr.push_back(E->get().path);
+ arr.push_back(E->get().format);
+ arr.push_back(E->get().type);
+ arr.push_back(E->get().vram);
+ }
+ return arr;
+}
+
+bool ScriptDebuggerRemote::ResourceUsage::deserialize(const Array &p_arr) {
+ CHECK_SIZE(p_arr, 1, "ResourceUsage");
+ uint32_t size = p_arr[0];
+ CHECK_SIZE(p_arr, size, "ResourceUsage");
+ int idx = 1;
+ for (uint32_t i = 0; i < size / 4; i++) {
+ ResourceInfo info;
+ info.path = p_arr[idx];
+ info.format = p_arr[idx + 1];
+ info.type = p_arr[idx + 2];
+ info.vram = p_arr[idx + 3];
+ infos.push_back(info);
+ }
+ CHECK_END(p_arr, idx, "ResourceUsage");
+ return true;
+}
+
+Array ScriptDebuggerRemote::ProfilerSignature::serialize() {
+ Array arr;
+ arr.push_back(name);
+ arr.push_back(id);
+ return arr;
+}
+
+bool ScriptDebuggerRemote::ProfilerSignature::deserialize(const Array &p_arr) {
+ CHECK_SIZE(p_arr, 2, "ProfilerSignature");
+ name = p_arr[0];
+ id = p_arr[1];
+ CHECK_END(p_arr, 2, "ProfilerSignature");
+ return true;
+}
+
+Array ScriptDebuggerRemote::ProfilerFrame::serialize() {
+ Array arr;
+ arr.push_back(frame_number);
+ arr.push_back(frame_time);
+ arr.push_back(idle_time);
+ arr.push_back(physics_time);
+ arr.push_back(physics_frame_time);
+ arr.push_back(USEC_TO_SEC(script_time));
+
+ arr.push_back(frames_data.size());
+ arr.push_back(frame_functions.size() * 4);
+
+ // Servers profiling info.
+ for (int i = 0; i < frames_data.size(); i++) {
+ arr.push_back(frames_data[i].name); // Type (physics/process/audio/...)
+ arr.push_back(frames_data[i].data.size());
+ for (int j = 0; j < frames_data[i].data.size() / 2; j++) {
+ arr.push_back(frames_data[i].data[2 * j]); // NAME
+ arr.push_back(frames_data[i].data[2 * j + 1]); // TIME
+ }
+ }
+ for (int i = 0; i < frame_functions.size(); i++) {
+ arr.push_back(frame_functions[i].sig_id);
+ arr.push_back(frame_functions[i].call_count);
+ arr.push_back(frame_functions[i].self_time);
+ arr.push_back(frame_functions[i].total_time);
+ }
+ return arr;
+}
+
+bool ScriptDebuggerRemote::ProfilerFrame::deserialize(const Array &p_arr) {
+ CHECK_SIZE(p_arr, 8, "ProfilerFrame");
+ frame_number = p_arr[0];
+ frame_time = p_arr[1];
+ idle_time = p_arr[2];
+ physics_time = p_arr[3];
+ physics_frame_time = p_arr[4];
+ script_time = p_arr[5];
+ uint32_t frame_data_size = p_arr[6];
+ int frame_func_size = p_arr[7];
+ int idx = 8;
+ while (frame_data_size) {
+ CHECK_SIZE(p_arr, idx + 2, "ProfilerFrame");
+ frame_data_size--;
+ FrameData fd;
+ fd.name = p_arr[idx];
+ int sub_data_size = p_arr[idx + 1];
+ idx += 2;
+ CHECK_SIZE(p_arr, idx + sub_data_size, "ProfilerFrame");
+ for (int j = 0; j < sub_data_size / 2; j++) {
+ fd.data.push_back(p_arr[idx]); // NAME
+ fd.data.push_back(p_arr[idx + 1]); // TIME
+ idx += 2;
+ }
+ frames_data.push_back(fd);
+ }
+ CHECK_SIZE(p_arr, idx + frame_func_size, "ProfilerFrame");
+ for (int i = 0; i < frame_func_size / 4; i++) {
+ FrameFunction ff;
+ ff.sig_id = p_arr[idx];
+ ff.call_count = p_arr[idx + 1];
+ ff.self_time = p_arr[idx + 2];
+ ff.total_time = p_arr[idx + 3];
+ frame_functions.push_back(ff);
+ idx += 4;
+ }
+ CHECK_END(p_arr, idx, "ProfilerFrame");
+ return true;
+}
+
+Array ScriptDebuggerRemote::NetworkProfilerFrame::serialize() {
+ Array arr;
+ arr.push_back(infos.size() * 6);
+ for (int i = 0; i < infos.size(); ++i) {
+ arr.push_back(uint64_t(infos[i].node));
+ arr.push_back(infos[i].node_path);
+ arr.push_back(infos[i].incoming_rpc);
+ arr.push_back(infos[i].incoming_rset);
+ arr.push_back(infos[i].outgoing_rpc);
+ arr.push_back(infos[i].outgoing_rset);
+ }
+ return arr;
+}
+
+bool ScriptDebuggerRemote::NetworkProfilerFrame::deserialize(const Array &p_arr) {
+ CHECK_SIZE(p_arr, 1, "NetworkProfilerFrame");
+ uint32_t size = p_arr[0];
+ CHECK_SIZE(p_arr, size, "NetworkProfilerFrame");
+ infos.resize(size);
+ int idx = 1;
+ for (uint32_t i = 0; i < size / 6; ++i) {
+ infos.write[i].node = uint64_t(p_arr[idx]);
+ infos.write[i].node_path = p_arr[idx + 1];
+ infos.write[i].incoming_rpc = p_arr[idx + 2];
+ infos.write[i].incoming_rset = p_arr[idx + 3];
+ infos.write[i].outgoing_rpc = p_arr[idx + 4];
+ infos.write[i].outgoing_rset = p_arr[idx + 5];
+ }
+ CHECK_END(p_arr, idx, "NetworkProfilerFrame");
+ return true;
+}
+
+void ScriptDebuggerRemote::_put_msg(String p_message, Array p_data) {
+ Array msg;
+ msg.push_back(p_message);
+ msg.push_back(p_data);
+ packet_peer_stream->put_var(msg);
+}
+
+bool ScriptDebuggerRemote::is_peer_connected() {
+ return tcp_client->is_connected_to_host() && tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED;
+}
+
+void ScriptDebuggerRemote::_send_video_memory() {
+
+ ResourceUsage usage;
+ if (resource_usage_func)
+ resource_usage_func(&usage);
+
+ _put_msg("message:video_mem", usage.serialize());
+}
+
+Error ScriptDebuggerRemote::connect_to_host(const String &p_host, uint16_t p_port) {
+
+ IP_Address ip;
+ if (p_host.is_valid_ip_address())
+ ip = p_host;
+ else
+ ip = IP::get_singleton()->resolve_hostname(p_host);
+
+ int port = p_port;
+
+ const int tries = 6;
+ int waits[tries] = { 1, 10, 100, 1000, 1000, 1000 };
+
+ tcp_client->connect_to_host(ip, port);
+
+ for (int i = 0; i < tries; i++) {
+
+ if (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED) {
+ print_verbose("Remote Debugger: Connected!");
+ break;
+ } else {
+
+ const int ms = waits[i];
+ OS::get_singleton()->delay_usec(ms * 1000);
+ print_verbose("Remote Debugger: Connection failed with status: '" + String::num(tcp_client->get_status()) + "', retrying in " + String::num(ms) + " msec.");
+ };
+ };
+
+ if (tcp_client->get_status() != StreamPeerTCP::STATUS_CONNECTED) {
+
+ ERR_PRINT("Remote Debugger: Unable to connect. Status: " + String::num(tcp_client->get_status()) + ".");
+ return FAILED;
+ };
+
+ packet_peer_stream->set_stream_peer(tcp_client);
+ Array msg;
+ msg.push_back(OS::get_singleton()->get_process_id());
+ send_message("set_pid", msg);
+
+ return OK;
+}
+
+void ScriptDebuggerRemote::_parse_message(const String p_command, const Array &p_data, ScriptLanguage *p_script) {
+
+ if (p_command == "request_video_mem") {
+ _send_video_memory();
+
+ } else if (p_command == "start_profiling") {
+ ERR_FAIL_COND(p_data.size() < 1);
+
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ ScriptServer::get_language(i)->profiling_start();
+ }
+
+ max_frame_functions = p_data[0];
+ profiler_function_signature_map.clear();
+ profiling = true;
+ frame_time = 0;
+ idle_time = 0;
+ physics_time = 0;
+ physics_frame_time = 0;
+ print_line("PROFILING ALRIGHT!");
+
+ } else if (p_command == "stop_profiling") {
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ ScriptServer::get_language(i)->profiling_stop();
+ }
+ profiling = false;
+ _send_profiling_data(false);
+ print_line("PROFILING END!");
+
+ } else if (p_command == "start_visual_profiling") {
+
+ visual_profiling = true;
+ VS::get_singleton()->set_frame_profiling_enabled(true);
+ } else if (p_command == "stop_visual_profiling") {
+
+ visual_profiling = false;
+ VS::get_singleton()->set_frame_profiling_enabled(false);
+
+ } else if (p_command == "start_network_profiling") {
+
+ network_profiling = true;
+ multiplayer->profiling_start();
+
+ } else if (p_command == "stop_network_profiling") {
+
+ network_profiling = false;
+ multiplayer->profiling_end();
+
+ } else if (p_command == "reload_scripts") {
+ reload_all_scripts = true;
+
+ } else if (p_command == "breakpoint") {
+ ERR_FAIL_COND(p_data.size() < 3);
+ bool set = p_data[2];
+ if (set)
+ insert_breakpoint(p_data[1], p_data[0]);
+ else
+ remove_breakpoint(p_data[1], p_data[0]);
+
+ } else if (p_command == "set_skip_breakpoints") {
+ ERR_FAIL_COND(p_data.size() < 1);
+ skip_breakpoints = p_data[0];
+
+ } else if (p_command == "get_stack_dump") {
+ ERR_FAIL_COND(!p_script);
+ ScriptStackDump dump;
+ int slc = p_script->debug_get_stack_level_count();
+ for (int i = 0; i < slc; i++) {
+ ScriptLanguage::StackInfo frame;
+ frame.file = p_script->debug_get_stack_level_source(i);
+ frame.line = p_script->debug_get_stack_level_line(i);
+ frame.func = p_script->debug_get_stack_level_function(i);
+ dump.frames.push_back(frame);
+ }
+ _put_msg("stack_dump", dump.serialize());
+
+ } else if (p_command == "get_stack_frame_vars") {
+ ERR_FAIL_COND(p_data.size() != 1);
+ ERR_FAIL_COND(!p_script);
+ int lv = p_data[0];
+
+ List<String> members;
+ List<Variant> member_vals;
+ if (ScriptInstance *inst = p_script->debug_get_stack_level_instance(lv)) {
+ members.push_back("self");
+ member_vals.push_back(inst->get_owner());
+ }
+ p_script->debug_get_stack_level_members(lv, &members, &member_vals);
+ ERR_FAIL_COND(members.size() != member_vals.size());
+
+ List<String> locals;
+ List<Variant> local_vals;
+ p_script->debug_get_stack_level_locals(lv, &locals, &local_vals);
+ ERR_FAIL_COND(locals.size() != local_vals.size());
+
+ List<String> globals;
+ List<Variant> globals_vals;
+ p_script->debug_get_globals(&globals, &globals_vals);
+ ERR_FAIL_COND(globals.size() != globals_vals.size());
+
+ _put_msg("stack_frame_vars", Array());
+
+ ScriptStackVariable stvar;
+ { //locals
+ List<String>::Element *E = locals.front();
+ List<Variant>::Element *F = local_vals.front();
+ while (E) {
+ stvar.name = E->get();
+ stvar.value = F->get();
+ stvar.type = 0;
+ _put_msg("stack_frame_var", stvar.serialize());
+
+ E = E->next();
+ F = F->next();
+ }
+ }
+
+ { //members
+ List<String>::Element *E = members.front();
+ List<Variant>::Element *F = member_vals.front();
+ while (E) {
+ stvar.name = E->get();
+ stvar.value = F->get();
+ stvar.type = 1;
+ _put_msg("stack_frame_var", stvar.serialize());
+
+ E = E->next();
+ F = F->next();
+ }
+ }
+
+ { //globals
+ List<String>::Element *E = globals.front();
+ List<Variant>::Element *F = globals_vals.front();
+ while (E) {
+ stvar.name = E->get();
+ stvar.value = F->get();
+ stvar.type = 2;
+ _put_msg("stack_frame_var", stvar.serialize());
+
+ E = E->next();
+ F = F->next();
+ }
+ }
+
+ } else {
+ if (scene_tree_parse_func) {
+ scene_tree_parse_func(p_command, p_data);
+ }
+ // Unknown message...
+ }
+}
+
+void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue, bool p_is_error_breakpoint) {
+
+ //this function is called when there is a debugger break (bug on script)
+ //or when execution is paused from editor
+
+ if (skip_breakpoints && !p_is_error_breakpoint)
+ return;
+
+ ERR_FAIL_COND_MSG(!is_peer_connected(), "Script Debugger failed to connect, but being used anyway.");
+
+ Array msg;
+ msg.push_back(p_can_continue);
+ msg.push_back(p_script->debug_get_error());
+ _put_msg("debug_enter", msg);
+
+ skip_profile_frame = true; // to avoid super long frame time for the frame
+
+ Input::MouseMode mouse_mode = Input::get_singleton()->get_mouse_mode();
+ if (mouse_mode != Input::MOUSE_MODE_VISIBLE)
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+
+ uint64_t loop_begin_usec = 0;
+ uint64_t loop_time_sec = 0;
+ while (true) {
+ loop_begin_usec = OS::get_singleton()->get_ticks_usec();
+
+ _get_output();
+
+ if (packet_peer_stream->get_available_packet_count() > 0) {
+
+ Variant var;
+ Error err = packet_peer_stream->get_var(var);
+
+ ERR_CONTINUE(err != OK);
+ ERR_CONTINUE(var.get_type() != Variant::ARRAY);
+
+ Array cmd = var;
+
+ ERR_CONTINUE(cmd.size() != 2);
+ ERR_CONTINUE(cmd[0].get_type() != Variant::STRING);
+ ERR_CONTINUE(cmd[1].get_type() != Variant::ARRAY);
+
+ String command = cmd[0];
+ Array data = cmd[1];
+ if (command == "step") {
+
+ set_depth(-1);
+ set_lines_left(1);
+ break;
+ } else if (command == "next") {
+
+ set_depth(0);
+ set_lines_left(1);
+ break;
+
+ } else if (command == "continue") {
+ set_depth(-1);
+ set_lines_left(-1);
+ OS::get_singleton()->move_window_to_foreground();
+ break;
+ } else if (command == "break") {
+ ERR_PRINT("Got break when already broke!");
+ break;
+ }
+
+ _parse_message(command, data, p_script);
+ } else {
+ OS::get_singleton()->delay_usec(10000);
+ OS::get_singleton()->process_and_drop_events();
+ }
+
+ // This is for the camera override to stay live even when the game is paused from the editor
+ loop_time_sec = (OS::get_singleton()->get_ticks_usec() - loop_begin_usec) / 1000000.0f;
+ VisualServer::get_singleton()->sync();
+ if (VisualServer::get_singleton()->has_changed()) {
+ VisualServer::get_singleton()->draw(true, loop_time_sec * Engine::get_singleton()->get_time_scale());
+ }
+ }
+
+ _put_msg("debug_exit", Array());
+
+ if (mouse_mode != Input::MOUSE_MODE_VISIBLE)
+ Input::get_singleton()->set_mouse_mode(mouse_mode);
+}
+
+void ScriptDebuggerRemote::_get_output() {
+
+ MutexLock lock(mutex);
+
+ if (output_strings.size()) {
+
+ locking = true;
+
+ while (output_strings.size()) {
+
+ Array arr;
+ arr.push_back(output_strings.front()->get());
+ _put_msg("output", arr);
+ output_strings.pop_front();
+ }
+ locking = false;
+ }
+
+ if (n_messages_dropped > 0) {
+ Message msg;
+ msg.message = "Too many messages! " + String::num_int64(n_messages_dropped) + " messages were dropped.";
+ messages.push_back(msg);
+ n_messages_dropped = 0;
+ }
+
+ while (messages.size()) {
+ locking = true;
+ Message msg = messages.front()->get();
+ _put_msg("message:" + msg.message, msg.data);
+ messages.pop_front();
+ locking = false;
+ }
+
+ if (n_errors_dropped == 1) {
+ // Only print one message about dropping per second
+ OutputError oe;
+ oe.error = "TOO_MANY_ERRORS";
+ oe.error_descr = "Too many errors! Ignoring errors for up to 1 second.";
+ oe.warning = false;
+ uint64_t time = OS::get_singleton()->get_ticks_msec();
+ oe.hr = time / 3600000;
+ oe.min = (time / 60000) % 60;
+ oe.sec = (time / 1000) % 60;
+ oe.msec = time % 1000;
+ errors.push_back(oe);
+ }
+
+ if (n_warnings_dropped == 1) {
+ // Only print one message about dropping per second
+ OutputError oe;
+ oe.error = "TOO_MANY_WARNINGS";
+ oe.error_descr = "Too many warnings! Ignoring warnings for up to 1 second.";
+ oe.warning = true;
+ uint64_t time = OS::get_singleton()->get_ticks_msec();
+ oe.hr = time / 3600000;
+ oe.min = (time / 60000) % 60;
+ oe.sec = (time / 1000) % 60;
+ oe.msec = time % 1000;
+ errors.push_back(oe);
+ }
+
+ while (errors.size()) {
+ locking = true;
+ OutputError oe = errors.front()->get();
+ _put_msg("error", oe.serialize());
+ errors.pop_front();
+ locking = false;
+ }
+}
+
+void ScriptDebuggerRemote::line_poll() {
+
+ //the purpose of this is just processing events every now and then when the script might get too busy
+ //otherwise bugs like infinite loops can't be caught
+ if (poll_every % 2048 == 0)
+ _poll_events();
+ poll_every++;
+}
+
+void ScriptDebuggerRemote::_err_handler(void *ud, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, ErrorHandlerType p_type) {
+
+ if (p_type == ERR_HANDLER_SCRIPT)
+ return; //ignore script errors, those go through debugger
+
+ Vector<ScriptLanguage::StackInfo> si;
+
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ si = ScriptServer::get_language(i)->debug_get_current_stack_info();
+ if (si.size())
+ break;
+ }
+
+ ScriptDebuggerRemote *sdr = (ScriptDebuggerRemote *)ud;
+ sdr->send_error(p_func, p_file, p_line, p_err, p_descr, p_type, si);
+}
+
+void ScriptDebuggerRemote::_poll_events() {
+
+ //this si called from ::idle_poll, happens only when running the game,
+ //does not get called while on debug break
+
+ while (packet_peer_stream->get_available_packet_count() > 0) {
+
+ _get_output();
+
+ //send over output_strings
+
+ Variant var;
+ Error err = packet_peer_stream->get_var(var);
+
+ ERR_CONTINUE(err != OK);
+ ERR_CONTINUE(var.get_type() != Variant::ARRAY);
+
+ Array cmd = var;
+
+ ERR_CONTINUE(cmd.size() < 2);
+ ERR_CONTINUE(cmd[0].get_type() != Variant::STRING);
+ ERR_CONTINUE(cmd[1].get_type() != Variant::ARRAY);
+
+ String command = cmd[0];
+ Array data = cmd[1];
+
+ if (command == "break") {
+
+ if (get_break_language())
+ debug(get_break_language());
+ } else {
+ _parse_message(command, data);
+ }
+ }
+}
+
+void ScriptDebuggerRemote::_send_profiling_data(bool p_for_frame) {
+
+ int ofs = 0;
+
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ if (p_for_frame)
+ ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&profile_info.write[ofs], profile_info.size() - ofs);
+ else
+ ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&profile_info.write[ofs], profile_info.size() - ofs);
+ }
+
+ for (int i = 0; i < ofs; i++) {
+ profile_info_ptrs.write[i] = &profile_info.write[i];
+ }
+
+ SortArray<ScriptLanguage::ProfilingInfo *, ProfileInfoSort> sa;
+ sa.sort(profile_info_ptrs.ptrw(), ofs);
+
+ int to_send = MIN(ofs, max_frame_functions);
+
+ //check signatures first
+ uint64_t total_script_time = 0;
+
+ for (int i = 0; i < to_send; i++) {
+
+ if (!profiler_function_signature_map.has(profile_info_ptrs[i]->signature)) {
+
+ int idx = profiler_function_signature_map.size();
+ ProfilerSignature sig;
+ sig.name = profile_info_ptrs[i]->signature;
+ sig.id = idx;
+ _put_msg("profile_sig", sig.serialize());
+ profiler_function_signature_map[profile_info_ptrs[i]->signature] = idx;
+ }
+
+ total_script_time += profile_info_ptrs[i]->self_time;
+ }
+
+ //send frames then
+ ProfilerFrame metric;
+ metric.frame_number = Engine::get_singleton()->get_frames_drawn();
+ metric.frame_time = frame_time;
+ metric.idle_time = idle_time;
+ metric.physics_time = physics_time;
+ metric.physics_frame_time = physics_frame_time;
+ metric.script_time = total_script_time;
+
+ // Add script functions information.
+ metric.frame_functions.resize(to_send);
+ FrameFunction *w = metric.frame_functions.ptrw();
+ for (int i = 0; i < to_send; i++) {
+
+ if (profiler_function_signature_map.has(profile_info_ptrs[i]->signature)) {
+ w[i].sig_id = profiler_function_signature_map[profile_info_ptrs[i]->signature];
+ }
+
+ w[i].call_count = profile_info_ptrs[i]->call_count;
+ w[i].total_time = profile_info_ptrs[i]->total_time / 1000000.0;
+ w[i].self_time = profile_info_ptrs[i]->self_time / 1000000.0;
+ }
+ if (p_for_frame) {
+ // Add profile frame data information.
+ metric.frames_data.append_array(profile_frame_data);
+ _put_msg("profile_frame", metric.serialize());
+ profile_frame_data.clear();
+ } else {
+ _put_msg("profile_total", metric.serialize());
+ }
+}
+
+void ScriptDebuggerRemote::idle_poll() {
+
+ // this function is called every frame, except when there is a debugger break (::debug() in this class)
+ // execution stops and remains in the ::debug function
+
+ _get_output();
+
+ if (requested_quit) {
+
+ _put_msg("kill_me", Array());
+ requested_quit = false;
+ }
+
+ if (performance) {
+
+ uint64_t pt = OS::get_singleton()->get_ticks_msec();
+ if (pt - last_perf_time > 1000) {
+
+ last_perf_time = pt;
+ int max = performance->get("MONITOR_MAX");
+ Array arr;
+ arr.resize(max);
+ for (int i = 0; i < max; i++) {
+ arr[i] = performance->call("get_monitor", i);
+ }
+ _put_msg("performance", arr);
+ }
+ }
+
+ if (visual_profiling) {
+ Vector<VS::FrameProfileArea> profile_areas = VS::get_singleton()->get_frame_profile();
+ if (profile_areas.size()) {
+ Vector<String> area_names;
+ Vector<real_t> area_times;
+ area_names.resize(profile_areas.size());
+ area_times.resize(profile_areas.size() * 2);
+ {
+ String *area_namesw = area_names.ptrw();
+ real_t *area_timesw = area_times.ptrw();
+
+ for (int i = 0; i < profile_areas.size(); i++) {
+ area_namesw[i] = profile_areas[i].name;
+ area_timesw[i * 2 + 0] = profile_areas[i].cpu_msec;
+ area_timesw[i * 2 + 1] = profile_areas[i].gpu_msec;
+ }
+ }
+ Array msg;
+ msg.push_back(VS::get_singleton()->get_frame_profile_frame());
+ msg.push_back(area_names);
+ msg.push_back(area_times);
+ _put_msg("visual_profile", msg);
+ }
+ }
+
+ if (profiling) {
+
+ if (skip_profile_frame) {
+ skip_profile_frame = false;
+ } else {
+ //send profiling info normally
+ _send_profiling_data(true);
+ }
+ }
+
+ if (network_profiling) {
+ uint64_t pt = OS::get_singleton()->get_ticks_msec();
+ if (pt - last_net_bandwidth_time > 200) {
+ last_net_bandwidth_time = pt;
+ _send_network_bandwidth_usage();
+ }
+ if (pt - last_net_prof_time > 100) {
+ last_net_prof_time = pt;
+ _send_network_profiling_data();
+ }
+ }
+
+ if (reload_all_scripts) {
+
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ ScriptServer::get_language(i)->reload_all_scripts();
+ }
+ reload_all_scripts = false;
+ }
+
+ _poll_events();
+}
+
+void ScriptDebuggerRemote::_send_network_profiling_data() {
+ ERR_FAIL_COND(multiplayer.is_null());
+
+ int n_nodes = multiplayer->get_profiling_frame(&network_profile_info.write[0]);
+
+ NetworkProfilerFrame frame;
+ for (int i = 0; i < n_nodes; i++) {
+ frame.infos.push_back(network_profile_info[i]);
+ }
+ _put_msg("network_profile", frame.serialize());
+}
+
+void ScriptDebuggerRemote::_send_network_bandwidth_usage() {
+ ERR_FAIL_COND(multiplayer.is_null());
+
+ int incoming_bandwidth = multiplayer->get_incoming_bandwidth_usage();
+ int outgoing_bandwidth = multiplayer->get_outgoing_bandwidth_usage();
+
+ Array arr;
+ arr.push_back(incoming_bandwidth);
+ arr.push_back(outgoing_bandwidth);
+ _put_msg("network_bandwidth", arr);
+}
+
+void ScriptDebuggerRemote::send_message(const String &p_message, const Array &p_args) {
+
+ MutexLock lock(mutex);
+
+ if (!locking && is_peer_connected()) {
+
+ if (messages.size() >= max_messages_per_frame) {
+ n_messages_dropped++;
+ } else {
+ Message msg;
+ msg.message = p_message;
+ msg.data = p_args;
+ messages.push_back(msg);
+ }
+ }
+}
+
+void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<ScriptLanguage::StackInfo> &p_stack_info) {
+
+ OutputError oe;
+ oe.error = p_err;
+ oe.error_descr = p_descr;
+ oe.source_file = p_file;
+ oe.source_line = p_line;
+ oe.source_func = p_func;
+ oe.warning = p_type == ERR_HANDLER_WARNING;
+ uint64_t time = OS::get_singleton()->get_ticks_msec();
+ oe.hr = time / 3600000;
+ oe.min = (time / 60000) % 60;
+ oe.sec = (time / 1000) % 60;
+ oe.msec = time % 1000;
+ Array cstack;
+
+ uint64_t ticks = OS::get_singleton()->get_ticks_usec() / 1000;
+ msec_count += ticks - last_msec;
+ last_msec = ticks;
+
+ if (msec_count > 1000) {
+ msec_count = 0;
+
+ err_count = 0;
+ n_errors_dropped = 0;
+ warn_count = 0;
+ n_warnings_dropped = 0;
+ }
+
+ cstack.resize(p_stack_info.size() * 3);
+ for (int i = 0; i < p_stack_info.size(); i++) {
+ cstack[i * 3 + 0] = p_stack_info[i].file;
+ cstack[i * 3 + 1] = p_stack_info[i].func;
+ cstack[i * 3 + 2] = p_stack_info[i].line;
+ }
+
+ //oe.callstack = cstack;
+ if (oe.warning) {
+ warn_count++;
+ } else {
+ err_count++;
+ }
+
+ MutexLock lock(mutex);
+
+ if (!locking && is_peer_connected()) {
+
+ if (oe.warning) {
+ if (warn_count > max_warnings_per_second) {
+ n_warnings_dropped++;
+ } else {
+ errors.push_back(oe);
+ }
+ } else {
+ if (err_count > max_errors_per_second) {
+ n_errors_dropped++;
+ } else {
+ errors.push_back(oe);
+ }
+ }
+ }
+}
+
+void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string, bool p_error) {
+
+ ScriptDebuggerRemote *sdr = (ScriptDebuggerRemote *)p_this;
+
+ uint64_t ticks = OS::get_singleton()->get_ticks_usec() / 1000;
+ sdr->msec_count += ticks - sdr->last_msec;
+ sdr->last_msec = ticks;
+
+ if (sdr->msec_count > 1000) {
+ sdr->char_count = 0;
+ sdr->msec_count = 0;
+ }
+
+ String s = p_string;
+ int allowed_chars = MIN(MAX(sdr->max_cps - sdr->char_count, 0), s.length());
+
+ if (allowed_chars == 0)
+ return;
+
+ if (allowed_chars < s.length()) {
+ s = s.substr(0, allowed_chars);
+ }
+
+ sdr->char_count += allowed_chars;
+ bool overflowed = sdr->char_count >= sdr->max_cps;
+
+ {
+ MutexLock lock(sdr->mutex);
+
+ if (!sdr->locking && sdr->is_peer_connected()) {
+
+ if (overflowed)
+ s += "[...]";
+
+ sdr->output_strings.push_back(s);
+
+ if (overflowed) {
+ sdr->output_strings.push_back("[output overflow, print less text!]");
+ }
+ }
+ }
+}
+
+void ScriptDebuggerRemote::request_quit() {
+
+ requested_quit = true;
+}
+
+void ScriptDebuggerRemote::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
+ multiplayer = p_multiplayer;
+}
+
+bool ScriptDebuggerRemote::is_profiling() const {
+
+ return profiling;
+}
+void ScriptDebuggerRemote::add_profiling_frame_data(const StringName &p_name, const Array &p_data) {
+
+ int idx = -1;
+ for (int i = 0; i < profile_frame_data.size(); i++) {
+ if (profile_frame_data[i].name == p_name) {
+ idx = i;
+ break;
+ }
+ }
+
+ FrameData fd;
+ fd.name = p_name;
+ fd.data = p_data;
+
+ if (idx == -1) {
+ profile_frame_data.push_back(fd);
+ } else {
+ profile_frame_data.write[idx] = fd;
+ }
+}
+
+void ScriptDebuggerRemote::profiling_start() {
+ //ignores this, uses it via connection
+}
+
+void ScriptDebuggerRemote::profiling_end() {
+ //ignores this, uses it via connection
+}
+
+void ScriptDebuggerRemote::profiling_set_frame_times(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time) {
+
+ frame_time = p_frame_time;
+ idle_time = p_idle_time;
+ physics_time = p_physics_time;
+ physics_frame_time = p_physics_frame_time;
+}
+
+void ScriptDebuggerRemote::set_skip_breakpoints(bool p_skip_breakpoints) {
+ skip_breakpoints = p_skip_breakpoints;
+}
+
+ScriptDebuggerRemote::ResourceUsageFunc ScriptDebuggerRemote::resource_usage_func = NULL;
+ScriptDebuggerRemote::ParseMessageFunc ScriptDebuggerRemote::scene_tree_parse_func = NULL;
+
+ScriptDebuggerRemote::ScriptDebuggerRemote() :
+ profiling(false),
+ visual_profiling(false),
+ network_profiling(false),
+ max_frame_functions(16),
+ skip_profile_frame(false),
+ reload_all_scripts(false),
+ tcp_client(Ref<StreamPeerTCP>(memnew(StreamPeerTCP))),
+ packet_peer_stream(Ref<PacketPeerStream>(memnew(PacketPeerStream))),
+ last_perf_time(0),
+ last_net_prof_time(0),
+ last_net_bandwidth_time(0),
+ performance(Engine::get_singleton()->get_singleton_object("Performance")),
+ requested_quit(false),
+ max_messages_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_messages_per_frame")),
+ n_messages_dropped(0),
+ max_errors_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_second")),
+ max_warnings_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_warnings_per_second")),
+ n_errors_dropped(0),
+ max_cps(GLOBAL_GET("network/limits/debugger_stdout/max_chars_per_second")),
+ char_count(0),
+ err_count(0),
+ warn_count(0),
+ last_msec(0),
+ msec_count(0),
+ locking(false),
+ poll_every(0) {
+
+ packet_peer_stream->set_stream_peer(tcp_client);
+ packet_peer_stream->set_output_buffer_max_size((1024 * 1024 * 8) - 4); // 8 MiB should be way more than enough, minus 4 bytes for separator.
+
+ phl.printfunc = _print_handler;
+ phl.userdata = this;
+ add_print_handler(&phl);
+
+ eh.errfunc = _err_handler;
+ eh.userdata = this;
+ add_error_handler(&eh);
+
+ profile_info.resize(GLOBAL_GET("debug/settings/profiler/max_functions"));
+ network_profile_info.resize(GLOBAL_GET("debug/settings/profiler/max_functions"));
+ profile_info_ptrs.resize(profile_info.size());
+}
+
+ScriptDebuggerRemote::~ScriptDebuggerRemote() {
+
+ remove_print_handler(&phl);
+ remove_error_handler(&eh);
+}
diff --git a/core/script_debugger_remote.h b/core/script_debugger_remote.h
new file mode 100644
index 0000000000..b7a309b2f9
--- /dev/null
+++ b/core/script_debugger_remote.h
@@ -0,0 +1,316 @@
+/*************************************************************************/
+/* script_debugger_remote.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 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 SCRIPT_DEBUGGER_REMOTE_H
+#define SCRIPT_DEBUGGER_REMOTE_H
+
+#include "core/io/packet_peer.h"
+#include "core/io/stream_peer_tcp.h"
+#include "core/list.h"
+#include "core/os/os.h"
+#include "core/script_language.h"
+
+class ScriptDebuggerRemote : public ScriptDebugger {
+
+public:
+ class ResourceInfo {
+ public:
+ String path;
+ String format;
+ String type;
+ RID id;
+ int vram;
+ bool operator<(const ResourceInfo &p_img) const { return vram == p_img.vram ? id < p_img.id : vram > p_img.vram; }
+ ResourceInfo() {
+ vram = 0;
+ }
+ };
+
+ class ResourceUsage {
+ public:
+ List<ResourceInfo> infos;
+
+ Array serialize();
+ bool deserialize(const Array &p_arr);
+ };
+
+ class FrameInfo {
+ public:
+ StringName name;
+ float self_time;
+ float total_time;
+
+ FrameInfo() {
+ self_time = 0;
+ total_time = 0;
+ }
+ };
+
+ class FrameFunction {
+ public:
+ int sig_id;
+ int call_count;
+ StringName name;
+ float self_time;
+ float total_time;
+
+ FrameFunction() {
+ sig_id = -1;
+ call_count = 0;
+ self_time = 0;
+ total_time = 0;
+ }
+ };
+
+ class ScriptStackVariable {
+ public:
+ String name;
+ Variant value;
+ int type;
+ ScriptStackVariable() {
+ type = -1;
+ }
+
+ Array serialize(int max_size = 1 << 20); // 1 MiB default.
+ bool deserialize(const Array &p_arr);
+ };
+
+ class ScriptStackDump {
+ public:
+ List<ScriptLanguage::StackInfo> frames;
+ ScriptStackDump() {}
+
+ Array serialize();
+ bool deserialize(const Array &p_arr);
+ };
+
+ class Message {
+
+ public:
+ String message;
+ Array data;
+
+ Message() {}
+ };
+
+ class OutputError {
+ public:
+ int hr;
+ int min;
+ int sec;
+ int msec;
+ String source_file;
+ String source_func;
+ int source_line;
+ String error;
+ String error_descr;
+ bool warning;
+ Vector<ScriptLanguage::StackInfo> callstack;
+
+ OutputError() {
+ hr = -1;
+ min = -1;
+ sec = -1;
+ msec = -1;
+ source_line = -1;
+ warning = false;
+ }
+
+ Array serialize();
+ bool deserialize(const Array &p_arr);
+ };
+
+ struct FrameData {
+
+ StringName name;
+ Array data;
+ };
+
+ class ProfilerSignature {
+ public:
+ StringName name;
+ int id;
+
+ Array serialize();
+ bool deserialize(const Array &p_arr);
+
+ ProfilerSignature() {
+ id = -1;
+ };
+ };
+
+ class ProfilerFrame {
+ public:
+ int frame_number;
+ float frame_time;
+ float idle_time;
+ float physics_time;
+ float physics_frame_time;
+ float script_time;
+
+ Vector<FrameData> frames_data;
+ Vector<FrameFunction> frame_functions;
+
+ ProfilerFrame() {
+ frame_number = 0;
+ frame_time = 0;
+ idle_time = 0;
+ physics_time = 0;
+ physics_frame_time = 0;
+ }
+
+ Array serialize();
+ bool deserialize(const Array &p_arr);
+ };
+
+ class NetworkProfilerFrame {
+ public:
+ Vector<MultiplayerAPI::ProfilingInfo> infos;
+
+ Array serialize();
+ bool deserialize(const Array &p_arr);
+
+ NetworkProfilerFrame(){};
+ };
+
+protected:
+ struct ProfileInfoSort {
+
+ bool operator()(ScriptLanguage::ProfilingInfo *A, ScriptLanguage::ProfilingInfo *B) const {
+ return A->total_time < B->total_time;
+ }
+ };
+
+ Vector<ScriptLanguage::ProfilingInfo> profile_info;
+ Vector<ScriptLanguage::ProfilingInfo *> profile_info_ptrs;
+ Vector<MultiplayerAPI::ProfilingInfo> network_profile_info;
+
+ Map<StringName, int> profiler_function_signature_map;
+ float frame_time, idle_time, physics_time, physics_frame_time;
+
+ bool profiling;
+ bool visual_profiling;
+ bool network_profiling;
+ int max_frame_functions;
+ bool skip_profile_frame;
+ bool reload_all_scripts;
+
+ Ref<StreamPeerTCP> tcp_client;
+ Ref<PacketPeerStream> packet_peer_stream;
+
+ uint64_t last_perf_time;
+ uint64_t last_net_prof_time;
+ uint64_t last_net_bandwidth_time;
+ Object *performance;
+ bool requested_quit;
+ Mutex mutex;
+
+ List<String> output_strings;
+ List<Message> messages;
+ int max_messages_per_frame;
+ int n_messages_dropped;
+ List<OutputError> errors;
+ int max_errors_per_second;
+ int max_warnings_per_second;
+ int n_errors_dropped;
+ int n_warnings_dropped;
+
+ int max_cps;
+ int char_count;
+ int err_count;
+ int warn_count;
+ uint64_t last_msec;
+ uint64_t msec_count;
+
+ bool locking; //hack to avoid a deadloop
+ static void _print_handler(void *p_this, const String &p_string, bool p_error);
+
+ PrintHandlerList phl;
+
+ void _get_output();
+ void _poll_events();
+ uint32_t poll_every;
+
+ void _parse_message(const String p_command, const Array &p_data, ScriptLanguage *p_script = NULL);
+
+ void _set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value);
+
+ void _send_object_id(ObjectID p_id);
+ void _send_video_memory();
+
+ Ref<MultiplayerAPI> multiplayer;
+
+ ErrorHandlerList eh;
+ static void _err_handler(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type);
+
+ void _put_msg(String p_message, Array p_data);
+ void _send_profiling_data(bool p_for_frame);
+ void _send_network_profiling_data();
+ void _send_network_bandwidth_usage();
+
+ Vector<FrameData> profile_frame_data;
+
+ bool skip_breakpoints;
+
+public:
+ typedef void (*ResourceUsageFunc)(ResourceUsage *);
+ typedef Error (*ParseMessageFunc)(const String &p_name, const Array &p_msg); // Returns true if something was found (stopping propagation).
+
+ static ResourceUsageFunc resource_usage_func;
+ static ParseMessageFunc scene_tree_parse_func; // Could be made into list, extensible...
+
+ Error connect_to_host(const String &p_host, uint16_t p_port);
+ bool is_peer_connected();
+ virtual void debug(ScriptLanguage *p_script, bool p_can_continue = true, bool p_is_error_breakpoint = false);
+ virtual void idle_poll();
+ virtual void line_poll();
+
+ virtual bool is_remote() const { return true; }
+ virtual void request_quit();
+
+ virtual void send_message(const String &p_message, const Array &p_args);
+ virtual void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<ScriptLanguage::StackInfo> &p_stack_info);
+
+ virtual void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer);
+
+ virtual bool is_profiling() const;
+ virtual void add_profiling_frame_data(const StringName &p_name, const Array &p_data);
+
+ virtual void profiling_start();
+ virtual void profiling_end();
+ virtual void profiling_set_frame_times(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time);
+
+ virtual void set_skip_breakpoints(bool p_skip_breakpoints);
+
+ ScriptDebuggerRemote();
+ ~ScriptDebuggerRemote();
+};
+
+#endif // SCRIPT_DEBUGGER_REMOTE_H
diff --git a/core/script_language.cpp b/core/script_language.cpp
index 1149feac38..0b00247502 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -307,17 +307,17 @@ Variant ScriptInstance::call(const StringName &p_method, VARIANT_ARG_DECLARE) {
argc++;
}
- Variant::CallError error;
+ Callable::CallError error;
return call(p_method, argptr, argc, error);
}
void ScriptInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) {
- Variant::CallError ce;
+ Callable::CallError ce;
call(p_method, p_args, p_argcount, ce); // script may not support multilevel calls
}
void ScriptInstance::call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) {
- Variant::CallError ce;
+ Callable::CallError ce;
call(p_method, p_args, p_argcount, ce); // script may not support multilevel calls
}
diff --git a/core/script_language.h b/core/script_language.h
index 788f5d6976..48570ae546 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -197,7 +197,7 @@ public:
virtual void get_method_list(List<MethodInfo> *p_list) const = 0;
virtual bool has_method(const StringName &p_method) const = 0;
virtual Variant call(const StringName &p_method, VARIANT_ARG_LIST);
- virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) = 0;
+ virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) = 0;
virtual void call_multilevel(const StringName &p_method, VARIANT_ARG_LIST);
virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount);
@@ -313,7 +313,7 @@ public:
virtual bool supports_builtin_mode() const = 0;
virtual bool can_inherit_from_file() { return false; }
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 String make_function(const String &p_class, const String &p_name, const PackedStringArray &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; }
@@ -424,12 +424,12 @@ public:
virtual void get_method_list(List<MethodInfo> *p_list) const;
virtual bool has_method(const StringName &p_method) const;
virtual Variant call(const StringName &p_method, VARIANT_ARG_LIST) { return Variant(); }
- virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
//virtual void call_multilevel(const StringName& p_method,VARIANT_ARG_LIST) { return Variant(); }
- //virtual void call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount,Variant::CallError &r_error) { return Variant(); }
+ //virtual void call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount,Callable::CallError &r_error) { return Variant(); }
virtual void notification(int p_notification) {}
virtual Ref<Script> get_script() const { return script; }
diff --git a/core/string_name.cpp b/core/string_name.cpp
index 6f7b10c5fe..4ec9af008e 100644
--- a/core/string_name.cpp
+++ b/core/string_name.cpp
@@ -47,12 +47,10 @@ StringName _scs_create(const char *p_chr) {
}
bool StringName::configured = false;
-Mutex *StringName::lock = NULL;
+Mutex StringName::mutex;
void StringName::setup() {
- lock = Mutex::create();
-
ERR_FAIL_COND(configured);
for (int i = 0; i < STRING_TABLE_LEN; i++) {
@@ -63,7 +61,7 @@ void StringName::setup() {
void StringName::cleanup() {
- lock->lock();
+ MutexLock lock(mutex);
int lost_strings = 0;
for (int i = 0; i < STRING_TABLE_LEN; i++) {
@@ -87,9 +85,6 @@ void StringName::cleanup() {
if (lost_strings) {
print_verbose("StringName: " + itos(lost_strings) + " unclaimed string names at exit.");
}
- lock->unlock();
-
- memdelete(lock);
}
void StringName::unref() {
@@ -98,7 +93,7 @@ void StringName::unref() {
if (_data && _data->refcount.unref()) {
- lock->lock();
+ MutexLock lock(mutex);
if (_data->prev) {
_data->prev->next = _data->next;
@@ -113,7 +108,6 @@ void StringName::unref() {
_data->next->prev = _data->prev;
}
memdelete(_data);
- lock->unlock();
}
_data = NULL;
@@ -184,7 +178,7 @@ StringName::StringName(const char *p_name) {
if (!p_name || p_name[0] == 0)
return; //empty, ignore
- lock->lock();
+ MutexLock lock(mutex);
uint32_t hash = String::hash(p_name);
@@ -203,7 +197,6 @@ StringName::StringName(const char *p_name) {
if (_data) {
if (_data->refcount.ref()) {
// exists
- lock->unlock();
return;
}
}
@@ -219,8 +212,6 @@ StringName::StringName(const char *p_name) {
if (_table[idx])
_table[idx]->prev = _data;
_table[idx] = _data;
-
- lock->unlock();
}
StringName::StringName(const StaticCString &p_static_string) {
@@ -231,7 +222,7 @@ StringName::StringName(const StaticCString &p_static_string) {
ERR_FAIL_COND(!p_static_string.ptr || !p_static_string.ptr[0]);
- lock->lock();
+ MutexLock lock(mutex);
uint32_t hash = String::hash(p_static_string.ptr);
@@ -250,7 +241,6 @@ StringName::StringName(const StaticCString &p_static_string) {
if (_data) {
if (_data->refcount.ref()) {
// exists
- lock->unlock();
return;
}
}
@@ -266,8 +256,6 @@ StringName::StringName(const StaticCString &p_static_string) {
if (_table[idx])
_table[idx]->prev = _data;
_table[idx] = _data;
-
- lock->unlock();
}
StringName::StringName(const String &p_name) {
@@ -279,10 +267,9 @@ StringName::StringName(const String &p_name) {
if (p_name == String())
return;
- lock->lock();
+ MutexLock lock(mutex);
uint32_t hash = p_name.hash();
-
uint32_t idx = hash & STRING_TABLE_MASK;
_data = _table[idx];
@@ -297,7 +284,6 @@ StringName::StringName(const String &p_name) {
if (_data) {
if (_data->refcount.ref()) {
// exists
- lock->unlock();
return;
}
}
@@ -313,8 +299,6 @@ StringName::StringName(const String &p_name) {
if (_table[idx])
_table[idx]->prev = _data;
_table[idx] = _data;
-
- lock->unlock();
}
StringName StringName::search(const char *p_name) {
@@ -325,10 +309,9 @@ StringName StringName::search(const char *p_name) {
if (!p_name[0])
return StringName();
- lock->lock();
+ MutexLock lock(mutex);
uint32_t hash = String::hash(p_name);
-
uint32_t idx = hash & STRING_TABLE_MASK;
_Data *_data = _table[idx];
@@ -342,12 +325,9 @@ StringName StringName::search(const char *p_name) {
}
if (_data && _data->refcount.ref()) {
- lock->unlock();
-
return StringName(_data);
}
- lock->unlock();
return StringName(); //does not exist
}
@@ -359,7 +339,7 @@ StringName StringName::search(const CharType *p_name) {
if (!p_name[0])
return StringName();
- lock->lock();
+ MutexLock lock(mutex);
uint32_t hash = String::hash(p_name);
@@ -376,18 +356,16 @@ StringName StringName::search(const CharType *p_name) {
}
if (_data && _data->refcount.ref()) {
- lock->unlock();
return StringName(_data);
}
- lock->unlock();
return StringName(); //does not exist
}
StringName StringName::search(const String &p_name) {
ERR_FAIL_COND_V(p_name == "", StringName());
- lock->lock();
+ MutexLock lock(mutex);
uint32_t hash = p_name.hash();
@@ -404,11 +382,9 @@ StringName StringName::search(const String &p_name) {
}
if (_data && _data->refcount.ref()) {
- lock->unlock();
return StringName(_data);
}
- lock->unlock();
return StringName(); //does not exist
}
diff --git a/core/string_name.h b/core/string_name.h
index 4096b8f650..e68ab8bfa3 100644
--- a/core/string_name.h
+++ b/core/string_name.h
@@ -82,7 +82,7 @@ class StringName {
friend void register_core_types();
friend void unregister_core_types();
- static Mutex *lock;
+ static Mutex mutex;
static void setup();
static void cleanup();
static bool configured;
diff --git a/core/translation.cpp b/core/translation.cpp
index cf76de1c9e..17c23b86cd 100644
--- a/core/translation.cpp
+++ b/core/translation.cpp
@@ -794,9 +794,9 @@ static const char *locale_renames[][2] = {
///////////////////////////////////////////////
-PoolVector<String> Translation::_get_messages() const {
+Vector<String> Translation::_get_messages() const {
- PoolVector<String> msgs;
+ Vector<String> msgs;
msgs.resize(translation_map.size() * 2);
int idx = 0;
for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) {
@@ -809,9 +809,9 @@ PoolVector<String> Translation::_get_messages() const {
return msgs;
}
-PoolVector<String> Translation::_get_message_list() const {
+Vector<String> Translation::_get_message_list() const {
- PoolVector<String> msgs;
+ Vector<String> msgs;
msgs.resize(translation_map.size());
int idx = 0;
for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) {
@@ -823,12 +823,12 @@ PoolVector<String> Translation::_get_message_list() const {
return msgs;
}
-void Translation::_set_messages(const PoolVector<String> &p_messages) {
+void Translation::_set_messages(const Vector<String> &p_messages) {
int msg_count = p_messages.size();
ERR_FAIL_COND(msg_count % 2);
- PoolVector<String>::Read r = p_messages.read();
+ const String *r = p_messages.ptr();
for (int i = 0; i < msg_count; i += 2) {
@@ -898,7 +898,7 @@ void Translation::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_messages"), &Translation::_set_messages);
ClassDB::bind_method(D_METHOD("_get_messages"), &Translation::_get_messages);
- ADD_PROPERTY(PropertyInfo(Variant::POOL_STRING_ARRAY, "messages", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_messages", "_get_messages");
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "messages", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_messages", "_get_messages");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "locale"), "set_locale", "get_locale");
}
@@ -1146,12 +1146,12 @@ TranslationServer *TranslationServer::singleton = NULL;
bool TranslationServer::_load_translations(const String &p_from) {
if (ProjectSettings::get_singleton()->has_setting(p_from)) {
- PoolVector<String> translations = ProjectSettings::get_singleton()->get(p_from);
+ Vector<String> translations = ProjectSettings::get_singleton()->get(p_from);
int tcount = translations.size();
if (tcount) {
- PoolVector<String>::Read r = translations.read();
+ const String *r = translations.ptr();
for (int i = 0; i < tcount; i++) {
diff --git a/core/translation.h b/core/translation.h
index 8f56b7271d..0448ea56c5 100644
--- a/core/translation.h
+++ b/core/translation.h
@@ -42,10 +42,10 @@ class Translation : public Resource {
String locale;
Map<StringName, StringName> translation_map;
- PoolVector<String> _get_message_list() const;
+ Vector<String> _get_message_list() const;
- PoolVector<String> _get_messages() const;
- void _set_messages(const PoolVector<String> &p_messages);
+ Vector<String> _get_messages() const;
+ void _set_messages(const Vector<String> &p_messages);
protected:
static void _bind_methods();
diff --git a/core/type_info.h b/core/type_info.h
index 9ca6d7fe73..5dacf67de4 100644
--- a/core/type_info.h
+++ b/core/type_info.h
@@ -137,8 +137,8 @@ MAKE_TYPE_INFO_WITH_META(int32_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_I
MAKE_TYPE_INFO_WITH_META(uint64_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_UINT64)
MAKE_TYPE_INFO_WITH_META(int64_t, Variant::INT, GodotTypeInfo::METADATA_INT_IS_INT64)
MAKE_TYPE_INFO(wchar_t, Variant::INT)
-MAKE_TYPE_INFO_WITH_META(float, Variant::REAL, GodotTypeInfo::METADATA_REAL_IS_FLOAT)
-MAKE_TYPE_INFO_WITH_META(double, Variant::REAL, GodotTypeInfo::METADATA_REAL_IS_DOUBLE)
+MAKE_TYPE_INFO_WITH_META(float, Variant::FLOAT, GodotTypeInfo::METADATA_REAL_IS_FLOAT)
+MAKE_TYPE_INFO_WITH_META(double, Variant::FLOAT, GodotTypeInfo::METADATA_REAL_IS_DOUBLE)
MAKE_TYPE_INFO(String, Variant::STRING)
MAKE_TYPE_INFO(Vector2, Variant::VECTOR2)
@@ -151,23 +151,24 @@ MAKE_TYPE_INFO(AABB, Variant::AABB)
MAKE_TYPE_INFO(Basis, Variant::BASIS)
MAKE_TYPE_INFO(Transform, Variant::TRANSFORM)
MAKE_TYPE_INFO(Color, Variant::COLOR)
+MAKE_TYPE_INFO(StringName, Variant::STRING_NAME)
MAKE_TYPE_INFO(NodePath, Variant::NODE_PATH)
MAKE_TYPE_INFO(RID, Variant::_RID)
+MAKE_TYPE_INFO(Callable, Variant::CALLABLE)
+MAKE_TYPE_INFO(Signal, Variant::SIGNAL)
MAKE_TYPE_INFO(Dictionary, Variant::DICTIONARY)
MAKE_TYPE_INFO(Array, Variant::ARRAY)
-MAKE_TYPE_INFO(PoolByteArray, Variant::POOL_BYTE_ARRAY)
-MAKE_TYPE_INFO(PoolIntArray, Variant::POOL_INT_ARRAY)
-MAKE_TYPE_INFO(PoolRealArray, Variant::POOL_REAL_ARRAY)
-MAKE_TYPE_INFO(PoolStringArray, Variant::POOL_STRING_ARRAY)
-MAKE_TYPE_INFO(PoolVector2Array, Variant::POOL_VECTOR2_ARRAY)
-MAKE_TYPE_INFO(PoolVector3Array, Variant::POOL_VECTOR3_ARRAY)
-MAKE_TYPE_INFO(PoolColorArray, Variant::POOL_COLOR_ARRAY)
-
-MAKE_TYPE_INFO(StringName, Variant::STRING)
-MAKE_TYPE_INFO(IP_Address, Variant::STRING)
+MAKE_TYPE_INFO(PackedByteArray, Variant::PACKED_BYTE_ARRAY)
+MAKE_TYPE_INFO(PackedInt32Array, Variant::PACKED_INT32_ARRAY)
+MAKE_TYPE_INFO(PackedInt64Array, Variant::PACKED_INT64_ARRAY)
+MAKE_TYPE_INFO(PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY)
+MAKE_TYPE_INFO(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
+MAKE_TYPE_INFO(PackedStringArray, Variant::PACKED_STRING_ARRAY)
+MAKE_TYPE_INFO(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
+MAKE_TYPE_INFO(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
+MAKE_TYPE_INFO(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
-class BSP_Tree;
-MAKE_TYPE_INFO(BSP_Tree, Variant::DICTIONARY)
+MAKE_TYPE_INFO(IP_Address, Variant::STRING)
//objectID
template <>
@@ -216,21 +217,11 @@ struct GetTypeInfo<const Variant &> {
} \
};
-MAKE_TEMPLATE_TYPE_INFO(Vector, uint8_t, Variant::POOL_BYTE_ARRAY)
-MAKE_TEMPLATE_TYPE_INFO(Vector, int, Variant::POOL_INT_ARRAY)
-MAKE_TEMPLATE_TYPE_INFO(Vector, float, Variant::POOL_REAL_ARRAY)
-MAKE_TEMPLATE_TYPE_INFO(Vector, String, Variant::POOL_STRING_ARRAY)
-MAKE_TEMPLATE_TYPE_INFO(Vector, Vector2, Variant::POOL_VECTOR2_ARRAY)
-MAKE_TEMPLATE_TYPE_INFO(Vector, Vector3, Variant::POOL_VECTOR3_ARRAY)
-MAKE_TEMPLATE_TYPE_INFO(Vector, Color, Variant::POOL_COLOR_ARRAY)
-
MAKE_TEMPLATE_TYPE_INFO(Vector, Variant, Variant::ARRAY)
MAKE_TEMPLATE_TYPE_INFO(Vector, RID, Variant::ARRAY)
MAKE_TEMPLATE_TYPE_INFO(Vector, Plane, Variant::ARRAY)
-MAKE_TEMPLATE_TYPE_INFO(Vector, StringName, Variant::POOL_STRING_ARRAY)
-
-MAKE_TEMPLATE_TYPE_INFO(PoolVector, Plane, Variant::ARRAY)
-MAKE_TEMPLATE_TYPE_INFO(PoolVector, Face3, Variant::POOL_VECTOR3_ARRAY)
+MAKE_TEMPLATE_TYPE_INFO(Vector, Face3, Variant::PACKED_VECTOR3_ARRAY)
+MAKE_TEMPLATE_TYPE_INFO(Vector, StringName, Variant::PACKED_STRING_ARRAY)
template <typename T>
struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
diff --git a/core/typedefs.h b/core/typedefs.h
index 0bb80cb2dd..5376b0718a 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -335,26 +335,16 @@ struct _GlobalLock {
*/
#define CAST_INT_TO_UCHAR_PTR(ptr) ((uint8_t *)(uintptr_t)(ptr))
-/** Hint for compilers that this fallthrough in a switch is intentional.
- * Can be replaced by [[fallthrough]] annotation if we move to C++17.
- * Including conditional support for it for people who set -std=c++17
- * themselves.
- * Requires a trailing semicolon when used.
- */
-#if __cplusplus >= 201703L
-#define FALLTHROUGH [[fallthrough]]
-#elif defined(__GNUC__) && __GNUC__ >= 7
-#define FALLTHROUGH __attribute__((fallthrough))
-#elif defined(__llvm__) && __cplusplus >= 201103L && defined(__has_feature)
-#if __has_feature(cxx_attributes) && defined(__has_warning)
-#if __has_warning("-Wimplicit-fallthrough")
-#define FALLTHROUGH [[clang::fallthrough]]
-#endif
-#endif
-#endif
+// Home-made index sequence trick, so it can be used everywhere without the costly include of std::tuple.
+// https://stackoverflow.com/questions/15014096/c-index-of-type-during-variadic-template-expansion
-#ifndef FALLTHROUGH
-#define FALLTHROUGH
-#endif
+template <size_t... Is>
+struct IndexSequence {};
+
+template <size_t N, size_t... Is>
+struct BuildIndexSequence : BuildIndexSequence<N - 1, N - 1, Is...> {};
+
+template <size_t... Is>
+struct BuildIndexSequence<0, Is...> : IndexSequence<Is...> {};
#endif // TYPEDEFS_H
diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp
index 577879d448..02f460c93d 100644
--- a/core/undo_redo.cpp
+++ b/core/undo_redo.cpp
@@ -105,7 +105,7 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
action_level++;
}
-void UndoRedo::add_do_method(Object *p_object, const String &p_method, VARIANT_ARG_DECLARE) {
+void UndoRedo::add_do_method(Object *p_object, const StringName &p_method, VARIANT_ARG_DECLARE) {
VARIANT_ARGPTRS
ERR_FAIL_COND(p_object == NULL);
@@ -125,7 +125,7 @@ void UndoRedo::add_do_method(Object *p_object, const String &p_method, VARIANT_A
actions.write[current_action + 1].do_ops.push_back(do_op);
}
-void UndoRedo::add_undo_method(Object *p_object, const String &p_method, VARIANT_ARG_DECLARE) {
+void UndoRedo::add_undo_method(Object *p_object, const StringName &p_method, VARIANT_ARG_DECLARE) {
VARIANT_ARGPTRS
ERR_FAIL_COND(p_object == NULL);
@@ -149,7 +149,7 @@ void UndoRedo::add_undo_method(Object *p_object, const String &p_method, VARIANT
}
actions.write[current_action + 1].undo_ops.push_back(undo_op);
}
-void UndoRedo::add_do_property(Object *p_object, const String &p_property, const Variant &p_value) {
+void UndoRedo::add_do_property(Object *p_object, const StringName &p_property, const Variant &p_value) {
ERR_FAIL_COND(p_object == NULL);
ERR_FAIL_COND(action_level <= 0);
@@ -164,7 +164,7 @@ void UndoRedo::add_do_property(Object *p_object, const String &p_property, const
do_op.args[0] = p_value;
actions.write[current_action + 1].do_ops.push_back(do_op);
}
-void UndoRedo::add_undo_property(Object *p_object, const String &p_property, const Variant &p_value) {
+void UndoRedo::add_undo_property(Object *p_object, const StringName &p_property, const Variant &p_value) {
ERR_FAIL_COND(p_object == NULL);
ERR_FAIL_COND(action_level <= 0);
@@ -290,9 +290,9 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
}
argptrs.resize(argc);
- Variant::CallError ce;
+ Callable::CallError ce;
obj->call(op.name, (const Variant **)argptrs.ptr(), argc, ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
ERR_PRINT("Error calling method from signal '" + String(op.name) + "': " + Variant::get_call_error_text(obj, op.name, (const Variant **)argptrs.ptr(), argc, ce));
}
#ifdef TOOLS_ENABLED
@@ -431,32 +431,32 @@ UndoRedo::~UndoRedo() {
clear_history();
}
-Variant UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (p_argcount < 2) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
return Variant();
}
if (p_args[0]->get_type() != Variant::OBJECT) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
return Variant();
}
- if (p_args[1]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ if (p_args[1]->get_type() != Variant::STRING_NAME && p_args[1]->get_type() != Variant::STRING) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
- r_error.expected = Variant::STRING;
+ r_error.expected = Variant::STRING_NAME;
return Variant();
}
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
Object *object = *p_args[0];
- String method = *p_args[1];
+ StringName method = *p_args[1];
Variant v[VARIANT_ARG_MAX];
@@ -469,32 +469,32 @@ Variant UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Variant
return Variant();
}
-Variant UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+Variant UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (p_argcount < 2) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
return Variant();
}
if (p_args[0]->get_type() != Variant::OBJECT) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
return Variant();
}
- if (p_args[1]->get_type() != Variant::STRING) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ if (p_args[1]->get_type() != Variant::STRING_NAME && p_args[1]->get_type() != Variant::STRING) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
- r_error.expected = Variant::STRING;
+ r_error.expected = Variant::STRING_NAME;
return Variant();
}
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
Object *object = *p_args[0];
- String method = *p_args[1];
+ StringName method = *p_args[1];
Variant v[VARIANT_ARG_MAX];
@@ -518,7 +518,7 @@ void UndoRedo::_bind_methods() {
MethodInfo mi;
mi.name = "add_do_method";
mi.arguments.push_back(PropertyInfo(Variant::OBJECT, "object"));
- mi.arguments.push_back(PropertyInfo(Variant::STRING, "method"));
+ mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method"));
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "add_do_method", &UndoRedo::_add_do_method, mi, varray(), false);
}
@@ -527,7 +527,7 @@ void UndoRedo::_bind_methods() {
MethodInfo mi;
mi.name = "add_undo_method";
mi.arguments.push_back(PropertyInfo(Variant::OBJECT, "object"));
- mi.arguments.push_back(PropertyInfo(Variant::STRING, "method"));
+ mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method"));
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "add_undo_method", &UndoRedo::_add_undo_method, mi, varray(), false);
}
diff --git a/core/undo_redo.h b/core/undo_redo.h
index bb9a4d1642..3b91e9ce36 100644
--- a/core/undo_redo.h
+++ b/core/undo_redo.h
@@ -47,8 +47,8 @@ public:
};
typedef void (*CommitNotifyCallback)(void *p_ud, const String &p_name);
- Variant _add_do_method(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
- Variant _add_undo_method(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+ Variant _add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
+ Variant _add_undo_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
typedef void (*MethodNotifyCallback)(void *p_ud, Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE);
typedef void (*PropertyNotifyCallback)(void *p_ud, Object *p_base, const StringName &p_property, const Variant &p_value);
@@ -65,7 +65,7 @@ private:
Type type;
Ref<Resource> resref;
ObjectID object;
- String name;
+ StringName name;
Variant args[VARIANT_ARG_MAX];
};
@@ -103,10 +103,10 @@ protected:
public:
void create_action(const String &p_name = "", MergeMode p_mode = MERGE_DISABLE);
- void add_do_method(Object *p_object, const String &p_method, VARIANT_ARG_LIST);
- void add_undo_method(Object *p_object, const String &p_method, VARIANT_ARG_LIST);
- void add_do_property(Object *p_object, const String &p_property, const Variant &p_value);
- void add_undo_property(Object *p_object, const String &p_property, const Variant &p_value);
+ void add_do_method(Object *p_object, const StringName &p_method, VARIANT_ARG_LIST);
+ void add_undo_method(Object *p_object, const StringName &p_method, VARIANT_ARG_LIST);
+ void add_do_property(Object *p_object, const StringName &p_property, const Variant &p_value);
+ void add_undo_property(Object *p_object, const StringName &p_property, const Variant &p_value);
void add_do_reference(Object *p_object);
void add_undo_reference(Object *p_object);
diff --git a/core/ustring.cpp b/core/ustring.cpp
index c4543b89da..1d4d9c2dfd 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -2169,6 +2169,7 @@ int64_t String::to_int(const CharType *p_str, int p_len) {
} else {
break;
}
+ [[fallthrough]];
}
case READING_INT: {
diff --git a/core/variant.cpp b/core/variant.cpp
index c2ffe3721f..550974363b 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -57,7 +57,7 @@ String Variant::get_type_name(Variant::Type p_type) {
return "int";
} break;
- case REAL: {
+ case FLOAT: {
return "float";
@@ -72,10 +72,18 @@ String Variant::get_type_name(Variant::Type p_type) {
return "Vector2";
} break;
+ case VECTOR2I: {
+
+ return "Vector2i";
+ } break;
case RECT2: {
return "Rect2";
} break;
+ case RECT2I: {
+
+ return "Rect2i";
+ } break;
case TRANSFORM2D: {
return "Transform2D";
@@ -84,6 +92,10 @@ String Variant::get_type_name(Variant::Type p_type) {
return "Vector3";
} break;
+ case VECTOR3I: {
+
+ return "Vector3i";
+ } break;
case PLANE: {
return "Plane";
@@ -128,6 +140,19 @@ String Variant::get_type_name(Variant::Type p_type) {
return "Object";
} break;
+ case CALLABLE: {
+
+ return "Callable";
+ } break;
+ case SIGNAL: {
+
+ return "Signal";
+ } break;
+ case STRING_NAME: {
+
+ return "StringName";
+
+ } break;
case NODE_PATH: {
return "NodePath";
@@ -145,38 +170,48 @@ String Variant::get_type_name(Variant::Type p_type) {
} break;
// arrays
- case POOL_BYTE_ARRAY: {
+ case PACKED_BYTE_ARRAY: {
+
+ return "PackedByteArray";
+
+ } break;
+ case PACKED_INT32_ARRAY: {
+
+ return "PackedInt32Array";
+
+ } break;
+ case PACKED_INT64_ARRAY: {
- return "PoolByteArray";
+ return "PackedInt64Array";
} break;
- case POOL_INT_ARRAY: {
+ case PACKED_FLOAT32_ARRAY: {
- return "PoolIntArray";
+ return "PackedFloat32Array";
} break;
- case POOL_REAL_ARRAY: {
+ case PACKED_FLOAT64_ARRAY: {
- return "PoolRealArray";
+ return "PackedFloat64Array";
} break;
- case POOL_STRING_ARRAY: {
+ case PACKED_STRING_ARRAY: {
- return "PoolStringArray";
+ return "PackedStringArray";
} break;
- case POOL_VECTOR2_ARRAY: {
+ case PACKED_VECTOR2_ARRAY: {
- return "PoolVector2Array";
+ return "PackedVector2Array";
} break;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
- return "PoolVector3Array";
+ return "PackedVector3Array";
} break;
- case POOL_COLOR_ARRAY: {
+ case PACKED_COLOR_ARRAY: {
- return "PoolColorArray";
+ return "PackedColorArray";
} break;
default: {
@@ -205,7 +240,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
static const Type valid[] = {
INT,
- REAL,
+ FLOAT,
STRING,
NIL,
};
@@ -216,7 +251,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
static const Type valid[] = {
BOOL,
- REAL,
+ FLOAT,
STRING,
NIL,
};
@@ -224,7 +259,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
- case REAL: {
+ case FLOAT: {
static const Type valid[] = {
BOOL,
@@ -245,6 +280,46 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
invalid_types = invalid;
} break;
+ case VECTOR2: {
+
+ static const Type valid[] = {
+ VECTOR2I,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
+ case VECTOR2I: {
+
+ static const Type valid[] = {
+ VECTOR2,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
+ case RECT2: {
+
+ static const Type valid[] = {
+ RECT2I,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
+ case RECT2I: {
+
+ static const Type valid[] = {
+ RECT2,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
case TRANSFORM2D: {
static const Type valid[] = {
@@ -254,6 +329,27 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
+ case VECTOR3: {
+
+ static const Type valid[] = {
+ VECTOR3I,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
+ case VECTOR3I: {
+
+ static const Type valid[] = {
+ VECTOR3,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
+
case QUAT: {
static const Type valid[] = {
@@ -317,6 +413,15 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
+ case STRING_NAME: {
+
+ static const Type valid[] = {
+ STRING,
+ NIL
+ };
+
+ valid_types = valid;
+ } break;
case NODE_PATH: {
static const Type valid[] = {
@@ -329,37 +434,56 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
case ARRAY: {
static const Type valid[] = {
- POOL_BYTE_ARRAY,
- POOL_INT_ARRAY,
- POOL_STRING_ARRAY,
- POOL_REAL_ARRAY,
- POOL_COLOR_ARRAY,
- POOL_VECTOR2_ARRAY,
- POOL_VECTOR3_ARRAY,
+ PACKED_BYTE_ARRAY,
+ PACKED_INT32_ARRAY,
+ PACKED_INT64_ARRAY,
+ PACKED_FLOAT32_ARRAY,
+ PACKED_FLOAT64_ARRAY,
+ PACKED_STRING_ARRAY,
+ PACKED_COLOR_ARRAY,
+ PACKED_VECTOR2_ARRAY,
+ PACKED_VECTOR3_ARRAY,
NIL
};
valid_types = valid;
} break;
// arrays
- case POOL_BYTE_ARRAY: {
+ case PACKED_BYTE_ARRAY: {
+
+ static const Type valid[] = {
+ ARRAY,
+ NIL
+ };
+
+ valid_types = valid;
+ } break;
+ case PACKED_INT32_ARRAY: {
static const Type valid[] = {
ARRAY,
NIL
};
+ valid_types = valid;
+ } break;
+ case PACKED_INT64_ARRAY: {
+ static const Type valid[] = {
+ ARRAY,
+ NIL
+ };
valid_types = valid;
} break;
- case POOL_INT_ARRAY: {
+ case PACKED_FLOAT32_ARRAY: {
static const Type valid[] = {
ARRAY,
NIL
};
+
valid_types = valid;
} break;
- case POOL_REAL_ARRAY: {
+ case PACKED_FLOAT64_ARRAY: {
static const Type valid[] = {
ARRAY,
@@ -368,7 +492,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
- case POOL_STRING_ARRAY: {
+ case PACKED_STRING_ARRAY: {
static const Type valid[] = {
ARRAY,
@@ -376,7 +500,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
};
valid_types = valid;
} break;
- case POOL_VECTOR2_ARRAY: {
+ case PACKED_VECTOR2_ARRAY: {
static const Type valid[] = {
ARRAY,
@@ -385,7 +509,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
static const Type valid[] = {
ARRAY,
@@ -394,7 +518,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
- case POOL_COLOR_ARRAY: {
+ case PACKED_COLOR_ARRAY: {
static const Type valid[] = {
ARRAY,
@@ -452,7 +576,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
static const Type valid[] = {
INT,
- REAL,
+ FLOAT,
//STRING,
NIL,
};
@@ -463,7 +587,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
static const Type valid[] = {
BOOL,
- REAL,
+ FLOAT,
//STRING,
NIL,
};
@@ -471,7 +595,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
- case REAL: {
+ case FLOAT: {
static const Type valid[] = {
BOOL,
@@ -487,11 +611,52 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
static const Type valid[] = {
NODE_PATH,
+ STRING_NAME,
NIL
};
valid_types = valid;
} break;
+ case VECTOR2: {
+
+ static const Type valid[] = {
+ VECTOR2I,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
+ case VECTOR2I: {
+
+ static const Type valid[] = {
+ VECTOR2,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
+ case RECT2: {
+
+ static const Type valid[] = {
+ RECT2I,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
+ case RECT2I: {
+
+ static const Type valid[] = {
+ RECT2,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
case TRANSFORM2D: {
static const Type valid[] = {
@@ -501,6 +666,27 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
+ case VECTOR3: {
+
+ static const Type valid[] = {
+ VECTOR3I,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
+ case VECTOR3I: {
+
+ static const Type valid[] = {
+ VECTOR3,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
+
case QUAT: {
static const Type valid[] = {
@@ -564,6 +750,15 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
+ case STRING_NAME: {
+
+ static const Type valid[] = {
+ STRING,
+ NIL
+ };
+
+ valid_types = valid;
+ } break;
case NODE_PATH: {
static const Type valid[] = {
@@ -576,37 +771,56 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
case ARRAY: {
static const Type valid[] = {
- POOL_BYTE_ARRAY,
- POOL_INT_ARRAY,
- POOL_STRING_ARRAY,
- POOL_REAL_ARRAY,
- POOL_COLOR_ARRAY,
- POOL_VECTOR2_ARRAY,
- POOL_VECTOR3_ARRAY,
+ PACKED_BYTE_ARRAY,
+ PACKED_INT32_ARRAY,
+ PACKED_INT64_ARRAY,
+ PACKED_FLOAT32_ARRAY,
+ PACKED_FLOAT64_ARRAY,
+ PACKED_STRING_ARRAY,
+ PACKED_COLOR_ARRAY,
+ PACKED_VECTOR2_ARRAY,
+ PACKED_VECTOR3_ARRAY,
NIL
};
valid_types = valid;
} break;
// arrays
- case POOL_BYTE_ARRAY: {
+ case PACKED_BYTE_ARRAY: {
+
+ static const Type valid[] = {
+ ARRAY,
+ NIL
+ };
+
+ valid_types = valid;
+ } break;
+ case PACKED_INT32_ARRAY: {
static const Type valid[] = {
ARRAY,
NIL
};
+ valid_types = valid;
+ } break;
+ case PACKED_INT64_ARRAY: {
+ static const Type valid[] = {
+ ARRAY,
+ NIL
+ };
valid_types = valid;
} break;
- case POOL_INT_ARRAY: {
+ case PACKED_FLOAT32_ARRAY: {
static const Type valid[] = {
ARRAY,
NIL
};
+
valid_types = valid;
} break;
- case POOL_REAL_ARRAY: {
+ case PACKED_FLOAT64_ARRAY: {
static const Type valid[] = {
ARRAY,
@@ -615,7 +829,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
- case POOL_STRING_ARRAY: {
+ case PACKED_STRING_ARRAY: {
static const Type valid[] = {
ARRAY,
@@ -623,7 +837,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
};
valid_types = valid;
} break;
- case POOL_VECTOR2_ARRAY: {
+ case PACKED_VECTOR2_ARRAY: {
static const Type valid[] = {
ARRAY,
@@ -632,7 +846,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
static const Type valid[] = {
ARRAY,
@@ -641,7 +855,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
- case POOL_COLOR_ARRAY: {
+ case PACKED_COLOR_ARRAY: {
static const Type valid[] = {
ARRAY,
@@ -716,9 +930,9 @@ bool Variant::is_zero() const {
return _data._int == 0;
} break;
- case REAL: {
+ case FLOAT: {
- return _data._real == 0;
+ return _data._float == 0;
} break;
case STRING: {
@@ -733,11 +947,21 @@ bool Variant::is_zero() const {
return *reinterpret_cast<const Vector2 *>(_data._mem) == Vector2();
} break;
+ case VECTOR2I: {
+
+ return *reinterpret_cast<const Vector2i *>(_data._mem) == Vector2i();
+
+ } break;
case RECT2: {
return *reinterpret_cast<const Rect2 *>(_data._mem) == Rect2();
} break;
+ case RECT2I: {
+
+ return *reinterpret_cast<const Rect2i *>(_data._mem) == Rect2i();
+
+ } break;
case TRANSFORM2D: {
return *_data._transform2d == Transform2D();
@@ -748,6 +972,11 @@ bool Variant::is_zero() const {
return *reinterpret_cast<const Vector3 *>(_data._mem) == Vector3();
} break;
+ case VECTOR3I: {
+
+ return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i();
+
+ } break;
case PLANE: {
return *reinterpret_cast<const Plane *>(_data._mem) == Plane();
@@ -792,6 +1021,19 @@ bool Variant::is_zero() const {
return _get_obj().obj == NULL;
} break;
+ case CALLABLE: {
+
+ return reinterpret_cast<const Callable *>(_data._mem)->is_null();
+ } break;
+ case SIGNAL: {
+
+ return reinterpret_cast<const Signal *>(_data._mem)->is_null();
+ } break;
+ case STRING_NAME: {
+
+ return *reinterpret_cast<const StringName *>(_data._mem) != StringName();
+
+ } break;
case NODE_PATH: {
return reinterpret_cast<const NodePath *>(_data._mem)->is_empty();
@@ -809,39 +1051,49 @@ bool Variant::is_zero() const {
} break;
// arrays
- case POOL_BYTE_ARRAY: {
+ case PACKED_BYTE_ARRAY: {
+
+ return PackedArrayRef<uint8_t>::get_array(_data.packed_array).size() == 0;
+
+ } break;
+ case PACKED_INT32_ARRAY: {
- return reinterpret_cast<const PoolVector<uint8_t> *>(_data._mem)->size() == 0;
+ return PackedArrayRef<int32_t>::get_array(_data.packed_array).size() == 0;
} break;
- case POOL_INT_ARRAY: {
+ case PACKED_INT64_ARRAY: {
- return reinterpret_cast<const PoolVector<int> *>(_data._mem)->size() == 0;
+ return PackedArrayRef<int64_t>::get_array(_data.packed_array).size() == 0;
} break;
- case POOL_REAL_ARRAY: {
+ case PACKED_FLOAT32_ARRAY: {
- return reinterpret_cast<const PoolVector<real_t> *>(_data._mem)->size() == 0;
+ return PackedArrayRef<float>::get_array(_data.packed_array).size() == 0;
} break;
- case POOL_STRING_ARRAY: {
+ case PACKED_FLOAT64_ARRAY: {
- return reinterpret_cast<const PoolVector<String> *>(_data._mem)->size() == 0;
+ return PackedArrayRef<double>::get_array(_data.packed_array).size() == 0;
} break;
- case POOL_VECTOR2_ARRAY: {
+ case PACKED_STRING_ARRAY: {
- return reinterpret_cast<const PoolVector<Vector2> *>(_data._mem)->size() == 0;
+ return PackedArrayRef<String>::get_array(_data.packed_array).size() == 0;
} break;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR2_ARRAY: {
- return reinterpret_cast<const PoolVector<Vector3> *>(_data._mem)->size() == 0;
+ return PackedArrayRef<Vector2>::get_array(_data.packed_array).size() == 0;
} break;
- case POOL_COLOR_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
- return reinterpret_cast<const PoolVector<Color> *>(_data._mem)->size() == 0;
+ return PackedArrayRef<Vector3>::get_array(_data.packed_array).size() == 0;
+
+ } break;
+ case PACKED_COLOR_ARRAY: {
+
+ return PackedArrayRef<Color>::get_array(_data.packed_array).size() == 0;
} break;
default: {
@@ -869,9 +1121,9 @@ bool Variant::is_one() const {
return _data._int == 1;
} break;
- case REAL: {
+ case FLOAT: {
- return _data._real == 1;
+ return _data._float == 1;
} break;
case VECTOR2: {
@@ -879,16 +1131,31 @@ bool Variant::is_one() const {
return *reinterpret_cast<const Vector2 *>(_data._mem) == Vector2(1, 1);
} break;
+ case VECTOR2I: {
+
+ return *reinterpret_cast<const Vector2i *>(_data._mem) == Vector2i(1, 1);
+
+ } break;
case RECT2: {
return *reinterpret_cast<const Rect2 *>(_data._mem) == Rect2(1, 1, 1, 1);
} break;
+ case RECT2I: {
+
+ return *reinterpret_cast<const Rect2i *>(_data._mem) == Rect2i(1, 1, 1, 1);
+
+ } break;
case VECTOR3: {
return *reinterpret_cast<const Vector3 *>(_data._mem) == Vector3(1, 1, 1);
} break;
+ case VECTOR3I: {
+
+ return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(1, 1, 1);
+
+ } break;
case PLANE: {
return *reinterpret_cast<const Plane *>(_data._mem) == Plane(1, 1, 1, 1);
@@ -922,7 +1189,7 @@ void Variant::reference(const Variant &p_variant) {
case NIL:
case BOOL:
case INT:
- case REAL:
+ case FLOAT:
break;
default:
clear();
@@ -945,9 +1212,9 @@ void Variant::reference(const Variant &p_variant) {
_data._int = p_variant._data._int;
} break;
- case REAL: {
+ case FLOAT: {
- _data._real = p_variant._data._real;
+ _data._float = p_variant._data._float;
} break;
case STRING: {
@@ -959,10 +1226,18 @@ void Variant::reference(const Variant &p_variant) {
memnew_placement(_data._mem, Vector2(*reinterpret_cast<const Vector2 *>(p_variant._data._mem)));
} break;
+ case VECTOR2I: {
+
+ memnew_placement(_data._mem, Vector2i(*reinterpret_cast<const Vector2i *>(p_variant._data._mem)));
+ } break;
case RECT2: {
memnew_placement(_data._mem, Rect2(*reinterpret_cast<const Rect2 *>(p_variant._data._mem)));
} break;
+ case RECT2I: {
+
+ memnew_placement(_data._mem, Rect2i(*reinterpret_cast<const Rect2i *>(p_variant._data._mem)));
+ } break;
case TRANSFORM2D: {
_data._transform2d = memnew(Transform2D(*p_variant._data._transform2d));
@@ -971,6 +1246,10 @@ void Variant::reference(const Variant &p_variant) {
memnew_placement(_data._mem, Vector3(*reinterpret_cast<const Vector3 *>(p_variant._data._mem)));
} break;
+ case VECTOR3I: {
+
+ memnew_placement(_data._mem, Vector3i(*reinterpret_cast<const Vector3i *>(p_variant._data._mem)));
+ } break;
case PLANE: {
memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem)));
@@ -1022,6 +1301,19 @@ void Variant::reference(const Variant &p_variant) {
_get_obj().id = p_variant._get_obj().id;
} break;
+ case CALLABLE: {
+
+ memnew_placement(_data._mem, Callable(*reinterpret_cast<const Callable *>(p_variant._data._mem)));
+ } break;
+ case SIGNAL: {
+
+ memnew_placement(_data._mem, Signal(*reinterpret_cast<const Signal *>(p_variant._data._mem)));
+ } break;
+ case STRING_NAME: {
+
+ memnew_placement(_data._mem, StringName(*reinterpret_cast<const StringName *>(p_variant._data._mem)));
+
+ } break;
case NODE_PATH: {
memnew_placement(_data._mem, NodePath(*reinterpret_cast<const NodePath *>(p_variant._data._mem)));
@@ -1039,39 +1331,76 @@ void Variant::reference(const Variant &p_variant) {
} break;
// arrays
- case POOL_BYTE_ARRAY: {
+ case PACKED_BYTE_ARRAY: {
- memnew_placement(_data._mem, PoolVector<uint8_t>(*reinterpret_cast<const PoolVector<uint8_t> *>(p_variant._data._mem)));
+ _data.packed_array = static_cast<PackedArrayRef<uint8_t> *>(p_variant._data.packed_array)->reference();
+ if (!_data.packed_array) {
+ _data.packed_array = PackedArrayRef<uint8_t>::create();
+ }
} break;
- case POOL_INT_ARRAY: {
+ case PACKED_INT32_ARRAY: {
- memnew_placement(_data._mem, PoolVector<int>(*reinterpret_cast<const PoolVector<int> *>(p_variant._data._mem)));
+ _data.packed_array = static_cast<PackedArrayRef<int32_t> *>(p_variant._data.packed_array)->reference();
+ if (!_data.packed_array) {
+ _data.packed_array = PackedArrayRef<int32_t>::create();
+ }
+
+ } break;
+ case PACKED_INT64_ARRAY: {
+
+ _data.packed_array = static_cast<PackedArrayRef<int64_t> *>(p_variant._data.packed_array)->reference();
+ if (!_data.packed_array) {
+ _data.packed_array = PackedArrayRef<int64_t>::create();
+ }
+
+ } break;
+ case PACKED_FLOAT32_ARRAY: {
+
+ _data.packed_array = static_cast<PackedArrayRef<float> *>(p_variant._data.packed_array)->reference();
+ if (!_data.packed_array) {
+ _data.packed_array = PackedArrayRef<float>::create();
+ }
} break;
- case POOL_REAL_ARRAY: {
+ case PACKED_FLOAT64_ARRAY: {
- memnew_placement(_data._mem, PoolVector<real_t>(*reinterpret_cast<const PoolVector<real_t> *>(p_variant._data._mem)));
+ _data.packed_array = static_cast<PackedArrayRef<double> *>(p_variant._data.packed_array)->reference();
+ if (!_data.packed_array) {
+ _data.packed_array = PackedArrayRef<double>::create();
+ }
} break;
- case POOL_STRING_ARRAY: {
+ case PACKED_STRING_ARRAY: {
- memnew_placement(_data._mem, PoolVector<String>(*reinterpret_cast<const PoolVector<String> *>(p_variant._data._mem)));
+ _data.packed_array = static_cast<PackedArrayRef<String> *>(p_variant._data.packed_array)->reference();
+ if (!_data.packed_array) {
+ _data.packed_array = PackedArrayRef<String>::create();
+ }
} break;
- case POOL_VECTOR2_ARRAY: {
+ case PACKED_VECTOR2_ARRAY: {
- memnew_placement(_data._mem, PoolVector<Vector2>(*reinterpret_cast<const PoolVector<Vector2> *>(p_variant._data._mem)));
+ _data.packed_array = static_cast<PackedArrayRef<Vector2> *>(p_variant._data.packed_array)->reference();
+ if (!_data.packed_array) {
+ _data.packed_array = PackedArrayRef<Vector2>::create();
+ }
} break;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
- memnew_placement(_data._mem, PoolVector<Vector3>(*reinterpret_cast<const PoolVector<Vector3> *>(p_variant._data._mem)));
+ _data.packed_array = static_cast<PackedArrayRef<Vector3> *>(p_variant._data.packed_array)->reference();
+ if (!_data.packed_array) {
+ _data.packed_array = PackedArrayRef<Vector3>::create();
+ }
} break;
- case POOL_COLOR_ARRAY: {
+ case PACKED_COLOR_ARRAY: {
- memnew_placement(_data._mem, PoolVector<Color>(*reinterpret_cast<const PoolVector<Color> *>(p_variant._data._mem)));
+ _data.packed_array = static_cast<PackedArrayRef<Color> *>(p_variant._data.packed_array)->reference();
+ if (!_data.packed_array) {
+ _data.packed_array = PackedArrayRef<Color>::create();
+ }
} break;
default: {
@@ -1084,10 +1413,13 @@ void Variant::zero() {
case NIL: break;
case BOOL: this->_data._bool = false; break;
case INT: this->_data._int = 0; break;
- case REAL: this->_data._real = 0; break;
+ case FLOAT: this->_data._float = 0; break;
case VECTOR2: *reinterpret_cast<Vector2 *>(this->_data._mem) = Vector2(); break;
+ case VECTOR2I: *reinterpret_cast<Vector2i *>(this->_data._mem) = Vector2i(); break;
case RECT2: *reinterpret_cast<Rect2 *>(this->_data._mem) = Rect2(); break;
+ case RECT2I: *reinterpret_cast<Rect2i *>(this->_data._mem) = Rect2i(); break;
case VECTOR3: *reinterpret_cast<Vector3 *>(this->_data._mem) = Vector3(); break;
+ case VECTOR3I: *reinterpret_cast<Vector3i *>(this->_data._mem) = Vector3i(); break;
case PLANE: *reinterpret_cast<Plane *>(this->_data._mem) = Plane(); break;
case QUAT: *reinterpret_cast<Quat *>(this->_data._mem) = Quat(); break;
case COLOR: *reinterpret_cast<Color *>(this->_data._mem) = Color(); break;
@@ -1128,7 +1460,11 @@ void Variant::clear() {
memdelete(_data._transform);
} break;
- // misc types
+ // misc types
+ case STRING_NAME: {
+
+ reinterpret_cast<StringName *>(_data._mem)->~StringName();
+ } break;
case NODE_PATH: {
reinterpret_cast<NodePath *>(_data._mem)->~NodePath();
@@ -1149,6 +1485,14 @@ void Variant::clear() {
// not much need probably
reinterpret_cast<RID *>(_data._mem)->~RID();
} break;
+ case CALLABLE: {
+
+ reinterpret_cast<Callable *>(_data._mem)->~Callable();
+ } break;
+ case SIGNAL: {
+
+ reinterpret_cast<Signal *>(_data._mem)->~Signal();
+ } break;
case DICTIONARY: {
reinterpret_cast<Dictionary *>(_data._mem)->~Dictionary();
@@ -1158,33 +1502,41 @@ void Variant::clear() {
reinterpret_cast<Array *>(_data._mem)->~Array();
} break;
// arrays
- case POOL_BYTE_ARRAY: {
+ case PACKED_BYTE_ARRAY: {
+
+ PackedArrayRefBase::destroy(_data.packed_array);
+ } break;
+ case PACKED_INT32_ARRAY: {
- reinterpret_cast<PoolVector<uint8_t> *>(_data._mem)->~PoolVector<uint8_t>();
+ PackedArrayRefBase::destroy(_data.packed_array);
} break;
- case POOL_INT_ARRAY: {
+ case PACKED_INT64_ARRAY: {
- reinterpret_cast<PoolVector<int> *>(_data._mem)->~PoolVector<int>();
+ PackedArrayRefBase::destroy(_data.packed_array);
} break;
- case POOL_REAL_ARRAY: {
+ case PACKED_FLOAT32_ARRAY: {
- reinterpret_cast<PoolVector<real_t> *>(_data._mem)->~PoolVector<real_t>();
+ PackedArrayRefBase::destroy(_data.packed_array);
} break;
- case POOL_STRING_ARRAY: {
+ case PACKED_FLOAT64_ARRAY: {
- reinterpret_cast<PoolVector<String> *>(_data._mem)->~PoolVector<String>();
+ PackedArrayRefBase::destroy(_data.packed_array);
} break;
- case POOL_VECTOR2_ARRAY: {
+ case PACKED_STRING_ARRAY: {
- reinterpret_cast<PoolVector<Vector2> *>(_data._mem)->~PoolVector<Vector2>();
+ PackedArrayRefBase::destroy(_data.packed_array);
} break;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR2_ARRAY: {
- reinterpret_cast<PoolVector<Vector3> *>(_data._mem)->~PoolVector<Vector3>();
+ PackedArrayRefBase::destroy(_data.packed_array);
} break;
- case POOL_COLOR_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
- reinterpret_cast<PoolVector<Color> *>(_data._mem)->~PoolVector<Color>();
+ PackedArrayRefBase::destroy(_data.packed_array);
+ } break;
+ case PACKED_COLOR_ARRAY: {
+
+ PackedArrayRefBase::destroy(_data.packed_array);
} break;
default: {
} /* not needed */
@@ -1200,7 +1552,7 @@ Variant::operator signed int() const {
case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
- case REAL: return _data._real;
+ case FLOAT: return _data._float;
case STRING: return operator String().to_int();
default: {
@@ -1215,7 +1567,7 @@ Variant::operator unsigned int() const {
case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
- case REAL: return _data._real;
+ case FLOAT: return _data._float;
case STRING: return operator String().to_int();
default: {
@@ -1231,7 +1583,7 @@ Variant::operator int64_t() const {
case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
- case REAL: return _data._real;
+ case FLOAT: return _data._float;
case STRING: return operator String().to_int64();
default: {
@@ -1248,7 +1600,7 @@ Variant::operator long unsigned int() const {
case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
- case REAL: return _data._real;
+ case FLOAT: return _data._real;
case STRING: return operator String().to_int();
default: {
@@ -1267,7 +1619,7 @@ Variant::operator uint64_t() const {
case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
- case REAL: return _data._real;
+ case FLOAT: return _data._float;
case STRING: return operator String().to_int();
default: {
@@ -1279,6 +1631,8 @@ Variant::operator uint64_t() const {
Variant::operator ObjectID() const {
if (type == INT) {
return ObjectID(_data._int);
+ } else if (type == OBJECT) {
+ return _get_obj().id;
} else {
return ObjectID();
}
@@ -1292,7 +1646,7 @@ Variant::operator signed long() const {
case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
- case REAL: return _data._real;
+ case FLOAT: return _data._real;
case STRING: return operator String().to_int();
default: {
@@ -1310,7 +1664,7 @@ Variant::operator unsigned long() const {
case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
- case REAL: return _data._real;
+ case FLOAT: return _data._real;
case STRING: return operator String().to_int();
default: {
@@ -1329,7 +1683,7 @@ Variant::operator signed short() const {
case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
- case REAL: return _data._real;
+ case FLOAT: return _data._float;
case STRING: return operator String().to_int();
default: {
@@ -1344,7 +1698,7 @@ Variant::operator unsigned short() const {
case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
- case REAL: return _data._real;
+ case FLOAT: return _data._float;
case STRING: return operator String().to_int();
default: {
@@ -1359,7 +1713,7 @@ Variant::operator signed char() const {
case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
- case REAL: return _data._real;
+ case FLOAT: return _data._float;
case STRING: return operator String().to_int();
default: {
@@ -1374,7 +1728,7 @@ Variant::operator unsigned char() const {
case NIL: return 0;
case BOOL: return _data._bool ? 1 : 0;
case INT: return _data._int;
- case REAL: return _data._real;
+ case FLOAT: return _data._float;
case STRING: return operator String().to_int();
default: {
@@ -1395,7 +1749,7 @@ Variant::operator float() const {
case NIL: return 0;
case BOOL: return _data._bool ? 1.0 : 0.0;
case INT: return (float)_data._int;
- case REAL: return _data._real;
+ case FLOAT: return _data._float;
case STRING: return operator String().to_double();
default: {
@@ -1410,7 +1764,7 @@ Variant::operator double() const {
case NIL: return 0;
case BOOL: return _data._bool ? 1.0 : 0.0;
case INT: return (double)_data._int;
- case REAL: return _data._real;
+ case FLOAT: return _data._float;
case STRING: return operator String().to_double();
default: {
@@ -1421,10 +1775,13 @@ Variant::operator double() const {
Variant::operator StringName() const {
- if (type == NODE_PATH) {
- return reinterpret_cast<const NodePath *>(_data._mem)->get_sname();
+ if (type == STRING_NAME) {
+ return *reinterpret_cast<const StringName *>(_data._mem);
+ } else if (type == STRING) {
+ return *reinterpret_cast<const String *>(_data._mem);
}
- return StringName(operator String());
+
+ return StringName();
}
struct _VariantStrPair {
@@ -1450,16 +1807,19 @@ String Variant::stringify(List<const void *> &stack) const {
case NIL: return "Null";
case BOOL: return _data._bool ? "True" : "False";
case INT: return itos(_data._int);
- case REAL: return rtos(_data._real);
+ case FLOAT: return rtos(_data._float);
case STRING: return *reinterpret_cast<const String *>(_data._mem);
case VECTOR2: return "(" + operator Vector2() + ")";
+ case VECTOR2I: return "(" + operator Vector2i() + ")";
case RECT2: return "(" + operator Rect2() + ")";
+ case RECT2I: return "(" + operator Rect2i() + ")";
case TRANSFORM2D: {
Transform2D mat32 = operator Transform2D();
return "(" + Variant(mat32.elements[0]).operator String() + ", " + Variant(mat32.elements[1]).operator String() + ", " + Variant(mat32.elements[2]).operator String() + ")";
} break;
case VECTOR3: return "(" + operator Vector3() + ")";
+ case VECTOR3I: return "(" + operator Vector3i() + ")";
case PLANE:
return operator Plane();
//case QUAT:
@@ -1491,6 +1851,7 @@ String Variant::stringify(List<const void *> &stack) const {
return mtx + ")";
} break;
case TRANSFORM: return operator Transform();
+ case STRING_NAME: return operator StringName();
case NODE_PATH: return operator NodePath();
case COLOR: return String::num(operator Color().r) + "," + String::num(operator Color().g) + "," + String::num(operator Color().b) + "," + String::num(operator Color().a);
case DICTIONARY: {
@@ -1529,9 +1890,9 @@ String Variant::stringify(List<const void *> &stack) const {
return str;
} break;
- case POOL_VECTOR2_ARRAY: {
+ case PACKED_VECTOR2_ARRAY: {
- PoolVector<Vector2> vec = operator PoolVector<Vector2>();
+ Vector<Vector2> vec = operator Vector<Vector2>();
String str("[");
for (int i = 0; i < vec.size(); i++) {
@@ -1542,9 +1903,9 @@ String Variant::stringify(List<const void *> &stack) const {
str += "]";
return str;
} break;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
- PoolVector<Vector3> vec = operator PoolVector<Vector3>();
+ Vector<Vector3> vec = operator Vector<Vector3>();
String str("[");
for (int i = 0; i < vec.size(); i++) {
@@ -1555,9 +1916,9 @@ String Variant::stringify(List<const void *> &stack) const {
str += "]";
return str;
} break;
- case POOL_STRING_ARRAY: {
+ case PACKED_STRING_ARRAY: {
- PoolVector<String> vec = operator PoolVector<String>();
+ Vector<String> vec = operator Vector<String>();
String str("[");
for (int i = 0; i < vec.size(); i++) {
@@ -1568,9 +1929,9 @@ String Variant::stringify(List<const void *> &stack) const {
str += "]";
return str;
} break;
- case POOL_INT_ARRAY: {
+ case PACKED_INT32_ARRAY: {
- PoolVector<int> vec = operator PoolVector<int>();
+ Vector<int32_t> vec = operator Vector<int32_t>();
String str("[");
for (int i = 0; i < vec.size(); i++) {
@@ -1581,9 +1942,35 @@ String Variant::stringify(List<const void *> &stack) const {
str += "]";
return str;
} break;
- case POOL_REAL_ARRAY: {
+ case PACKED_INT64_ARRAY: {
- PoolVector<real_t> vec = operator PoolVector<real_t>();
+ Vector<int64_t> vec = operator Vector<int64_t>();
+ String str("[");
+ for (int i = 0; i < vec.size(); i++) {
+
+ if (i > 0)
+ str += ", ";
+ str = str + itos(vec[i]);
+ }
+ str += "]";
+ return str;
+ } break;
+ case PACKED_FLOAT32_ARRAY: {
+
+ Vector<float> vec = operator Vector<float>();
+ String str("[");
+ for (int i = 0; i < vec.size(); i++) {
+
+ if (i > 0)
+ str += ", ";
+ str = str + rtos(vec[i]);
+ }
+ str += "]";
+ return str;
+ } break;
+ case PACKED_FLOAT64_ARRAY: {
+
+ Vector<double> vec = operator Vector<double>();
String str("[");
for (int i = 0; i < vec.size(); i++) {
@@ -1627,6 +2014,18 @@ String Variant::stringify(List<const void *> &stack) const {
return "[Object:null]";
} break;
+ case CALLABLE: {
+ const Callable &c = *reinterpret_cast<const Callable *>(_data._mem);
+ return c;
+ } break;
+ case SIGNAL: {
+ const Signal &s = *reinterpret_cast<const Signal *>(_data._mem);
+ return s;
+ } break;
+ case _RID: {
+ const RID &s = *reinterpret_cast<const RID *>(_data._mem);
+ return "RID(" + itos(s.get_id()) + ")";
+ } break;
default: {
return "[" + get_type_name(type) + "]";
}
@@ -1639,28 +2038,78 @@ Variant::operator Vector2() const {
if (type == VECTOR2)
return *reinterpret_cast<const Vector2 *>(_data._mem);
+ else if (type == VECTOR2I)
+ return *reinterpret_cast<const Vector2i *>(_data._mem);
else if (type == VECTOR3)
return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y);
+ else if (type == VECTOR3I)
+ return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y);
else
return Vector2();
}
+
+Variant::operator Vector2i() const {
+
+ if (type == VECTOR2I)
+ return *reinterpret_cast<const Vector2i *>(_data._mem);
+ else if (type == VECTOR2)
+ return *reinterpret_cast<const Vector2 *>(_data._mem);
+ else if (type == VECTOR3)
+ return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y);
+ else if (type == VECTOR3I)
+ return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y);
+ else
+ return Vector2i();
+}
+
Variant::operator Rect2() const {
if (type == RECT2)
return *reinterpret_cast<const Rect2 *>(_data._mem);
+ else if (type == RECT2I)
+ return *reinterpret_cast<const Rect2i *>(_data._mem);
else
return Rect2();
}
+Variant::operator Rect2i() const {
+
+ if (type == RECT2I)
+ return *reinterpret_cast<const Rect2i *>(_data._mem);
+ else if (type == RECT2)
+ return *reinterpret_cast<const Rect2 *>(_data._mem);
+ else
+ return Rect2i();
+}
+
Variant::operator Vector3() const {
if (type == VECTOR3)
return *reinterpret_cast<const Vector3 *>(_data._mem);
+ else if (type == VECTOR3I)
+ return *reinterpret_cast<const Vector3i *>(_data._mem);
else if (type == VECTOR2)
return Vector3(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0);
+ else if (type == VECTOR2I)
+ return Vector3(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0);
else
return Vector3();
}
+
+Variant::operator Vector3i() const {
+
+ if (type == VECTOR3I)
+ return *reinterpret_cast<const Vector3i *>(_data._mem);
+ else if (type == VECTOR3)
+ return *reinterpret_cast<const Vector3 *>(_data._mem);
+ else if (type == VECTOR2)
+ return Vector3i(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0);
+ else if (type == VECTOR2I)
+ return Vector3i(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0);
+ else
+ return Vector3i();
+}
+
Variant::operator Plane() const {
if (type == PLANE)
@@ -1776,9 +2225,9 @@ Variant::operator RID() const {
ERR_FAIL_COND_V_MSG(ObjectDB::get_instance(_get_obj().id) == nullptr, RID(), "Invalid pointer (object was freed).");
};
#endif
- Variant::CallError ce;
+ Callable::CallError ce;
Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->get_rid, NULL, 0, ce);
- if (ce.error == Variant::CallError::CALL_OK && ret.get_type() == Variant::_RID) {
+ if (ce.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::_RID) {
return ret;
}
return RID();
@@ -1836,6 +2285,22 @@ Variant::operator Dictionary() const {
return Dictionary();
}
+Variant::operator Callable() const {
+
+ if (type == CALLABLE)
+ return *reinterpret_cast<const Callable *>(_data._mem);
+ else
+ return Callable();
+}
+
+Variant::operator Signal() const {
+
+ if (type == SIGNAL)
+ return *reinterpret_cast<const Signal *>(_data._mem);
+ else
+ return Signal();
+}
+
template <class DA, class SA>
inline DA _convert_array(const SA &p_array) {
@@ -1858,26 +2323,32 @@ inline DA _convert_array_from_variant(const Variant &p_variant) {
case Variant::ARRAY: {
return _convert_array<DA, Array>(p_variant.operator Array());
}
- case Variant::POOL_BYTE_ARRAY: {
- return _convert_array<DA, PoolVector<uint8_t> >(p_variant.operator PoolVector<uint8_t>());
+ case Variant::PACKED_BYTE_ARRAY: {
+ return _convert_array<DA, Vector<uint8_t> >(p_variant.operator Vector<uint8_t>());
+ }
+ case Variant::PACKED_INT32_ARRAY: {
+ return _convert_array<DA, Vector<int32_t> >(p_variant.operator Vector<int32_t>());
}
- case Variant::POOL_INT_ARRAY: {
- return _convert_array<DA, PoolVector<int> >(p_variant.operator PoolVector<int>());
+ case Variant::PACKED_INT64_ARRAY: {
+ return _convert_array<DA, Vector<int64_t> >(p_variant.operator Vector<int64_t>());
}
- case Variant::POOL_REAL_ARRAY: {
- return _convert_array<DA, PoolVector<real_t> >(p_variant.operator PoolVector<real_t>());
+ case Variant::PACKED_FLOAT32_ARRAY: {
+ return _convert_array<DA, Vector<float> >(p_variant.operator Vector<float>());
}
- case Variant::POOL_STRING_ARRAY: {
- return _convert_array<DA, PoolVector<String> >(p_variant.operator PoolVector<String>());
+ case Variant::PACKED_FLOAT64_ARRAY: {
+ return _convert_array<DA, Vector<double> >(p_variant.operator Vector<double>());
}
- case Variant::POOL_VECTOR2_ARRAY: {
- return _convert_array<DA, PoolVector<Vector2> >(p_variant.operator PoolVector<Vector2>());
+ case Variant::PACKED_STRING_ARRAY: {
+ return _convert_array<DA, Vector<String> >(p_variant.operator Vector<String>());
}
- case Variant::POOL_VECTOR3_ARRAY: {
- return _convert_array<DA, PoolVector<Vector3> >(p_variant.operator PoolVector<Vector3>());
+ case Variant::PACKED_VECTOR2_ARRAY: {
+ return _convert_array<DA, Vector<Vector2> >(p_variant.operator Vector<Vector2>());
}
- case Variant::POOL_COLOR_ARRAY: {
- return _convert_array<DA, PoolVector<Color> >(p_variant.operator PoolVector<Color>());
+ case Variant::PACKED_VECTOR3_ARRAY: {
+ return _convert_array<DA, Vector<Vector3> >(p_variant.operator Vector<Vector3>());
+ }
+ case Variant::PACKED_COLOR_ARRAY: {
+ return _convert_array<DA, Vector<Color> >(p_variant.operator Vector<Color>());
}
default: {
return DA();
@@ -1893,56 +2364,72 @@ Variant::operator Array() const {
return _convert_array_from_variant<Array>(*this);
}
-Variant::operator PoolVector<uint8_t>() const {
+Variant::operator Vector<uint8_t>() const {
+
+ if (type == PACKED_BYTE_ARRAY)
+ return static_cast<PackedArrayRef<uint8_t> *>(_data.packed_array)->array;
+ else
+ return _convert_array_from_variant<Vector<uint8_t> >(*this);
+}
+Variant::operator Vector<int32_t>() const {
+
+ if (type == PACKED_INT32_ARRAY)
+ return static_cast<PackedArrayRef<int32_t> *>(_data.packed_array)->array;
+ else
+ return _convert_array_from_variant<Vector<int> >(*this);
+}
+Variant::operator Vector<int64_t>() const {
- if (type == POOL_BYTE_ARRAY)
- return *reinterpret_cast<const PoolVector<uint8_t> *>(_data._mem);
+ if (type == PACKED_INT64_ARRAY)
+ return static_cast<PackedArrayRef<int64_t> *>(_data.packed_array)->array;
else
- return _convert_array_from_variant<PoolVector<uint8_t> >(*this);
+ return _convert_array_from_variant<Vector<int64_t> >(*this);
}
-Variant::operator PoolVector<int>() const {
- if (type == POOL_INT_ARRAY)
- return *reinterpret_cast<const PoolVector<int> *>(_data._mem);
+Variant::operator Vector<float>() const {
+
+ if (type == PACKED_FLOAT32_ARRAY)
+ return static_cast<PackedArrayRef<float> *>(_data.packed_array)->array;
else
- return _convert_array_from_variant<PoolVector<int> >(*this);
+ return _convert_array_from_variant<Vector<float> >(*this);
}
-Variant::operator PoolVector<real_t>() const {
- if (type == POOL_REAL_ARRAY)
- return *reinterpret_cast<const PoolVector<real_t> *>(_data._mem);
+Variant::operator Vector<double>() const {
+
+ if (type == PACKED_FLOAT64_ARRAY)
+ return static_cast<PackedArrayRef<double> *>(_data.packed_array)->array;
else
- return _convert_array_from_variant<PoolVector<real_t> >(*this);
+ return _convert_array_from_variant<Vector<double> >(*this);
}
-Variant::operator PoolVector<String>() const {
+Variant::operator Vector<String>() const {
- if (type == POOL_STRING_ARRAY)
- return *reinterpret_cast<const PoolVector<String> *>(_data._mem);
+ if (type == PACKED_STRING_ARRAY)
+ return static_cast<PackedArrayRef<String> *>(_data.packed_array)->array;
else
- return _convert_array_from_variant<PoolVector<String> >(*this);
+ return _convert_array_from_variant<Vector<String> >(*this);
}
-Variant::operator PoolVector<Vector3>() const {
+Variant::operator Vector<Vector3>() const {
- if (type == POOL_VECTOR3_ARRAY)
- return *reinterpret_cast<const PoolVector<Vector3> *>(_data._mem);
+ if (type == PACKED_VECTOR3_ARRAY)
+ return static_cast<PackedArrayRef<Vector3> *>(_data.packed_array)->array;
else
- return _convert_array_from_variant<PoolVector<Vector3> >(*this);
+ return _convert_array_from_variant<Vector<Vector3> >(*this);
}
-Variant::operator PoolVector<Vector2>() const {
+Variant::operator Vector<Vector2>() const {
- if (type == POOL_VECTOR2_ARRAY)
- return *reinterpret_cast<const PoolVector<Vector2> *>(_data._mem);
+ if (type == PACKED_VECTOR2_ARRAY)
+ return static_cast<PackedArrayRef<Vector2> *>(_data.packed_array)->array;
else
- return _convert_array_from_variant<PoolVector<Vector2> >(*this);
+ return _convert_array_from_variant<Vector<Vector2> >(*this);
}
-Variant::operator PoolVector<Color>() const {
+Variant::operator Vector<Color>() const {
- if (type == POOL_COLOR_ARRAY)
- return *reinterpret_cast<const PoolVector<Color> *>(_data._mem);
+ if (type == PACKED_COLOR_ARRAY)
+ return static_cast<PackedArrayRef<Color> *>(_data.packed_array)->array;
else
- return _convert_array_from_variant<PoolVector<Color> >(*this);
+ return _convert_array_from_variant<Vector<Color> >(*this);
}
/* helpers */
@@ -1957,33 +2444,16 @@ Variant::operator Vector<RID>() const {
return rids;
}
-Variant::operator Vector<Vector2>() const {
-
- PoolVector<Vector2> from = operator PoolVector<Vector2>();
- Vector<Vector2> to;
- int len = from.size();
- if (len == 0)
- return Vector<Vector2>();
- to.resize(len);
- PoolVector<Vector2>::Read r = from.read();
- Vector2 *w = to.ptrw();
- for (int i = 0; i < len; i++) {
-
- w[i] = r[i];
- }
- return to;
-}
-
-Variant::operator PoolVector<Plane>() const {
+Variant::operator Vector<Plane>() const {
Array va = operator Array();
- PoolVector<Plane> planes;
+ Vector<Plane> planes;
int va_size = va.size();
if (va_size == 0)
return planes;
planes.resize(va_size);
- PoolVector<Plane>::Write w = planes.write();
+ Plane *w = planes.ptrw();
for (int i = 0; i < va_size; i++)
w[i] = va[i];
@@ -1991,17 +2461,17 @@ Variant::operator PoolVector<Plane>() const {
return planes;
}
-Variant::operator PoolVector<Face3>() const {
+Variant::operator Vector<Face3>() const {
- PoolVector<Vector3> va = operator PoolVector<Vector3>();
- PoolVector<Face3> faces;
+ Vector<Vector3> va = operator Vector<Vector3>();
+ Vector<Face3> faces;
int va_size = va.size();
if (va_size == 0)
return faces;
faces.resize(va_size / 3);
- PoolVector<Face3>::Write w = faces.write();
- PoolVector<Vector3>::Read r = va.read();
+ Face3 *w = faces.ptrw();
+ const Vector3 *r = va.ptr();
for (int i = 0; i < va_size; i++)
w[i / 3].vertex[i % 3] = r[i];
@@ -2009,87 +2479,24 @@ Variant::operator PoolVector<Face3>() const {
return faces;
}
-Variant::operator Vector<Plane>() const {
+Variant::operator Vector<Variant>() const {
Array va = operator Array();
- Vector<Plane> planes;
+ Vector<Variant> variants;
int va_size = va.size();
if (va_size == 0)
- return planes;
-
- planes.resize(va_size);
+ return variants;
+ variants.resize(va_size);
+ Variant *w = variants.ptrw();
for (int i = 0; i < va_size; i++)
- planes.write[i] = va[i];
-
- return planes;
-}
-
-Variant::operator Vector<Variant>() const {
-
- Array from = operator Array();
- Vector<Variant> to;
- int len = from.size();
- to.resize(len);
- for (int i = 0; i < len; i++) {
-
- to.write[i] = from[i];
- }
- return to;
-}
-
-Variant::operator Vector<uint8_t>() const {
-
- PoolVector<uint8_t> from = operator PoolVector<uint8_t>();
- Vector<uint8_t> to;
- int len = from.size();
- to.resize(len);
- for (int i = 0; i < len; i++) {
-
- to.write[i] = from[i];
- }
- return to;
-}
-Variant::operator Vector<int>() const {
-
- PoolVector<int> from = operator PoolVector<int>();
- Vector<int> to;
- int len = from.size();
- to.resize(len);
- for (int i = 0; i < len; i++) {
-
- to.write[i] = from[i];
- }
- return to;
-}
-Variant::operator Vector<real_t>() const {
-
- PoolVector<real_t> from = operator PoolVector<real_t>();
- Vector<real_t> to;
- int len = from.size();
- to.resize(len);
- for (int i = 0; i < len; i++) {
-
- to.write[i] = from[i];
- }
- return to;
-}
-
-Variant::operator Vector<String>() const {
-
- PoolVector<String> from = operator PoolVector<String>();
- Vector<String> to;
- int len = from.size();
- to.resize(len);
- for (int i = 0; i < len; i++) {
+ w[i] = va[i];
- to.write[i] = from[i];
- }
- return to;
+ return variants;
}
Variant::operator Vector<StringName>() const {
- PoolVector<String> from = operator PoolVector<String>();
+ Vector<String> from = operator Vector<String>();
Vector<StringName> to;
int len = from.size();
to.resize(len);
@@ -2100,39 +2507,6 @@ Variant::operator Vector<StringName>() const {
return to;
}
-Variant::operator Vector<Vector3>() const {
-
- PoolVector<Vector3> from = operator PoolVector<Vector3>();
- Vector<Vector3> to;
- int len = from.size();
- if (len == 0)
- return Vector<Vector3>();
- to.resize(len);
- PoolVector<Vector3>::Read r = from.read();
- Vector3 *w = to.ptrw();
- for (int i = 0; i < len; i++) {
-
- w[i] = r[i];
- }
- return to;
-}
-Variant::operator Vector<Color>() const {
-
- PoolVector<Color> from = operator PoolVector<Color>();
- Vector<Color> to;
- int len = from.size();
- if (len == 0)
- return Vector<Color>();
- to.resize(len);
- PoolVector<Color>::Read r = from.read();
- Color *w = to.ptrw();
- for (int i = 0; i < len; i++) {
-
- w[i] = r[i];
- }
- return to;
-}
-
Variant::operator Margin() const {
return (Margin) operator int();
@@ -2144,9 +2518,9 @@ Variant::operator Orientation() const {
Variant::operator IP_Address() const {
- if (type == POOL_REAL_ARRAY || type == POOL_INT_ARRAY || type == POOL_BYTE_ARRAY) {
+ if (type == PACKED_FLOAT32_ARRAY || type == PACKED_INT32_ARRAY || type == PACKED_FLOAT64_ARRAY || type == PACKED_INT64_ARRAY || type == PACKED_BYTE_ARRAY) {
- PoolVector<int> addr = operator PoolVector<int>();
+ Vector<int> addr = operator Vector<int>();
if (addr.size() == 4) {
return IP_Address(addr.get(0), addr.get(1), addr.get(2), addr.get(3));
}
@@ -2228,13 +2602,13 @@ Variant::Variant(unsigned char p_char) {
}
Variant::Variant(float p_float) {
- type = REAL;
- _data._real = p_float;
+ type = FLOAT;
+ _data._float = p_float;
}
Variant::Variant(double p_double) {
- type = REAL;
- _data._real = p_double;
+ type = FLOAT;
+ _data._float = p_double;
}
Variant::Variant(const ObjectID &p_id) {
@@ -2244,8 +2618,8 @@ Variant::Variant(const ObjectID &p_id) {
Variant::Variant(const StringName &p_string) {
- type = STRING;
- memnew_placement(_data._mem, String(p_string.operator String()));
+ type = STRING_NAME;
+ memnew_placement(_data._mem, StringName(p_string));
}
Variant::Variant(const String &p_string) {
@@ -2269,17 +2643,36 @@ Variant::Variant(const Vector3 &p_vector3) {
type = VECTOR3;
memnew_placement(_data._mem, Vector3(p_vector3));
}
+Variant::Variant(const Vector3i &p_vector3i) {
+
+ type = VECTOR3I;
+ memnew_placement(_data._mem, Vector3i(p_vector3i));
+}
+
Variant::Variant(const Vector2 &p_vector2) {
type = VECTOR2;
memnew_placement(_data._mem, Vector2(p_vector2));
}
+
+Variant::Variant(const Vector2i &p_vector2i) {
+
+ type = VECTOR2I;
+ memnew_placement(_data._mem, Vector2i(p_vector2i));
+}
+
Variant::Variant(const Rect2 &p_rect2) {
type = RECT2;
memnew_placement(_data._mem, Rect2(p_rect2));
}
+Variant::Variant(const Rect2i &p_rect2i) {
+
+ type = RECT2I;
+ memnew_placement(_data._mem, Rect2i(p_rect2i));
+}
+
Variant::Variant(const Plane &p_plane) {
type = PLANE;
@@ -2356,6 +2749,17 @@ Variant::Variant(const Object *p_object) {
}
}
+Variant::Variant(const Callable &p_callable) {
+
+ type = CALLABLE;
+ memnew_placement(_data._mem, Callable(p_callable));
+}
+Variant::Variant(const Signal &p_callable) {
+
+ type = SIGNAL;
+ memnew_placement(_data._mem, Signal(p_callable));
+}
+
Variant::Variant(const Dictionary &p_dictionary) {
type = DICTIONARY;
@@ -2368,20 +2772,6 @@ Variant::Variant(const Array &p_array) {
memnew_placement(_data._mem, Array(p_array));
}
-Variant::Variant(const PoolVector<Plane> &p_array) {
-
- type = ARRAY;
-
- Array *plane_array = memnew_placement(_data._mem, Array);
-
- plane_array->resize(p_array.size());
-
- for (int i = 0; i < p_array.size(); i++) {
-
- plane_array->operator[](i) = Variant(p_array[i]);
- }
-}
-
Variant::Variant(const Vector<Plane> &p_array) {
type = ARRAY;
@@ -2410,68 +2800,67 @@ Variant::Variant(const Vector<RID> &p_array) {
}
}
-Variant::Variant(const Vector<Vector2> &p_array) {
+Variant::Variant(const Vector<uint8_t> &p_byte_array) {
- type = NIL;
- PoolVector<Vector2> v;
- int len = p_array.size();
- if (len > 0) {
- v.resize(len);
- PoolVector<Vector2>::Write w = v.write();
- const Vector2 *r = p_array.ptr();
+ type = PACKED_BYTE_ARRAY;
- for (int i = 0; i < len; i++)
- w[i] = r[i];
- }
- *this = v;
+ _data.packed_array = PackedArrayRef<uint8_t>::create(p_byte_array);
+}
+Variant::Variant(const Vector<int32_t> &p_int32_array) {
+
+ type = PACKED_INT32_ARRAY;
+ _data.packed_array = PackedArrayRef<int32_t>::create(p_int32_array);
}
-Variant::Variant(const PoolVector<uint8_t> &p_raw_array) {
+Variant::Variant(const Vector<int64_t> &p_int64_array) {
- type = POOL_BYTE_ARRAY;
- memnew_placement(_data._mem, PoolVector<uint8_t>(p_raw_array));
+ type = PACKED_INT64_ARRAY;
+ _data.packed_array = PackedArrayRef<int64_t>::create(p_int64_array);
}
-Variant::Variant(const PoolVector<int> &p_int_array) {
- type = POOL_INT_ARRAY;
- memnew_placement(_data._mem, PoolVector<int>(p_int_array));
+Variant::Variant(const Vector<float> &p_float32_array) {
+
+ type = PACKED_FLOAT32_ARRAY;
+ _data.packed_array = PackedArrayRef<float>::create(p_float32_array);
}
-Variant::Variant(const PoolVector<real_t> &p_real_array) {
- type = POOL_REAL_ARRAY;
- memnew_placement(_data._mem, PoolVector<real_t>(p_real_array));
+Variant::Variant(const Vector<double> &p_float64_array) {
+
+ type = PACKED_FLOAT64_ARRAY;
+ _data.packed_array = PackedArrayRef<double>::create(p_float64_array);
}
-Variant::Variant(const PoolVector<String> &p_string_array) {
- type = POOL_STRING_ARRAY;
- memnew_placement(_data._mem, PoolVector<String>(p_string_array));
+Variant::Variant(const Vector<String> &p_string_array) {
+
+ type = PACKED_STRING_ARRAY;
+ _data.packed_array = PackedArrayRef<String>::create(p_string_array);
}
-Variant::Variant(const PoolVector<Vector3> &p_vector3_array) {
+Variant::Variant(const Vector<Vector3> &p_vector3_array) {
- type = POOL_VECTOR3_ARRAY;
- memnew_placement(_data._mem, PoolVector<Vector3>(p_vector3_array));
+ type = PACKED_VECTOR3_ARRAY;
+ _data.packed_array = PackedArrayRef<Vector3>::create(p_vector3_array);
}
-Variant::Variant(const PoolVector<Vector2> &p_vector2_array) {
+Variant::Variant(const Vector<Vector2> &p_vector2_array) {
- type = POOL_VECTOR2_ARRAY;
- memnew_placement(_data._mem, PoolVector<Vector2>(p_vector2_array));
+ type = PACKED_VECTOR2_ARRAY;
+ _data.packed_array = PackedArrayRef<Vector2>::create(p_vector2_array);
}
-Variant::Variant(const PoolVector<Color> &p_color_array) {
+Variant::Variant(const Vector<Color> &p_color_array) {
- type = POOL_COLOR_ARRAY;
- memnew_placement(_data._mem, PoolVector<Color>(p_color_array));
+ type = PACKED_COLOR_ARRAY;
+ _data.packed_array = PackedArrayRef<Color>::create(p_color_array);
}
-Variant::Variant(const PoolVector<Face3> &p_face_array) {
+Variant::Variant(const Vector<Face3> &p_face_array) {
- PoolVector<Vector3> vertices;
+ Vector<Vector3> vertices;
int face_count = p_face_array.size();
vertices.resize(face_count * 3);
if (face_count) {
- PoolVector<Face3>::Read r = p_face_array.read();
- PoolVector<Vector3>::Write w = vertices.write();
+ const Face3 *r = p_face_array.ptr();
+ Vector3 *w = vertices.ptrw();
for (int i = 0; i < face_count; i++) {
@@ -2486,93 +2875,20 @@ Variant::Variant(const PoolVector<Face3> &p_face_array) {
}
/* helpers */
-
Variant::Variant(const Vector<Variant> &p_array) {
-
- type = NIL;
- Array v;
- int len = p_array.size();
- v.resize(len);
- for (int i = 0; i < len; i++)
- v.set(i, p_array[i]);
- *this = v;
-}
-
-Variant::Variant(const Vector<uint8_t> &p_array) {
-
- type = NIL;
- PoolVector<uint8_t> v;
- int len = p_array.size();
- v.resize(len);
- for (int i = 0; i < len; i++)
- v.set(i, p_array[i]);
- *this = v;
-}
-
-Variant::Variant(const Vector<int> &p_array) {
-
- type = NIL;
- PoolVector<int> v;
- int len = p_array.size();
- v.resize(len);
- for (int i = 0; i < len; i++)
- v.set(i, p_array[i]);
- *this = v;
-}
-
-Variant::Variant(const Vector<real_t> &p_array) {
-
- type = NIL;
- PoolVector<real_t> v;
- int len = p_array.size();
- v.resize(len);
- for (int i = 0; i < len; i++)
- v.set(i, p_array[i]);
- *this = v;
-}
-
-Variant::Variant(const Vector<String> &p_array) {
-
- type = NIL;
- PoolVector<String> v;
- int len = p_array.size();
- v.resize(len);
- for (int i = 0; i < len; i++)
- v.set(i, p_array[i]);
- *this = v;
-}
-
-Variant::Variant(const Vector<StringName> &p_array) {
-
- type = NIL;
- PoolVector<String> v;
- int len = p_array.size();
- v.resize(len);
- for (int i = 0; i < len; i++)
- v.set(i, p_array[i]);
- *this = v;
-}
-
-Variant::Variant(const Vector<Vector3> &p_array) {
-
type = NIL;
- PoolVector<Vector3> v;
- int len = p_array.size();
- if (len > 0) {
- v.resize(len);
- PoolVector<Vector3>::Write w = v.write();
- const Vector3 *r = p_array.ptr();
-
- for (int i = 0; i < len; i++)
- w[i] = r[i];
+ Array arr;
+ arr.resize(p_array.size());
+ for (int i = 0; i < p_array.size(); i++) {
+ arr[i] = p_array[i];
}
- *this = v;
+ *this = arr;
}
-Variant::Variant(const Vector<Color> &p_array) {
+Variant::Variant(const Vector<StringName> &p_array) {
type = NIL;
- PoolVector<Color> v;
+ Vector<String> v;
int len = p_array.size();
v.resize(len);
for (int i = 0; i < len; i++)
@@ -2605,9 +2921,9 @@ void Variant::operator=(const Variant &p_variant) {
_data._int = p_variant._data._int;
} break;
- case REAL: {
+ case FLOAT: {
- _data._real = p_variant._data._real;
+ _data._float = p_variant._data._float;
} break;
case STRING: {
@@ -2619,10 +2935,18 @@ void Variant::operator=(const Variant &p_variant) {
*reinterpret_cast<Vector2 *>(_data._mem) = *reinterpret_cast<const Vector2 *>(p_variant._data._mem);
} break;
+ case VECTOR2I: {
+
+ *reinterpret_cast<Vector2i *>(_data._mem) = *reinterpret_cast<const Vector2i *>(p_variant._data._mem);
+ } break;
case RECT2: {
*reinterpret_cast<Rect2 *>(_data._mem) = *reinterpret_cast<const Rect2 *>(p_variant._data._mem);
} break;
+ case RECT2I: {
+
+ *reinterpret_cast<Rect2i *>(_data._mem) = *reinterpret_cast<const Rect2i *>(p_variant._data._mem);
+ } break;
case TRANSFORM2D: {
*_data._transform2d = *(p_variant._data._transform2d);
@@ -2631,6 +2955,10 @@ void Variant::operator=(const Variant &p_variant) {
*reinterpret_cast<Vector3 *>(_data._mem) = *reinterpret_cast<const Vector3 *>(p_variant._data._mem);
} break;
+ case VECTOR3I: {
+
+ *reinterpret_cast<Vector3i *>(_data._mem) = *reinterpret_cast<const Vector3i *>(p_variant._data._mem);
+ } break;
case PLANE: {
*reinterpret_cast<Plane *>(_data._mem) = *reinterpret_cast<const Plane *>(p_variant._data._mem);
@@ -2685,6 +3013,19 @@ void Variant::operator=(const Variant &p_variant) {
_get_obj().id = p_variant._get_obj().id;
} break;
+ case CALLABLE: {
+
+ *reinterpret_cast<Callable *>(_data._mem) = *reinterpret_cast<const Callable *>(p_variant._data._mem);
+ } break;
+ case SIGNAL: {
+
+ *reinterpret_cast<Signal *>(_data._mem) = *reinterpret_cast<const Signal *>(p_variant._data._mem);
+ } break;
+
+ case STRING_NAME: {
+
+ *reinterpret_cast<StringName *>(_data._mem) = *reinterpret_cast<const StringName *>(p_variant._data._mem);
+ } break;
case NODE_PATH: {
*reinterpret_cast<NodePath *>(_data._mem) = *reinterpret_cast<const NodePath *>(p_variant._data._mem);
@@ -2699,33 +3040,41 @@ void Variant::operator=(const Variant &p_variant) {
} break;
// arrays
- case POOL_BYTE_ARRAY: {
+ case PACKED_BYTE_ARRAY: {
+
+ _data.packed_array = PackedArrayRef<uint8_t>::reference_from(_data.packed_array, p_variant._data.packed_array);
+ } break;
+ case PACKED_INT32_ARRAY: {
+
+ _data.packed_array = PackedArrayRef<int32_t>::reference_from(_data.packed_array, p_variant._data.packed_array);
+ } break;
+ case PACKED_INT64_ARRAY: {
- *reinterpret_cast<PoolVector<uint8_t> *>(_data._mem) = *reinterpret_cast<const PoolVector<uint8_t> *>(p_variant._data._mem);
+ _data.packed_array = PackedArrayRef<int64_t>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
- case POOL_INT_ARRAY: {
+ case PACKED_FLOAT32_ARRAY: {
- *reinterpret_cast<PoolVector<int> *>(_data._mem) = *reinterpret_cast<const PoolVector<int> *>(p_variant._data._mem);
+ _data.packed_array = PackedArrayRef<float>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
- case POOL_REAL_ARRAY: {
+ case PACKED_FLOAT64_ARRAY: {
- *reinterpret_cast<PoolVector<real_t> *>(_data._mem) = *reinterpret_cast<const PoolVector<real_t> *>(p_variant._data._mem);
+ _data.packed_array = PackedArrayRef<double>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
- case POOL_STRING_ARRAY: {
+ case PACKED_STRING_ARRAY: {
- *reinterpret_cast<PoolVector<String> *>(_data._mem) = *reinterpret_cast<const PoolVector<String> *>(p_variant._data._mem);
+ _data.packed_array = PackedArrayRef<String>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
- case POOL_VECTOR2_ARRAY: {
+ case PACKED_VECTOR2_ARRAY: {
- *reinterpret_cast<PoolVector<Vector2> *>(_data._mem) = *reinterpret_cast<const PoolVector<Vector2> *>(p_variant._data._mem);
+ _data.packed_array = PackedArrayRef<Vector2>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
- *reinterpret_cast<PoolVector<Vector3> *>(_data._mem) = *reinterpret_cast<const PoolVector<Vector3> *>(p_variant._data._mem);
+ _data.packed_array = PackedArrayRef<Vector3>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
- case POOL_COLOR_ARRAY: {
+ case PACKED_COLOR_ARRAY: {
- *reinterpret_cast<PoolVector<Color> *>(_data._mem) = *reinterpret_cast<const PoolVector<Color> *>(p_variant._data._mem);
+ _data.packed_array = PackedArrayRef<Color>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
default: {
}
@@ -2765,9 +3114,9 @@ uint32_t Variant::hash() const {
return _data._int;
} break;
- case REAL: {
+ case FLOAT: {
- return hash_djb2_one_float(_data._real);
+ return hash_djb2_one_float(_data._float);
} break;
case STRING: {
@@ -2780,6 +3129,11 @@ uint32_t Variant::hash() const {
uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Vector2 *>(_data._mem)->x);
return hash_djb2_one_float(reinterpret_cast<const Vector2 *>(_data._mem)->y, hash);
} break;
+ case VECTOR2I: {
+
+ uint32_t hash = hash_djb2_one_32(reinterpret_cast<const Vector2i *>(_data._mem)->x);
+ return hash_djb2_one_32(reinterpret_cast<const Vector2i *>(_data._mem)->y, hash);
+ } break;
case RECT2: {
uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->position.x);
@@ -2787,6 +3141,13 @@ uint32_t Variant::hash() const {
hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->size.x, hash);
return hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->size.y, hash);
} break;
+ case RECT2I: {
+
+ uint32_t hash = hash_djb2_one_32(reinterpret_cast<const Rect2i *>(_data._mem)->position.x);
+ hash = hash_djb2_one_32(reinterpret_cast<const Rect2i *>(_data._mem)->position.y, hash);
+ hash = hash_djb2_one_32(reinterpret_cast<const Rect2i *>(_data._mem)->size.x, hash);
+ return hash_djb2_one_32(reinterpret_cast<const Rect2i *>(_data._mem)->size.y, hash);
+ } break;
case TRANSFORM2D: {
uint32_t hash = 5831;
@@ -2805,6 +3166,12 @@ uint32_t Variant::hash() const {
hash = hash_djb2_one_float(reinterpret_cast<const Vector3 *>(_data._mem)->y, hash);
return hash_djb2_one_float(reinterpret_cast<const Vector3 *>(_data._mem)->z, hash);
} break;
+ case VECTOR3I: {
+
+ uint32_t hash = hash_djb2_one_32(reinterpret_cast<const Vector3i *>(_data._mem)->x);
+ hash = hash_djb2_one_32(reinterpret_cast<const Vector3i *>(_data._mem)->y, hash);
+ return hash_djb2_one_32(reinterpret_cast<const Vector3i *>(_data._mem)->z, hash);
+ } break;
case PLANE: {
uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Plane *>(_data._mem)->normal.x);
@@ -2883,6 +3250,10 @@ uint32_t Variant::hash() const {
return hash_djb2_one_64(make_uint64_t(_get_obj().obj));
} break;
+ case STRING_NAME: {
+
+ return reinterpret_cast<const StringName *>(_data._mem)->hash();
+ } break;
case NODE_PATH: {
return reinterpret_cast<const NodePath *>(_data._mem)->hash();
@@ -2892,57 +3263,93 @@ uint32_t Variant::hash() const {
return reinterpret_cast<const Dictionary *>(_data._mem)->hash();
} break;
+ case CALLABLE: {
+
+ return reinterpret_cast<const Callable *>(_data._mem)->hash();
+
+ } break;
+ case SIGNAL: {
+
+ const Signal &s = *reinterpret_cast<const Signal *>(_data._mem);
+ uint32_t hash = s.get_name().hash();
+ return hash_djb2_one_64(s.get_object_id(), hash);
+ } break;
case ARRAY: {
const Array &arr = *reinterpret_cast<const Array *>(_data._mem);
return arr.hash();
} break;
- case POOL_BYTE_ARRAY: {
+ case PACKED_BYTE_ARRAY: {
- const PoolVector<uint8_t> &arr = *reinterpret_cast<const PoolVector<uint8_t> *>(_data._mem);
+ const Vector<uint8_t> &arr = PackedArrayRef<uint8_t>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
- PoolVector<uint8_t>::Read r = arr.read();
+ const uint8_t *r = arr.ptr();
return hash_djb2_buffer((uint8_t *)&r[0], len);
} else {
return hash_djb2_one_64(0);
}
} break;
- case POOL_INT_ARRAY: {
+ case PACKED_INT32_ARRAY: {
- const PoolVector<int> &arr = *reinterpret_cast<const PoolVector<int> *>(_data._mem);
+ const Vector<int32_t> &arr = PackedArrayRef<int32_t>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
- PoolVector<int>::Read r = arr.read();
- return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int));
+ const int32_t *r = arr.ptr();
+ return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int32_t));
} else {
return hash_djb2_one_64(0);
}
} break;
- case POOL_REAL_ARRAY: {
+ case PACKED_INT64_ARRAY: {
- const PoolVector<real_t> &arr = *reinterpret_cast<const PoolVector<real_t> *>(_data._mem);
+ const Vector<int64_t> &arr = PackedArrayRef<int64_t>::get_array(_data.packed_array);
+ int len = arr.size();
+ if (likely(len)) {
+ const int64_t *r = arr.ptr();
+ return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int64_t));
+ } else {
+ return hash_djb2_one_64(0);
+ }
+
+ } break;
+ case PACKED_FLOAT32_ARRAY: {
+
+ const Vector<float> &arr = PackedArrayRef<float>::get_array(_data.packed_array);
+ int len = arr.size();
+
+ if (likely(len)) {
+ const float *r = arr.ptr();
+ return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(float));
+ } else {
+ return hash_djb2_one_float(0.0);
+ }
+
+ } break;
+ case PACKED_FLOAT64_ARRAY: {
+
+ const Vector<double> &arr = PackedArrayRef<double>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
- PoolVector<real_t>::Read r = arr.read();
- return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(real_t));
+ const double *r = arr.ptr();
+ return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(double));
} else {
return hash_djb2_one_float(0.0);
}
} break;
- case POOL_STRING_ARRAY: {
+ case PACKED_STRING_ARRAY: {
uint32_t hash = 5831;
- const PoolVector<String> &arr = *reinterpret_cast<const PoolVector<String> *>(_data._mem);
+ const Vector<String> &arr = PackedArrayRef<String>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
- PoolVector<String>::Read r = arr.read();
+ const String *r = arr.ptr();
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_32(r[i].hash(), hash);
@@ -2951,14 +3358,14 @@ uint32_t Variant::hash() const {
return hash;
} break;
- case POOL_VECTOR2_ARRAY: {
+ case PACKED_VECTOR2_ARRAY: {
uint32_t hash = 5831;
- const PoolVector<Vector2> &arr = *reinterpret_cast<const PoolVector<Vector2> *>(_data._mem);
+ const Vector<Vector2> &arr = PackedArrayRef<Vector2>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
- PoolVector<Vector2>::Read r = arr.read();
+ const Vector2 *r = arr.ptr();
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_float(r[i].x, hash);
@@ -2968,14 +3375,14 @@ uint32_t Variant::hash() const {
return hash;
} break;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
uint32_t hash = 5831;
- const PoolVector<Vector3> &arr = *reinterpret_cast<const PoolVector<Vector3> *>(_data._mem);
+ const Vector<Vector3> &arr = PackedArrayRef<Vector3>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
- PoolVector<Vector3>::Read r = arr.read();
+ const Vector3 *r = arr.ptr();
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_float(r[i].x, hash);
@@ -2986,14 +3393,14 @@ uint32_t Variant::hash() const {
return hash;
} break;
- case POOL_COLOR_ARRAY: {
+ case PACKED_COLOR_ARRAY: {
uint32_t hash = 5831;
- const PoolVector<Color> &arr = *reinterpret_cast<const PoolVector<Color> *>(_data._mem);
+ const Vector<Color> &arr = PackedArrayRef<Color>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
- PoolVector<Color>::Read r = arr.read();
+ const Color *r = arr.ptr();
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_float(r[i].r, hash);
@@ -3036,21 +3443,21 @@ uint32_t Variant::hash() const {
(hash_compare_scalar((p_lhs).b, (p_rhs).b)) && \
(hash_compare_scalar((p_lhs).a, (p_rhs).a))
-#define hash_compare_pool_array(p_lhs, p_rhs, p_type, p_compare_func) \
- const PoolVector<p_type> &l = *reinterpret_cast<const PoolVector<p_type> *>(p_lhs); \
- const PoolVector<p_type> &r = *reinterpret_cast<const PoolVector<p_type> *>(p_rhs); \
- \
- if (l.size() != r.size()) \
- return false; \
- \
- PoolVector<p_type>::Read lr = l.read(); \
- PoolVector<p_type>::Read rr = r.read(); \
- \
- for (int i = 0; i < l.size(); ++i) { \
- if (!p_compare_func((lr[i]), (rr[i]))) \
- return false; \
- } \
- \
+#define hash_compare_packed_array(p_lhs, p_rhs, p_type, p_compare_func) \
+ const Vector<p_type> &l = PackedArrayRef<p_type>::get_array(p_lhs); \
+ const Vector<p_type> &r = PackedArrayRef<p_type>::get_array(p_rhs); \
+ \
+ if (l.size() != r.size()) \
+ return false; \
+ \
+ const p_type *lr = l.ptr(); \
+ const p_type *rr = r.ptr(); \
+ \
+ for (int i = 0; i < l.size(); ++i) { \
+ if (!p_compare_func((lr[i]), (rr[i]))) \
+ return false; \
+ } \
+ \
return true
bool Variant::hash_compare(const Variant &p_variant) const {
@@ -3058,8 +3465,8 @@ bool Variant::hash_compare(const Variant &p_variant) const {
return false;
switch (type) {
- case REAL: {
- return hash_compare_scalar(_data._real, p_variant._data._real);
+ case FLOAT: {
+ return hash_compare_scalar(_data._float, p_variant._data._float);
} break;
case VECTOR2: {
@@ -3068,6 +3475,11 @@ bool Variant::hash_compare(const Variant &p_variant) const {
return hash_compare_vector2(*l, *r);
} break;
+ case VECTOR2I: {
+ const Vector2i *l = reinterpret_cast<const Vector2i *>(_data._mem);
+ const Vector2i *r = reinterpret_cast<const Vector2i *>(p_variant._data._mem);
+ return *l == *r;
+ } break;
case RECT2: {
const Rect2 *l = reinterpret_cast<const Rect2 *>(_data._mem);
@@ -3076,6 +3488,12 @@ bool Variant::hash_compare(const Variant &p_variant) const {
return (hash_compare_vector2(l->position, r->position)) &&
(hash_compare_vector2(l->size, r->size));
} break;
+ case RECT2I: {
+ const Rect2i *l = reinterpret_cast<const Rect2i *>(_data._mem);
+ const Rect2i *r = reinterpret_cast<const Rect2i *>(p_variant._data._mem);
+
+ return *l == *r;
+ } break;
case TRANSFORM2D: {
Transform2D *l = _data._transform2d;
@@ -3095,6 +3513,12 @@ bool Variant::hash_compare(const Variant &p_variant) const {
return hash_compare_vector3(*l, *r);
} break;
+ case VECTOR3I: {
+ const Vector3i *l = reinterpret_cast<const Vector3i *>(_data._mem);
+ const Vector3i *r = reinterpret_cast<const Vector3i *>(p_variant._data._mem);
+
+ return *l == *r;
+ } break;
case PLANE: {
const Plane *l = reinterpret_cast<const Plane *>(_data._mem);
@@ -3166,20 +3590,25 @@ bool Variant::hash_compare(const Variant &p_variant) const {
return true;
} break;
- case POOL_REAL_ARRAY: {
- hash_compare_pool_array(_data._mem, p_variant._data._mem, real_t, hash_compare_scalar);
+ // This is for floating point comparisons only.
+ case PACKED_FLOAT32_ARRAY: {
+ hash_compare_packed_array(_data.packed_array, p_variant._data.packed_array, float, hash_compare_scalar);
} break;
- case POOL_VECTOR2_ARRAY: {
- hash_compare_pool_array(_data._mem, p_variant._data._mem, Vector2, hash_compare_vector2);
+ case PACKED_FLOAT64_ARRAY: {
+ hash_compare_packed_array(_data.packed_array, p_variant._data.packed_array, double, hash_compare_scalar);
} break;
- case POOL_VECTOR3_ARRAY: {
- hash_compare_pool_array(_data._mem, p_variant._data._mem, Vector3, hash_compare_vector3);
+ case PACKED_VECTOR2_ARRAY: {
+ hash_compare_packed_array(_data.packed_array, p_variant._data.packed_array, Vector2, hash_compare_vector2);
} break;
- case POOL_COLOR_ARRAY: {
- hash_compare_pool_array(_data._mem, p_variant._data._mem, Color, hash_compare_color);
+ case PACKED_VECTOR3_ARRAY: {
+ hash_compare_packed_array(_data.packed_array, p_variant._data.packed_array, Vector3, hash_compare_vector3);
+ } break;
+
+ case PACKED_COLOR_ARRAY: {
+ hash_compare_packed_array(_data.packed_array, p_variant._data.packed_array, Color, hash_compare_color);
} break;
default:
@@ -3270,24 +3699,24 @@ Variant Variant::call(const StringName &p_method, VARIANT_ARG_DECLARE) {
argc++;
}
- CallError error;
+ Callable::CallError error;
Variant ret = call(p_method, argptr, argc, error);
switch (error.error) {
- case CallError::CALL_ERROR_INVALID_ARGUMENT: {
+ case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
- String err = "Invalid type for argument #" + itos(error.argument) + ", expected '" + Variant::get_type_name(error.expected) + "'.";
+ String err = "Invalid type for argument #" + itos(error.argument) + ", expected '" + Variant::get_type_name(Variant::Type(error.expected)) + "'.";
ERR_PRINT(err.utf8().get_data());
} break;
- case CallError::CALL_ERROR_INVALID_METHOD: {
+ case Callable::CallError::CALL_ERROR_INVALID_METHOD: {
String err = "Invalid method '" + p_method + "' for type '" + Variant::get_type_name(type) + "'.";
ERR_PRINT(err.utf8().get_data());
} break;
- case CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
+ case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
String err = "Too many arguments for method '" + p_method + "'";
ERR_PRINT(err.utf8().get_data());
@@ -3312,26 +3741,26 @@ String Variant::get_construct_string() const {
return vars;
}
-String Variant::get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Variant::CallError &ce) {
+String Variant::get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) {
String err_text;
- if (ce.error == Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) {
+ if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
int errorarg = ce.argument;
if (p_argptrs) {
- err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(ce.expected) + ".";
+ err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + ".";
} else {
- err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(ce.expected) + ".";
+ err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + ".";
}
- } else if (ce.error == Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
+ } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + ".";
- } else if (ce.error == Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
+ } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + ".";
- } else if (ce.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) {
+ } else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) {
err_text = "Method not found.";
- } else if (ce.error == Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
+ } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
err_text = "Instance is null";
- } else if (ce.error == Variant::CallError::CALL_OK) {
+ } else if (ce.error == Callable::CallError::CALL_OK) {
return "Call OK";
}
@@ -3344,6 +3773,32 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method,
return "'" + class_name + "::" + String(p_method) + "': " + err_text;
}
+String Variant::get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) {
+
+ String err_text;
+
+ if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
+ int errorarg = ce.argument;
+ if (p_argptrs) {
+ err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + ".";
+ } else {
+ err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + ".";
+ }
+ } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
+ err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + ".";
+ } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
+ err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + ".";
+ } else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) {
+ err_text = "Method not found.";
+ } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
+ err_text = "Instance is null";
+ } else if (ce.error == Callable::CallError::CALL_OK) {
+ return "Call OK";
+ }
+
+ return String(p_callable) + " : " + err_text;
+}
+
String vformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) {
Array args;
diff --git a/core/variant.h b/core/variant.h
index bb3840932d..614d39e84a 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -32,6 +32,7 @@
#define VARIANT_H
#include "core/array.h"
+#include "core/callable.h"
#include "core/color.h"
#include "core/dictionary.h"
#include "core/io/ip_address.h"
@@ -43,9 +44,9 @@
#include "core/math/transform.h"
#include "core/math/transform_2d.h"
#include "core/math/vector3.h"
+#include "core/math/vector3i.h"
#include "core/node_path.h"
#include "core/object_id.h"
-#include "core/pool_vector.h"
#include "core/rid.h"
#include "core/ustring.h"
@@ -56,13 +57,15 @@ class Control; // helper
struct PropertyInfo;
struct MethodInfo;
-typedef PoolVector<uint8_t> PoolByteArray;
-typedef PoolVector<int> PoolIntArray;
-typedef PoolVector<real_t> PoolRealArray;
-typedef PoolVector<String> PoolStringArray;
-typedef PoolVector<Vector2> PoolVector2Array;
-typedef PoolVector<Vector3> PoolVector3Array;
-typedef PoolVector<Color> PoolColorArray;
+typedef Vector<uint8_t> PackedByteArray;
+typedef Vector<int32_t> PackedInt32Array;
+typedef Vector<int64_t> PackedInt64Array;
+typedef Vector<float> PackedFloat32Array;
+typedef Vector<double> PackedFloat64Array;
+typedef Vector<String> PackedStringArray;
+typedef Vector<Vector2> PackedVector2Array;
+typedef Vector<Vector3> PackedVector3Array;
+typedef Vector<Color> PackedColorArray;
// Temporary workaround until c++11 alignas()
#ifdef __GNUC__
@@ -75,46 +78,51 @@ class Variant {
public:
// If this changes the table in variant_op must be updated
enum Type {
-
NIL,
// atomic types
BOOL,
INT,
- REAL,
+ FLOAT,
STRING,
// math types
-
- VECTOR2, // 5
+ VECTOR2,
+ VECTOR2I,
RECT2,
+ RECT2I,
VECTOR3,
+ VECTOR3I,
TRANSFORM2D,
PLANE,
- QUAT, // 10
+ QUAT,
AABB,
BASIS,
TRANSFORM,
// misc types
COLOR,
- NODE_PATH, // 15
+ STRING_NAME,
+ NODE_PATH,
_RID,
OBJECT,
+ CALLABLE,
+ SIGNAL,
DICTIONARY,
ARRAY,
- // arrays
- POOL_BYTE_ARRAY, // 20
- POOL_INT_ARRAY,
- POOL_REAL_ARRAY,
- POOL_STRING_ARRAY,
- POOL_VECTOR2_ARRAY,
- POOL_VECTOR3_ARRAY, // 25
- POOL_COLOR_ARRAY,
+ // typed arrays
+ PACKED_BYTE_ARRAY,
+ PACKED_INT32_ARRAY,
+ PACKED_INT64_ARRAY,
+ PACKED_FLOAT32_ARRAY,
+ PACKED_FLOAT64_ARRAY,
+ PACKED_STRING_ARRAY,
+ PACKED_VECTOR2_ARRAY,
+ PACKED_VECTOR3_ARRAY,
+ PACKED_COLOR_ARRAY,
VARIANT_MAX
-
};
private:
@@ -130,17 +138,77 @@ private:
Object *obj;
};
+ /* array helpers */
+ struct PackedArrayRefBase {
+ SafeRefCount refcount;
+ _FORCE_INLINE_ PackedArrayRefBase *reference() {
+ if (this->refcount.ref()) {
+ return this;
+ } else {
+ return nullptr;
+ }
+ }
+ static _FORCE_INLINE_ PackedArrayRefBase *reference_from(PackedArrayRefBase *p_base, PackedArrayRefBase *p_from) {
+ if (p_base == p_from) {
+ return p_base; //same thing, do nothing
+ }
+
+ if (p_from->reference()) {
+ if (p_base->refcount.unref()) {
+ memdelete(p_base);
+ }
+ return p_from;
+ } else {
+ return p_base; //keep, could not reference new
+ }
+ }
+ static _FORCE_INLINE_ void destroy(PackedArrayRefBase *p_array) {
+ if (p_array->refcount.unref()) {
+ memdelete(p_array);
+ }
+ }
+ _FORCE_INLINE_ virtual ~PackedArrayRefBase() {} //needs virtual destructor, but make inline
+ };
+
+ template <class T>
+ struct PackedArrayRef : public PackedArrayRefBase {
+ Vector<T> array;
+ static _FORCE_INLINE_ PackedArrayRef<T> *create() {
+ return memnew(PackedArrayRef<T>);
+ }
+ static _FORCE_INLINE_ PackedArrayRef<T> *create(const Vector<T> &p_from) {
+ return memnew(PackedArrayRef<T>(p_from));
+ }
+
+ static _FORCE_INLINE_ const Vector<T> &get_array(PackedArrayRefBase *p_base) {
+ return static_cast<PackedArrayRef<T> *>(p_base)->array;
+ }
+ static _FORCE_INLINE_ Vector<T> *get_array_ptr(const PackedArrayRefBase *p_base) {
+ return &const_cast<PackedArrayRef<T> *>(static_cast<const PackedArrayRef<T> *>(p_base))->array;
+ }
+
+ _FORCE_INLINE_ PackedArrayRef(const Vector<T> &p_from) {
+ array = p_from;
+ refcount.init();
+ }
+ _FORCE_INLINE_ PackedArrayRef() {
+ refcount.init();
+ }
+ };
+
+ /* end of array helpers */
_ALWAYS_INLINE_ ObjData &_get_obj();
_ALWAYS_INLINE_ const ObjData &_get_obj() const;
union {
bool _bool;
int64_t _int;
- double _real;
+ double _float;
Transform2D *_transform2d;
::AABB *_aabb;
Basis *_basis;
Transform *_transform;
+ PackedArrayRefBase *packed_array;
void *_ptr; //generic pointer
uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)];
} _data GCC_ALIGNED_8;
@@ -149,14 +217,20 @@ private:
void clear();
public:
- _FORCE_INLINE_ Type get_type() const { return type; }
+ _FORCE_INLINE_ Type get_type() const {
+ return type;
+ }
static String get_type_name(Variant::Type p_type);
static bool can_convert(Type p_type_from, Type p_type_to);
static bool can_convert_strict(Type p_type_from, Type p_type_to);
bool is_ref() const;
- _FORCE_INLINE_ bool is_num() const { return type == INT || type == REAL; };
- _FORCE_INLINE_ bool is_array() const { return type >= ARRAY; };
+ _FORCE_INLINE_ bool is_num() const {
+ return type == INT || type == FLOAT;
+ };
+ _FORCE_INLINE_ bool is_array() const {
+ return type >= ARRAY;
+ };
bool is_shared() const;
bool is_zero() const;
bool is_one() const;
@@ -185,8 +259,11 @@ public:
operator String() const;
operator StringName() const;
operator Vector2() const;
+ operator Vector2i() const;
operator Rect2() const;
+ operator Rect2i() const;
operator Vector3() const;
+ operator Vector3i() const;
operator Plane() const;
operator ::AABB() const;
operator Quat() const;
@@ -202,30 +279,27 @@ public:
operator Node *() const;
operator Control *() const;
+ operator Callable() const;
+ operator Signal() const;
+
operator Dictionary() const;
operator Array() const;
- operator PoolVector<uint8_t>() const;
- operator PoolVector<int>() const;
- operator PoolVector<real_t>() const;
- operator PoolVector<String>() const;
- operator PoolVector<Vector3>() const;
- operator PoolVector<Color>() const;
- operator PoolVector<Plane>() const;
- operator PoolVector<Face3>() const;
-
- operator Vector<Variant>() const;
operator Vector<uint8_t>() const;
- operator Vector<int>() const;
- operator Vector<real_t>() const;
+ operator Vector<int32_t>() const;
+ operator Vector<int64_t>() const;
+ operator Vector<float>() const;
+ operator Vector<double>() const;
operator Vector<String>() const;
- operator Vector<StringName>() const;
operator Vector<Vector3>() const;
operator Vector<Color>() const;
+ operator Vector<Plane>() const;
+ operator Vector<Face3>() const;
+
+ operator Vector<Variant>() const;
+ operator Vector<StringName>() const;
operator Vector<RID>() const;
operator Vector<Vector2>() const;
- operator PoolVector<Vector2>() const;
- operator Vector<Plane>() const;
// some core type enums to convert to
operator Margin() const;
@@ -258,8 +332,11 @@ public:
Variant(const char *const p_cstring);
Variant(const CharType *p_wstring);
Variant(const Vector2 &p_vector2);
+ Variant(const Vector2i &p_vector2i);
Variant(const Rect2 &p_rect2);
+ Variant(const Rect2i &p_rect2i);
Variant(const Vector3 &p_vector3);
+ Variant(const Vector3i &p_vector3i);
Variant(const Plane &p_plane);
Variant(const ::AABB &p_aabb);
Variant(const Quat &p_quat);
@@ -270,30 +347,26 @@ public:
Variant(const NodePath &p_node_path);
Variant(const RID &p_rid);
Variant(const Object *p_object);
+ Variant(const Callable &p_callable);
+ Variant(const Signal &p_signal);
Variant(const Dictionary &p_dictionary);
Variant(const Array &p_array);
- Variant(const PoolVector<Plane> &p_array); // helper
- Variant(const PoolVector<uint8_t> &p_raw_array);
- Variant(const PoolVector<int> &p_int_array);
- Variant(const PoolVector<real_t> &p_real_array);
- Variant(const PoolVector<String> &p_string_array);
- Variant(const PoolVector<Vector3> &p_vector3_array);
- Variant(const PoolVector<Color> &p_color_array);
- Variant(const PoolVector<Face3> &p_face_array);
+ Variant(const Vector<Plane> &p_array); // helper
+ Variant(const Vector<uint8_t> &p_byte_array);
+ Variant(const Vector<int32_t> &p_int32_array);
+ Variant(const Vector<int64_t> &p_int64_array);
+ Variant(const Vector<float> &p_float32_array);
+ Variant(const Vector<double> &p_float64_array);
+ Variant(const Vector<String> &p_string_array);
+ Variant(const Vector<Vector3> &p_vector3_array);
+ Variant(const Vector<Color> &p_color_array);
+ Variant(const Vector<Face3> &p_face_array);
Variant(const Vector<Variant> &p_array);
- Variant(const Vector<uint8_t> &p_array);
- Variant(const Vector<int> &p_array);
- Variant(const Vector<real_t> &p_array);
- Variant(const Vector<String> &p_array);
Variant(const Vector<StringName> &p_array);
- Variant(const Vector<Vector3> &p_array);
- Variant(const Vector<Color> &p_array);
- Variant(const Vector<Plane> &p_array); // helper
Variant(const Vector<RID> &p_array); // helper
Variant(const Vector<Vector2> &p_array); // helper
- Variant(const PoolVector<Vector2> &p_vector2_array); // helper
Variant(const IP_Address &p_address);
@@ -349,27 +422,14 @@ public:
static void blend(const Variant &a, const Variant &b, float c, Variant &r_dst);
static void interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst);
- struct CallError {
- enum Error {
- CALL_OK,
- CALL_ERROR_INVALID_METHOD,
- CALL_ERROR_INVALID_ARGUMENT,
- CALL_ERROR_TOO_MANY_ARGUMENTS,
- CALL_ERROR_TOO_FEW_ARGUMENTS,
- CALL_ERROR_INSTANCE_IS_NULL,
- };
- Error error;
- int argument;
- Type expected;
- };
-
- void call_ptr(const StringName &p_method, const Variant **p_args, int p_argcount, Variant *r_ret, CallError &r_error);
- Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, CallError &r_error);
+ void call_ptr(const StringName &p_method, const Variant **p_args, int p_argcount, Variant *r_ret, Callable::CallError &r_error);
+ Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant());
- static String get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Variant::CallError &ce);
+ static String get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce);
+ static String get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce);
- static Variant construct(const Variant::Type, const Variant **p_args, int p_argcount, CallError &r_error, bool p_strict = true);
+ static Variant construct(const Variant::Type, const Variant **p_args, int p_argcount, Callable::CallError &r_error, bool p_strict = true);
void get_method_list(List<MethodInfo> *p_list) const;
bool has_method(const StringName &p_method) const;
@@ -417,7 +477,9 @@ public:
void operator=(const Variant &p_variant); // only this is enough for all the other types
Variant(const Variant &p_variant);
- _FORCE_INLINE_ Variant() { type = NIL; }
+ _FORCE_INLINE_ Variant() {
+ type = NIL;
+ }
_FORCE_INLINE_ ~Variant() {
if (type != Variant::NIL) clear();
}
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index ac995d1c78..99cfc7ed3c 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -61,7 +61,7 @@ struct _VariantCall {
VariantFunc func;
- _FORCE_INLINE_ bool verify_arguments(const Variant **p_args, Variant::CallError &r_error) {
+ _FORCE_INLINE_ bool verify_arguments(const Variant **p_args, Callable::CallError &r_error) {
if (arg_count == 0)
return true;
@@ -73,7 +73,7 @@ struct _VariantCall {
if (tptr[i] == Variant::NIL || tptr[i] == p_args[i]->type)
continue; // all good
if (!Variant::can_convert(p_args[i]->type, tptr[i])) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = i;
r_error.expected = tptr[i];
return false;
@@ -82,10 +82,10 @@ struct _VariantCall {
return true;
}
- _FORCE_INLINE_ void call(Variant &r_ret, Variant &p_self, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+ _FORCE_INLINE_ void call(Variant &r_ret, Variant &p_self, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
#ifdef DEBUG_ENABLED
if (p_argcount > arg_count) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument = arg_count;
return;
} else
@@ -94,7 +94,7 @@ struct _VariantCall {
int def_argcount = default_args.size();
#ifdef DEBUG_ENABLED
if (p_argcount < (arg_count - def_argcount)) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = arg_count - def_argcount;
return;
}
@@ -317,17 +317,16 @@ struct _VariantCall {
String *s = reinterpret_cast<String *>(p_self._data._mem);
if (s->empty()) {
- r_ret = PoolByteArray();
+ r_ret = PackedByteArray();
return;
}
CharString charstr = s->ascii();
- PoolByteArray retval;
+ PackedByteArray retval;
size_t len = charstr.length();
retval.resize(len);
- PoolByteArray::Write w = retval.write();
- copymem(w.ptr(), charstr.ptr(), len);
- w.release();
+ uint8_t *w = retval.ptrw();
+ copymem(w, charstr.ptr(), len);
r_ret = retval;
}
@@ -336,17 +335,16 @@ struct _VariantCall {
String *s = reinterpret_cast<String *>(p_self._data._mem);
if (s->empty()) {
- r_ret = PoolByteArray();
+ r_ret = PackedByteArray();
return;
}
CharString charstr = s->utf8();
- PoolByteArray retval;
+ PackedByteArray retval;
size_t len = charstr.length();
retval.resize(len);
- PoolByteArray::Write w = retval.write();
- copymem(w.ptr(), charstr.ptr(), len);
- w.release();
+ uint8_t *w = retval.ptrw();
+ copymem(w, charstr.ptr(), len);
r_ret = retval;
}
@@ -385,11 +383,15 @@ struct _VariantCall {
VCALL_LOCALMEM1R(Vector2, clamped);
VCALL_LOCALMEM0R(Vector2, sign);
+ VCALL_LOCALMEM0R(Vector2i, aspect);
+ VCALL_LOCALMEM0R(Vector2i, sign);
+ VCALL_LOCALMEM0R(Vector2i, abs);
+
VCALL_LOCALMEM0R(Rect2, get_area);
VCALL_LOCALMEM0R(Rect2, has_no_area);
VCALL_LOCALMEM1R(Rect2, has_point);
VCALL_LOCALMEM1R(Rect2, is_equal_approx);
- VCALL_LOCALMEM1R(Rect2, intersects);
+ VCALL_LOCALMEM2R(Rect2, intersects);
VCALL_LOCALMEM1R(Rect2, encloses);
VCALL_LOCALMEM1R(Rect2, clip);
VCALL_LOCALMEM1R(Rect2, merge);
@@ -399,6 +401,19 @@ struct _VariantCall {
VCALL_LOCALMEM4R(Rect2, grow_individual);
VCALL_LOCALMEM0R(Rect2, abs);
+ VCALL_LOCALMEM0R(Rect2i, get_area);
+ VCALL_LOCALMEM0R(Rect2i, has_no_area);
+ VCALL_LOCALMEM1R(Rect2i, has_point);
+ VCALL_LOCALMEM1R(Rect2i, intersects);
+ VCALL_LOCALMEM1R(Rect2i, encloses);
+ VCALL_LOCALMEM1R(Rect2i, clip);
+ VCALL_LOCALMEM1R(Rect2i, merge);
+ VCALL_LOCALMEM1R(Rect2i, expand);
+ VCALL_LOCALMEM1R(Rect2i, grow);
+ VCALL_LOCALMEM2R(Rect2i, grow_margin);
+ VCALL_LOCALMEM4R(Rect2i, grow_individual);
+ VCALL_LOCALMEM0R(Rect2i, abs);
+
VCALL_LOCALMEM0R(Vector3, min_axis);
VCALL_LOCALMEM0R(Vector3, max_axis);
VCALL_LOCALMEM1R(Vector3, distance_to);
@@ -433,6 +448,10 @@ struct _VariantCall {
VCALL_LOCALMEM1R(Vector3, reflect);
VCALL_LOCALMEM0R(Vector3, sign);
+ VCALL_LOCALMEM0R(Vector3i, min_axis);
+ VCALL_LOCALMEM0R(Vector3i, max_axis);
+ VCALL_LOCALMEM0R(Vector3i, sign);
+
VCALL_LOCALMEM0R(Plane, normalized);
VCALL_LOCALMEM0R(Plane, center);
VCALL_LOCALMEM0R(Plane, get_any_point);
@@ -521,6 +540,23 @@ struct _VariantCall {
VCALL_LOCALMEM1R(Dictionary, duplicate);
VCALL_LOCALMEM2R(Dictionary, get);
+ VCALL_LOCALMEM0R(Callable, is_null);
+ VCALL_LOCALMEM0R(Callable, is_custom);
+ VCALL_LOCALMEM0(Callable, is_standard);
+ VCALL_LOCALMEM0(Callable, get_object);
+ VCALL_LOCALMEM0(Callable, get_object_id);
+ VCALL_LOCALMEM0(Callable, get_method);
+ VCALL_LOCALMEM0(Callable, hash);
+
+ VCALL_LOCALMEM0R(Signal, is_null);
+ VCALL_LOCALMEM0R(Signal, get_object);
+ VCALL_LOCALMEM0R(Signal, get_object_id);
+ VCALL_LOCALMEM0R(Signal, get_name);
+ VCALL_LOCALMEM3R(Signal, connect);
+ VCALL_LOCALMEM1(Signal, disconnect);
+ VCALL_LOCALMEM1R(Signal, is_connected);
+ VCALL_LOCALMEM0R(Signal, get_connections);
+
VCALL_LOCALMEM2(Array, set);
VCALL_LOCALMEM1R(Array, get);
VCALL_LOCALMEM0R(Array, size);
@@ -554,15 +590,15 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Array, max);
VCALL_LOCALMEM0R(Array, min);
- static void _call_PoolByteArray_get_string_from_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ static void _call_PackedByteArray_get_string_from_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) {
- PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem);
+ PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
String s;
if (ba->size() > 0) {
- PoolByteArray::Read r = ba->read();
+ const uint8_t *r = ba->ptr();
CharString cs;
cs.resize(ba->size() + 1);
- copymem(cs.ptrw(), r.ptr(), ba->size());
+ copymem(cs.ptrw(), r, ba->size());
cs[ba->size()] = 0;
s = cs.get_data();
@@ -570,26 +606,26 @@ struct _VariantCall {
r_ret = s;
}
- static void _call_PoolByteArray_get_string_from_utf8(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ static void _call_PackedByteArray_get_string_from_utf8(Variant &r_ret, Variant &p_self, const Variant **p_args) {
- PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem);
+ PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
String s;
if (ba->size() > 0) {
- PoolByteArray::Read r = ba->read();
- s.parse_utf8((const char *)r.ptr(), ba->size());
+ const uint8_t *r = ba->ptr();
+ s.parse_utf8((const char *)r, ba->size());
}
r_ret = s;
}
- static void _call_PoolByteArray_compress(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ static void _call_PackedByteArray_compress(Variant &r_ret, Variant &p_self, const Variant **p_args) {
- PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem);
- PoolByteArray compressed;
+ PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
+ PackedByteArray compressed;
if (ba->size() > 0) {
Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]);
compressed.resize(Compression::get_max_compressed_buffer_size(ba->size(), mode));
- int result = Compression::compress(compressed.write().ptr(), ba->read().ptr(), ba->size(), mode);
+ int result = Compression::compress(compressed.ptrw(), ba->ptr(), ba->size(), mode);
result = result >= 0 ? result : 0;
compressed.resize(result);
@@ -597,10 +633,10 @@ struct _VariantCall {
r_ret = compressed;
}
- static void _call_PoolByteArray_decompress(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ static void _call_PackedByteArray_decompress(Variant &r_ret, Variant &p_self, const Variant **p_args) {
- PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem);
- PoolByteArray decompressed;
+ PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
+ PackedByteArray decompressed;
Compression::Mode mode = (Compression::Mode)(int)(*p_args[1]);
int buffer_size = (int)(*p_args[0]);
@@ -611,7 +647,7 @@ struct _VariantCall {
}
decompressed.resize(buffer_size);
- int result = Compression::decompress(decompressed.write().ptr(), buffer_size, ba->read().ptr(), ba->size(), mode);
+ int result = Compression::decompress(decompressed.ptrw(), buffer_size, ba->ptr(), ba->size(), mode);
result = result >= 0 ? result : 0;
decompressed.resize(result);
@@ -619,102 +655,150 @@ struct _VariantCall {
r_ret = decompressed;
}
- static void _call_PoolByteArray_hex_encode(Variant &r_ret, Variant &p_self, const Variant **p_args) {
- PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem);
+ static void _call_PackedByteArray_hex_encode(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+ PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
if (ba->size() == 0) {
r_ret = String();
return;
}
- PoolByteArray::Read r = ba->read();
+ const uint8_t *r = ba->ptr();
String s = String::hex_encode_buffer(&r[0], ba->size());
r_ret = s;
}
- VCALL_LOCALMEM0R(PoolByteArray, size);
- VCALL_LOCALMEM0R(PoolByteArray, empty);
- VCALL_LOCALMEM2(PoolByteArray, set);
- VCALL_LOCALMEM1R(PoolByteArray, get);
- VCALL_LOCALMEM1(PoolByteArray, push_back);
- VCALL_LOCALMEM1(PoolByteArray, resize);
- VCALL_LOCALMEM2R(PoolByteArray, insert);
- VCALL_LOCALMEM1(PoolByteArray, remove);
- VCALL_LOCALMEM1(PoolByteArray, append);
- VCALL_LOCALMEM1(PoolByteArray, append_array);
- VCALL_LOCALMEM0(PoolByteArray, invert);
- VCALL_LOCALMEM2R(PoolByteArray, subarray);
-
- VCALL_LOCALMEM0R(PoolIntArray, size);
- VCALL_LOCALMEM0R(PoolIntArray, empty);
- VCALL_LOCALMEM2(PoolIntArray, set);
- VCALL_LOCALMEM1R(PoolIntArray, get);
- VCALL_LOCALMEM1(PoolIntArray, push_back);
- VCALL_LOCALMEM1(PoolIntArray, resize);
- VCALL_LOCALMEM2R(PoolIntArray, insert);
- VCALL_LOCALMEM1(PoolIntArray, remove);
- VCALL_LOCALMEM1(PoolIntArray, append);
- VCALL_LOCALMEM1(PoolIntArray, append_array);
- VCALL_LOCALMEM0(PoolIntArray, invert);
-
- VCALL_LOCALMEM0R(PoolRealArray, size);
- VCALL_LOCALMEM0R(PoolRealArray, empty);
- VCALL_LOCALMEM2(PoolRealArray, set);
- VCALL_LOCALMEM1R(PoolRealArray, get);
- VCALL_LOCALMEM1(PoolRealArray, push_back);
- VCALL_LOCALMEM1(PoolRealArray, resize);
- VCALL_LOCALMEM2R(PoolRealArray, insert);
- VCALL_LOCALMEM1(PoolRealArray, remove);
- VCALL_LOCALMEM1(PoolRealArray, append);
- VCALL_LOCALMEM1(PoolRealArray, append_array);
- VCALL_LOCALMEM0(PoolRealArray, invert);
-
- VCALL_LOCALMEM0R(PoolStringArray, size);
- VCALL_LOCALMEM0R(PoolStringArray, empty);
- VCALL_LOCALMEM2(PoolStringArray, set);
- VCALL_LOCALMEM1R(PoolStringArray, get);
- VCALL_LOCALMEM1(PoolStringArray, push_back);
- VCALL_LOCALMEM1(PoolStringArray, resize);
- VCALL_LOCALMEM2R(PoolStringArray, insert);
- VCALL_LOCALMEM1(PoolStringArray, remove);
- VCALL_LOCALMEM1(PoolStringArray, append);
- VCALL_LOCALMEM1(PoolStringArray, append_array);
- VCALL_LOCALMEM0(PoolStringArray, invert);
- VCALL_LOCALMEM1R(PoolStringArray, join);
-
- VCALL_LOCALMEM0R(PoolVector2Array, size);
- VCALL_LOCALMEM0R(PoolVector2Array, empty);
- VCALL_LOCALMEM2(PoolVector2Array, set);
- VCALL_LOCALMEM1R(PoolVector2Array, get);
- VCALL_LOCALMEM1(PoolVector2Array, push_back);
- VCALL_LOCALMEM1(PoolVector2Array, resize);
- VCALL_LOCALMEM2R(PoolVector2Array, insert);
- VCALL_LOCALMEM1(PoolVector2Array, remove);
- VCALL_LOCALMEM1(PoolVector2Array, append);
- VCALL_LOCALMEM1(PoolVector2Array, append_array);
- VCALL_LOCALMEM0(PoolVector2Array, invert);
-
- VCALL_LOCALMEM0R(PoolVector3Array, size);
- VCALL_LOCALMEM0R(PoolVector3Array, empty);
- VCALL_LOCALMEM2(PoolVector3Array, set);
- VCALL_LOCALMEM1R(PoolVector3Array, get);
- VCALL_LOCALMEM1(PoolVector3Array, push_back);
- VCALL_LOCALMEM1(PoolVector3Array, resize);
- VCALL_LOCALMEM2R(PoolVector3Array, insert);
- VCALL_LOCALMEM1(PoolVector3Array, remove);
- VCALL_LOCALMEM1(PoolVector3Array, append);
- VCALL_LOCALMEM1(PoolVector3Array, append_array);
- VCALL_LOCALMEM0(PoolVector3Array, invert);
-
- VCALL_LOCALMEM0R(PoolColorArray, size);
- VCALL_LOCALMEM0R(PoolColorArray, empty);
- VCALL_LOCALMEM2(PoolColorArray, set);
- VCALL_LOCALMEM1R(PoolColorArray, get);
- VCALL_LOCALMEM1(PoolColorArray, push_back);
- VCALL_LOCALMEM1(PoolColorArray, resize);
- VCALL_LOCALMEM2R(PoolColorArray, insert);
- VCALL_LOCALMEM1(PoolColorArray, remove);
- VCALL_LOCALMEM1(PoolColorArray, append);
- VCALL_LOCALMEM1(PoolColorArray, append_array);
- VCALL_LOCALMEM0(PoolColorArray, invert);
+#define VCALL_PARRMEM0(m_type, m_elemtype, m_method) \
+ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { Variant::PackedArrayRef<m_elemtype>::get_array_ptr(p_self._data.packed_array)->m_method(); }
+#define VCALL_PARRMEM0R(m_type, m_elemtype, m_method) \
+ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { r_ret = Variant::PackedArrayRef<m_elemtype>::get_array_ptr(p_self._data.packed_array)->m_method(); }
+#define VCALL_PARRMEM1(m_type, m_elemtype, m_method) \
+ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { Variant::PackedArrayRef<m_elemtype>::get_array_ptr(p_self._data.packed_array)->m_method(*p_args[0]); }
+#define VCALL_PARRMEM1R(m_type, m_elemtype, m_method) \
+ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { r_ret = Variant::PackedArrayRef<m_elemtype>::get_array_ptr(p_self._data.packed_array)->m_method(*p_args[0]); }
+#define VCALL_PARRMEM2(m_type, m_elemtype, m_method) \
+ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { Variant::PackedArrayRef<m_elemtype>::get_array_ptr(p_self._data.packed_array)->m_method(*p_args[0], *p_args[1]); }
+#define VCALL_PARRMEM2R(m_type, m_elemtype, m_method) \
+ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { r_ret = Variant::PackedArrayRef<m_elemtype>::get_array_ptr(p_self._data.packed_array)->m_method(*p_args[0], *p_args[1]); }
+#define VCALL_PARRMEM3(m_type, m_elemtype, m_method) \
+ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { Variant::PackedArrayRef<m_elemtype>::get_array_ptr(p_self._data.packed_array)->m_method(*p_args[0], *p_args[1], *p_args[2]); }
+#define VCALL_PARRMEM3R(m_type, m_elemtype, m_method) \
+ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { r_ret = Variant::PackedArrayRef<m_elemtype>::get_array_ptr(p_self._data.packed_array)->m_method(*p_args[0], *p_args[1], *p_args[2]); }
+#define VCALL_PARRMEM4(m_type, m_elemtype, m_method) \
+ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { Variant::PackedArrayRef<m_elemtype>::get_array_ptr(p_self._data.packed_array)->m_method(*p_args[0], *p_args[1], *p_args[2], *p_args[3]); }
+#define VCALL_PARRMEM4R(m_type, m_elemtype, m_method) \
+ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { r_ret = Variant::PackedArrayRef<m_elemtype>::get_array_ptr(p_self._data.packed_array)->m_method(*p_args[0], *p_args[1], *p_args[2], *p_args[3]); }
+#define VCALL_PARRMEM5(m_type, m_elemtype, m_method) \
+ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { Variant::PackedArrayRef<m_elemtype>::get_array_ptr(p_self._data.packed_array)->m_method(*p_args[0], *p_args[1], *p_args[2], *p_args[3], *p_args[4]); }
+#define VCALL_PARRMEM5R(m_type, m_elemtype, m_method) \
+ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { r_ret = Variant::PackedArrayRef<m_elemtype>::get_array_ptr(p_self._data.packed_array)->m_method(*p_args[0], *p_args[1], *p_args[2], *p_args[3], *p_args[4]); }
+
+ VCALL_PARRMEM0R(PackedByteArray, uint8_t, size);
+ VCALL_PARRMEM0R(PackedByteArray, uint8_t, empty);
+ VCALL_PARRMEM2(PackedByteArray, uint8_t, set);
+ VCALL_PARRMEM1R(PackedByteArray, uint8_t, get);
+ VCALL_PARRMEM1(PackedByteArray, uint8_t, push_back);
+ VCALL_PARRMEM1(PackedByteArray, uint8_t, resize);
+ VCALL_PARRMEM2R(PackedByteArray, uint8_t, insert);
+ VCALL_PARRMEM1(PackedByteArray, uint8_t, remove);
+ VCALL_PARRMEM1(PackedByteArray, uint8_t, append);
+ VCALL_PARRMEM1(PackedByteArray, uint8_t, append_array);
+ VCALL_PARRMEM0(PackedByteArray, uint8_t, invert);
+ VCALL_PARRMEM2R(PackedByteArray, uint8_t, subarray);
+
+ VCALL_PARRMEM0R(PackedInt32Array, int32_t, size);
+ VCALL_PARRMEM0R(PackedInt32Array, int32_t, empty);
+ VCALL_PARRMEM2(PackedInt32Array, int32_t, set);
+ VCALL_PARRMEM1R(PackedInt32Array, int32_t, get);
+ VCALL_PARRMEM1(PackedInt32Array, int32_t, push_back);
+ VCALL_PARRMEM1(PackedInt32Array, int32_t, resize);
+ VCALL_PARRMEM2R(PackedInt32Array, int32_t, insert);
+ VCALL_PARRMEM1(PackedInt32Array, int32_t, remove);
+ VCALL_PARRMEM1(PackedInt32Array, int32_t, append);
+ VCALL_PARRMEM1(PackedInt32Array, int32_t, append_array);
+ VCALL_PARRMEM0(PackedInt32Array, int32_t, invert);
+
+ VCALL_PARRMEM0R(PackedInt64Array, int64_t, size);
+ VCALL_PARRMEM0R(PackedInt64Array, int64_t, empty);
+ VCALL_PARRMEM2(PackedInt64Array, int64_t, set);
+ VCALL_PARRMEM1R(PackedInt64Array, int64_t, get);
+ VCALL_PARRMEM1(PackedInt64Array, int64_t, push_back);
+ VCALL_PARRMEM1(PackedInt64Array, int64_t, resize);
+ VCALL_PARRMEM2R(PackedInt64Array, int64_t, insert);
+ VCALL_PARRMEM1(PackedInt64Array, int64_t, remove);
+ VCALL_PARRMEM1(PackedInt64Array, int64_t, append);
+ VCALL_PARRMEM1(PackedInt64Array, int64_t, append_array);
+ VCALL_PARRMEM0(PackedInt64Array, int64_t, invert);
+
+ VCALL_PARRMEM0R(PackedFloat32Array, float, size);
+ VCALL_PARRMEM0R(PackedFloat32Array, float, empty);
+ VCALL_PARRMEM2(PackedFloat32Array, float, set);
+ VCALL_PARRMEM1R(PackedFloat32Array, float, get);
+ VCALL_PARRMEM1(PackedFloat32Array, float, push_back);
+ VCALL_PARRMEM1(PackedFloat32Array, float, resize);
+ VCALL_PARRMEM2R(PackedFloat32Array, float, insert);
+ VCALL_PARRMEM1(PackedFloat32Array, float, remove);
+ VCALL_PARRMEM1(PackedFloat32Array, float, append);
+ VCALL_PARRMEM1(PackedFloat32Array, float, append_array);
+ VCALL_PARRMEM0(PackedFloat32Array, float, invert);
+
+ VCALL_PARRMEM0R(PackedFloat64Array, double, size);
+ VCALL_PARRMEM0R(PackedFloat64Array, double, empty);
+ VCALL_PARRMEM2(PackedFloat64Array, double, set);
+ VCALL_PARRMEM1R(PackedFloat64Array, double, get);
+ VCALL_PARRMEM1(PackedFloat64Array, double, push_back);
+ VCALL_PARRMEM1(PackedFloat64Array, double, resize);
+ VCALL_PARRMEM2R(PackedFloat64Array, double, insert);
+ VCALL_PARRMEM1(PackedFloat64Array, double, remove);
+ VCALL_PARRMEM1(PackedFloat64Array, double, append);
+ VCALL_PARRMEM1(PackedFloat64Array, double, append_array);
+ VCALL_PARRMEM0(PackedFloat64Array, double, invert);
+
+ VCALL_PARRMEM0R(PackedStringArray, String, size);
+ VCALL_PARRMEM0R(PackedStringArray, String, empty);
+ VCALL_PARRMEM2(PackedStringArray, String, set);
+ VCALL_PARRMEM1R(PackedStringArray, String, get);
+ VCALL_PARRMEM1(PackedStringArray, String, push_back);
+ VCALL_PARRMEM1(PackedStringArray, String, resize);
+ VCALL_PARRMEM2R(PackedStringArray, String, insert);
+ VCALL_PARRMEM1(PackedStringArray, String, remove);
+ VCALL_PARRMEM1(PackedStringArray, String, append);
+ VCALL_PARRMEM1(PackedStringArray, String, append_array);
+ VCALL_PARRMEM0(PackedStringArray, String, invert);
+
+ VCALL_PARRMEM0R(PackedVector2Array, Vector2, size);
+ VCALL_PARRMEM0R(PackedVector2Array, Vector2, empty);
+ VCALL_PARRMEM2(PackedVector2Array, Vector2, set);
+ VCALL_PARRMEM1R(PackedVector2Array, Vector2, get);
+ VCALL_PARRMEM1(PackedVector2Array, Vector2, push_back);
+ VCALL_PARRMEM1(PackedVector2Array, Vector2, resize);
+ VCALL_PARRMEM2R(PackedVector2Array, Vector2, insert);
+ VCALL_PARRMEM1(PackedVector2Array, Vector2, remove);
+ VCALL_PARRMEM1(PackedVector2Array, Vector2, append);
+ VCALL_PARRMEM1(PackedVector2Array, Vector2, append_array);
+ VCALL_PARRMEM0(PackedVector2Array, Vector2, invert);
+
+ VCALL_PARRMEM0R(PackedVector3Array, Vector3, size);
+ VCALL_PARRMEM0R(PackedVector3Array, Vector3, empty);
+ VCALL_PARRMEM2(PackedVector3Array, Vector3, set);
+ VCALL_PARRMEM1R(PackedVector3Array, Vector3, get);
+ VCALL_PARRMEM1(PackedVector3Array, Vector3, push_back);
+ VCALL_PARRMEM1(PackedVector3Array, Vector3, resize);
+ VCALL_PARRMEM2R(PackedVector3Array, Vector3, insert);
+ VCALL_PARRMEM1(PackedVector3Array, Vector3, remove);
+ VCALL_PARRMEM1(PackedVector3Array, Vector3, append);
+ VCALL_PARRMEM1(PackedVector3Array, Vector3, append_array);
+ VCALL_PARRMEM0(PackedVector3Array, Vector3, invert);
+
+ VCALL_PARRMEM0R(PackedColorArray, Color, size);
+ VCALL_PARRMEM0R(PackedColorArray, Color, empty);
+ VCALL_PARRMEM2(PackedColorArray, Color, set);
+ VCALL_PARRMEM1R(PackedColorArray, Color, get);
+ VCALL_PARRMEM1(PackedColorArray, Color, push_back);
+ VCALL_PARRMEM1(PackedColorArray, Color, resize);
+ VCALL_PARRMEM2R(PackedColorArray, Color, insert);
+ VCALL_PARRMEM1(PackedColorArray, Color, remove);
+ VCALL_PARRMEM1(PackedColorArray, Color, append);
+ VCALL_PARRMEM1(PackedColorArray, Color, append_array);
+ VCALL_PARRMEM0(PackedColorArray, Color, invert);
#define VCALL_PTR0(m_type, m_method) \
static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { reinterpret_cast<m_type *>(p_self._data._ptr)->m_method(); }
@@ -781,7 +865,7 @@ struct _VariantCall {
case Variant::VECTOR2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator Vector2()); return;
case Variant::RECT2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator Rect2()); return;
- case Variant::POOL_VECTOR2_ARRAY: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator PoolVector2Array()); return;
+ case Variant::PACKED_VECTOR2_ARRAY: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator PackedVector2Array()); return;
default: r_ret = Variant();
}
}
@@ -792,7 +876,7 @@ struct _VariantCall {
case Variant::VECTOR2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector2()); return;
case Variant::RECT2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Rect2()); return;
- case Variant::POOL_VECTOR2_ARRAY: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator PoolVector2Array()); return;
+ case Variant::PACKED_VECTOR2_ARRAY: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator PackedVector2Array()); return;
default: r_ret = Variant();
}
}
@@ -850,7 +934,7 @@ struct _VariantCall {
case Variant::VECTOR3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Vector3()); return;
case Variant::PLANE: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Plane()); return;
case Variant::AABB: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::AABB()); return;
- case Variant::POOL_VECTOR3_ARRAY: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::PoolVector3Array()); return;
+ case Variant::PACKED_VECTOR3_ARRAY: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::PackedVector3Array()); return;
default: r_ret = Variant();
}
}
@@ -862,7 +946,7 @@ struct _VariantCall {
case Variant::VECTOR3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector3()); return;
case Variant::PLANE: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Plane()); return;
case Variant::AABB: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::AABB()); return;
- case Variant::POOL_VECTOR3_ARRAY: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::PoolVector3Array()); return;
+ case Variant::PACKED_VECTOR3_ARRAY: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::PackedVector3Array()); return;
default: r_ret = Variant();
}
}
@@ -895,6 +979,11 @@ struct _VariantCall {
r_ret = Vector2(*p_args[0], *p_args[1]);
}
+ static void Vector2i_init1(Variant &r_ret, const Variant **p_args) {
+
+ r_ret = Vector2i(*p_args[0], *p_args[1]);
+ }
+
static void Rect2_init1(Variant &r_ret, const Variant **p_args) {
r_ret = Rect2(*p_args[0], *p_args[1]);
@@ -905,6 +994,16 @@ struct _VariantCall {
r_ret = Rect2(*p_args[0], *p_args[1], *p_args[2], *p_args[3]);
}
+ static void Rect2i_init1(Variant &r_ret, const Variant **p_args) {
+
+ r_ret = Rect2i(*p_args[0], *p_args[1]);
+ }
+
+ static void Rect2i_init2(Variant &r_ret, const Variant **p_args) {
+
+ r_ret = Rect2i(*p_args[0], *p_args[1], *p_args[2], *p_args[3]);
+ }
+
static void Transform2D_init2(Variant &r_ret, const Variant **p_args) {
Transform2D m(*p_args[0], *p_args[1]);
@@ -925,6 +1024,11 @@ struct _VariantCall {
r_ret = Vector3(*p_args[0], *p_args[1], *p_args[2]);
}
+ static void Vector3i_init1(Variant &r_ret, const Variant **p_args) {
+
+ r_ret = Vector3i(*p_args[0], *p_args[1], *p_args[2]);
+ }
+
static void Plane_init1(Variant &r_ret, const Variant **p_args) {
r_ret = Plane(*p_args[0], *p_args[1], *p_args[2], *p_args[3]);
@@ -1013,6 +1117,16 @@ struct _VariantCall {
r_ret = Transform(p_args[0]->operator Basis(), p_args[1]->operator Vector3());
}
+ static void Callable_init2(Variant &r_ret, const Variant **p_args) {
+
+ r_ret = Callable(p_args[0]->operator ObjectID(), p_args[1]->operator String());
+ }
+
+ static void Signal_init2(Variant &r_ret, const Variant **p_args) {
+
+ r_ret = Signal(p_args[0]->operator ObjectID(), p_args[1]->operator String());
+ }
+
static void add_constructor(VariantConstructFunc p_func, const Variant::Type p_type,
const String &p_name1 = "", const Variant::Type p_type1 = Variant::NIL,
const String &p_name2 = "", const Variant::Type p_type2 = Variant::NIL,
@@ -1081,26 +1195,26 @@ _VariantCall::TypeFunc *_VariantCall::type_funcs = NULL;
_VariantCall::ConstructFunc *_VariantCall::construct_funcs = NULL;
_VariantCall::ConstantData *_VariantCall::constant_data = NULL;
-Variant Variant::call(const StringName &p_method, const Variant **p_args, int p_argcount, CallError &r_error) {
+Variant Variant::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
Variant ret;
call_ptr(p_method, p_args, p_argcount, &ret, r_error);
return ret;
}
-void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p_argcount, Variant *r_ret, CallError &r_error) {
+void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p_argcount, Variant *r_ret, Callable::CallError &r_error) {
Variant ret;
if (type == Variant::OBJECT) {
//call object
Object *obj = _get_obj().obj;
if (!obj) {
- r_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return;
}
#ifdef DEBUG_ENABLED
if (ScriptDebugger::get_singleton() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
- r_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return;
}
@@ -1111,31 +1225,57 @@ void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p
} else {
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
Map<StringName, _VariantCall::FuncData>::Element *E = _VariantCall::type_funcs[type].functions.find(p_method);
-#ifdef DEBUG_ENABLED
- if (!E) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
- return;
+
+ if (E) {
+
+ _VariantCall::FuncData &funcdata = E->get();
+ funcdata.call(ret, *this, p_args, p_argcount, r_error);
+
+ } else {
+ //handle vararg functions manually
+ bool valid = false;
+ if (type == CALLABLE) {
+ if (p_method == CoreStringNames::get_singleton()->call) {
+
+ reinterpret_cast<const Callable *>(_data._mem)->call(p_args, p_argcount, ret, r_error);
+ valid = true;
+ }
+ if (p_method == CoreStringNames::get_singleton()->call_deferred) {
+ reinterpret_cast<const Callable *>(_data._mem)->call_deferred(p_args, p_argcount);
+ valid = true;
+ }
+ } else if (type == SIGNAL) {
+ if (p_method == CoreStringNames::get_singleton()->emit) {
+ if (r_ret) {
+ *r_ret = Variant();
+ }
+ reinterpret_cast<const Signal *>(_data._mem)->emit(p_args, p_argcount);
+ valid = true;
+ }
+ }
+ if (!valid) {
+ //ok fail because not found
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
+ return;
+ }
}
-#endif
- _VariantCall::FuncData &funcdata = E->get();
- funcdata.call(ret, *this, p_args, p_argcount, r_error);
}
- if (r_error.error == Variant::CallError::CALL_OK && r_ret)
+ if (r_error.error == Callable::CallError::CALL_OK && r_ret)
*r_ret = ret;
}
#define VCALL(m_type, m_method) _VariantCall::_call_##m_type##_##m_method
-Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, int p_argcount, CallError &r_error, bool p_strict) {
+Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, int p_argcount, Callable::CallError &r_error, bool p_strict) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, Variant());
- r_error.error = Variant::CallError::CALL_OK;
+ r_error.error = Callable::CallError::CALL_OK;
if (p_argcount == 0) { //generic construct
switch (p_type) {
@@ -1145,41 +1285,47 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
// atomic types
case BOOL: return Variant(false);
case INT: return 0;
- case REAL: return 0.0f;
+ case FLOAT: return 0.0f;
case STRING:
return String();
// math types
case VECTOR2:
- return Vector2(); // 5
+ return Vector2();
case RECT2: return Rect2();
case VECTOR3: return Vector3();
case TRANSFORM2D: return Transform2D();
case PLANE: return Plane();
case QUAT: return Quat();
case AABB:
- return ::AABB(); // 10
+ return ::AABB();
case BASIS: return Basis();
case TRANSFORM:
return Transform();
// misc types
case COLOR: return Color();
+ case STRING_NAME:
+ return StringName();
case NODE_PATH:
- return NodePath(); // 15
+ return NodePath();
case _RID: return RID();
case OBJECT: return (Object *)NULL;
+ case CALLABLE: return Callable();
+ case SIGNAL: return Signal();
case DICTIONARY: return Dictionary();
case ARRAY:
- return Array(); // 20
- case POOL_BYTE_ARRAY: return PoolByteArray();
- case POOL_INT_ARRAY: return PoolIntArray();
- case POOL_REAL_ARRAY: return PoolRealArray();
- case POOL_STRING_ARRAY: return PoolStringArray();
- case POOL_VECTOR2_ARRAY:
- return PoolVector2Array(); // 25
- case POOL_VECTOR3_ARRAY: return PoolVector3Array();
- case POOL_COLOR_ARRAY: return PoolColorArray();
+ return Array();
+ case PACKED_BYTE_ARRAY: return PackedByteArray();
+ case PACKED_INT32_ARRAY: return PackedInt32Array();
+ case PACKED_INT64_ARRAY: return PackedInt64Array();
+ case PACKED_FLOAT32_ARRAY: return PackedFloat32Array();
+ case PACKED_FLOAT64_ARRAY: return PackedFloat64Array();
+ case PACKED_STRING_ARRAY: return PackedStringArray();
+ case PACKED_VECTOR2_ARRAY:
+ return PackedVector2Array();
+ case PACKED_VECTOR3_ARRAY: return PackedVector3Array();
+ case PACKED_COLOR_ARRAY: return PackedColorArray();
default: return Variant();
}
@@ -1199,7 +1345,7 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
case INT: {
return (int64_t(*p_args[0]));
}
- case REAL: {
+ case FLOAT: {
return real_t(*p_args[0]);
}
case STRING: {
@@ -1208,35 +1354,46 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
case VECTOR2: {
return Vector2(*p_args[0]);
}
+ case VECTOR2I: {
+ return Vector2i(*p_args[0]);
+ }
case RECT2: return (Rect2(*p_args[0]));
+ case RECT2I: return (Rect2i(*p_args[0]));
case VECTOR3: return (Vector3(*p_args[0]));
+ case VECTOR3I: return (Vector3i(*p_args[0]));
case PLANE: return (Plane(*p_args[0]));
case QUAT: return (p_args[0]->operator Quat());
case AABB:
- return (::AABB(*p_args[0])); // 10
+ return (::AABB(*p_args[0]));
case BASIS: return (Basis(p_args[0]->operator Basis()));
case TRANSFORM:
return (Transform(p_args[0]->operator Transform()));
// misc types
case COLOR: return p_args[0]->type == Variant::STRING ? Color::html(*p_args[0]) : Color::hex(*p_args[0]);
+ case STRING_NAME:
+ return (StringName(p_args[0]->operator StringName()));
case NODE_PATH:
- return (NodePath(p_args[0]->operator NodePath())); // 15
+ return (NodePath(p_args[0]->operator NodePath()));
case _RID: return (RID(*p_args[0]));
case OBJECT: return ((Object *)(p_args[0]->operator Object *()));
+ case CALLABLE: return ((Callable)(p_args[0]->operator Callable()));
+ case SIGNAL: return ((Signal)(p_args[0]->operator Signal()));
case DICTIONARY: return p_args[0]->operator Dictionary();
case ARRAY:
- return p_args[0]->operator Array(); // 20
+ return p_args[0]->operator Array();
// arrays
- case POOL_BYTE_ARRAY: return (PoolByteArray(*p_args[0]));
- case POOL_INT_ARRAY: return (PoolIntArray(*p_args[0]));
- case POOL_REAL_ARRAY: return (PoolRealArray(*p_args[0]));
- case POOL_STRING_ARRAY: return (PoolStringArray(*p_args[0]));
- case POOL_VECTOR2_ARRAY:
- return (PoolVector2Array(*p_args[0])); // 25
- case POOL_VECTOR3_ARRAY: return (PoolVector3Array(*p_args[0]));
- case POOL_COLOR_ARRAY: return (PoolColorArray(*p_args[0]));
+ case PACKED_BYTE_ARRAY: return (PackedByteArray(*p_args[0]));
+ case PACKED_INT32_ARRAY: return (PackedInt32Array(*p_args[0]));
+ case PACKED_INT64_ARRAY: return (PackedInt64Array(*p_args[0]));
+ case PACKED_FLOAT32_ARRAY: return (PackedFloat32Array(*p_args[0]));
+ case PACKED_FLOAT64_ARRAY: return (PackedFloat64Array(*p_args[0]));
+ case PACKED_STRING_ARRAY: return (PackedStringArray(*p_args[0]));
+ case PACKED_VECTOR2_ARRAY:
+ return (PackedVector2Array(*p_args[0]));
+ case PACKED_VECTOR3_ARRAY: return (PackedVector3Array(*p_args[0]));
+ case PACKED_COLOR_ARRAY: return (PackedColorArray(*p_args[0]));
default: return Variant();
}
} else if (p_argcount >= 1) {
@@ -1252,7 +1409,7 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
//validate parameters
for (int i = 0; i < cd.arg_count; i++) {
if (!Variant::can_convert(p_args[i]->type, cd.arg_types[i])) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; //no such constructor
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; //no such constructor
r_error.argument = i;
r_error.expected = cd.arg_types[i];
return Variant();
@@ -1264,7 +1421,7 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
return v;
}
}
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; //no such constructor
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; //no such constructor
return Variant();
}
@@ -1376,6 +1533,30 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const {
p_list->push_back(mi);
}
+
+ if (type == CALLABLE) {
+
+ MethodInfo mi;
+ mi.name = "call";
+ mi.return_val.usage = PROPERTY_USAGE_NIL_IS_VARIANT;
+ mi.flags |= METHOD_FLAG_VARARG;
+
+ p_list->push_back(mi);
+
+ mi.name = "call_deferred";
+ mi.return_val.usage = 0;
+
+ p_list->push_back(mi);
+ }
+
+ if (type == SIGNAL) {
+
+ MethodInfo mi;
+ mi.name = "emit";
+ mi.flags |= METHOD_FLAG_VARARG;
+
+ p_list->push_back(mi);
+ }
}
void Variant::get_constructor_list(Variant::Type p_type, List<MethodInfo> *p_list) {
@@ -1543,8 +1724,8 @@ void register_variant_methods() {
ADDFUNC1R(STRING, BOOL, String, ends_with, STRING, "text", varray());
ADDFUNC1R(STRING, BOOL, String, is_subsequence_of, STRING, "text", varray());
ADDFUNC1R(STRING, BOOL, String, is_subsequence_ofi, STRING, "text", varray());
- ADDFUNC0R(STRING, POOL_STRING_ARRAY, String, bigrams, varray());
- ADDFUNC1R(STRING, REAL, String, similarity, STRING, "text", varray());
+ ADDFUNC0R(STRING, PACKED_STRING_ARRAY, String, bigrams, varray());
+ ADDFUNC1R(STRING, FLOAT, String, similarity, STRING, "text", varray());
ADDFUNC2R(STRING, STRING, String, format, NIL, "values", STRING, "placeholder", varray("{_}"));
ADDFUNC2R(STRING, STRING, String, replace, STRING, "what", STRING, "forwhat", varray());
@@ -1552,9 +1733,9 @@ void register_variant_methods() {
ADDFUNC1R(STRING, STRING, String, repeat, INT, "count", varray());
ADDFUNC2R(STRING, STRING, String, insert, INT, "position", STRING, "what", varray());
ADDFUNC0R(STRING, STRING, String, capitalize, varray());
- ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, split, STRING, "delimiter", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0));
- ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, rsplit, STRING, "delimiter", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0));
- ADDFUNC2R(STRING, POOL_REAL_ARRAY, String, split_floats, STRING, "delimiter", BOOL, "allow_empty", varray(true));
+ ADDFUNC3R(STRING, PACKED_STRING_ARRAY, String, split, STRING, "delimiter", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0));
+ ADDFUNC3R(STRING, PACKED_STRING_ARRAY, String, rsplit, STRING, "delimiter", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0));
+ ADDFUNC2R(STRING, PACKED_FLOAT32_ARRAY, String, split_floats, STRING, "delimiter", BOOL, "allow_empty", varray(true));
ADDFUNC0R(STRING, STRING, String, to_upper, varray());
ADDFUNC0R(STRING, STRING, String, to_lower, varray());
@@ -1575,9 +1756,9 @@ void register_variant_methods() {
ADDFUNC0R(STRING, STRING, String, md5_text, varray());
ADDFUNC0R(STRING, STRING, String, sha1_text, varray());
ADDFUNC0R(STRING, STRING, String, sha256_text, varray());
- ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, md5_buffer, varray());
- ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, sha1_buffer, varray());
- ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, sha256_buffer, varray());
+ ADDFUNC0R(STRING, PACKED_BYTE_ARRAY, String, md5_buffer, varray());
+ ADDFUNC0R(STRING, PACKED_BYTE_ARRAY, String, sha1_buffer, varray());
+ ADDFUNC0R(STRING, PACKED_BYTE_ARRAY, String, sha256_buffer, varray());
ADDFUNC0R(STRING, BOOL, String, empty, varray());
ADDFUNC1R(STRING, STRING, String, humanize_size, INT, "size", varray());
ADDFUNC0R(STRING, BOOL, String, is_abs_path, varray());
@@ -1601,83 +1782,100 @@ void register_variant_methods() {
ADDFUNC0R(STRING, BOOL, String, is_valid_ip_address, varray());
ADDFUNC0R(STRING, BOOL, String, is_valid_filename, varray());
ADDFUNC0R(STRING, INT, String, to_int, varray());
- ADDFUNC0R(STRING, REAL, String, to_float, varray());
+ ADDFUNC0R(STRING, FLOAT, String, to_float, varray());
ADDFUNC0R(STRING, INT, String, hex_to_int, varray());
ADDFUNC1R(STRING, STRING, String, pad_decimals, INT, "digits", varray());
ADDFUNC1R(STRING, STRING, String, pad_zeros, INT, "digits", varray());
ADDFUNC1R(STRING, STRING, String, trim_prefix, STRING, "prefix", varray());
ADDFUNC1R(STRING, STRING, String, trim_suffix, STRING, "suffix", varray());
- ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, to_ascii, varray());
- ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, to_utf8, varray());
+ ADDFUNC0R(STRING, PACKED_BYTE_ARRAY, String, to_ascii, varray());
+ ADDFUNC0R(STRING, PACKED_BYTE_ARRAY, String, to_utf8, varray());
- ADDFUNC0R(VECTOR2, REAL, Vector2, angle, varray());
- ADDFUNC1R(VECTOR2, REAL, Vector2, angle_to, VECTOR2, "to", varray());
- ADDFUNC1R(VECTOR2, REAL, Vector2, angle_to_point, VECTOR2, "to", varray());
+ ADDFUNC0R(VECTOR2, FLOAT, Vector2, angle, varray());
+ ADDFUNC1R(VECTOR2, FLOAT, Vector2, angle_to, VECTOR2, "to", varray());
+ ADDFUNC1R(VECTOR2, FLOAT, Vector2, angle_to_point, VECTOR2, "to", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, direction_to, VECTOR2, "b", varray());
- ADDFUNC1R(VECTOR2, REAL, Vector2, distance_to, VECTOR2, "to", varray());
- ADDFUNC1R(VECTOR2, REAL, Vector2, distance_squared_to, VECTOR2, "to", varray());
- ADDFUNC0R(VECTOR2, REAL, Vector2, length, varray());
- ADDFUNC0R(VECTOR2, REAL, Vector2, length_squared, varray());
+ ADDFUNC1R(VECTOR2, FLOAT, Vector2, distance_to, VECTOR2, "to", varray());
+ ADDFUNC1R(VECTOR2, FLOAT, Vector2, distance_squared_to, VECTOR2, "to", varray());
+ ADDFUNC0R(VECTOR2, FLOAT, Vector2, length, varray());
+ ADDFUNC0R(VECTOR2, FLOAT, Vector2, length_squared, varray());
ADDFUNC0R(VECTOR2, VECTOR2, Vector2, normalized, varray());
ADDFUNC0R(VECTOR2, BOOL, Vector2, is_normalized, varray());
ADDFUNC1R(VECTOR2, BOOL, Vector2, is_equal_approx, VECTOR2, "v", varray());
- ADDFUNC1R(VECTOR2, VECTOR2, Vector2, posmod, REAL, "mod", varray());
+ ADDFUNC1R(VECTOR2, VECTOR2, Vector2, posmod, FLOAT, "mod", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, posmodv, VECTOR2, "modv", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, project, VECTOR2, "b", varray());
- ADDFUNC2R(VECTOR2, VECTOR2, Vector2, linear_interpolate, VECTOR2, "b", REAL, "t", varray());
- ADDFUNC2R(VECTOR2, VECTOR2, Vector2, slerp, VECTOR2, "b", REAL, "t", varray());
- ADDFUNC4R(VECTOR2, VECTOR2, Vector2, cubic_interpolate, VECTOR2, "b", VECTOR2, "pre_a", VECTOR2, "post_b", REAL, "t", varray());
- ADDFUNC2R(VECTOR2, VECTOR2, Vector2, move_toward, VECTOR2, "to", REAL, "delta", varray());
- ADDFUNC1R(VECTOR2, VECTOR2, Vector2, rotated, REAL, "phi", varray());
+ ADDFUNC2R(VECTOR2, VECTOR2, Vector2, linear_interpolate, VECTOR2, "b", FLOAT, "t", varray());
+ ADDFUNC2R(VECTOR2, VECTOR2, Vector2, slerp, VECTOR2, "b", FLOAT, "t", varray());
+ ADDFUNC4R(VECTOR2, VECTOR2, Vector2, cubic_interpolate, VECTOR2, "b", VECTOR2, "pre_a", VECTOR2, "post_b", FLOAT, "t", varray());
+ ADDFUNC2R(VECTOR2, VECTOR2, Vector2, move_toward, VECTOR2, "to", FLOAT, "delta", varray());
+ ADDFUNC1R(VECTOR2, VECTOR2, Vector2, rotated, FLOAT, "phi", varray());
ADDFUNC0R(VECTOR2, VECTOR2, Vector2, tangent, varray());
ADDFUNC0R(VECTOR2, VECTOR2, Vector2, floor, varray());
ADDFUNC0R(VECTOR2, VECTOR2, Vector2, ceil, varray());
ADDFUNC0R(VECTOR2, VECTOR2, Vector2, round, varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, snapped, VECTOR2, "by", varray());
- ADDFUNC0R(VECTOR2, REAL, Vector2, aspect, varray());
- ADDFUNC1R(VECTOR2, REAL, Vector2, dot, VECTOR2, "with", varray());
+ ADDFUNC0R(VECTOR2, FLOAT, Vector2, aspect, varray());
+ ADDFUNC1R(VECTOR2, FLOAT, Vector2, dot, VECTOR2, "with", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, slide, VECTOR2, "n", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, bounce, VECTOR2, "n", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, reflect, VECTOR2, "n", varray());
- ADDFUNC1R(VECTOR2, REAL, Vector2, cross, VECTOR2, "with", varray());
+ ADDFUNC1R(VECTOR2, FLOAT, Vector2, cross, VECTOR2, "with", varray());
ADDFUNC0R(VECTOR2, VECTOR2, Vector2, abs, varray());
- ADDFUNC1R(VECTOR2, VECTOR2, Vector2, clamped, REAL, "length", varray());
+ ADDFUNC1R(VECTOR2, VECTOR2, Vector2, clamped, FLOAT, "length", varray());
ADDFUNC0R(VECTOR2, VECTOR2, Vector2, sign, varray());
- ADDFUNC0R(RECT2, REAL, Rect2, get_area, varray());
+ ADDFUNC0R(VECTOR2I, FLOAT, Vector2i, aspect, varray());
+ ADDFUNC0R(VECTOR2I, VECTOR2I, Vector2i, sign, varray());
+ ADDFUNC0R(VECTOR2I, VECTOR2I, Vector2i, abs, varray());
+
+ ADDFUNC0R(RECT2, FLOAT, Rect2, get_area, varray());
ADDFUNC0R(RECT2, BOOL, Rect2, has_no_area, varray());
ADDFUNC1R(RECT2, BOOL, Rect2, has_point, VECTOR2, "point", varray());
ADDFUNC1R(RECT2, BOOL, Rect2, is_equal_approx, RECT2, "rect", varray());
- ADDFUNC1R(RECT2, BOOL, Rect2, intersects, RECT2, "b", varray());
+ ADDFUNC2R(RECT2, BOOL, Rect2, intersects, RECT2, "b", BOOL, "include_borders", varray(false));
ADDFUNC1R(RECT2, BOOL, Rect2, encloses, RECT2, "b", varray());
ADDFUNC1R(RECT2, RECT2, Rect2, clip, RECT2, "b", varray());
ADDFUNC1R(RECT2, RECT2, Rect2, merge, RECT2, "b", varray());
ADDFUNC1R(RECT2, RECT2, Rect2, expand, VECTOR2, "to", varray());
- ADDFUNC1R(RECT2, RECT2, Rect2, grow, REAL, "by", varray());
- ADDFUNC2R(RECT2, RECT2, Rect2, grow_margin, INT, "margin", REAL, "by", varray());
- ADDFUNC4R(RECT2, RECT2, Rect2, grow_individual, REAL, "left", REAL, "top", REAL, "right", REAL, " bottom", varray());
+ ADDFUNC1R(RECT2, RECT2, Rect2, grow, FLOAT, "by", varray());
+ ADDFUNC2R(RECT2, RECT2, Rect2, grow_margin, INT, "margin", FLOAT, "by", varray());
+ ADDFUNC4R(RECT2, RECT2, Rect2, grow_individual, FLOAT, "left", FLOAT, "top", FLOAT, "right", FLOAT, " bottom", varray());
ADDFUNC0R(RECT2, RECT2, Rect2, abs, varray());
+ ADDFUNC0R(RECT2I, INT, Rect2i, get_area, varray());
+ ADDFUNC0R(RECT2I, BOOL, Rect2i, has_no_area, varray());
+ ADDFUNC1R(RECT2I, BOOL, Rect2i, has_point, VECTOR2I, "point", varray());
+ ADDFUNC1R(RECT2I, BOOL, Rect2i, intersects, RECT2I, "b", varray());
+ ADDFUNC1R(RECT2I, BOOL, Rect2i, encloses, RECT2I, "b", varray());
+ ADDFUNC1R(RECT2I, RECT2I, Rect2i, clip, RECT2I, "b", varray());
+ ADDFUNC1R(RECT2I, RECT2I, Rect2i, merge, RECT2I, "b", varray());
+ ADDFUNC1R(RECT2I, RECT2I, Rect2i, expand, VECTOR2I, "to", varray());
+ ADDFUNC1R(RECT2I, RECT2I, Rect2i, grow, INT, "by", varray());
+ ADDFUNC2R(RECT2I, RECT2I, Rect2i, grow_margin, INT, "margin", INT, "by", varray());
+ ADDFUNC4R(RECT2I, RECT2I, Rect2i, grow_individual, INT, "left", INT, "top", INT, "right", INT, " bottom", varray());
+ ADDFUNC0R(RECT2I, RECT2I, Rect2i, abs, varray());
+
ADDFUNC0R(VECTOR3, INT, Vector3, min_axis, varray());
ADDFUNC0R(VECTOR3, INT, Vector3, max_axis, varray());
- ADDFUNC1R(VECTOR3, REAL, Vector3, angle_to, VECTOR3, "to", varray());
+ ADDFUNC1R(VECTOR3, FLOAT, Vector3, angle_to, VECTOR3, "to", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, direction_to, VECTOR3, "b", varray());
- ADDFUNC1R(VECTOR3, REAL, Vector3, distance_to, VECTOR3, "b", varray());
- ADDFUNC1R(VECTOR3, REAL, Vector3, distance_squared_to, VECTOR3, "b", varray());
- ADDFUNC0R(VECTOR3, REAL, Vector3, length, varray());
- ADDFUNC0R(VECTOR3, REAL, Vector3, length_squared, varray());
+ ADDFUNC1R(VECTOR3, FLOAT, Vector3, distance_to, VECTOR3, "b", varray());
+ ADDFUNC1R(VECTOR3, FLOAT, Vector3, distance_squared_to, VECTOR3, "b", varray());
+ ADDFUNC0R(VECTOR3, FLOAT, Vector3, length, varray());
+ ADDFUNC0R(VECTOR3, FLOAT, Vector3, length_squared, varray());
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, normalized, varray());
ADDFUNC0R(VECTOR3, BOOL, Vector3, is_normalized, varray());
ADDFUNC1R(VECTOR3, BOOL, Vector3, is_equal_approx, VECTOR3, "v", varray());
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, inverse, varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, snapped, VECTOR3, "by", varray());
- ADDFUNC2R(VECTOR3, VECTOR3, Vector3, rotated, VECTOR3, "axis", REAL, "phi", varray());
- ADDFUNC2R(VECTOR3, VECTOR3, Vector3, linear_interpolate, VECTOR3, "b", REAL, "t", varray());
- ADDFUNC2R(VECTOR3, VECTOR3, Vector3, slerp, VECTOR3, "b", REAL, "t", varray());
- ADDFUNC4R(VECTOR3, VECTOR3, Vector3, cubic_interpolate, VECTOR3, "b", VECTOR3, "pre_a", VECTOR3, "post_b", REAL, "t", varray());
- ADDFUNC2R(VECTOR3, VECTOR3, Vector3, move_toward, VECTOR3, "to", REAL, "delta", varray());
- ADDFUNC1R(VECTOR3, REAL, Vector3, dot, VECTOR3, "b", varray());
+ ADDFUNC2R(VECTOR3, VECTOR3, Vector3, rotated, VECTOR3, "axis", FLOAT, "phi", varray());
+ ADDFUNC2R(VECTOR3, VECTOR3, Vector3, linear_interpolate, VECTOR3, "b", FLOAT, "t", varray());
+ ADDFUNC2R(VECTOR3, VECTOR3, Vector3, slerp, VECTOR3, "b", FLOAT, "t", varray());
+ ADDFUNC4R(VECTOR3, VECTOR3, Vector3, cubic_interpolate, VECTOR3, "b", VECTOR3, "pre_a", VECTOR3, "post_b", FLOAT, "t", varray());
+ ADDFUNC2R(VECTOR3, VECTOR3, Vector3, move_toward, VECTOR3, "to", FLOAT, "delta", varray());
+ ADDFUNC1R(VECTOR3, FLOAT, Vector3, dot, VECTOR3, "b", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, cross, VECTOR3, "b", varray());
ADDFUNC1R(VECTOR3, BASIS, Vector3, outer, VECTOR3, "b", varray());
ADDFUNC0R(VECTOR3, BASIS, Vector3, to_diagonal_matrix, varray());
@@ -1685,7 +1883,7 @@ void register_variant_methods() {
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, floor, varray());
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, ceil, varray());
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, round, varray());
- ADDFUNC1R(VECTOR3, VECTOR3, Vector3, posmod, REAL, "mod", varray());
+ ADDFUNC1R(VECTOR3, VECTOR3, Vector3, posmod, FLOAT, "mod", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, posmodv, VECTOR3, "modv", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, project, VECTOR3, "b", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, slide, VECTOR3, "n", varray());
@@ -1693,32 +1891,36 @@ void register_variant_methods() {
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, reflect, VECTOR3, "n", varray());
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, sign, varray());
+ ADDFUNC0R(VECTOR3I, INT, Vector3i, min_axis, varray());
+ ADDFUNC0R(VECTOR3I, INT, Vector3i, max_axis, varray());
+ ADDFUNC0R(VECTOR3I, VECTOR3I, Vector3i, sign, varray());
+
ADDFUNC0R(PLANE, PLANE, Plane, normalized, varray());
ADDFUNC0R(PLANE, VECTOR3, Plane, center, varray());
ADDFUNC0R(PLANE, VECTOR3, Plane, get_any_point, varray());
ADDFUNC1R(PLANE, BOOL, Plane, is_equal_approx, PLANE, "plane", varray());
ADDFUNC1R(PLANE, BOOL, Plane, is_point_over, VECTOR3, "point", varray());
- ADDFUNC1R(PLANE, REAL, Plane, distance_to, VECTOR3, "point", varray());
- ADDFUNC2R(PLANE, BOOL, Plane, has_point, VECTOR3, "point", REAL, "epsilon", varray(CMP_EPSILON));
+ ADDFUNC1R(PLANE, FLOAT, Plane, distance_to, VECTOR3, "point", varray());
+ ADDFUNC2R(PLANE, BOOL, Plane, has_point, VECTOR3, "point", FLOAT, "epsilon", varray(CMP_EPSILON));
ADDFUNC1R(PLANE, VECTOR3, Plane, project, VECTOR3, "point", varray());
ADDFUNC2R(PLANE, VECTOR3, Plane, intersect_3, PLANE, "b", PLANE, "c", varray());
ADDFUNC2R(PLANE, VECTOR3, Plane, intersects_ray, VECTOR3, "from", VECTOR3, "dir", varray());
ADDFUNC2R(PLANE, VECTOR3, Plane, intersects_segment, VECTOR3, "begin", VECTOR3, "end", varray());
- ADDFUNC0R(QUAT, REAL, Quat, length, varray());
- ADDFUNC0R(QUAT, REAL, Quat, length_squared, varray());
+ ADDFUNC0R(QUAT, FLOAT, Quat, length, varray());
+ ADDFUNC0R(QUAT, FLOAT, Quat, length_squared, varray());
ADDFUNC0R(QUAT, QUAT, Quat, normalized, varray());
ADDFUNC0R(QUAT, BOOL, Quat, is_normalized, varray());
ADDFUNC1R(QUAT, BOOL, Quat, is_equal_approx, QUAT, "quat", varray());
ADDFUNC0R(QUAT, QUAT, Quat, inverse, varray());
- ADDFUNC1R(QUAT, REAL, Quat, dot, QUAT, "b", varray());
+ ADDFUNC1R(QUAT, FLOAT, Quat, dot, QUAT, "b", varray());
ADDFUNC1R(QUAT, VECTOR3, Quat, xform, VECTOR3, "v", varray());
- ADDFUNC2R(QUAT, QUAT, Quat, slerp, QUAT, "b", REAL, "t", varray());
- ADDFUNC2R(QUAT, QUAT, Quat, slerpni, QUAT, "b", REAL, "t", varray());
- ADDFUNC4R(QUAT, QUAT, Quat, cubic_slerp, QUAT, "b", QUAT, "pre_a", QUAT, "post_b", REAL, "t", varray());
+ ADDFUNC2R(QUAT, QUAT, Quat, slerp, QUAT, "b", FLOAT, "t", varray());
+ ADDFUNC2R(QUAT, QUAT, Quat, slerpni, QUAT, "b", FLOAT, "t", varray());
+ ADDFUNC4R(QUAT, QUAT, Quat, cubic_slerp, QUAT, "b", QUAT, "pre_a", QUAT, "post_b", FLOAT, "t", varray());
ADDFUNC0R(QUAT, VECTOR3, Quat, get_euler, varray());
ADDFUNC1(QUAT, NIL, Quat, set_euler, VECTOR3, "euler", varray());
- ADDFUNC2(QUAT, NIL, Quat, set_axis_angle, VECTOR3, "axis", REAL, "angle", varray());
+ ADDFUNC2(QUAT, NIL, Quat, set_axis_angle, VECTOR3, "axis", FLOAT, "angle", varray());
ADDFUNC0R(COLOR, INT, Color, to_argb32, varray());
ADDFUNC0R(COLOR, INT, Color, to_abgr32, varray());
@@ -1728,12 +1930,12 @@ void register_variant_methods() {
ADDFUNC0R(COLOR, INT, Color, to_rgba64, varray());
ADDFUNC0R(COLOR, COLOR, Color, inverted, varray());
ADDFUNC0R(COLOR, COLOR, Color, contrasted, varray());
- ADDFUNC2R(COLOR, COLOR, Color, linear_interpolate, COLOR, "b", REAL, "t", varray());
+ ADDFUNC2R(COLOR, COLOR, Color, linear_interpolate, COLOR, "b", FLOAT, "t", varray());
ADDFUNC1R(COLOR, COLOR, Color, blend, COLOR, "over", varray());
- ADDFUNC1R(COLOR, COLOR, Color, lightened, REAL, "amount", varray());
- ADDFUNC1R(COLOR, COLOR, Color, darkened, REAL, "amount", varray());
+ ADDFUNC1R(COLOR, COLOR, Color, lightened, FLOAT, "amount", varray());
+ ADDFUNC1R(COLOR, COLOR, Color, darkened, FLOAT, "amount", varray());
ADDFUNC1R(COLOR, STRING, Color, to_html, BOOL, "with_alpha", varray(true));
- ADDFUNC4R(COLOR, COLOR, Color, from_hsv, REAL, "h", REAL, "s", REAL, "v", REAL, "a", varray(1.0));
+ ADDFUNC4R(COLOR, COLOR, Color, from_hsv, FLOAT, "h", FLOAT, "s", FLOAT, "v", FLOAT, "a", varray(1.0));
ADDFUNC1R(COLOR, BOOL, Color, is_equal_approx, COLOR, "color", varray());
ADDFUNC0R(_RID, INT, RID, get_id, varray());
@@ -1759,6 +1961,25 @@ void register_variant_methods() {
ADDFUNC1R(DICTIONARY, DICTIONARY, Dictionary, duplicate, BOOL, "deep", varray(false));
ADDFUNC2R(DICTIONARY, NIL, Dictionary, get, NIL, "key", NIL, "default", varray(Variant()));
+ ADDFUNC0R(CALLABLE, BOOL, Callable, is_null, varray());
+ ADDFUNC0R(CALLABLE, BOOL, Callable, is_custom, varray());
+ ADDFUNC0R(CALLABLE, BOOL, Callable, is_standard, varray());
+ ADDFUNC0R(CALLABLE, OBJECT, Callable, get_object, varray());
+ ADDFUNC0R(CALLABLE, INT, Callable, get_object_id, varray());
+ ADDFUNC0R(CALLABLE, STRING_NAME, Callable, get_method, varray());
+ ADDFUNC0R(CALLABLE, INT, Callable, hash, varray());
+
+ ADDFUNC0R(SIGNAL, BOOL, Signal, is_null, varray());
+ ADDFUNC0R(SIGNAL, OBJECT, Signal, get_object, varray());
+ ADDFUNC0R(SIGNAL, INT, Signal, get_object_id, varray());
+ ADDFUNC0R(SIGNAL, STRING_NAME, Signal, get_name, varray());
+
+ ADDFUNC3R(SIGNAL, INT, Signal, connect, CALLABLE, "callable", ARRAY, "binds", INT, "flags", varray(Array(), 0));
+
+ ADDFUNC1R(SIGNAL, NIL, Signal, disconnect, CALLABLE, "callable", varray());
+ ADDFUNC1R(SIGNAL, BOOL, Signal, is_connected, CALLABLE, "callable", varray());
+ ADDFUNC0R(SIGNAL, ARRAY, Signal, get_connections, varray());
+
ADDFUNC0R(ARRAY, INT, Array, size, varray());
ADDFUNC0R(ARRAY, BOOL, Array, empty, varray());
ADDFUNC0NC(ARRAY, NIL, Array, clear, varray());
@@ -1790,94 +2011,115 @@ void register_variant_methods() {
ADDFUNC0R(ARRAY, NIL, Array, max, varray());
ADDFUNC0R(ARRAY, NIL, Array, min, varray());
- ADDFUNC0R(POOL_BYTE_ARRAY, INT, PoolByteArray, size, varray());
- ADDFUNC0R(POOL_BYTE_ARRAY, BOOL, PoolByteArray, empty, varray());
- ADDFUNC2(POOL_BYTE_ARRAY, NIL, PoolByteArray, set, INT, "idx", INT, "byte", varray());
- ADDFUNC1(POOL_BYTE_ARRAY, NIL, PoolByteArray, push_back, INT, "byte", varray());
- ADDFUNC1(POOL_BYTE_ARRAY, NIL, PoolByteArray, append, INT, "byte", varray());
- ADDFUNC1(POOL_BYTE_ARRAY, NIL, PoolByteArray, append_array, POOL_BYTE_ARRAY, "array", varray());
- ADDFUNC1(POOL_BYTE_ARRAY, NIL, PoolByteArray, remove, INT, "idx", varray());
- ADDFUNC2R(POOL_BYTE_ARRAY, INT, PoolByteArray, insert, INT, "idx", INT, "byte", varray());
- ADDFUNC1(POOL_BYTE_ARRAY, NIL, PoolByteArray, resize, INT, "idx", varray());
- ADDFUNC0(POOL_BYTE_ARRAY, NIL, PoolByteArray, invert, varray());
- ADDFUNC2R(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, subarray, INT, "from", INT, "to", varray());
-
- ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_ascii, varray());
- ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_utf8, varray());
- ADDFUNC0R(POOL_BYTE_ARRAY, STRING, PoolByteArray, hex_encode, varray());
- ADDFUNC1R(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, compress, INT, "compression_mode", varray(0));
- ADDFUNC2R(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, decompress, INT, "buffer_size", INT, "compression_mode", varray(0));
-
- ADDFUNC0R(POOL_INT_ARRAY, INT, PoolIntArray, size, varray());
- ADDFUNC0R(POOL_INT_ARRAY, BOOL, PoolIntArray, empty, varray());
- ADDFUNC2(POOL_INT_ARRAY, NIL, PoolIntArray, set, INT, "idx", INT, "integer", varray());
- ADDFUNC1(POOL_INT_ARRAY, NIL, PoolIntArray, push_back, INT, "integer", varray());
- ADDFUNC1(POOL_INT_ARRAY, NIL, PoolIntArray, append, INT, "integer", varray());
- ADDFUNC1(POOL_INT_ARRAY, NIL, PoolIntArray, append_array, POOL_INT_ARRAY, "array", varray());
- ADDFUNC1(POOL_INT_ARRAY, NIL, PoolIntArray, remove, INT, "idx", varray());
- ADDFUNC2R(POOL_INT_ARRAY, INT, PoolIntArray, insert, INT, "idx", INT, "integer", varray());
- ADDFUNC1(POOL_INT_ARRAY, NIL, PoolIntArray, resize, INT, "idx", varray());
- ADDFUNC0(POOL_INT_ARRAY, NIL, PoolIntArray, invert, varray());
-
- ADDFUNC0R(POOL_REAL_ARRAY, INT, PoolRealArray, size, varray());
- ADDFUNC0R(POOL_REAL_ARRAY, BOOL, PoolRealArray, empty, varray());
- ADDFUNC2(POOL_REAL_ARRAY, NIL, PoolRealArray, set, INT, "idx", REAL, "value", varray());
- ADDFUNC1(POOL_REAL_ARRAY, NIL, PoolRealArray, push_back, REAL, "value", varray());
- ADDFUNC1(POOL_REAL_ARRAY, NIL, PoolRealArray, append, REAL, "value", varray());
- ADDFUNC1(POOL_REAL_ARRAY, NIL, PoolRealArray, append_array, POOL_REAL_ARRAY, "array", varray());
- ADDFUNC1(POOL_REAL_ARRAY, NIL, PoolRealArray, remove, INT, "idx", varray());
- ADDFUNC2R(POOL_REAL_ARRAY, INT, PoolRealArray, insert, INT, "idx", REAL, "value", varray());
- ADDFUNC1(POOL_REAL_ARRAY, NIL, PoolRealArray, resize, INT, "idx", varray());
- ADDFUNC0(POOL_REAL_ARRAY, NIL, PoolRealArray, invert, varray());
-
- ADDFUNC0R(POOL_STRING_ARRAY, INT, PoolStringArray, size, varray());
- ADDFUNC0R(POOL_STRING_ARRAY, BOOL, PoolStringArray, empty, varray());
- ADDFUNC2(POOL_STRING_ARRAY, NIL, PoolStringArray, set, INT, "idx", STRING, "string", varray());
- ADDFUNC1(POOL_STRING_ARRAY, NIL, PoolStringArray, push_back, STRING, "string", varray());
- ADDFUNC1(POOL_STRING_ARRAY, NIL, PoolStringArray, append, STRING, "string", varray());
- ADDFUNC1(POOL_STRING_ARRAY, NIL, PoolStringArray, append_array, POOL_STRING_ARRAY, "array", varray());
- ADDFUNC1(POOL_STRING_ARRAY, NIL, PoolStringArray, remove, INT, "idx", varray());
- ADDFUNC2R(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, "delimiter", varray());
-
- ADDFUNC0R(POOL_VECTOR2_ARRAY, INT, PoolVector2Array, size, varray());
- ADDFUNC0R(POOL_VECTOR2_ARRAY, BOOL, PoolVector2Array, empty, varray());
- ADDFUNC2(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, set, INT, "idx", VECTOR2, "vector2", varray());
- ADDFUNC1(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, push_back, VECTOR2, "vector2", varray());
- ADDFUNC1(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, append, VECTOR2, "vector2", varray());
- ADDFUNC1(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, append_array, POOL_VECTOR2_ARRAY, "array", varray());
- ADDFUNC1(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, remove, INT, "idx", varray());
- ADDFUNC2R(POOL_VECTOR2_ARRAY, INT, PoolVector2Array, insert, INT, "idx", VECTOR2, "vector2", varray());
- ADDFUNC1(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, resize, INT, "idx", varray());
- ADDFUNC0(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, invert, varray());
-
- ADDFUNC0R(POOL_VECTOR3_ARRAY, INT, PoolVector3Array, size, varray());
- ADDFUNC0R(POOL_VECTOR3_ARRAY, BOOL, PoolVector3Array, empty, varray());
- ADDFUNC2(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, set, INT, "idx", VECTOR3, "vector3", varray());
- ADDFUNC1(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, push_back, VECTOR3, "vector3", varray());
- ADDFUNC1(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, append, VECTOR3, "vector3", varray());
- ADDFUNC1(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, append_array, POOL_VECTOR3_ARRAY, "array", varray());
- ADDFUNC1(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, remove, INT, "idx", varray());
- ADDFUNC2R(POOL_VECTOR3_ARRAY, INT, PoolVector3Array, insert, INT, "idx", VECTOR3, "vector3", varray());
- ADDFUNC1(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, resize, INT, "idx", varray());
- ADDFUNC0(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, invert, varray());
-
- ADDFUNC0R(POOL_COLOR_ARRAY, INT, PoolColorArray, size, varray());
- ADDFUNC0R(POOL_COLOR_ARRAY, BOOL, PoolColorArray, empty, varray());
- ADDFUNC2(POOL_COLOR_ARRAY, NIL, PoolColorArray, set, INT, "idx", COLOR, "color", varray());
- ADDFUNC1(POOL_COLOR_ARRAY, NIL, PoolColorArray, push_back, COLOR, "color", varray());
- ADDFUNC1(POOL_COLOR_ARRAY, NIL, PoolColorArray, append, COLOR, "color", varray());
- ADDFUNC1(POOL_COLOR_ARRAY, NIL, PoolColorArray, append_array, POOL_COLOR_ARRAY, "array", varray());
- ADDFUNC1(POOL_COLOR_ARRAY, NIL, PoolColorArray, remove, INT, "idx", varray());
- ADDFUNC2R(POOL_COLOR_ARRAY, INT, PoolColorArray, insert, INT, "idx", COLOR, "color", varray());
- ADDFUNC1(POOL_COLOR_ARRAY, NIL, PoolColorArray, resize, INT, "idx", varray());
- ADDFUNC0(POOL_COLOR_ARRAY, NIL, PoolColorArray, invert, varray());
+ ADDFUNC0R(PACKED_BYTE_ARRAY, INT, PackedByteArray, size, varray());
+ ADDFUNC0R(PACKED_BYTE_ARRAY, BOOL, PackedByteArray, empty, varray());
+ ADDFUNC2(PACKED_BYTE_ARRAY, NIL, PackedByteArray, set, INT, "idx", INT, "byte", varray());
+ ADDFUNC1(PACKED_BYTE_ARRAY, NIL, PackedByteArray, push_back, INT, "byte", varray());
+ ADDFUNC1(PACKED_BYTE_ARRAY, NIL, PackedByteArray, append, INT, "byte", varray());
+ ADDFUNC1(PACKED_BYTE_ARRAY, NIL, PackedByteArray, append_array, PACKED_BYTE_ARRAY, "array", varray());
+ ADDFUNC1(PACKED_BYTE_ARRAY, NIL, PackedByteArray, remove, INT, "idx", varray());
+ ADDFUNC2R(PACKED_BYTE_ARRAY, INT, PackedByteArray, insert, INT, "idx", INT, "byte", varray());
+ ADDFUNC1(PACKED_BYTE_ARRAY, NIL, PackedByteArray, resize, INT, "idx", varray());
+ ADDFUNC0(PACKED_BYTE_ARRAY, NIL, PackedByteArray, invert, varray());
+ ADDFUNC2R(PACKED_BYTE_ARRAY, PACKED_BYTE_ARRAY, PackedByteArray, subarray, INT, "from", INT, "to", varray());
+
+ ADDFUNC0R(PACKED_BYTE_ARRAY, STRING, PackedByteArray, get_string_from_ascii, varray());
+ ADDFUNC0R(PACKED_BYTE_ARRAY, STRING, PackedByteArray, get_string_from_utf8, varray());
+ ADDFUNC0R(PACKED_BYTE_ARRAY, STRING, PackedByteArray, hex_encode, varray());
+ ADDFUNC1R(PACKED_BYTE_ARRAY, PACKED_BYTE_ARRAY, PackedByteArray, compress, INT, "compression_mode", varray(0));
+ ADDFUNC2R(PACKED_BYTE_ARRAY, PACKED_BYTE_ARRAY, PackedByteArray, decompress, INT, "buffer_size", INT, "compression_mode", varray(0));
+
+ ADDFUNC0R(PACKED_INT32_ARRAY, INT, PackedInt32Array, size, varray());
+ ADDFUNC0R(PACKED_INT32_ARRAY, BOOL, PackedInt32Array, empty, varray());
+ ADDFUNC2(PACKED_INT32_ARRAY, NIL, PackedInt32Array, set, INT, "idx", INT, "integer", varray());
+ ADDFUNC1(PACKED_INT32_ARRAY, NIL, PackedInt32Array, push_back, INT, "integer", varray());
+ ADDFUNC1(PACKED_INT32_ARRAY, NIL, PackedInt32Array, append, INT, "integer", varray());
+ ADDFUNC1(PACKED_INT32_ARRAY, NIL, PackedInt32Array, append_array, PACKED_INT32_ARRAY, "array", varray());
+ ADDFUNC1(PACKED_INT32_ARRAY, NIL, PackedInt32Array, remove, INT, "idx", varray());
+ ADDFUNC2R(PACKED_INT32_ARRAY, INT, PackedInt32Array, insert, INT, "idx", INT, "integer", varray());
+ ADDFUNC1(PACKED_INT32_ARRAY, NIL, PackedInt32Array, resize, INT, "idx", varray());
+ ADDFUNC0(PACKED_INT32_ARRAY, NIL, PackedInt32Array, invert, varray());
+
+ ADDFUNC0R(PACKED_INT64_ARRAY, INT, PackedInt64Array, size, varray());
+ ADDFUNC0R(PACKED_INT64_ARRAY, BOOL, PackedInt64Array, empty, varray());
+ ADDFUNC2(PACKED_INT64_ARRAY, NIL, PackedInt64Array, set, INT, "idx", INT, "integer", varray());
+ ADDFUNC1(PACKED_INT64_ARRAY, NIL, PackedInt64Array, push_back, INT, "integer", varray());
+ ADDFUNC1(PACKED_INT64_ARRAY, NIL, PackedInt64Array, append, INT, "integer", varray());
+ ADDFUNC1(PACKED_INT64_ARRAY, NIL, PackedInt64Array, append_array, PACKED_INT64_ARRAY, "array", varray());
+ ADDFUNC1(PACKED_INT64_ARRAY, NIL, PackedInt64Array, remove, INT, "idx", varray());
+ ADDFUNC2R(PACKED_INT64_ARRAY, INT, PackedInt64Array, insert, INT, "idx", INT, "integer", varray());
+ ADDFUNC1(PACKED_INT64_ARRAY, NIL, PackedInt64Array, resize, INT, "idx", varray());
+ ADDFUNC0(PACKED_INT64_ARRAY, NIL, PackedInt64Array, invert, varray());
+
+ ADDFUNC0R(PACKED_FLOAT32_ARRAY, INT, PackedFloat32Array, size, varray());
+ ADDFUNC0R(PACKED_FLOAT32_ARRAY, BOOL, PackedFloat32Array, empty, varray());
+ ADDFUNC2(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, set, INT, "idx", FLOAT, "value", varray());
+ ADDFUNC1(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, push_back, FLOAT, "value", varray());
+ ADDFUNC1(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, append, FLOAT, "value", varray());
+ ADDFUNC1(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, append_array, PACKED_FLOAT32_ARRAY, "array", varray());
+ ADDFUNC1(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, remove, INT, "idx", varray());
+ ADDFUNC2R(PACKED_FLOAT32_ARRAY, INT, PackedFloat32Array, insert, INT, "idx", FLOAT, "value", varray());
+ ADDFUNC1(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, resize, INT, "idx", varray());
+ ADDFUNC0(PACKED_FLOAT32_ARRAY, NIL, PackedFloat32Array, invert, varray());
+
+ ADDFUNC0R(PACKED_FLOAT64_ARRAY, INT, PackedFloat64Array, size, varray());
+ ADDFUNC0R(PACKED_FLOAT64_ARRAY, BOOL, PackedFloat64Array, empty, varray());
+ ADDFUNC2(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, set, INT, "idx", FLOAT, "value", varray());
+ ADDFUNC1(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, push_back, FLOAT, "value", varray());
+ ADDFUNC1(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, append, FLOAT, "value", varray());
+ ADDFUNC1(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, append_array, PACKED_FLOAT64_ARRAY, "array", varray());
+ ADDFUNC1(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, remove, INT, "idx", varray());
+ ADDFUNC2R(PACKED_FLOAT64_ARRAY, INT, PackedFloat64Array, insert, INT, "idx", FLOAT, "value", varray());
+ ADDFUNC1(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, resize, INT, "idx", varray());
+ ADDFUNC0(PACKED_FLOAT64_ARRAY, NIL, PackedFloat64Array, invert, varray());
+
+ ADDFUNC0R(PACKED_STRING_ARRAY, INT, PackedStringArray, size, varray());
+ ADDFUNC0R(PACKED_STRING_ARRAY, BOOL, PackedStringArray, empty, varray());
+ ADDFUNC2(PACKED_STRING_ARRAY, NIL, PackedStringArray, set, INT, "idx", STRING, "string", varray());
+ ADDFUNC1(PACKED_STRING_ARRAY, NIL, PackedStringArray, push_back, STRING, "string", varray());
+ ADDFUNC1(PACKED_STRING_ARRAY, NIL, PackedStringArray, append, STRING, "string", varray());
+ ADDFUNC1(PACKED_STRING_ARRAY, NIL, PackedStringArray, append_array, PACKED_STRING_ARRAY, "array", varray());
+ ADDFUNC1(PACKED_STRING_ARRAY, NIL, PackedStringArray, remove, INT, "idx", varray());
+ ADDFUNC2R(PACKED_STRING_ARRAY, INT, PackedStringArray, insert, INT, "idx", STRING, "string", varray());
+ ADDFUNC1(PACKED_STRING_ARRAY, NIL, PackedStringArray, resize, INT, "idx", varray());
+ ADDFUNC0(PACKED_STRING_ARRAY, NIL, PackedStringArray, invert, varray());
+
+ ADDFUNC0R(PACKED_VECTOR2_ARRAY, INT, PackedVector2Array, size, varray());
+ ADDFUNC0R(PACKED_VECTOR2_ARRAY, BOOL, PackedVector2Array, empty, varray());
+ ADDFUNC2(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, set, INT, "idx", VECTOR2, "vector2", varray());
+ ADDFUNC1(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, push_back, VECTOR2, "vector2", varray());
+ ADDFUNC1(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, append, VECTOR2, "vector2", varray());
+ ADDFUNC1(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, append_array, PACKED_VECTOR2_ARRAY, "array", varray());
+ ADDFUNC1(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, remove, INT, "idx", varray());
+ ADDFUNC2R(PACKED_VECTOR2_ARRAY, INT, PackedVector2Array, insert, INT, "idx", VECTOR2, "vector2", varray());
+ ADDFUNC1(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, resize, INT, "idx", varray());
+ ADDFUNC0(PACKED_VECTOR2_ARRAY, NIL, PackedVector2Array, invert, varray());
+
+ ADDFUNC0R(PACKED_VECTOR3_ARRAY, INT, PackedVector3Array, size, varray());
+ ADDFUNC0R(PACKED_VECTOR3_ARRAY, BOOL, PackedVector3Array, empty, varray());
+ ADDFUNC2(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, set, INT, "idx", VECTOR3, "vector3", varray());
+ ADDFUNC1(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, push_back, VECTOR3, "vector3", varray());
+ ADDFUNC1(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, append, VECTOR3, "vector3", varray());
+ ADDFUNC1(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, append_array, PACKED_VECTOR3_ARRAY, "array", varray());
+ ADDFUNC1(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, remove, INT, "idx", varray());
+ ADDFUNC2R(PACKED_VECTOR3_ARRAY, INT, PackedVector3Array, insert, INT, "idx", VECTOR3, "vector3", varray());
+ ADDFUNC1(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, resize, INT, "idx", varray());
+ ADDFUNC0(PACKED_VECTOR3_ARRAY, NIL, PackedVector3Array, invert, varray());
+
+ ADDFUNC0R(PACKED_COLOR_ARRAY, INT, PackedColorArray, size, varray());
+ ADDFUNC0R(PACKED_COLOR_ARRAY, BOOL, PackedColorArray, empty, varray());
+ ADDFUNC2(PACKED_COLOR_ARRAY, NIL, PackedColorArray, set, INT, "idx", COLOR, "color", varray());
+ ADDFUNC1(PACKED_COLOR_ARRAY, NIL, PackedColorArray, push_back, COLOR, "color", varray());
+ ADDFUNC1(PACKED_COLOR_ARRAY, NIL, PackedColorArray, append, COLOR, "color", varray());
+ ADDFUNC1(PACKED_COLOR_ARRAY, NIL, PackedColorArray, append_array, PACKED_COLOR_ARRAY, "array", varray());
+ ADDFUNC1(PACKED_COLOR_ARRAY, NIL, PackedColorArray, remove, INT, "idx", varray());
+ ADDFUNC2R(PACKED_COLOR_ARRAY, INT, PackedColorArray, insert, INT, "idx", COLOR, "color", varray());
+ ADDFUNC1(PACKED_COLOR_ARRAY, NIL, PackedColorArray, resize, INT, "idx", varray());
+ ADDFUNC0(PACKED_COLOR_ARRAY, NIL, PackedColorArray, invert, varray());
//pointerbased
- ADDFUNC0R(AABB, REAL, AABB, get_area, varray());
+ ADDFUNC0R(AABB, FLOAT, AABB, get_area, varray());
ADDFUNC0R(AABB, BOOL, AABB, has_no_area, varray());
ADDFUNC0R(AABB, BOOL, AABB, has_no_surface, varray());
ADDFUNC1R(AABB, BOOL, AABB, has_point, VECTOR3, "point", varray());
@@ -1889,93 +2131,101 @@ void register_variant_methods() {
ADDFUNC1R(AABB, AABB, AABB, intersection, AABB, "with", varray());
ADDFUNC1R(AABB, AABB, AABB, merge, AABB, "with", varray());
ADDFUNC1R(AABB, AABB, AABB, expand, VECTOR3, "to_point", varray());
- ADDFUNC1R(AABB, AABB, AABB, grow, REAL, "by", varray());
+ ADDFUNC1R(AABB, AABB, AABB, grow, FLOAT, "by", varray());
ADDFUNC1R(AABB, VECTOR3, AABB, get_support, VECTOR3, "dir", varray());
ADDFUNC0R(AABB, VECTOR3, AABB, get_longest_axis, varray());
ADDFUNC0R(AABB, INT, AABB, get_longest_axis_index, varray());
- ADDFUNC0R(AABB, REAL, AABB, get_longest_axis_size, varray());
+ ADDFUNC0R(AABB, FLOAT, AABB, get_longest_axis_size, varray());
ADDFUNC0R(AABB, VECTOR3, AABB, get_shortest_axis, varray());
ADDFUNC0R(AABB, INT, AABB, get_shortest_axis_index, varray());
- ADDFUNC0R(AABB, REAL, AABB, get_shortest_axis_size, varray());
+ ADDFUNC0R(AABB, FLOAT, AABB, get_shortest_axis_size, varray());
ADDFUNC1R(AABB, VECTOR3, AABB, get_endpoint, INT, "idx", varray());
ADDFUNC0R(TRANSFORM2D, TRANSFORM2D, Transform2D, inverse, varray());
ADDFUNC0R(TRANSFORM2D, TRANSFORM2D, Transform2D, affine_inverse, varray());
- ADDFUNC0R(TRANSFORM2D, REAL, Transform2D, get_rotation, varray());
+ ADDFUNC0R(TRANSFORM2D, FLOAT, Transform2D, get_rotation, varray());
ADDFUNC0R(TRANSFORM2D, VECTOR2, Transform2D, get_origin, varray());
ADDFUNC0R(TRANSFORM2D, VECTOR2, Transform2D, get_scale, varray());
ADDFUNC0R(TRANSFORM2D, TRANSFORM2D, Transform2D, orthonormalized, varray());
- ADDFUNC1R(TRANSFORM2D, TRANSFORM2D, Transform2D, rotated, REAL, "phi", varray());
+ ADDFUNC1R(TRANSFORM2D, TRANSFORM2D, Transform2D, rotated, FLOAT, "phi", varray());
ADDFUNC1R(TRANSFORM2D, TRANSFORM2D, Transform2D, scaled, VECTOR2, "scale", varray());
ADDFUNC1R(TRANSFORM2D, TRANSFORM2D, Transform2D, translated, VECTOR2, "offset", varray());
ADDFUNC1R(TRANSFORM2D, NIL, Transform2D, xform, NIL, "v", varray());
ADDFUNC1R(TRANSFORM2D, NIL, Transform2D, xform_inv, NIL, "v", varray());
ADDFUNC1R(TRANSFORM2D, VECTOR2, Transform2D, basis_xform, VECTOR2, "v", varray());
ADDFUNC1R(TRANSFORM2D, VECTOR2, Transform2D, basis_xform_inv, VECTOR2, "v", varray());
- ADDFUNC2R(TRANSFORM2D, TRANSFORM2D, Transform2D, interpolate_with, TRANSFORM2D, "transform", REAL, "weight", varray());
+ ADDFUNC2R(TRANSFORM2D, TRANSFORM2D, Transform2D, interpolate_with, TRANSFORM2D, "transform", FLOAT, "weight", varray());
ADDFUNC1R(TRANSFORM2D, BOOL, Transform2D, is_equal_approx, TRANSFORM2D, "transform", varray());
ADDFUNC0R(BASIS, BASIS, Basis, inverse, varray());
ADDFUNC0R(BASIS, BASIS, Basis, transposed, varray());
ADDFUNC0R(BASIS, BASIS, Basis, orthonormalized, varray());
- ADDFUNC0R(BASIS, REAL, Basis, determinant, varray());
- ADDFUNC2R(BASIS, BASIS, Basis, rotated, VECTOR3, "axis", REAL, "phi", varray());
+ ADDFUNC0R(BASIS, FLOAT, Basis, determinant, varray());
+ ADDFUNC2R(BASIS, BASIS, Basis, rotated, VECTOR3, "axis", FLOAT, "phi", varray());
ADDFUNC1R(BASIS, BASIS, Basis, scaled, VECTOR3, "scale", varray());
ADDFUNC0R(BASIS, VECTOR3, Basis, get_scale, varray());
ADDFUNC0R(BASIS, VECTOR3, Basis, get_euler, varray());
- ADDFUNC1R(BASIS, REAL, Basis, tdotx, VECTOR3, "with", varray());
- ADDFUNC1R(BASIS, REAL, Basis, tdoty, VECTOR3, "with", varray());
- ADDFUNC1R(BASIS, REAL, Basis, tdotz, VECTOR3, "with", varray());
+ ADDFUNC1R(BASIS, FLOAT, Basis, tdotx, VECTOR3, "with", varray());
+ ADDFUNC1R(BASIS, FLOAT, Basis, tdoty, VECTOR3, "with", varray());
+ ADDFUNC1R(BASIS, FLOAT, Basis, tdotz, VECTOR3, "with", varray());
ADDFUNC1R(BASIS, VECTOR3, Basis, xform, VECTOR3, "v", varray());
ADDFUNC1R(BASIS, VECTOR3, Basis, xform_inv, VECTOR3, "v", varray());
ADDFUNC0R(BASIS, INT, Basis, get_orthogonal_index, varray());
- ADDFUNC2R(BASIS, BASIS, Basis, slerp, BASIS, "b", REAL, "t", varray());
- ADDFUNC2R(BASIS, BOOL, Basis, is_equal_approx, BASIS, "b", REAL, "epsilon", varray(CMP_EPSILON)); // TODO: Replace in 4.0, see other TODO.
+ ADDFUNC2R(BASIS, BASIS, Basis, slerp, BASIS, "b", FLOAT, "t", varray());
+ ADDFUNC2R(BASIS, BOOL, Basis, is_equal_approx, BASIS, "b", FLOAT, "epsilon", varray(CMP_EPSILON)); // TODO: Replace in 4.0, see other TODO.
ADDFUNC0R(BASIS, QUAT, Basis, get_rotation_quat, varray());
ADDFUNC0R(TRANSFORM, TRANSFORM, Transform, inverse, varray());
ADDFUNC0R(TRANSFORM, TRANSFORM, Transform, affine_inverse, varray());
ADDFUNC0R(TRANSFORM, TRANSFORM, Transform, orthonormalized, varray());
- ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, rotated, VECTOR3, "axis", REAL, "phi", varray());
+ ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, rotated, VECTOR3, "axis", FLOAT, "phi", varray());
ADDFUNC1R(TRANSFORM, TRANSFORM, Transform, scaled, VECTOR3, "scale", varray());
ADDFUNC1R(TRANSFORM, TRANSFORM, Transform, translated, VECTOR3, "offset", varray());
ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, looking_at, VECTOR3, "target", VECTOR3, "up", varray());
- ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, interpolate_with, TRANSFORM, "transform", REAL, "weight", varray());
+ ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, interpolate_with, TRANSFORM, "transform", FLOAT, "weight", varray());
ADDFUNC1R(TRANSFORM, BOOL, Transform, is_equal_approx, TRANSFORM, "transform", varray());
ADDFUNC1R(TRANSFORM, NIL, Transform, xform, NIL, "v", varray());
ADDFUNC1R(TRANSFORM, NIL, Transform, xform_inv, NIL, "v", varray());
/* REGISTER CONSTRUCTORS */
- _VariantCall::add_constructor(_VariantCall::Vector2_init1, Variant::VECTOR2, "x", Variant::REAL, "y", Variant::REAL);
+ _VariantCall::add_constructor(_VariantCall::Vector2_init1, Variant::VECTOR2, "x", Variant::FLOAT, "y", Variant::FLOAT);
+ _VariantCall::add_constructor(_VariantCall::Vector2i_init1, Variant::VECTOR2I, "x", Variant::INT, "y", Variant::INT);
_VariantCall::add_constructor(_VariantCall::Rect2_init1, Variant::RECT2, "position", Variant::VECTOR2, "size", Variant::VECTOR2);
- _VariantCall::add_constructor(_VariantCall::Rect2_init2, Variant::RECT2, "x", Variant::REAL, "y", Variant::REAL, "width", Variant::REAL, "height", Variant::REAL);
+ _VariantCall::add_constructor(_VariantCall::Rect2_init2, Variant::RECT2, "x", Variant::FLOAT, "y", Variant::FLOAT, "width", Variant::FLOAT, "height", Variant::FLOAT);
- _VariantCall::add_constructor(_VariantCall::Transform2D_init2, Variant::TRANSFORM2D, "rotation", Variant::REAL, "position", Variant::VECTOR2);
+ _VariantCall::add_constructor(_VariantCall::Rect2i_init1, Variant::RECT2I, "position", Variant::VECTOR2, "size", Variant::VECTOR2);
+ _VariantCall::add_constructor(_VariantCall::Rect2i_init2, Variant::RECT2I, "x", Variant::INT, "y", Variant::INT, "width", Variant::INT, "height", Variant::INT);
+
+ _VariantCall::add_constructor(_VariantCall::Transform2D_init2, Variant::TRANSFORM2D, "rotation", Variant::FLOAT, "position", Variant::VECTOR2);
_VariantCall::add_constructor(_VariantCall::Transform2D_init3, Variant::TRANSFORM2D, "x_axis", Variant::VECTOR2, "y_axis", Variant::VECTOR2, "origin", Variant::VECTOR2);
- _VariantCall::add_constructor(_VariantCall::Vector3_init1, Variant::VECTOR3, "x", Variant::REAL, "y", Variant::REAL, "z", Variant::REAL);
+ _VariantCall::add_constructor(_VariantCall::Vector3_init1, Variant::VECTOR3, "x", Variant::FLOAT, "y", Variant::FLOAT, "z", Variant::FLOAT);
+ _VariantCall::add_constructor(_VariantCall::Vector3i_init1, Variant::VECTOR3I, "x", Variant::INT, "y", Variant::INT, "z", Variant::INT);
- _VariantCall::add_constructor(_VariantCall::Plane_init1, Variant::PLANE, "a", Variant::REAL, "b", Variant::REAL, "c", Variant::REAL, "d", Variant::REAL);
+ _VariantCall::add_constructor(_VariantCall::Plane_init1, Variant::PLANE, "a", Variant::FLOAT, "b", Variant::FLOAT, "c", Variant::FLOAT, "d", Variant::FLOAT);
_VariantCall::add_constructor(_VariantCall::Plane_init2, Variant::PLANE, "v1", Variant::VECTOR3, "v2", Variant::VECTOR3, "v3", Variant::VECTOR3);
- _VariantCall::add_constructor(_VariantCall::Plane_init3, Variant::PLANE, "normal", Variant::VECTOR3, "d", Variant::REAL);
+ _VariantCall::add_constructor(_VariantCall::Plane_init3, Variant::PLANE, "normal", Variant::VECTOR3, "d", Variant::FLOAT);
- _VariantCall::add_constructor(_VariantCall::Quat_init1, Variant::QUAT, "x", Variant::REAL, "y", Variant::REAL, "z", Variant::REAL, "w", Variant::REAL);
- _VariantCall::add_constructor(_VariantCall::Quat_init2, Variant::QUAT, "axis", Variant::VECTOR3, "angle", Variant::REAL);
+ _VariantCall::add_constructor(_VariantCall::Quat_init1, Variant::QUAT, "x", Variant::FLOAT, "y", Variant::FLOAT, "z", Variant::FLOAT, "w", Variant::FLOAT);
+ _VariantCall::add_constructor(_VariantCall::Quat_init2, Variant::QUAT, "axis", Variant::VECTOR3, "angle", Variant::FLOAT);
_VariantCall::add_constructor(_VariantCall::Quat_init3, Variant::QUAT, "euler", Variant::VECTOR3);
- _VariantCall::add_constructor(_VariantCall::Color_init1, Variant::COLOR, "r", Variant::REAL, "g", Variant::REAL, "b", Variant::REAL, "a", Variant::REAL);
- _VariantCall::add_constructor(_VariantCall::Color_init2, Variant::COLOR, "r", Variant::REAL, "g", Variant::REAL, "b", Variant::REAL);
+ _VariantCall::add_constructor(_VariantCall::Color_init1, Variant::COLOR, "r", Variant::FLOAT, "g", Variant::FLOAT, "b", Variant::FLOAT, "a", Variant::FLOAT);
+ _VariantCall::add_constructor(_VariantCall::Color_init2, Variant::COLOR, "r", Variant::FLOAT, "g", Variant::FLOAT, "b", Variant::FLOAT);
_VariantCall::add_constructor(_VariantCall::AABB_init1, Variant::AABB, "position", Variant::VECTOR3, "size", Variant::VECTOR3);
_VariantCall::add_constructor(_VariantCall::Basis_init1, Variant::BASIS, "x_axis", Variant::VECTOR3, "y_axis", Variant::VECTOR3, "z_axis", Variant::VECTOR3);
- _VariantCall::add_constructor(_VariantCall::Basis_init2, Variant::BASIS, "axis", Variant::VECTOR3, "phi", Variant::REAL);
+ _VariantCall::add_constructor(_VariantCall::Basis_init2, Variant::BASIS, "axis", Variant::VECTOR3, "phi", Variant::FLOAT);
_VariantCall::add_constructor(_VariantCall::Transform_init1, Variant::TRANSFORM, "x_axis", Variant::VECTOR3, "y_axis", Variant::VECTOR3, "z_axis", Variant::VECTOR3, "origin", Variant::VECTOR3);
_VariantCall::add_constructor(_VariantCall::Transform_init2, Variant::TRANSFORM, "basis", Variant::BASIS, "origin", Variant::VECTOR3);
+ _VariantCall::add_constructor(_VariantCall::Callable_init2, Variant::CALLABLE, "object", Variant::OBJECT, "method_name", Variant::STRING_NAME);
+ _VariantCall::add_constructor(_VariantCall::Signal_init2, Variant::SIGNAL, "object", Variant::OBJECT, "signal_name", Variant::STRING_NAME);
+
/* REGISTER CONSTANTS */
_populate_named_colors();
@@ -1997,9 +2247,25 @@ void register_variant_methods() {
_VariantCall::add_variant_constant(Variant::VECTOR3, "FORWARD", Vector3(0, 0, -1));
_VariantCall::add_variant_constant(Variant::VECTOR3, "BACK", Vector3(0, 0, 1));
+ _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_X", Vector3::AXIS_X);
+ _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Y", Vector3::AXIS_Y);
+ _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Z", Vector3::AXIS_Z);
+
+ _VariantCall::add_variant_constant(Variant::VECTOR3I, "ZERO", Vector3i(0, 0, 0));
+ _VariantCall::add_variant_constant(Variant::VECTOR3I, "ONE", Vector3i(1, 1, 1));
+ _VariantCall::add_variant_constant(Variant::VECTOR3I, "LEFT", Vector3i(-1, 0, 0));
+ _VariantCall::add_variant_constant(Variant::VECTOR3I, "RIGHT", Vector3i(1, 0, 0));
+ _VariantCall::add_variant_constant(Variant::VECTOR3I, "UP", Vector3i(0, 1, 0));
+ _VariantCall::add_variant_constant(Variant::VECTOR3I, "DOWN", Vector3i(0, -1, 0));
+ _VariantCall::add_variant_constant(Variant::VECTOR3I, "FORWARD", Vector3i(0, 0, -1));
+ _VariantCall::add_variant_constant(Variant::VECTOR3I, "BACK", Vector3i(0, 0, 1));
+
_VariantCall::add_constant(Variant::VECTOR2, "AXIS_X", Vector2::AXIS_X);
_VariantCall::add_constant(Variant::VECTOR2, "AXIS_Y", Vector2::AXIS_Y);
+ _VariantCall::add_constant(Variant::VECTOR2I, "AXIS_X", Vector2::AXIS_X);
+ _VariantCall::add_constant(Variant::VECTOR2I, "AXIS_Y", Vector2::AXIS_Y);
+
_VariantCall::add_variant_constant(Variant::VECTOR2, "ZERO", Vector2(0, 0));
_VariantCall::add_variant_constant(Variant::VECTOR2, "ONE", Vector2(1, 1));
_VariantCall::add_variant_constant(Variant::VECTOR2, "INF", Vector2(Math_INF, Math_INF));
@@ -2008,6 +2274,13 @@ void register_variant_methods() {
_VariantCall::add_variant_constant(Variant::VECTOR2, "UP", Vector2(0, -1));
_VariantCall::add_variant_constant(Variant::VECTOR2, "DOWN", Vector2(0, 1));
+ _VariantCall::add_variant_constant(Variant::VECTOR2I, "ZERO", Vector2i(0, 0));
+ _VariantCall::add_variant_constant(Variant::VECTOR2I, "ONE", Vector2i(1, 1));
+ _VariantCall::add_variant_constant(Variant::VECTOR2I, "LEFT", Vector2i(-1, 0));
+ _VariantCall::add_variant_constant(Variant::VECTOR2I, "RIGHT", Vector2i(1, 0));
+ _VariantCall::add_variant_constant(Variant::VECTOR2I, "UP", Vector2i(0, -1));
+ _VariantCall::add_variant_constant(Variant::VECTOR2I, "DOWN", Vector2i(0, 1));
+
_VariantCall::add_variant_constant(Variant::TRANSFORM2D, "IDENTITY", Transform2D());
_VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_X", Transform2D(-1, 0, 0, 1, 0, 0));
_VariantCall::add_variant_constant(Variant::TRANSFORM2D, "FLIP_Y", Transform2D(1, 0, 0, -1, 0, 0));
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index c7a52b0347..36d1278929 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -38,33 +38,41 @@
CASE_TYPE(PREFIX, OP, INT) \
CASE_TYPE_ALL_BUT_INT(PREFIX, OP)
-#define CASE_TYPE_ALL_BUT_INT(PREFIX, OP) \
- CASE_TYPE(PREFIX, OP, NIL) \
- CASE_TYPE(PREFIX, OP, BOOL) \
- CASE_TYPE(PREFIX, OP, REAL) \
- CASE_TYPE(PREFIX, OP, STRING) \
- CASE_TYPE(PREFIX, OP, VECTOR2) \
- CASE_TYPE(PREFIX, OP, RECT2) \
- CASE_TYPE(PREFIX, OP, VECTOR3) \
- CASE_TYPE(PREFIX, OP, TRANSFORM2D) \
- CASE_TYPE(PREFIX, OP, PLANE) \
- CASE_TYPE(PREFIX, OP, QUAT) \
- CASE_TYPE(PREFIX, OP, AABB) \
- CASE_TYPE(PREFIX, OP, BASIS) \
- CASE_TYPE(PREFIX, OP, TRANSFORM) \
- CASE_TYPE(PREFIX, OP, COLOR) \
- CASE_TYPE(PREFIX, OP, NODE_PATH) \
- CASE_TYPE(PREFIX, OP, _RID) \
- CASE_TYPE(PREFIX, OP, OBJECT) \
- CASE_TYPE(PREFIX, OP, DICTIONARY) \
- CASE_TYPE(PREFIX, OP, ARRAY) \
- CASE_TYPE(PREFIX, OP, POOL_BYTE_ARRAY) \
- CASE_TYPE(PREFIX, OP, POOL_INT_ARRAY) \
- CASE_TYPE(PREFIX, OP, POOL_REAL_ARRAY) \
- CASE_TYPE(PREFIX, OP, POOL_STRING_ARRAY) \
- CASE_TYPE(PREFIX, OP, POOL_VECTOR2_ARRAY) \
- CASE_TYPE(PREFIX, OP, POOL_VECTOR3_ARRAY) \
- CASE_TYPE(PREFIX, OP, POOL_COLOR_ARRAY)
+#define CASE_TYPE_ALL_BUT_INT(PREFIX, OP) \
+ CASE_TYPE(PREFIX, OP, NIL) \
+ CASE_TYPE(PREFIX, OP, BOOL) \
+ CASE_TYPE(PREFIX, OP, FLOAT) \
+ CASE_TYPE(PREFIX, OP, STRING) \
+ CASE_TYPE(PREFIX, OP, VECTOR2) \
+ CASE_TYPE(PREFIX, OP, VECTOR2I) \
+ CASE_TYPE(PREFIX, OP, RECT2) \
+ CASE_TYPE(PREFIX, OP, RECT2I) \
+ CASE_TYPE(PREFIX, OP, VECTOR3) \
+ CASE_TYPE(PREFIX, OP, VECTOR3I) \
+ CASE_TYPE(PREFIX, OP, TRANSFORM2D) \
+ CASE_TYPE(PREFIX, OP, PLANE) \
+ CASE_TYPE(PREFIX, OP, QUAT) \
+ CASE_TYPE(PREFIX, OP, AABB) \
+ CASE_TYPE(PREFIX, OP, BASIS) \
+ CASE_TYPE(PREFIX, OP, TRANSFORM) \
+ CASE_TYPE(PREFIX, OP, COLOR) \
+ CASE_TYPE(PREFIX, OP, STRING_NAME) \
+ CASE_TYPE(PREFIX, OP, NODE_PATH) \
+ CASE_TYPE(PREFIX, OP, _RID) \
+ CASE_TYPE(PREFIX, OP, OBJECT) \
+ CASE_TYPE(PREFIX, OP, CALLABLE) \
+ CASE_TYPE(PREFIX, OP, SIGNAL) \
+ CASE_TYPE(PREFIX, OP, DICTIONARY) \
+ CASE_TYPE(PREFIX, OP, ARRAY) \
+ CASE_TYPE(PREFIX, OP, PACKED_BYTE_ARRAY) \
+ CASE_TYPE(PREFIX, OP, PACKED_INT32_ARRAY) \
+ CASE_TYPE(PREFIX, OP, PACKED_INT64_ARRAY) \
+ CASE_TYPE(PREFIX, OP, PACKED_FLOAT32_ARRAY) \
+ CASE_TYPE(PREFIX, OP, PACKED_FLOAT64_ARRAY) \
+ CASE_TYPE(PREFIX, OP, PACKED_STRING_ARRAY) \
+ CASE_TYPE(PREFIX, OP, PACKED_VECTOR2_ARRAY) \
+ CASE_TYPE(PREFIX, OP, PACKED_VECTOR3_ARRAY) \
+ CASE_TYPE(PREFIX, OP, PACKED_COLOR_ARRAY)
#ifdef __GNUC__
#define TYPE(PREFIX, OP, TYPE) &&PREFIX##_##OP##_##TYPE
@@ -74,11 +82,14 @@
TYPE(PREFIX, OP, NIL), \
TYPE(PREFIX, OP, BOOL), \
TYPE(PREFIX, OP, INT), \
- TYPE(PREFIX, OP, REAL), \
+ TYPE(PREFIX, OP, FLOAT), \
TYPE(PREFIX, OP, STRING), \
TYPE(PREFIX, OP, VECTOR2), \
+ TYPE(PREFIX, OP, VECTOR2I), \
TYPE(PREFIX, OP, RECT2), \
+ TYPE(PREFIX, OP, RECT2I), \
TYPE(PREFIX, OP, VECTOR3), \
+ TYPE(PREFIX, OP, VECTOR3I), \
TYPE(PREFIX, OP, TRANSFORM2D), \
TYPE(PREFIX, OP, PLANE), \
TYPE(PREFIX, OP, QUAT), \
@@ -86,47 +97,52 @@
TYPE(PREFIX, OP, BASIS), \
TYPE(PREFIX, OP, TRANSFORM), \
TYPE(PREFIX, OP, COLOR), \
+ TYPE(PREFIX, OP, STRING_NAME), \
TYPE(PREFIX, OP, NODE_PATH), \
TYPE(PREFIX, OP, _RID), \
TYPE(PREFIX, OP, OBJECT), \
+ TYPE(PREFIX, OP, CALLABLE), \
+ TYPE(PREFIX, OP, SIGNAL), \
TYPE(PREFIX, OP, DICTIONARY), \
TYPE(PREFIX, OP, ARRAY), \
- TYPE(PREFIX, OP, POOL_BYTE_ARRAY), \
- TYPE(PREFIX, OP, POOL_INT_ARRAY), \
- TYPE(PREFIX, OP, POOL_REAL_ARRAY), \
- TYPE(PREFIX, OP, POOL_STRING_ARRAY), \
- TYPE(PREFIX, OP, POOL_VECTOR2_ARRAY), \
- TYPE(PREFIX, OP, POOL_VECTOR3_ARRAY), \
- TYPE(PREFIX, OP, POOL_COLOR_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_BYTE_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_INT32_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_INT64_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_FLOAT32_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_FLOAT64_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_STRING_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_VECTOR2_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_VECTOR3_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_COLOR_ARRAY), \
}
/* clang-format on */
-#define CASES(PREFIX) static const void *switch_table_##PREFIX[25][27] = { \
- TYPES(PREFIX, OP_EQUAL), \
- TYPES(PREFIX, OP_NOT_EQUAL), \
- TYPES(PREFIX, OP_LESS), \
- TYPES(PREFIX, OP_LESS_EQUAL), \
- TYPES(PREFIX, OP_GREATER), \
- TYPES(PREFIX, OP_GREATER_EQUAL), \
- TYPES(PREFIX, OP_ADD), \
- TYPES(PREFIX, OP_SUBTRACT), \
- TYPES(PREFIX, OP_MULTIPLY), \
- TYPES(PREFIX, OP_DIVIDE), \
- TYPES(PREFIX, OP_NEGATE), \
- TYPES(PREFIX, OP_POSITIVE), \
- TYPES(PREFIX, OP_MODULE), \
- TYPES(PREFIX, OP_STRING_CONCAT), \
- TYPES(PREFIX, OP_SHIFT_LEFT), \
- TYPES(PREFIX, OP_SHIFT_RIGHT), \
- TYPES(PREFIX, OP_BIT_AND), \
- TYPES(PREFIX, OP_BIT_OR), \
- TYPES(PREFIX, OP_BIT_XOR), \
- TYPES(PREFIX, OP_BIT_NEGATE), \
- TYPES(PREFIX, OP_AND), \
- TYPES(PREFIX, OP_OR), \
- TYPES(PREFIX, OP_XOR), \
- TYPES(PREFIX, OP_NOT), \
- TYPES(PREFIX, OP_IN), \
+#define CASES(PREFIX) static const void *switch_table_##PREFIX[25][Variant::VARIANT_MAX] = { \
+ TYPES(PREFIX, OP_EQUAL), \
+ TYPES(PREFIX, OP_NOT_EQUAL), \
+ TYPES(PREFIX, OP_LESS), \
+ TYPES(PREFIX, OP_LESS_EQUAL), \
+ TYPES(PREFIX, OP_GREATER), \
+ TYPES(PREFIX, OP_GREATER_EQUAL), \
+ TYPES(PREFIX, OP_ADD), \
+ TYPES(PREFIX, OP_SUBTRACT), \
+ TYPES(PREFIX, OP_MULTIPLY), \
+ TYPES(PREFIX, OP_DIVIDE), \
+ TYPES(PREFIX, OP_NEGATE), \
+ TYPES(PREFIX, OP_POSITIVE), \
+ TYPES(PREFIX, OP_MODULE), \
+ TYPES(PREFIX, OP_STRING_CONCAT), \
+ TYPES(PREFIX, OP_SHIFT_LEFT), \
+ TYPES(PREFIX, OP_SHIFT_RIGHT), \
+ TYPES(PREFIX, OP_BIT_AND), \
+ TYPES(PREFIX, OP_BIT_OR), \
+ TYPES(PREFIX, OP_BIT_XOR), \
+ TYPES(PREFIX, OP_BIT_NEGATE), \
+ TYPES(PREFIX, OP_AND), \
+ TYPES(PREFIX, OP_OR), \
+ TYPES(PREFIX, OP_XOR), \
+ TYPES(PREFIX, OP_NOT), \
+ TYPES(PREFIX, OP_IN), \
}
#define SWITCH(PREFIX, op, val) goto *switch_table_##PREFIX[op][val];
@@ -165,21 +181,21 @@ bool Variant::booleanize() const {
return; \
}
-#define DEFAULT_OP_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \
- if (p_b.type == REAL) _RETURN(p_a._data.m_type m_op p_b._data._real); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \
+ if (p_b.type == FLOAT) _RETURN(p_a._data.m_type m_op p_b._data._float); \
+ \
+ _RETURN_FAIL \
};
-#define DEFAULT_OP_NUM_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \
- if (p_b.type == REAL) _RETURN(p_a._data.m_type m_op p_b._data._real); \
- if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_NUM_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \
+ if (p_b.type == FLOAT) _RETURN(p_a._data.m_type m_op p_b._data._float); \
+ if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \
+ \
+ _RETURN_FAIL \
};
#ifdef DEBUG_ENABLED
@@ -192,23 +208,23 @@ bool Variant::booleanize() const {
} \
_RETURN(p_a._data.m_type / p_b._data._int); \
} \
- if (p_b.type == REAL) { \
- if (p_b._data._real == 0) { \
+ if (p_b.type == FLOAT) { \
+ if (p_b._data._float == 0) { \
r_valid = false; \
_RETURN("Division By Zero"); \
} \
- _RETURN(p_a._data.m_type / p_b._data._real); \
+ _RETURN(p_a._data.m_type / p_b._data._float); \
} \
\
_RETURN_FAIL \
};
#else
-#define DEFAULT_OP_NUM_DIV(m_prefix, m_op_name, m_name, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == INT) _RETURN(p_a._data.m_type / p_b._data._int); \
- if (p_b.type == REAL) _RETURN(p_a._data.m_type / p_b._data._real); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_NUM_DIV(m_prefix, m_op_name, m_name, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == INT) _RETURN(p_a._data.m_type / p_b._data._int); \
+ if (p_b.type == FLOAT) _RETURN(p_a._data.m_type / p_b._data._float); \
+ \
+ _RETURN_FAIL \
};
#endif
@@ -222,33 +238,47 @@ bool Variant::booleanize() const {
_RETURN(p_a._data.m_type); \
};
-#define DEFAULT_OP_NUM_VEC(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \
- if (p_b.type == REAL) _RETURN(p_a._data.m_type m_op p_b._data._real); \
- if (p_b.type == VECTOR2) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
- if (p_b.type == VECTOR3) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_NUM_VEC(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \
+ if (p_b.type == FLOAT) _RETURN(p_a._data.m_type m_op p_b._data._float); \
+ if (p_b.type == VECTOR2) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
+ if (p_b.type == VECTOR3) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
+ if (p_b.type == VECTOR2I) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
+ if (p_b.type == VECTOR3I) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
+ \
+ _RETURN_FAIL \
};
-#define DEFAULT_OP_STR_REV(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const String *>(p_a._data._mem)); \
- if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const NodePath *>(p_a._data._mem)); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_STR_REV(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const String *>(p_a._data._mem)); \
+ if (p_b.type == STRING_NAME) _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const StringName *>(p_a._data._mem)); \
+ if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const NodePath *>(p_a._data._mem)); \
+ \
+ _RETURN_FAIL \
};
-#define DEFAULT_OP_STR(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
- if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_STR(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
+ if (p_b.type == STRING_NAME) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
+ if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
+ \
+ _RETURN_FAIL \
+ };
+
+#define DEFAULT_OP_STR_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
+ if (p_b.type == STRING_NAME) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
+ if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
+ if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \
+ \
+ _RETURN_FAIL \
};
-#define DEFAULT_OP_STR_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \
+#define DEFAULT_OP_STR_NULL_NP(m_prefix, m_op_name, m_name, m_op, m_type) \
CASE_TYPE(m_prefix, m_op_name, m_name) { \
if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
@@ -257,6 +287,15 @@ bool Variant::booleanize() const {
_RETURN_FAIL \
};
+#define DEFAULT_OP_STR_NULL_SN(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
+ if (p_b.type == STRING_NAME) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
+ if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \
+ \
+ _RETURN_FAIL \
+ };
+
#define DEFAULT_OP_LOCALMEM_REV(m_prefix, m_op_name, m_name, m_op, m_type) \
CASE_TYPE(m_prefix, m_op_name, m_name) { \
if (p_b.type == m_name) \
@@ -297,7 +336,7 @@ bool Variant::booleanize() const {
CASE_TYPE(m_prefix, m_op_name, m_name) { \
if (p_b.type == m_name) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \
if (p_b.type == INT) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._int); \
- if (p_b.type == REAL) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._real); \
+ if (p_b.type == FLOAT) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._float); \
\
_RETURN_FAIL \
}
@@ -357,16 +396,16 @@ bool Variant::booleanize() const {
if (p_a.type != p_b.type) \
_RETURN_FAIL \
\
- const PoolVector<m_type> &array_a = *reinterpret_cast<const PoolVector<m_type> *>(p_a._data._mem); \
- const PoolVector<m_type> &array_b = *reinterpret_cast<const PoolVector<m_type> *>(p_b._data._mem); \
+ const Vector<m_type> &array_a = PackedArrayRef<m_type>::get_array(p_a._data.packed_array); \
+ const Vector<m_type> &array_b = PackedArrayRef<m_type>::get_array(p_b._data.packed_array); \
\
int a_len = array_a.size(); \
if (a_len m_opa array_b.size()) { \
_RETURN(m_ret_s); \
} else { \
\
- PoolVector<m_type>::Read ra = array_a.read(); \
- PoolVector<m_type>::Read rb = array_b.read(); \
+ const m_type *ra = array_a.ptr(); \
+ const m_type *rb = array_b.ptr(); \
\
for (int i = 0; i < a_len; i++) { \
if (ra[i] m_opb rb[i]) \
@@ -376,16 +415,16 @@ bool Variant::booleanize() const {
_RETURN(m_ret_def); \
}
-#define DEFAULT_OP_ARRAY_ADD(m_prefix, m_op_name, m_name, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_a.type != p_b.type) \
- _RETURN_FAIL; \
- \
- const PoolVector<m_type> &array_a = *reinterpret_cast<const PoolVector<m_type> *>(p_a._data._mem); \
- const PoolVector<m_type> &array_b = *reinterpret_cast<const PoolVector<m_type> *>(p_b._data._mem); \
- PoolVector<m_type> sum = array_a; \
- sum.append_array(array_b); \
- _RETURN(sum); \
+#define DEFAULT_OP_ARRAY_ADD(m_prefix, m_op_name, m_name, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_a.type != p_b.type) \
+ _RETURN_FAIL; \
+ \
+ const Vector<m_type> &array_a = PackedArrayRef<m_type>::get_array(p_a._data.packed_array); \
+ const Vector<m_type> &array_b = PackedArrayRef<m_type>::get_array(p_b._data.packed_array); \
+ Vector<m_type> sum = array_a; \
+ sum.append_array(array_b); \
+ _RETURN(sum); \
}
void Variant::evaluate(const Operator &p_op, const Variant &p_a,
@@ -423,6 +462,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
_RETURN_FAIL;
}
+ DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, CALLABLE, ==, Callable);
+ DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, SIGNAL, ==, Signal);
+
CASE_TYPE(math, OP_EQUAL, DICTIONARY) {
if (p_b.type != DICTIONARY) {
if (p_b.type == NIL)
@@ -458,28 +500,34 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
}
DEFAULT_OP_NUM_NULL(math, OP_EQUAL, INT, ==, _int);
- DEFAULT_OP_NUM_NULL(math, OP_EQUAL, REAL, ==, _real);
+ DEFAULT_OP_NUM_NULL(math, OP_EQUAL, FLOAT, ==, _float);
DEFAULT_OP_STR_NULL(math, OP_EQUAL, STRING, ==, String);
DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, VECTOR2, ==, Vector2);
+ DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, VECTOR2I, ==, Vector2i);
DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, RECT2, ==, Rect2);
+ DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, RECT2I, ==, Rect2i);
DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, TRANSFORM2D, ==, _transform2d);
DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, VECTOR3, ==, Vector3);
+ DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, VECTOR3I, ==, Vector3i);
DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, PLANE, ==, Plane);
DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, QUAT, ==, Quat);
DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, AABB, ==, _aabb);
DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, BASIS, ==, _basis);
DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, TRANSFORM, ==, _transform);
DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, COLOR, ==, Color);
- DEFAULT_OP_STR_NULL(math, OP_EQUAL, NODE_PATH, ==, NodePath);
+ DEFAULT_OP_STR_NULL_SN(math, OP_EQUAL, STRING_NAME, ==, StringName);
+ DEFAULT_OP_STR_NULL_NP(math, OP_EQUAL, NODE_PATH, ==, NodePath);
DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, _RID, ==, RID);
- DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, POOL_BYTE_ARRAY, uint8_t);
- DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, POOL_INT_ARRAY, int);
- DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, POOL_REAL_ARRAY, real_t);
- DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, POOL_STRING_ARRAY, String);
- DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, POOL_VECTOR2_ARRAY, Vector2);
- DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, POOL_VECTOR3_ARRAY, Vector3);
- DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, POOL_COLOR_ARRAY, Color);
+ DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_BYTE_ARRAY, uint8_t);
+ DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_INT32_ARRAY, int32_t);
+ DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_INT64_ARRAY, int64_t);
+ DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_FLOAT32_ARRAY, float);
+ DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_FLOAT64_ARRAY, double);
+ DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_STRING_ARRAY, String);
+ DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_VECTOR2_ARRAY, Vector2);
+ DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_VECTOR3_ARRAY, Vector3);
+ DEFAULT_OP_ARRAY_EQ(math, OP_EQUAL, PACKED_COLOR_ARRAY, Color);
}
SWITCH_OP(math, OP_NOT_EQUAL, p_a.type) {
@@ -511,6 +559,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
_RETURN_FAIL;
}
+ DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, CALLABLE, !=, Callable);
+ DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, SIGNAL, !=, Signal);
+
CASE_TYPE(math, OP_NOT_EQUAL, DICTIONARY) {
if (p_b.type != DICTIONARY) {
if (p_b.type == NIL)
@@ -548,28 +599,34 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
}
DEFAULT_OP_NUM_NULL(math, OP_NOT_EQUAL, INT, !=, _int);
- DEFAULT_OP_NUM_NULL(math, OP_NOT_EQUAL, REAL, !=, _real);
+ DEFAULT_OP_NUM_NULL(math, OP_NOT_EQUAL, FLOAT, !=, _float);
DEFAULT_OP_STR_NULL(math, OP_NOT_EQUAL, STRING, !=, String);
DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, VECTOR2, !=, Vector2);
+ DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, VECTOR2I, !=, Vector2i);
DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, RECT2, !=, Rect2);
+ DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, RECT2I, !=, Rect2i);
DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, TRANSFORM2D, !=, _transform2d);
DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, VECTOR3, !=, Vector3);
+ DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, VECTOR3I, !=, Vector3i);
DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, PLANE, !=, Plane);
DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, QUAT, !=, Quat);
DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, AABB, !=, _aabb);
DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, BASIS, !=, _basis);
DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, TRANSFORM, !=, _transform);
DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, COLOR, !=, Color);
- DEFAULT_OP_STR_NULL(math, OP_NOT_EQUAL, NODE_PATH, !=, NodePath);
+ DEFAULT_OP_STR_NULL_SN(math, OP_NOT_EQUAL, STRING_NAME, !=, StringName);
+ DEFAULT_OP_STR_NULL_NP(math, OP_NOT_EQUAL, NODE_PATH, !=, NodePath);
DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, _RID, !=, RID);
- DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, POOL_BYTE_ARRAY, uint8_t);
- DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, POOL_INT_ARRAY, int);
- DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, POOL_REAL_ARRAY, real_t);
- DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, POOL_STRING_ARRAY, String);
- DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, POOL_VECTOR2_ARRAY, Vector2);
- DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, POOL_VECTOR3_ARRAY, Vector3);
- DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, POOL_COLOR_ARRAY, Color);
+ DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_BYTE_ARRAY, uint8_t);
+ DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_INT32_ARRAY, int32_t);
+ DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_INT64_ARRAY, int64_t);
+ DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_FLOAT32_ARRAY, float);
+ DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_FLOAT64_ARRAY, double);
+ DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_STRING_ARRAY, String);
+ DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_VECTOR2_ARRAY, Vector2);
+ DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_VECTOR3_ARRAY, Vector3);
+ DEFAULT_OP_ARRAY_NEQ(math, OP_NOT_EQUAL, PACKED_COLOR_ARRAY, Color);
}
SWITCH_OP(math, OP_LESS, p_a.type) {
@@ -592,6 +649,9 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
_RETURN((p_a._get_obj().obj < p_b._get_obj().obj));
}
+ DEFAULT_OP_LOCALMEM_NULL(math, OP_LESS, CALLABLE, <, Callable);
+ DEFAULT_OP_LOCALMEM_NULL(math, OP_LESS, SIGNAL, <, Signal);
+
CASE_TYPE(math, OP_LESS, ARRAY) {
if (p_b.type != ARRAY)
_RETURN_FAIL;
@@ -612,21 +672,26 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
}
DEFAULT_OP_NUM(math, OP_LESS, INT, <, _int);
- DEFAULT_OP_NUM(math, OP_LESS, REAL, <, _real);
+ DEFAULT_OP_NUM(math, OP_LESS, FLOAT, <, _float);
DEFAULT_OP_STR(math, OP_LESS, STRING, <, String);
DEFAULT_OP_LOCALMEM(math, OP_LESS, VECTOR2, <, Vector2);
+ DEFAULT_OP_LOCALMEM(math, OP_LESS, VECTOR2I, <, Vector2i);
DEFAULT_OP_LOCALMEM(math, OP_LESS, VECTOR3, <, Vector3);
+ DEFAULT_OP_LOCALMEM(math, OP_LESS, VECTOR3I, <, Vector3i);
DEFAULT_OP_LOCALMEM(math, OP_LESS, _RID, <, RID);
- DEFAULT_OP_ARRAY_LT(math, OP_LESS, POOL_BYTE_ARRAY, uint8_t);
- DEFAULT_OP_ARRAY_LT(math, OP_LESS, POOL_INT_ARRAY, int);
- DEFAULT_OP_ARRAY_LT(math, OP_LESS, POOL_REAL_ARRAY, real_t);
- DEFAULT_OP_ARRAY_LT(math, OP_LESS, POOL_STRING_ARRAY, String);
- DEFAULT_OP_ARRAY_LT(math, OP_LESS, POOL_VECTOR2_ARRAY, Vector3);
- DEFAULT_OP_ARRAY_LT(math, OP_LESS, POOL_VECTOR3_ARRAY, Vector3);
- DEFAULT_OP_ARRAY_LT(math, OP_LESS, POOL_COLOR_ARRAY, Color);
+ DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_BYTE_ARRAY, uint8_t);
+ DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_INT32_ARRAY, int32_t);
+ DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_INT64_ARRAY, int64_t);
+ DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_FLOAT32_ARRAY, float);
+ DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_FLOAT64_ARRAY, double);
+ DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_STRING_ARRAY, String);
+ DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_VECTOR2_ARRAY, Vector3);
+ DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_VECTOR3_ARRAY, Vector3);
+ DEFAULT_OP_ARRAY_LT(math, OP_LESS, PACKED_COLOR_ARRAY, Color);
CASE_TYPE(math, OP_LESS, NIL)
CASE_TYPE(math, OP_LESS, RECT2)
+ CASE_TYPE(math, OP_LESS, RECT2I)
CASE_TYPE(math, OP_LESS, TRANSFORM2D)
CASE_TYPE(math, OP_LESS, PLANE)
CASE_TYPE(math, OP_LESS, QUAT)
@@ -634,6 +699,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_LESS, BASIS)
CASE_TYPE(math, OP_LESS, TRANSFORM)
CASE_TYPE(math, OP_LESS, COLOR)
+ CASE_TYPE(math, OP_LESS, STRING_NAME)
CASE_TYPE(math, OP_LESS, NODE_PATH)
CASE_TYPE(math, OP_LESS, DICTIONARY)
_RETURN_FAIL;
@@ -647,15 +713,18 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
}
DEFAULT_OP_NUM(math, OP_LESS_EQUAL, INT, <=, _int);
- DEFAULT_OP_NUM(math, OP_LESS_EQUAL, REAL, <=, _real);
+ DEFAULT_OP_NUM(math, OP_LESS_EQUAL, FLOAT, <=, _float);
DEFAULT_OP_STR(math, OP_LESS_EQUAL, STRING, <=, String);
DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, VECTOR2, <=, Vector2);
+ DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, VECTOR2I, <=, Vector2i);
DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, VECTOR3, <=, Vector3);
+ DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, VECTOR3I, <=, Vector3i);
DEFAULT_OP_LOCALMEM(math, OP_LESS_EQUAL, _RID, <=, RID);
CASE_TYPE(math, OP_LESS_EQUAL, NIL)
CASE_TYPE(math, OP_LESS_EQUAL, BOOL)
CASE_TYPE(math, OP_LESS_EQUAL, RECT2)
+ CASE_TYPE(math, OP_LESS_EQUAL, RECT2I)
CASE_TYPE(math, OP_LESS_EQUAL, TRANSFORM2D)
CASE_TYPE(math, OP_LESS_EQUAL, PLANE)
CASE_TYPE(math, OP_LESS_EQUAL, QUAT)
@@ -663,16 +732,22 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_LESS_EQUAL, BASIS)
CASE_TYPE(math, OP_LESS_EQUAL, TRANSFORM)
CASE_TYPE(math, OP_LESS_EQUAL, COLOR)
+ CASE_TYPE(math, OP_LESS_EQUAL, STRING_NAME)
CASE_TYPE(math, OP_LESS_EQUAL, NODE_PATH)
+ CASE_TYPE(math, OP_LESS_EQUAL, CALLABLE)
+ CASE_TYPE(math, OP_LESS_EQUAL, SIGNAL)
+
CASE_TYPE(math, OP_LESS_EQUAL, DICTIONARY)
CASE_TYPE(math, OP_LESS_EQUAL, ARRAY)
- CASE_TYPE(math, OP_LESS_EQUAL, POOL_BYTE_ARRAY);
- CASE_TYPE(math, OP_LESS_EQUAL, POOL_INT_ARRAY);
- CASE_TYPE(math, OP_LESS_EQUAL, POOL_REAL_ARRAY);
- CASE_TYPE(math, OP_LESS_EQUAL, POOL_STRING_ARRAY);
- CASE_TYPE(math, OP_LESS_EQUAL, POOL_VECTOR2_ARRAY);
- CASE_TYPE(math, OP_LESS_EQUAL, POOL_VECTOR3_ARRAY);
- CASE_TYPE(math, OP_LESS_EQUAL, POOL_COLOR_ARRAY);
+ CASE_TYPE(math, OP_LESS_EQUAL, PACKED_BYTE_ARRAY);
+ CASE_TYPE(math, OP_LESS_EQUAL, PACKED_INT32_ARRAY);
+ CASE_TYPE(math, OP_LESS_EQUAL, PACKED_INT64_ARRAY);
+ CASE_TYPE(math, OP_LESS_EQUAL, PACKED_FLOAT32_ARRAY);
+ CASE_TYPE(math, OP_LESS_EQUAL, PACKED_FLOAT64_ARRAY);
+ CASE_TYPE(math, OP_LESS_EQUAL, PACKED_STRING_ARRAY);
+ CASE_TYPE(math, OP_LESS_EQUAL, PACKED_VECTOR2_ARRAY);
+ CASE_TYPE(math, OP_LESS_EQUAL, PACKED_VECTOR3_ARRAY);
+ CASE_TYPE(math, OP_LESS_EQUAL, PACKED_COLOR_ARRAY);
_RETURN_FAIL;
}
@@ -716,21 +791,26 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
}
DEFAULT_OP_NUM(math, OP_GREATER, INT, >, _int);
- DEFAULT_OP_NUM(math, OP_GREATER, REAL, >, _real);
+ DEFAULT_OP_NUM(math, OP_GREATER, FLOAT, >, _float);
DEFAULT_OP_STR_REV(math, OP_GREATER, STRING, <, String);
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, VECTOR2, <, Vector2);
+ DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, VECTOR2I, <, Vector2i);
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, VECTOR3, <, Vector3);
+ DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, VECTOR3I, <, Vector3i);
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER, _RID, <, RID);
- DEFAULT_OP_ARRAY_GT(math, OP_GREATER, POOL_BYTE_ARRAY, uint8_t);
- DEFAULT_OP_ARRAY_GT(math, OP_GREATER, POOL_INT_ARRAY, int);
- DEFAULT_OP_ARRAY_GT(math, OP_GREATER, POOL_REAL_ARRAY, real_t);
- DEFAULT_OP_ARRAY_GT(math, OP_GREATER, POOL_STRING_ARRAY, String);
- DEFAULT_OP_ARRAY_GT(math, OP_GREATER, POOL_VECTOR2_ARRAY, Vector3);
- DEFAULT_OP_ARRAY_GT(math, OP_GREATER, POOL_VECTOR3_ARRAY, Vector3);
- DEFAULT_OP_ARRAY_GT(math, OP_GREATER, POOL_COLOR_ARRAY, Color);
+ DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_BYTE_ARRAY, uint8_t);
+ DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_INT32_ARRAY, int32_t);
+ DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_INT64_ARRAY, int64_t);
+ DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_FLOAT32_ARRAY, float);
+ DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_FLOAT64_ARRAY, double);
+ DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_STRING_ARRAY, String);
+ DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_VECTOR2_ARRAY, Vector3);
+ DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_VECTOR3_ARRAY, Vector3);
+ DEFAULT_OP_ARRAY_GT(math, OP_GREATER, PACKED_COLOR_ARRAY, Color);
CASE_TYPE(math, OP_GREATER, NIL)
CASE_TYPE(math, OP_GREATER, RECT2)
+ CASE_TYPE(math, OP_GREATER, RECT2I)
CASE_TYPE(math, OP_GREATER, TRANSFORM2D)
CASE_TYPE(math, OP_GREATER, PLANE)
CASE_TYPE(math, OP_GREATER, QUAT)
@@ -738,8 +818,12 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_GREATER, BASIS)
CASE_TYPE(math, OP_GREATER, TRANSFORM)
CASE_TYPE(math, OP_GREATER, COLOR)
+ CASE_TYPE(math, OP_GREATER, STRING_NAME)
CASE_TYPE(math, OP_GREATER, NODE_PATH)
CASE_TYPE(math, OP_GREATER, DICTIONARY)
+ CASE_TYPE(math, OP_GREATER, CALLABLE)
+ CASE_TYPE(math, OP_GREATER, SIGNAL)
+
_RETURN_FAIL;
}
@@ -751,15 +835,18 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
}
DEFAULT_OP_NUM(math, OP_GREATER_EQUAL, INT, >=, _int);
- DEFAULT_OP_NUM(math, OP_GREATER_EQUAL, REAL, >=, _real);
+ DEFAULT_OP_NUM(math, OP_GREATER_EQUAL, FLOAT, >=, _float);
DEFAULT_OP_STR_REV(math, OP_GREATER_EQUAL, STRING, <=, String);
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, VECTOR2, <=, Vector2);
+ DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, VECTOR2I, <=, Vector2i);
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, VECTOR3, <=, Vector3);
+ DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, VECTOR3I, <=, Vector3i);
DEFAULT_OP_LOCALMEM_REV(math, OP_GREATER_EQUAL, _RID, <=, RID);
CASE_TYPE(math, OP_GREATER_EQUAL, NIL)
CASE_TYPE(math, OP_GREATER_EQUAL, BOOL)
CASE_TYPE(math, OP_GREATER_EQUAL, RECT2)
+ CASE_TYPE(math, OP_GREATER_EQUAL, RECT2I)
CASE_TYPE(math, OP_GREATER_EQUAL, TRANSFORM2D)
CASE_TYPE(math, OP_GREATER_EQUAL, PLANE)
CASE_TYPE(math, OP_GREATER_EQUAL, QUAT)
@@ -767,16 +854,22 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_GREATER_EQUAL, BASIS)
CASE_TYPE(math, OP_GREATER_EQUAL, TRANSFORM)
CASE_TYPE(math, OP_GREATER_EQUAL, COLOR)
+ CASE_TYPE(math, OP_GREATER_EQUAL, STRING_NAME)
CASE_TYPE(math, OP_GREATER_EQUAL, NODE_PATH)
+ CASE_TYPE(math, OP_GREATER_EQUAL, CALLABLE)
+ CASE_TYPE(math, OP_GREATER_EQUAL, SIGNAL)
+
CASE_TYPE(math, OP_GREATER_EQUAL, DICTIONARY)
CASE_TYPE(math, OP_GREATER_EQUAL, ARRAY)
- CASE_TYPE(math, OP_GREATER_EQUAL, POOL_BYTE_ARRAY);
- CASE_TYPE(math, OP_GREATER_EQUAL, POOL_INT_ARRAY);
- CASE_TYPE(math, OP_GREATER_EQUAL, POOL_REAL_ARRAY);
- CASE_TYPE(math, OP_GREATER_EQUAL, POOL_STRING_ARRAY);
- CASE_TYPE(math, OP_GREATER_EQUAL, POOL_VECTOR2_ARRAY);
- CASE_TYPE(math, OP_GREATER_EQUAL, POOL_VECTOR3_ARRAY);
- CASE_TYPE(math, OP_GREATER_EQUAL, POOL_COLOR_ARRAY);
+ CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_BYTE_ARRAY);
+ CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_INT32_ARRAY);
+ CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_INT64_ARRAY);
+ CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_FLOAT32_ARRAY);
+ CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_FLOAT64_ARRAY);
+ CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_STRING_ARRAY);
+ CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_VECTOR2_ARRAY);
+ CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_VECTOR3_ARRAY);
+ CASE_TYPE(math, OP_GREATER_EQUAL, PACKED_COLOR_ARRAY);
_RETURN_FAIL;
}
@@ -799,41 +892,52 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
}
DEFAULT_OP_NUM(math, OP_ADD, INT, +, _int);
- DEFAULT_OP_NUM(math, OP_ADD, REAL, +, _real);
+ DEFAULT_OP_NUM(math, OP_ADD, FLOAT, +, _float);
DEFAULT_OP_STR(math, OP_ADD, STRING, +, String);
DEFAULT_OP_LOCALMEM(math, OP_ADD, VECTOR2, +, Vector2);
+ DEFAULT_OP_LOCALMEM(math, OP_ADD, VECTOR2I, +, Vector2i);
DEFAULT_OP_LOCALMEM(math, OP_ADD, VECTOR3, +, Vector3);
+ DEFAULT_OP_LOCALMEM(math, OP_ADD, VECTOR3I, +, Vector3i);
DEFAULT_OP_LOCALMEM(math, OP_ADD, QUAT, +, Quat);
DEFAULT_OP_LOCALMEM(math, OP_ADD, COLOR, +, Color);
- DEFAULT_OP_ARRAY_ADD(math, OP_ADD, POOL_BYTE_ARRAY, uint8_t);
- DEFAULT_OP_ARRAY_ADD(math, OP_ADD, POOL_INT_ARRAY, int);
- DEFAULT_OP_ARRAY_ADD(math, OP_ADD, POOL_REAL_ARRAY, real_t);
- DEFAULT_OP_ARRAY_ADD(math, OP_ADD, POOL_STRING_ARRAY, String);
- DEFAULT_OP_ARRAY_ADD(math, OP_ADD, POOL_VECTOR2_ARRAY, Vector2);
- DEFAULT_OP_ARRAY_ADD(math, OP_ADD, POOL_VECTOR3_ARRAY, Vector3);
- DEFAULT_OP_ARRAY_ADD(math, OP_ADD, POOL_COLOR_ARRAY, Color);
+ DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_BYTE_ARRAY, uint8_t);
+ DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_INT32_ARRAY, int32_t);
+ DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_INT64_ARRAY, int64_t);
+ DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_FLOAT32_ARRAY, float);
+ DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_FLOAT64_ARRAY, double);
+ DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_STRING_ARRAY, String);
+ DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_VECTOR2_ARRAY, Vector2);
+ DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_VECTOR3_ARRAY, Vector3);
+ DEFAULT_OP_ARRAY_ADD(math, OP_ADD, PACKED_COLOR_ARRAY, Color);
CASE_TYPE(math, OP_ADD, NIL)
CASE_TYPE(math, OP_ADD, BOOL)
CASE_TYPE(math, OP_ADD, RECT2)
+ CASE_TYPE(math, OP_ADD, RECT2I)
CASE_TYPE(math, OP_ADD, TRANSFORM2D)
CASE_TYPE(math, OP_ADD, PLANE)
CASE_TYPE(math, OP_ADD, AABB)
CASE_TYPE(math, OP_ADD, BASIS)
CASE_TYPE(math, OP_ADD, TRANSFORM)
+ CASE_TYPE(math, OP_ADD, STRING_NAME)
CASE_TYPE(math, OP_ADD, NODE_PATH)
CASE_TYPE(math, OP_ADD, _RID)
CASE_TYPE(math, OP_ADD, OBJECT)
+ CASE_TYPE(math, OP_ADD, CALLABLE)
+ CASE_TYPE(math, OP_ADD, SIGNAL)
+
CASE_TYPE(math, OP_ADD, DICTIONARY)
_RETURN_FAIL;
}
SWITCH_OP(math, OP_SUBTRACT, p_a.type) {
DEFAULT_OP_NUM(math, OP_SUBTRACT, INT, -, _int);
- DEFAULT_OP_NUM(math, OP_SUBTRACT, REAL, -, _real);
+ DEFAULT_OP_NUM(math, OP_SUBTRACT, FLOAT, -, _float);
DEFAULT_OP_LOCALMEM(math, OP_SUBTRACT, VECTOR2, -, Vector2);
+ DEFAULT_OP_LOCALMEM(math, OP_SUBTRACT, VECTOR2I, -, Vector2i);
DEFAULT_OP_LOCALMEM(math, OP_SUBTRACT, VECTOR3, -, Vector3);
+ DEFAULT_OP_LOCALMEM(math, OP_SUBTRACT, VECTOR3I, -, Vector3i);
DEFAULT_OP_LOCALMEM(math, OP_SUBTRACT, QUAT, -, Quat);
DEFAULT_OP_LOCALMEM(math, OP_SUBTRACT, COLOR, -, Color);
@@ -841,23 +945,30 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_SUBTRACT, BOOL)
CASE_TYPE(math, OP_SUBTRACT, STRING)
CASE_TYPE(math, OP_SUBTRACT, RECT2)
+ CASE_TYPE(math, OP_SUBTRACT, RECT2I)
CASE_TYPE(math, OP_SUBTRACT, TRANSFORM2D)
CASE_TYPE(math, OP_SUBTRACT, PLANE)
CASE_TYPE(math, OP_SUBTRACT, AABB)
CASE_TYPE(math, OP_SUBTRACT, BASIS)
CASE_TYPE(math, OP_SUBTRACT, TRANSFORM)
+ CASE_TYPE(math, OP_SUBTRACT, STRING_NAME)
CASE_TYPE(math, OP_SUBTRACT, NODE_PATH)
CASE_TYPE(math, OP_SUBTRACT, _RID)
CASE_TYPE(math, OP_SUBTRACT, OBJECT)
+ CASE_TYPE(math, OP_SUBTRACT, CALLABLE)
+ CASE_TYPE(math, OP_SUBTRACT, SIGNAL)
+
CASE_TYPE(math, OP_SUBTRACT, DICTIONARY)
CASE_TYPE(math, OP_SUBTRACT, ARRAY)
- CASE_TYPE(math, OP_SUBTRACT, POOL_BYTE_ARRAY);
- CASE_TYPE(math, OP_SUBTRACT, POOL_INT_ARRAY);
- CASE_TYPE(math, OP_SUBTRACT, POOL_REAL_ARRAY);
- CASE_TYPE(math, OP_SUBTRACT, POOL_STRING_ARRAY);
- CASE_TYPE(math, OP_SUBTRACT, POOL_VECTOR2_ARRAY);
- CASE_TYPE(math, OP_SUBTRACT, POOL_VECTOR3_ARRAY);
- CASE_TYPE(math, OP_SUBTRACT, POOL_COLOR_ARRAY);
+ CASE_TYPE(math, OP_SUBTRACT, PACKED_BYTE_ARRAY);
+ CASE_TYPE(math, OP_SUBTRACT, PACKED_INT32_ARRAY);
+ CASE_TYPE(math, OP_SUBTRACT, PACKED_INT64_ARRAY);
+ CASE_TYPE(math, OP_SUBTRACT, PACKED_FLOAT32_ARRAY);
+ CASE_TYPE(math, OP_SUBTRACT, PACKED_FLOAT64_ARRAY);
+ CASE_TYPE(math, OP_SUBTRACT, PACKED_STRING_ARRAY);
+ CASE_TYPE(math, OP_SUBTRACT, PACKED_VECTOR2_ARRAY);
+ CASE_TYPE(math, OP_SUBTRACT, PACKED_VECTOR3_ARRAY);
+ CASE_TYPE(math, OP_SUBTRACT, PACKED_COLOR_ARRAY);
_RETURN_FAIL;
}
@@ -882,8 +993,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
case QUAT: {
_RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * *reinterpret_cast<const Quat *>(p_b._data._mem));
}
- case REAL: {
- _RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * p_b._data._real);
+ case FLOAT: {
+ _RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * p_b._data._float);
}
default: _RETURN_FAIL;
}
@@ -914,113 +1025,142 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
}
DEFAULT_OP_NUM_VEC(math, OP_MULTIPLY, INT, *, _int);
- DEFAULT_OP_NUM_VEC(math, OP_MULTIPLY, REAL, *, _real);
+ DEFAULT_OP_NUM_VEC(math, OP_MULTIPLY, FLOAT, *, _float);
DEFAULT_OP_LOCALMEM_NUM(math, OP_MULTIPLY, VECTOR2, *, Vector2);
+ DEFAULT_OP_LOCALMEM_NUM(math, OP_MULTIPLY, VECTOR2I, *, Vector2i);
DEFAULT_OP_LOCALMEM_NUM(math, OP_MULTIPLY, VECTOR3, *, Vector3);
+ DEFAULT_OP_LOCALMEM_NUM(math, OP_MULTIPLY, VECTOR3I, *, Vector3i);
DEFAULT_OP_LOCALMEM_NUM(math, OP_MULTIPLY, COLOR, *, Color);
CASE_TYPE(math, OP_MULTIPLY, NIL)
CASE_TYPE(math, OP_MULTIPLY, BOOL)
CASE_TYPE(math, OP_MULTIPLY, STRING)
CASE_TYPE(math, OP_MULTIPLY, RECT2)
+ CASE_TYPE(math, OP_MULTIPLY, RECT2I)
CASE_TYPE(math, OP_MULTIPLY, PLANE)
CASE_TYPE(math, OP_MULTIPLY, AABB)
+ CASE_TYPE(math, OP_MULTIPLY, STRING_NAME)
CASE_TYPE(math, OP_MULTIPLY, NODE_PATH)
CASE_TYPE(math, OP_MULTIPLY, _RID)
CASE_TYPE(math, OP_MULTIPLY, OBJECT)
+ CASE_TYPE(math, OP_MULTIPLY, CALLABLE)
+ CASE_TYPE(math, OP_MULTIPLY, SIGNAL)
+
CASE_TYPE(math, OP_MULTIPLY, DICTIONARY)
CASE_TYPE(math, OP_MULTIPLY, ARRAY)
- CASE_TYPE(math, OP_MULTIPLY, POOL_BYTE_ARRAY);
- CASE_TYPE(math, OP_MULTIPLY, POOL_INT_ARRAY);
- CASE_TYPE(math, OP_MULTIPLY, POOL_REAL_ARRAY);
- CASE_TYPE(math, OP_MULTIPLY, POOL_STRING_ARRAY);
- CASE_TYPE(math, OP_MULTIPLY, POOL_VECTOR2_ARRAY);
- CASE_TYPE(math, OP_MULTIPLY, POOL_VECTOR3_ARRAY);
- CASE_TYPE(math, OP_MULTIPLY, POOL_COLOR_ARRAY);
+ CASE_TYPE(math, OP_MULTIPLY, PACKED_BYTE_ARRAY);
+ CASE_TYPE(math, OP_MULTIPLY, PACKED_INT32_ARRAY);
+ CASE_TYPE(math, OP_MULTIPLY, PACKED_INT64_ARRAY);
+ CASE_TYPE(math, OP_MULTIPLY, PACKED_FLOAT32_ARRAY);
+ CASE_TYPE(math, OP_MULTIPLY, PACKED_FLOAT64_ARRAY);
+ CASE_TYPE(math, OP_MULTIPLY, PACKED_STRING_ARRAY);
+ CASE_TYPE(math, OP_MULTIPLY, PACKED_VECTOR2_ARRAY);
+ CASE_TYPE(math, OP_MULTIPLY, PACKED_VECTOR3_ARRAY);
+ CASE_TYPE(math, OP_MULTIPLY, PACKED_COLOR_ARRAY);
_RETURN_FAIL;
}
SWITCH_OP(math, OP_DIVIDE, p_a.type) {
CASE_TYPE(math, OP_DIVIDE, QUAT) {
- if (p_b.type != REAL)
+ if (p_b.type != FLOAT)
_RETURN_FAIL;
#ifdef DEBUG_ENABLED
- if (p_b._data._real == 0) {
+ if (p_b._data._float == 0) {
r_valid = false;
_RETURN("Division By Zero");
}
#endif
- _RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) / p_b._data._real);
+ _RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) / p_b._data._float);
}
DEFAULT_OP_NUM_DIV(math, OP_DIVIDE, INT, _int);
- DEFAULT_OP_NUM_DIV(math, OP_DIVIDE, REAL, _real);
+ DEFAULT_OP_NUM_DIV(math, OP_DIVIDE, FLOAT, _float);
DEFAULT_OP_LOCALMEM_NUM(math, OP_DIVIDE, VECTOR2, /, Vector2);
+ DEFAULT_OP_LOCALMEM_NUM(math, OP_DIVIDE, VECTOR2I, /, Vector2i);
DEFAULT_OP_LOCALMEM_NUM(math, OP_DIVIDE, VECTOR3, /, Vector3);
+ DEFAULT_OP_LOCALMEM_NUM(math, OP_DIVIDE, VECTOR3I, /, Vector3i);
DEFAULT_OP_LOCALMEM_NUM(math, OP_DIVIDE, COLOR, /, Color);
CASE_TYPE(math, OP_DIVIDE, NIL)
CASE_TYPE(math, OP_DIVIDE, BOOL)
CASE_TYPE(math, OP_DIVIDE, STRING)
CASE_TYPE(math, OP_DIVIDE, RECT2)
+ CASE_TYPE(math, OP_DIVIDE, RECT2I)
CASE_TYPE(math, OP_DIVIDE, TRANSFORM2D)
CASE_TYPE(math, OP_DIVIDE, PLANE)
CASE_TYPE(math, OP_DIVIDE, AABB)
CASE_TYPE(math, OP_DIVIDE, BASIS)
CASE_TYPE(math, OP_DIVIDE, TRANSFORM)
+ CASE_TYPE(math, OP_DIVIDE, STRING_NAME)
CASE_TYPE(math, OP_DIVIDE, NODE_PATH)
CASE_TYPE(math, OP_DIVIDE, _RID)
CASE_TYPE(math, OP_DIVIDE, OBJECT)
+ CASE_TYPE(math, OP_DIVIDE, CALLABLE)
+ CASE_TYPE(math, OP_DIVIDE, SIGNAL)
+
CASE_TYPE(math, OP_DIVIDE, DICTIONARY)
CASE_TYPE(math, OP_DIVIDE, ARRAY)
- CASE_TYPE(math, OP_DIVIDE, POOL_BYTE_ARRAY);
- CASE_TYPE(math, OP_DIVIDE, POOL_INT_ARRAY);
- CASE_TYPE(math, OP_DIVIDE, POOL_REAL_ARRAY);
- CASE_TYPE(math, OP_DIVIDE, POOL_STRING_ARRAY);
- CASE_TYPE(math, OP_DIVIDE, POOL_VECTOR2_ARRAY);
- CASE_TYPE(math, OP_DIVIDE, POOL_VECTOR3_ARRAY);
- CASE_TYPE(math, OP_DIVIDE, POOL_COLOR_ARRAY);
+ CASE_TYPE(math, OP_DIVIDE, PACKED_BYTE_ARRAY);
+ CASE_TYPE(math, OP_DIVIDE, PACKED_INT32_ARRAY);
+ CASE_TYPE(math, OP_DIVIDE, PACKED_INT64_ARRAY);
+ CASE_TYPE(math, OP_DIVIDE, PACKED_FLOAT32_ARRAY);
+ CASE_TYPE(math, OP_DIVIDE, PACKED_FLOAT64_ARRAY);
+ CASE_TYPE(math, OP_DIVIDE, PACKED_STRING_ARRAY);
+ CASE_TYPE(math, OP_DIVIDE, PACKED_VECTOR2_ARRAY);
+ CASE_TYPE(math, OP_DIVIDE, PACKED_VECTOR3_ARRAY);
+ CASE_TYPE(math, OP_DIVIDE, PACKED_COLOR_ARRAY);
_RETURN_FAIL;
}
SWITCH_OP(math, OP_POSITIVE, p_a.type) {
DEFAULT_OP_NUM_POS(math, OP_POSITIVE, INT, _int);
- DEFAULT_OP_NUM_POS(math, OP_POSITIVE, REAL, _real);
+ DEFAULT_OP_NUM_POS(math, OP_POSITIVE, FLOAT, _float);
DEFAULT_OP_LOCALMEM_POS(math, OP_POSITIVE, VECTOR3, Vector3);
+ DEFAULT_OP_LOCALMEM_POS(math, OP_POSITIVE, VECTOR3I, Vector3i);
DEFAULT_OP_LOCALMEM_POS(math, OP_POSITIVE, PLANE, Plane);
DEFAULT_OP_LOCALMEM_POS(math, OP_POSITIVE, QUAT, Quat);
DEFAULT_OP_LOCALMEM_POS(math, OP_POSITIVE, VECTOR2, Vector2);
+ DEFAULT_OP_LOCALMEM_POS(math, OP_POSITIVE, VECTOR2I, Vector2i);
CASE_TYPE(math, OP_POSITIVE, NIL)
CASE_TYPE(math, OP_POSITIVE, BOOL)
CASE_TYPE(math, OP_POSITIVE, STRING)
CASE_TYPE(math, OP_POSITIVE, RECT2)
+ CASE_TYPE(math, OP_POSITIVE, RECT2I)
CASE_TYPE(math, OP_POSITIVE, TRANSFORM2D)
CASE_TYPE(math, OP_POSITIVE, AABB)
CASE_TYPE(math, OP_POSITIVE, BASIS)
CASE_TYPE(math, OP_POSITIVE, TRANSFORM)
CASE_TYPE(math, OP_POSITIVE, COLOR)
+ CASE_TYPE(math, OP_POSITIVE, STRING_NAME)
CASE_TYPE(math, OP_POSITIVE, NODE_PATH)
CASE_TYPE(math, OP_POSITIVE, _RID)
CASE_TYPE(math, OP_POSITIVE, OBJECT)
+ CASE_TYPE(math, OP_POSITIVE, CALLABLE)
+ CASE_TYPE(math, OP_POSITIVE, SIGNAL)
+
CASE_TYPE(math, OP_POSITIVE, DICTIONARY)
CASE_TYPE(math, OP_POSITIVE, ARRAY)
- CASE_TYPE(math, OP_POSITIVE, POOL_BYTE_ARRAY)
- CASE_TYPE(math, OP_POSITIVE, POOL_INT_ARRAY)
- CASE_TYPE(math, OP_POSITIVE, POOL_REAL_ARRAY)
- CASE_TYPE(math, OP_POSITIVE, POOL_STRING_ARRAY)
- CASE_TYPE(math, OP_POSITIVE, POOL_VECTOR2_ARRAY)
- CASE_TYPE(math, OP_POSITIVE, POOL_VECTOR3_ARRAY)
- CASE_TYPE(math, OP_POSITIVE, POOL_COLOR_ARRAY)
+ CASE_TYPE(math, OP_POSITIVE, PACKED_BYTE_ARRAY)
+ CASE_TYPE(math, OP_POSITIVE, PACKED_INT32_ARRAY)
+ CASE_TYPE(math, OP_POSITIVE, PACKED_INT64_ARRAY)
+ CASE_TYPE(math, OP_POSITIVE, PACKED_FLOAT32_ARRAY)
+ CASE_TYPE(math, OP_POSITIVE, PACKED_FLOAT64_ARRAY)
+ CASE_TYPE(math, OP_POSITIVE, PACKED_STRING_ARRAY)
+ CASE_TYPE(math, OP_POSITIVE, PACKED_VECTOR2_ARRAY)
+ CASE_TYPE(math, OP_POSITIVE, PACKED_VECTOR3_ARRAY)
+ CASE_TYPE(math, OP_POSITIVE, PACKED_COLOR_ARRAY)
_RETURN_FAIL;
}
SWITCH_OP(math, OP_NEGATE, p_a.type) {
DEFAULT_OP_NUM_NEG(math, OP_NEGATE, INT, _int);
- DEFAULT_OP_NUM_NEG(math, OP_NEGATE, REAL, _real);
+ DEFAULT_OP_NUM_NEG(math, OP_NEGATE, FLOAT, _float);
DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, VECTOR2, Vector2);
+ DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, VECTOR2I, Vector2i);
DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, VECTOR3, Vector3);
+ DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, VECTOR3I, Vector3i);
DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, PLANE, Plane);
DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, QUAT, Quat);
DEFAULT_OP_LOCALMEM_NEG(math, OP_NEGATE, COLOR, Color);
@@ -1029,22 +1169,29 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_NEGATE, BOOL)
CASE_TYPE(math, OP_NEGATE, STRING)
CASE_TYPE(math, OP_NEGATE, RECT2)
+ CASE_TYPE(math, OP_NEGATE, RECT2I)
CASE_TYPE(math, OP_NEGATE, TRANSFORM2D)
CASE_TYPE(math, OP_NEGATE, AABB)
CASE_TYPE(math, OP_NEGATE, BASIS)
CASE_TYPE(math, OP_NEGATE, TRANSFORM)
+ CASE_TYPE(math, OP_NEGATE, STRING_NAME)
CASE_TYPE(math, OP_NEGATE, NODE_PATH)
CASE_TYPE(math, OP_NEGATE, _RID)
CASE_TYPE(math, OP_NEGATE, OBJECT)
+ CASE_TYPE(math, OP_NEGATE, CALLABLE)
+ CASE_TYPE(math, OP_NEGATE, SIGNAL)
+
CASE_TYPE(math, OP_NEGATE, DICTIONARY)
CASE_TYPE(math, OP_NEGATE, ARRAY)
- CASE_TYPE(math, OP_NEGATE, POOL_BYTE_ARRAY)
- CASE_TYPE(math, OP_NEGATE, POOL_INT_ARRAY)
- CASE_TYPE(math, OP_NEGATE, POOL_REAL_ARRAY)
- CASE_TYPE(math, OP_NEGATE, POOL_STRING_ARRAY)
- CASE_TYPE(math, OP_NEGATE, POOL_VECTOR2_ARRAY)
- CASE_TYPE(math, OP_NEGATE, POOL_VECTOR3_ARRAY)
- CASE_TYPE(math, OP_NEGATE, POOL_COLOR_ARRAY)
+ CASE_TYPE(math, OP_NEGATE, PACKED_BYTE_ARRAY)
+ CASE_TYPE(math, OP_NEGATE, PACKED_INT32_ARRAY)
+ CASE_TYPE(math, OP_NEGATE, PACKED_INT64_ARRAY)
+ CASE_TYPE(math, OP_NEGATE, PACKED_FLOAT32_ARRAY)
+ CASE_TYPE(math, OP_NEGATE, PACKED_FLOAT64_ARRAY)
+ CASE_TYPE(math, OP_NEGATE, PACKED_STRING_ARRAY)
+ CASE_TYPE(math, OP_NEGATE, PACKED_VECTOR2_ARRAY)
+ CASE_TYPE(math, OP_NEGATE, PACKED_VECTOR3_ARRAY)
+ CASE_TYPE(math, OP_NEGATE, PACKED_COLOR_ARRAY)
_RETURN_FAIL;
}
@@ -1082,10 +1229,13 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_MODULE, NIL)
CASE_TYPE(math, OP_MODULE, BOOL)
- CASE_TYPE(math, OP_MODULE, REAL)
+ CASE_TYPE(math, OP_MODULE, FLOAT)
CASE_TYPE(math, OP_MODULE, VECTOR2)
+ CASE_TYPE(math, OP_MODULE, VECTOR2I)
CASE_TYPE(math, OP_MODULE, RECT2)
+ CASE_TYPE(math, OP_MODULE, RECT2I)
CASE_TYPE(math, OP_MODULE, VECTOR3)
+ CASE_TYPE(math, OP_MODULE, VECTOR3I)
CASE_TYPE(math, OP_MODULE, TRANSFORM2D)
CASE_TYPE(math, OP_MODULE, PLANE)
CASE_TYPE(math, OP_MODULE, QUAT)
@@ -1093,18 +1243,24 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
CASE_TYPE(math, OP_MODULE, BASIS)
CASE_TYPE(math, OP_MODULE, TRANSFORM)
CASE_TYPE(math, OP_MODULE, COLOR)
+ CASE_TYPE(math, OP_MODULE, STRING_NAME)
CASE_TYPE(math, OP_MODULE, NODE_PATH)
CASE_TYPE(math, OP_MODULE, _RID)
CASE_TYPE(math, OP_MODULE, OBJECT)
+ CASE_TYPE(math, OP_MODULE, CALLABLE)
+ CASE_TYPE(math, OP_MODULE, SIGNAL)
+
CASE_TYPE(math, OP_MODULE, DICTIONARY)
CASE_TYPE(math, OP_MODULE, ARRAY)
- CASE_TYPE(math, OP_MODULE, POOL_BYTE_ARRAY)
- CASE_TYPE(math, OP_MODULE, POOL_INT_ARRAY)
- CASE_TYPE(math, OP_MODULE, POOL_REAL_ARRAY)
- CASE_TYPE(math, OP_MODULE, POOL_STRING_ARRAY)
- CASE_TYPE(math, OP_MODULE, POOL_VECTOR2_ARRAY)
- CASE_TYPE(math, OP_MODULE, POOL_VECTOR3_ARRAY)
- CASE_TYPE(math, OP_MODULE, POOL_COLOR_ARRAY)
+ CASE_TYPE(math, OP_MODULE, PACKED_BYTE_ARRAY)
+ CASE_TYPE(math, OP_MODULE, PACKED_INT32_ARRAY)
+ CASE_TYPE(math, OP_MODULE, PACKED_INT64_ARRAY)
+ CASE_TYPE(math, OP_MODULE, PACKED_FLOAT32_ARRAY)
+ CASE_TYPE(math, OP_MODULE, PACKED_FLOAT64_ARRAY)
+ CASE_TYPE(math, OP_MODULE, PACKED_STRING_ARRAY)
+ CASE_TYPE(math, OP_MODULE, PACKED_VECTOR2_ARRAY)
+ CASE_TYPE(math, OP_MODULE, PACKED_VECTOR3_ARRAY)
+ CASE_TYPE(math, OP_MODULE, PACKED_COLOR_ARRAY)
_RETURN_FAIL;
}
@@ -1237,13 +1393,35 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
v->y = p_value._data._int;
valid = true;
}
- } else if (p_value.type == Variant::REAL) {
+ } else if (p_value.type == Variant::FLOAT) {
Vector2 *v = reinterpret_cast<Vector2 *>(_data._mem);
if (p_index == CoreStringNames::singleton->x) {
- v->x = p_value._data._real;
+ v->x = p_value._data._float;
valid = true;
} else if (p_index == CoreStringNames::singleton->y) {
- v->y = p_value._data._real;
+ v->y = p_value._data._float;
+ valid = true;
+ }
+ }
+
+ } break;
+ case VECTOR2I: {
+ if (p_value.type == Variant::INT) {
+ Vector2i *v = reinterpret_cast<Vector2i *>(_data._mem);
+ if (p_index == CoreStringNames::singleton->x) {
+ v->x = p_value._data._int;
+ valid = true;
+ } else if (p_index == CoreStringNames::singleton->y) {
+ v->y = p_value._data._int;
+ valid = true;
+ }
+ } else if (p_value.type == Variant::FLOAT) {
+ Vector2i *v = reinterpret_cast<Vector2i *>(_data._mem);
+ if (p_index == CoreStringNames::singleton->x) {
+ v->x = p_value._data._float;
+ valid = true;
+ } else if (p_index == CoreStringNames::singleton->y) {
+ v->y = p_value._data._float;
valid = true;
}
}
@@ -1266,6 +1444,23 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
}
}
} break;
+ case RECT2I: {
+
+ if (p_value.type == Variant::VECTOR2I) {
+ Rect2i *v = reinterpret_cast<Rect2i *>(_data._mem);
+ //scalar name
+ if (p_index == CoreStringNames::singleton->position) {
+ v->position = *reinterpret_cast<const Vector2i *>(p_value._data._mem);
+ valid = true;
+ } else if (p_index == CoreStringNames::singleton->size) {
+ v->size = *reinterpret_cast<const Vector2i *>(p_value._data._mem);
+ valid = true;
+ } else if (p_index == CoreStringNames::singleton->end) {
+ v->size = *reinterpret_cast<const Vector2i *>(p_value._data._mem) - v->position;
+ valid = true;
+ }
+ }
+ } break;
case TRANSFORM2D: {
if (p_value.type == Variant::VECTOR2) {
@@ -1297,16 +1492,45 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
v->z = p_value._data._int;
valid = true;
}
- } else if (p_value.type == Variant::REAL) {
+ } else if (p_value.type == Variant::FLOAT) {
Vector3 *v = reinterpret_cast<Vector3 *>(_data._mem);
if (p_index == CoreStringNames::singleton->x) {
- v->x = p_value._data._real;
+ v->x = p_value._data._float;
valid = true;
} else if (p_index == CoreStringNames::singleton->y) {
- v->y = p_value._data._real;
+ v->y = p_value._data._float;
valid = true;
} else if (p_index == CoreStringNames::singleton->z) {
- v->z = p_value._data._real;
+ v->z = p_value._data._float;
+ valid = true;
+ }
+ }
+
+ } break;
+ case VECTOR3I: {
+
+ if (p_value.type == Variant::INT) {
+ Vector3i *v = reinterpret_cast<Vector3i *>(_data._mem);
+ if (p_index == CoreStringNames::singleton->x) {
+ v->x = p_value._data._int;
+ valid = true;
+ } else if (p_index == CoreStringNames::singleton->y) {
+ v->y = p_value._data._int;
+ valid = true;
+ } else if (p_index == CoreStringNames::singleton->z) {
+ v->z = p_value._data._int;
+ valid = true;
+ }
+ } else if (p_value.type == Variant::FLOAT) {
+ Vector3i *v = reinterpret_cast<Vector3i *>(_data._mem);
+ if (p_index == CoreStringNames::singleton->x) {
+ v->x = p_value._data._float;
+ valid = true;
+ } else if (p_index == CoreStringNames::singleton->y) {
+ v->y = p_value._data._float;
+ valid = true;
+ } else if (p_index == CoreStringNames::singleton->z) {
+ v->z = p_value._data._float;
valid = true;
}
}
@@ -1329,19 +1553,19 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
v->d = p_value._data._int;
valid = true;
}
- } else if (p_value.type == Variant::REAL) {
+ } else if (p_value.type == Variant::FLOAT) {
Plane *v = reinterpret_cast<Plane *>(_data._mem);
if (p_index == CoreStringNames::singleton->x) {
- v->normal.x = p_value._data._real;
+ v->normal.x = p_value._data._float;
valid = true;
} else if (p_index == CoreStringNames::singleton->y) {
- v->normal.y = p_value._data._real;
+ v->normal.y = p_value._data._float;
valid = true;
} else if (p_index == CoreStringNames::singleton->z) {
- v->normal.z = p_value._data._real;
+ v->normal.z = p_value._data._float;
valid = true;
} else if (p_index == CoreStringNames::singleton->d) {
- v->d = p_value._data._real;
+ v->d = p_value._data._float;
valid = true;
}
@@ -1371,24 +1595,24 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
v->w = p_value._data._int;
valid = true;
}
- } else if (p_value.type == Variant::REAL) {
+ } else if (p_value.type == Variant::FLOAT) {
Quat *v = reinterpret_cast<Quat *>(_data._mem);
if (p_index == CoreStringNames::singleton->x) {
- v->x = p_value._data._real;
+ v->x = p_value._data._float;
valid = true;
} else if (p_index == CoreStringNames::singleton->y) {
- v->y = p_value._data._real;
+ v->y = p_value._data._float;
valid = true;
} else if (p_index == CoreStringNames::singleton->z) {
- v->z = p_value._data._real;
+ v->z = p_value._data._float;
valid = true;
} else if (p_index == CoreStringNames::singleton->w) {
- v->w = p_value._data._real;
+ v->w = p_value._data._float;
valid = true;
}
}
- } break; // 10
+ } break;
case AABB: {
if (p_value.type == Variant::VECTOR3) {
@@ -1472,40 +1696,40 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
v->set_hsv(v->get_h(), v->get_v(), p_value._data._int, v->a);
valid = true;
}
- } else if (p_value.type == Variant::REAL) {
+ } else if (p_value.type == Variant::FLOAT) {
Color *v = reinterpret_cast<Color *>(_data._mem);
if (p_index == CoreStringNames::singleton->r) {
- v->r = p_value._data._real;
+ v->r = p_value._data._float;
valid = true;
} else if (p_index == CoreStringNames::singleton->g) {
- v->g = p_value._data._real;
+ v->g = p_value._data._float;
valid = true;
} else if (p_index == CoreStringNames::singleton->b) {
- v->b = p_value._data._real;
+ v->b = p_value._data._float;
valid = true;
} else if (p_index == CoreStringNames::singleton->a) {
- v->a = p_value._data._real;
+ v->a = p_value._data._float;
valid = true;
} else if (p_index == CoreStringNames::singleton->r8) {
- v->r = p_value._data._real / 255.0;
+ v->r = p_value._data._float / 255.0;
valid = true;
} else if (p_index == CoreStringNames::singleton->g8) {
- v->g = p_value._data._real / 255.0;
+ v->g = p_value._data._float / 255.0;
valid = true;
} else if (p_index == CoreStringNames::singleton->b8) {
- v->b = p_value._data._real / 255.0;
+ v->b = p_value._data._float / 255.0;
valid = true;
} else if (p_index == CoreStringNames::singleton->a8) {
- v->a = p_value._data._real / 255.0;
+ v->a = p_value._data._float / 255.0;
valid = true;
} else if (p_index == CoreStringNames::singleton->h) {
- v->set_hsv(p_value._data._real, v->get_s(), v->get_v(), v->a);
+ v->set_hsv(p_value._data._float, v->get_s(), v->get_v(), v->a);
valid = true;
} else if (p_index == CoreStringNames::singleton->s) {
- v->set_hsv(v->get_h(), p_value._data._real, v->get_v(), v->a);
+ v->set_hsv(v->get_h(), p_value._data._float, v->get_v(), v->a);
valid = true;
} else if (p_index == CoreStringNames::singleton->v) {
- v->set_hsv(v->get_h(), v->get_s(), p_value._data._real, v->a);
+ v->set_hsv(v->get_h(), v->get_s(), p_value._data._float, v->a);
valid = true;
}
}
@@ -1548,6 +1772,15 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
}
} break;
+ case VECTOR2I: {
+ const Vector2i *v = reinterpret_cast<const Vector2i *>(_data._mem);
+ if (p_index == CoreStringNames::singleton->x) {
+ return v->x;
+ } else if (p_index == CoreStringNames::singleton->y) {
+ return v->y;
+ }
+
+ } break;
case RECT2: {
const Rect2 *v = reinterpret_cast<const Rect2 *>(_data._mem);
@@ -1560,6 +1793,18 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
return v->size + v->position;
}
} break;
+ case RECT2I: {
+
+ const Rect2i *v = reinterpret_cast<const Rect2i *>(_data._mem);
+ //scalar name
+ if (p_index == CoreStringNames::singleton->position) {
+ return v->position;
+ } else if (p_index == CoreStringNames::singleton->size) {
+ return v->size;
+ } else if (p_index == CoreStringNames::singleton->end) {
+ return v->size + v->position;
+ }
+ } break;
case TRANSFORM2D: {
const Transform2D *v = _data._transform2d;
@@ -1584,6 +1829,18 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
}
} break;
+ case VECTOR3I: {
+
+ const Vector3i *v = reinterpret_cast<const Vector3i *>(_data._mem);
+ if (p_index == CoreStringNames::singleton->x) {
+ return v->x;
+ } else if (p_index == CoreStringNames::singleton->y) {
+ return v->y;
+ } else if (p_index == CoreStringNames::singleton->z) {
+ return v->z;
+ }
+
+ } break;
case PLANE: {
const Plane *v = reinterpret_cast<const Plane *>(_data._mem);
@@ -1613,7 +1870,7 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
return v->w;
}
- } break; // 10
+ } break;
case AABB: {
const ::AABB *v = _data._aabb;
@@ -1707,28 +1964,55 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
return Variant();
}
-#define DEFAULT_OP_ARRAY_CMD(m_name, m_type, skip_test, cmd) \
- case m_name: { \
- skip_test; \
- \
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) { \
- int index = p_index; \
- m_type *arr = reinterpret_cast<m_type *>(_data._mem); \
- \
- if (index < 0) \
- index += arr->size(); \
- if (index >= 0 && index < arr->size()) { \
- valid = true; \
- cmd; \
- } \
- } \
+#define DEFAULT_OP_ARRAY_CMD(m_name, m_type, skip_test, cmd) \
+ case m_name: { \
+ skip_test; \
+ \
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { \
+ int index = p_index; \
+ m_type *arr = reinterpret_cast<m_type *>(_data._mem); \
+ \
+ if (index < 0) \
+ index += arr->size(); \
+ if (index >= 0 && index < arr->size()) { \
+ valid = true; \
+ cmd; \
+ } \
+ } \
} break;
-#define DEFAULT_OP_DVECTOR_SET(m_name, dv_type, skip_cond) \
- DEFAULT_OP_ARRAY_CMD(m_name, PoolVector<dv_type>, if (skip_cond) return;, arr->set(index, p_value); return )
+#define DEFAULT_OP_DVECTOR_SET(m_name, m_type, skip_cond) \
+ case m_name: { \
+ if (skip_cond) return; \
+ \
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { \
+ int index = p_index; \
+ Vector<m_type> *arr = PackedArrayRef<m_type>::get_array_ptr(_data.packed_array); \
+ \
+ if (index < 0) \
+ index += arr->size(); \
+ if (index >= 0 && index < arr->size()) { \
+ valid = true; \
+ arr->set(index, p_value); \
+ } \
+ } \
+ } break;
-#define DEFAULT_OP_DVECTOR_GET(m_name, dv_type) \
- DEFAULT_OP_ARRAY_CMD(m_name, const PoolVector<dv_type>, ;, return arr->get(index))
+#define DEFAULT_OP_DVECTOR_GET(m_name, m_type) \
+ case m_name: { \
+ \
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { \
+ int index = p_index; \
+ const Vector<m_type> *arr = &PackedArrayRef<m_type>::get_array(_data.packed_array); \
+ \
+ if (index < 0) \
+ index += arr->size(); \
+ if (index >= 0 && index < arr->size()) { \
+ valid = true; \
+ return arr->get(index); \
+ } \
+ } \
+ } break;
void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) {
@@ -1747,12 +2031,12 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
case INT: {
return;
} break;
- case REAL: {
+ case FLOAT: {
return;
} break;
case STRING: {
- if (p_index.type != Variant::INT && p_index.type != Variant::REAL)
+ if (p_index.type != Variant::INT && p_index.type != Variant::FLOAT)
return;
int idx = p_index;
@@ -1764,7 +2048,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
return;
String chr;
- if (p_value.type == Variant::INT || p_value.type == Variant::REAL) {
+ if (p_value.type == Variant::INT || p_value.type == Variant::FLOAT) {
chr = String::chr(p_value);
} else if (p_value.type == Variant::STRING) {
@@ -1781,10 +2065,10 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case VECTOR2: {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
return;
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
// scalar index
int idx = p_index;
@@ -1813,7 +2097,42 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
}
- } break; // 5
+ } break;
+ case VECTOR2I: {
+
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
+ return;
+
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
+ // scalar index
+ int idx = p_index;
+
+ if (idx < 0)
+ idx += 2;
+ if (idx >= 0 && idx < 2) {
+
+ Vector2i *v = reinterpret_cast<Vector2i *>(_data._mem);
+ valid = true;
+ (*v)[idx] = p_value;
+ return;
+ }
+ } else if (p_index.get_type() == Variant::STRING) {
+ //scalar name
+
+ const String *str = reinterpret_cast<const String *>(p_index._data._mem);
+ Vector2i *v = reinterpret_cast<Vector2i *>(_data._mem);
+ if (*str == "x") {
+ valid = true;
+ v->x = p_value;
+ return;
+ } else if (*str == "y") {
+ valid = true;
+ v->y = p_value;
+ return;
+ }
+ }
+
+ } break;
case RECT2: {
if (p_value.type != Variant::VECTOR2)
@@ -1839,12 +2158,37 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
}
} break;
+ case RECT2I: {
+
+ if (p_value.type != Variant::VECTOR2I)
+ return;
+
+ if (p_index.get_type() == Variant::STRING) {
+ //scalar name
+
+ const String *str = reinterpret_cast<const String *>(p_index._data._mem);
+ Rect2i *v = reinterpret_cast<Rect2i *>(_data._mem);
+ if (*str == "position") {
+ valid = true;
+ v->position = p_value;
+ return;
+ } else if (*str == "size") {
+ valid = true;
+ v->size = p_value;
+ return;
+ } else if (*str == "end") {
+ valid = true;
+ v->size = Vector2i(p_value) - v->position;
+ return;
+ }
+ }
+ } break;
case TRANSFORM2D: {
if (p_value.type != Variant::VECTOR2)
return;
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
int index = p_index;
@@ -1880,10 +2224,10 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case VECTOR3: {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
return;
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
//scalar index
int idx = p_index;
if (idx < 0)
@@ -1916,6 +2260,44 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
} break;
+ case VECTOR3I: {
+
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
+ return;
+
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
+ //scalar index
+ int idx = p_index;
+ if (idx < 0)
+ idx += 3;
+ if (idx >= 0 && idx < 3) {
+
+ Vector3i *v = reinterpret_cast<Vector3i *>(_data._mem);
+ valid = true;
+ (*v)[idx] = p_value;
+ return;
+ }
+ } else if (p_index.get_type() == Variant::STRING) {
+
+ //scalar name
+ const String *str = reinterpret_cast<const String *>(p_index._data._mem);
+ Vector3i *v = reinterpret_cast<Vector3i *>(_data._mem);
+ if (*str == "x") {
+ valid = true;
+ v->x = p_value;
+ return;
+ } else if (*str == "y") {
+ valid = true;
+ v->y = p_value;
+ return;
+ } else if (*str == "z") {
+ valid = true;
+ v->z = p_value;
+ return;
+ }
+ }
+
+ } break;
case PLANE: {
if (p_index.get_type() == Variant::STRING) {
@@ -1923,21 +2305,21 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
Plane *v = reinterpret_cast<Plane *>(_data._mem);
if (*str == "x") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
return;
valid = true;
v->normal.x = p_value;
return;
} else if (*str == "y") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
return;
valid = true;
v->normal.y = p_value;
return;
} else if (*str == "z") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
return;
valid = true;
@@ -1960,7 +2342,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case QUAT: {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
return;
if (p_index.get_type() == Variant::STRING) {
@@ -1986,7 +2368,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
}
- } break; // 10
+ } break;
case AABB: {
if (p_value.type != Variant::VECTOR3)
@@ -2017,7 +2399,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
if (p_value.type != Variant::VECTOR3)
return;
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
int index = p_index;
@@ -2053,7 +2435,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case TRANSFORM: {
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
if (p_value.type != Variant::VECTOR3)
return;
@@ -2096,7 +2478,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case COLOR: {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
return;
if (p_index.get_type() == Variant::STRING) {
@@ -2161,8 +2543,10 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
} break;
+ case STRING_NAME: {
+ } break;
case NODE_PATH: {
- } break; // 15
+ } break;
case _RID: {
} break;
case OBJECT: {
@@ -2180,7 +2564,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
#endif
- if (p_index.get_type() != Variant::STRING) {
+ if (p_index.get_type() != Variant::STRING_NAME && p_index.get_type() != Variant::STRING) {
obj->setvar(p_index, p_value, r_valid);
return;
}
@@ -2196,14 +2580,16 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
valid = true; //always valid, i guess? should this really be ok?
return;
} break;
- DEFAULT_OP_ARRAY_CMD(ARRAY, Array, ;, (*arr)[index] = p_value; return ) // 20
- DEFAULT_OP_DVECTOR_SET(POOL_BYTE_ARRAY, uint8_t, p_value.type != Variant::REAL && p_value.type != Variant::INT)
- DEFAULT_OP_DVECTOR_SET(POOL_INT_ARRAY, int, p_value.type != Variant::REAL && p_value.type != Variant::INT)
- DEFAULT_OP_DVECTOR_SET(POOL_REAL_ARRAY, real_t, p_value.type != Variant::REAL && p_value.type != Variant::INT)
- DEFAULT_OP_DVECTOR_SET(POOL_STRING_ARRAY, String, p_value.type != Variant::STRING)
- DEFAULT_OP_DVECTOR_SET(POOL_VECTOR2_ARRAY, Vector2, p_value.type != Variant::VECTOR2) // 25
- DEFAULT_OP_DVECTOR_SET(POOL_VECTOR3_ARRAY, Vector3, p_value.type != Variant::VECTOR3)
- DEFAULT_OP_DVECTOR_SET(POOL_COLOR_ARRAY, Color, p_value.type != Variant::COLOR)
+ DEFAULT_OP_ARRAY_CMD(ARRAY, Array, ;, (*arr)[index] = p_value; return )
+ DEFAULT_OP_DVECTOR_SET(PACKED_BYTE_ARRAY, uint8_t, p_value.type != Variant::FLOAT && p_value.type != Variant::INT)
+ DEFAULT_OP_DVECTOR_SET(PACKED_INT32_ARRAY, int32_t, p_value.type != Variant::FLOAT && p_value.type != Variant::INT)
+ DEFAULT_OP_DVECTOR_SET(PACKED_INT64_ARRAY, int64_t, p_value.type != Variant::FLOAT && p_value.type != Variant::INT)
+ DEFAULT_OP_DVECTOR_SET(PACKED_FLOAT32_ARRAY, float, p_value.type != Variant::FLOAT && p_value.type != Variant::INT)
+ DEFAULT_OP_DVECTOR_SET(PACKED_FLOAT64_ARRAY, double, p_value.type != Variant::FLOAT && p_value.type != Variant::INT)
+ DEFAULT_OP_DVECTOR_SET(PACKED_STRING_ARRAY, String, p_value.type != Variant::STRING)
+ DEFAULT_OP_DVECTOR_SET(PACKED_VECTOR2_ARRAY, Vector2, p_value.type != Variant::VECTOR2)
+ DEFAULT_OP_DVECTOR_SET(PACKED_VECTOR3_ARRAY, Vector3, p_value.type != Variant::VECTOR3)
+ DEFAULT_OP_DVECTOR_SET(PACKED_COLOR_ARRAY, Color, p_value.type != Variant::COLOR)
default:
return;
}
@@ -2227,12 +2613,12 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
case INT: {
return Variant();
} break;
- case REAL: {
+ case FLOAT: {
return Variant();
} break;
case STRING: {
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
//string index
int idx = p_index;
@@ -2249,7 +2635,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case VECTOR2: {
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
// scalar index
int idx = p_index;
if (idx < 0)
@@ -2274,7 +2660,35 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
}
}
- } break; // 5
+ } break;
+ case VECTOR2I: {
+
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
+ // scalar index
+ int idx = p_index;
+ if (idx < 0)
+ idx += 2;
+ if (idx >= 0 && idx < 2) {
+
+ const Vector2i *v = reinterpret_cast<const Vector2i *>(_data._mem);
+ valid = true;
+ return (*v)[idx];
+ }
+ } else if (p_index.get_type() == Variant::STRING) {
+ //scalar name
+
+ const String *str = reinterpret_cast<const String *>(p_index._data._mem);
+ const Vector2i *v = reinterpret_cast<const Vector2i *>(_data._mem);
+ if (*str == "x") {
+ valid = true;
+ return v->x;
+ } else if (*str == "y") {
+ valid = true;
+ return v->y;
+ }
+ }
+
+ } break;
case RECT2: {
if (p_index.get_type() == Variant::STRING) {
@@ -2294,9 +2708,28 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
}
}
} break;
+ case RECT2I: {
+
+ if (p_index.get_type() == Variant::STRING) {
+ //scalar name
+
+ const String *str = reinterpret_cast<const String *>(p_index._data._mem);
+ const Rect2i *v = reinterpret_cast<const Rect2i *>(_data._mem);
+ if (*str == "position") {
+ valid = true;
+ return v->position;
+ } else if (*str == "size") {
+ valid = true;
+ return v->size;
+ } else if (*str == "end") {
+ valid = true;
+ return v->size + v->position;
+ }
+ }
+ } break;
case VECTOR3: {
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
//scalar index
int idx = p_index;
if (idx < 0)
@@ -2325,9 +2758,40 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
}
} break;
+ case VECTOR3I: {
+
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
+ //scalar index
+ int idx = p_index;
+ if (idx < 0)
+ idx += 3;
+ if (idx >= 0 && idx < 3) {
+
+ const Vector3i *v = reinterpret_cast<const Vector3i *>(_data._mem);
+ valid = true;
+ return (*v)[idx];
+ }
+ } else if (p_index.get_type() == Variant::STRING) {
+
+ //scalar name
+ const String *str = reinterpret_cast<const String *>(p_index._data._mem);
+ const Vector3i *v = reinterpret_cast<const Vector3i *>(_data._mem);
+ if (*str == "x") {
+ valid = true;
+ return v->x;
+ } else if (*str == "y") {
+ valid = true;
+ return v->y;
+ } else if (*str == "z") {
+ valid = true;
+ return v->z;
+ }
+ }
+
+ } break;
case TRANSFORM2D: {
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
int index = p_index;
@@ -2403,7 +2867,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
}
}
- } break; // 10
+ } break;
case AABB: {
if (p_index.get_type() == Variant::STRING) {
@@ -2425,7 +2889,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case BASIS: {
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
int index = p_index;
if (index < 0)
@@ -2456,7 +2920,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case TRANSFORM: {
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
int index = p_index;
if (index < 0)
@@ -2535,8 +2999,10 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
}
} break;
+ case STRING_NAME: {
+ } break;
case NODE_PATH: {
- } break; // 15
+ } break;
case _RID: {
} break;
case OBJECT: {
@@ -2568,14 +3034,16 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
return *res;
}
} break;
- DEFAULT_OP_ARRAY_CMD(ARRAY, const Array, ;, return (*arr)[index]) // 20
- DEFAULT_OP_DVECTOR_GET(POOL_BYTE_ARRAY, uint8_t)
- DEFAULT_OP_DVECTOR_GET(POOL_INT_ARRAY, int)
- DEFAULT_OP_DVECTOR_GET(POOL_REAL_ARRAY, real_t)
- DEFAULT_OP_DVECTOR_GET(POOL_STRING_ARRAY, String)
- DEFAULT_OP_DVECTOR_GET(POOL_VECTOR2_ARRAY, Vector2) // 25
- DEFAULT_OP_DVECTOR_GET(POOL_VECTOR3_ARRAY, Vector3)
- DEFAULT_OP_DVECTOR_GET(POOL_COLOR_ARRAY, Color)
+ DEFAULT_OP_ARRAY_CMD(ARRAY, const Array, ;, return (*arr)[index])
+ DEFAULT_OP_DVECTOR_GET(PACKED_BYTE_ARRAY, uint8_t)
+ DEFAULT_OP_DVECTOR_GET(PACKED_INT32_ARRAY, int32_t)
+ DEFAULT_OP_DVECTOR_GET(PACKED_INT64_ARRAY, int64_t)
+ DEFAULT_OP_DVECTOR_GET(PACKED_FLOAT32_ARRAY, float)
+ DEFAULT_OP_DVECTOR_GET(PACKED_FLOAT64_ARRAY, double)
+ DEFAULT_OP_DVECTOR_GET(PACKED_STRING_ARRAY, String)
+ DEFAULT_OP_DVECTOR_GET(PACKED_VECTOR2_ARRAY, Vector2)
+ DEFAULT_OP_DVECTOR_GET(PACKED_VECTOR3_ARRAY, Vector3)
+ DEFAULT_OP_DVECTOR_GET(PACKED_COLOR_ARRAY, Color)
default:
return Variant();
}
@@ -2635,7 +3103,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
return dic->has(p_index);
- } break; // 20
+ } break;
case ARRAY: {
const Array *arr = reinterpret_cast<const Array *>(_data._mem);
@@ -2651,14 +3119,14 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
return false;
} break;
- case POOL_BYTE_ARRAY: {
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ case PACKED_BYTE_ARRAY: {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
int index = p_index;
- const PoolVector<uint8_t> *arr = reinterpret_cast<const PoolVector<uint8_t> *>(_data._mem);
+ const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array);
int l = arr->size();
if (l) {
- PoolVector<uint8_t>::Read r = arr->read();
+ const uint8_t *r = arr->ptr();
for (int i = 0; i < l; i++) {
if (r[i] == index)
return true;
@@ -2669,14 +3137,49 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
}
} break;
- case POOL_INT_ARRAY: {
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ case PACKED_INT32_ARRAY: {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
- int index = p_index;
- const PoolVector<int> *arr = reinterpret_cast<const PoolVector<int> *>(_data._mem);
+ int32_t index = p_index;
+ const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array);
+ int32_t l = arr->size();
+ if (l) {
+ const int32_t *r = arr->ptr();
+ for (int32_t i = 0; i < l; i++) {
+ if (r[i] == index)
+ return true;
+ }
+ }
+
+ return false;
+ }
+ } break;
+ case PACKED_INT64_ARRAY: {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
+
+ int64_t index = p_index;
+ const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array);
+ int64_t l = arr->size();
+ if (l) {
+ const int64_t *r = arr->ptr();
+ for (int64_t i = 0; i < l; i++) {
+ if (r[i] == index)
+ return true;
+ }
+ }
+
+ return false;
+ }
+ } break;
+ case PACKED_FLOAT32_ARRAY: {
+
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
+
+ real_t index = p_index;
+ const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array);
int l = arr->size();
if (l) {
- PoolVector<int>::Read r = arr->read();
+ const float *r = arr->ptr();
for (int i = 0; i < l; i++) {
if (r[i] == index)
return true;
@@ -2685,16 +3188,17 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
return false;
}
+
} break;
- case POOL_REAL_ARRAY: {
+ case PACKED_FLOAT64_ARRAY: {
- if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
+ if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
real_t index = p_index;
- const PoolVector<real_t> *arr = reinterpret_cast<const PoolVector<real_t> *>(_data._mem);
+ const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array);
int l = arr->size();
if (l) {
- PoolVector<real_t>::Read r = arr->read();
+ const double *r = arr->ptr();
for (int i = 0; i < l; i++) {
if (r[i] == index)
return true;
@@ -2705,15 +3209,15 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
}
} break;
- case POOL_STRING_ARRAY: {
+ case PACKED_STRING_ARRAY: {
if (p_index.get_type() == Variant::STRING) {
String index = p_index;
- const PoolVector<String> *arr = reinterpret_cast<const PoolVector<String> *>(_data._mem);
+ const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array);
int l = arr->size();
if (l) {
- PoolVector<String>::Read r = arr->read();
+ const String *r = arr->ptr();
for (int i = 0; i < l; i++) {
if (r[i] == index)
return true;
@@ -2724,15 +3228,15 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
}
} break; //25
- case POOL_VECTOR2_ARRAY: {
+ case PACKED_VECTOR2_ARRAY: {
if (p_index.get_type() == Variant::VECTOR2) {
Vector2 index = p_index;
- const PoolVector<Vector2> *arr = reinterpret_cast<const PoolVector<Vector2> *>(_data._mem);
+ const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array);
int l = arr->size();
if (l) {
- PoolVector<Vector2>::Read r = arr->read();
+ const Vector2 *r = arr->ptr();
for (int i = 0; i < l; i++) {
if (r[i] == index)
return true;
@@ -2743,15 +3247,15 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
}
} break;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
if (p_index.get_type() == Variant::VECTOR3) {
Vector3 index = p_index;
- const PoolVector<Vector3> *arr = reinterpret_cast<const PoolVector<Vector3> *>(_data._mem);
+ const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array);
int l = arr->size();
if (l) {
- PoolVector<Vector3>::Read r = arr->read();
+ const Vector3 *r = arr->ptr();
for (int i = 0; i < l; i++) {
if (r[i] == index)
return true;
@@ -2762,16 +3266,16 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
}
} break;
- case POOL_COLOR_ARRAY: {
+ case PACKED_COLOR_ARRAY: {
if (p_index.get_type() == Variant::COLOR) {
Color index = p_index;
- const PoolVector<Color> *arr = reinterpret_cast<const PoolVector<Color> *>(_data._mem);
+ const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array);
int l = arr->size();
if (l) {
- PoolVector<Color>::Read r = arr->read();
+ const Color *r = arr->ptr();
for (int i = 0; i < l; i++) {
if (r[i] == index)
return true;
@@ -2795,10 +3299,16 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
switch (type) {
case VECTOR2: {
- p_list->push_back(PropertyInfo(Variant::REAL, "x"));
- p_list->push_back(PropertyInfo(Variant::REAL, "y"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "x"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "y"));
+
+ } break;
+ case VECTOR2I: {
+
+ p_list->push_back(PropertyInfo(Variant::INT, "x"));
+ p_list->push_back(PropertyInfo(Variant::INT, "y"));
- } break; // 5
+ } break;
case RECT2: {
p_list->push_back(PropertyInfo(Variant::VECTOR2, "position"));
@@ -2806,11 +3316,25 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::VECTOR2, "end"));
} break;
+ case RECT2I: {
+
+ p_list->push_back(PropertyInfo(Variant::VECTOR2I, "position"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2I, "size"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2I, "end"));
+
+ } break;
case VECTOR3: {
- p_list->push_back(PropertyInfo(Variant::REAL, "x"));
- p_list->push_back(PropertyInfo(Variant::REAL, "y"));
- p_list->push_back(PropertyInfo(Variant::REAL, "z"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "x"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "y"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "z"));
+
+ } break;
+ case VECTOR3I: {
+
+ p_list->push_back(PropertyInfo(Variant::INT, "x"));
+ p_list->push_back(PropertyInfo(Variant::INT, "y"));
+ p_list->push_back(PropertyInfo(Variant::INT, "z"));
} break;
case TRANSFORM2D: {
@@ -2823,20 +3347,20 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
case PLANE: {
p_list->push_back(PropertyInfo(Variant::VECTOR3, "normal"));
- p_list->push_back(PropertyInfo(Variant::REAL, "x"));
- p_list->push_back(PropertyInfo(Variant::REAL, "y"));
- p_list->push_back(PropertyInfo(Variant::REAL, "z"));
- p_list->push_back(PropertyInfo(Variant::REAL, "d"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "x"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "y"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "z"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "d"));
} break;
case QUAT: {
- p_list->push_back(PropertyInfo(Variant::REAL, "x"));
- p_list->push_back(PropertyInfo(Variant::REAL, "y"));
- p_list->push_back(PropertyInfo(Variant::REAL, "z"));
- p_list->push_back(PropertyInfo(Variant::REAL, "w"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "x"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "y"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "z"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "w"));
- } break; // 10
+ } break;
case AABB: {
p_list->push_back(PropertyInfo(Variant::VECTOR3, "position"));
p_list->push_back(PropertyInfo(Variant::VECTOR3, "size"));
@@ -2856,21 +3380,23 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
} break;
case COLOR: {
- p_list->push_back(PropertyInfo(Variant::REAL, "r"));
- p_list->push_back(PropertyInfo(Variant::REAL, "g"));
- p_list->push_back(PropertyInfo(Variant::REAL, "b"));
- p_list->push_back(PropertyInfo(Variant::REAL, "a"));
- p_list->push_back(PropertyInfo(Variant::REAL, "h"));
- p_list->push_back(PropertyInfo(Variant::REAL, "s"));
- p_list->push_back(PropertyInfo(Variant::REAL, "v"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "r"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "g"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "b"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "a"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "h"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "s"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, "v"));
p_list->push_back(PropertyInfo(Variant::INT, "r8"));
p_list->push_back(PropertyInfo(Variant::INT, "g8"));
p_list->push_back(PropertyInfo(Variant::INT, "b8"));
p_list->push_back(PropertyInfo(Variant::INT, "a8"));
} break;
+ case STRING_NAME: {
+ } break;
case NODE_PATH: {
- } break; // 15
+ } break;
case _RID: {
} break;
case OBJECT: {
@@ -2901,14 +3427,16 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
}
}
} break;
- case ARRAY: // 20
- case POOL_BYTE_ARRAY:
- case POOL_INT_ARRAY:
- case POOL_REAL_ARRAY:
- case POOL_STRING_ARRAY:
- case POOL_VECTOR2_ARRAY: // 25
- case POOL_VECTOR3_ARRAY:
- case POOL_COLOR_ARRAY: {
+ case ARRAY:
+ case PACKED_BYTE_ARRAY:
+ case PACKED_INT32_ARRAY:
+ case PACKED_INT64_ARRAY:
+ case PACKED_FLOAT32_ARRAY:
+ case PACKED_FLOAT64_ARRAY:
+ case PACKED_STRING_ARRAY:
+ case PACKED_VECTOR2_ARRAY:
+ case PACKED_VECTOR3_ARRAY:
+ case PACKED_COLOR_ARRAY: {
//nothing
} break;
@@ -2925,9 +3453,9 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
r_iter = 0;
return _data._int > 0;
} break;
- case REAL: {
+ case FLOAT: {
r_iter = 0;
- return _data._real > 0.0;
+ return _data._float > 0.0;
} break;
case VECTOR2: {
int64_t from = reinterpret_cast<const Vector2 *>(_data._mem)->x;
@@ -2968,15 +3496,15 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
}
#endif
- Variant::CallError ce;
- ce.error = Variant::CallError::CALL_OK;
+ Callable::CallError ce;
+ ce.error = Callable::CallError::CALL_OK;
Array ref;
ref.push_back(r_iter);
Variant vref = ref;
const Variant *refp[] = { &vref };
Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_init, refp, 1, ce);
- if (ref.size() != 1 || ce.error != Variant::CallError::CALL_OK) {
+ if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) {
valid = false;
return false;
}
@@ -3012,56 +3540,72 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
r_iter = 0;
return true;
} break;
- case POOL_BYTE_ARRAY: {
- const PoolVector<uint8_t> *arr = reinterpret_cast<const PoolVector<uint8_t> *>(_data._mem);
+ case PACKED_BYTE_ARRAY: {
+ const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array);
if (arr->size() == 0)
return false;
r_iter = 0;
return true;
} break;
- case POOL_INT_ARRAY: {
- const PoolVector<int> *arr = reinterpret_cast<const PoolVector<int> *>(_data._mem);
+ case PACKED_INT32_ARRAY: {
+ const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array);
if (arr->size() == 0)
return false;
r_iter = 0;
return true;
} break;
- case POOL_REAL_ARRAY: {
- const PoolVector<real_t> *arr = reinterpret_cast<const PoolVector<real_t> *>(_data._mem);
+ case PACKED_INT64_ARRAY: {
+ const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array);
if (arr->size() == 0)
return false;
r_iter = 0;
return true;
} break;
- case POOL_STRING_ARRAY: {
- const PoolVector<String> *arr = reinterpret_cast<const PoolVector<String> *>(_data._mem);
+ case PACKED_FLOAT32_ARRAY: {
+ const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array);
if (arr->size() == 0)
return false;
r_iter = 0;
return true;
+
} break;
- case POOL_VECTOR2_ARRAY: {
+ case PACKED_FLOAT64_ARRAY: {
+ const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array);
+ if (arr->size() == 0)
+ return false;
+ r_iter = 0;
+ return true;
- const PoolVector<Vector2> *arr = reinterpret_cast<const PoolVector<Vector2> *>(_data._mem);
+ } break;
+ case PACKED_STRING_ARRAY: {
+ const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array);
if (arr->size() == 0)
return false;
r_iter = 0;
return true;
} break;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR2_ARRAY: {
- const PoolVector<Vector3> *arr = reinterpret_cast<const PoolVector<Vector3> *>(_data._mem);
+ const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array);
if (arr->size() == 0)
return false;
r_iter = 0;
return true;
} break;
- case POOL_COLOR_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
- const PoolVector<Color> *arr = reinterpret_cast<const PoolVector<Color> *>(_data._mem);
+ const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array);
+ if (arr->size() == 0)
+ return false;
+ r_iter = 0;
+ return true;
+ } break;
+ case PACKED_COLOR_ARRAY: {
+
+ const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array);
if (arr->size() == 0)
return false;
r_iter = 0;
@@ -3087,10 +3631,10 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
r_iter = idx;
return true;
} break;
- case REAL: {
+ case FLOAT: {
int64_t idx = r_iter;
idx++;
- if (idx >= _data._real)
+ if (idx >= _data._float)
return false;
r_iter = idx;
return true;
@@ -3138,15 +3682,15 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
}
#endif
- Variant::CallError ce;
- ce.error = Variant::CallError::CALL_OK;
+ Callable::CallError ce;
+ ce.error = Callable::CallError::CALL_OK;
Array ref;
ref.push_back(r_iter);
Variant vref = ref;
const Variant *refp[] = { &vref };
Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_next, refp, 1, ce);
- if (ref.size() != 1 || ce.error != Variant::CallError::CALL_OK) {
+ if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) {
valid = false;
return false;
}
@@ -3187,8 +3731,8 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
r_iter = idx;
return true;
} break;
- case POOL_BYTE_ARRAY: {
- const PoolVector<uint8_t> *arr = reinterpret_cast<const PoolVector<uint8_t> *>(_data._mem);
+ case PACKED_BYTE_ARRAY: {
+ const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
if (idx >= arr->size())
@@ -3197,8 +3741,28 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
return true;
} break;
- case POOL_INT_ARRAY: {
- const PoolVector<int> *arr = reinterpret_cast<const PoolVector<int> *>(_data._mem);
+ case PACKED_INT32_ARRAY: {
+ const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array);
+ int32_t idx = r_iter;
+ idx++;
+ if (idx >= arr->size())
+ return false;
+ r_iter = idx;
+ return true;
+
+ } break;
+ case PACKED_INT64_ARRAY: {
+ const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array);
+ int64_t idx = r_iter;
+ idx++;
+ if (idx >= arr->size())
+ return false;
+ r_iter = idx;
+ return true;
+
+ } break;
+ case PACKED_FLOAT32_ARRAY: {
+ const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
if (idx >= arr->size())
@@ -3207,8 +3771,8 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
return true;
} break;
- case POOL_REAL_ARRAY: {
- const PoolVector<real_t> *arr = reinterpret_cast<const PoolVector<real_t> *>(_data._mem);
+ case PACKED_FLOAT64_ARRAY: {
+ const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
if (idx >= arr->size())
@@ -3217,8 +3781,8 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
return true;
} break;
- case POOL_STRING_ARRAY: {
- const PoolVector<String> *arr = reinterpret_cast<const PoolVector<String> *>(_data._mem);
+ case PACKED_STRING_ARRAY: {
+ const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
if (idx >= arr->size())
@@ -3226,9 +3790,9 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
r_iter = idx;
return true;
} break;
- case POOL_VECTOR2_ARRAY: {
+ case PACKED_VECTOR2_ARRAY: {
- const PoolVector<Vector2> *arr = reinterpret_cast<const PoolVector<Vector2> *>(_data._mem);
+ const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
if (idx >= arr->size())
@@ -3236,9 +3800,9 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
r_iter = idx;
return true;
} break;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
- const PoolVector<Vector3> *arr = reinterpret_cast<const PoolVector<Vector3> *>(_data._mem);
+ const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
if (idx >= arr->size())
@@ -3246,9 +3810,9 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
r_iter = idx;
return true;
} break;
- case POOL_COLOR_ARRAY: {
+ case PACKED_COLOR_ARRAY: {
- const PoolVector<Color> *arr = reinterpret_cast<const PoolVector<Color> *>(_data._mem);
+ const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
if (idx >= arr->size())
@@ -3272,7 +3836,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
return r_iter;
} break;
- case REAL: {
+ case FLOAT: {
return r_iter;
} break;
@@ -3297,12 +3861,12 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
}
#endif
- Variant::CallError ce;
- ce.error = Variant::CallError::CALL_OK;
+ Callable::CallError ce;
+ ce.error = Callable::CallError::CALL_OK;
const Variant *refp[] = { &r_iter };
Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_get, refp, 1, ce);
- if (ce.error != Variant::CallError::CALL_OK) {
+ if (ce.error != Callable::CallError::CALL_OK) {
r_valid = false;
return Variant();
}
@@ -3334,8 +3898,8 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
#endif
return arr->get(idx);
} break;
- case POOL_BYTE_ARRAY: {
- const PoolVector<uint8_t> *arr = reinterpret_cast<const PoolVector<uint8_t> *>(_data._mem);
+ case PACKED_BYTE_ARRAY: {
+ const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array);
int idx = r_iter;
#ifdef DEBUG_ENABLED
if (idx < 0 || idx >= arr->size()) {
@@ -3345,8 +3909,30 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
#endif
return arr->get(idx);
} break;
- case POOL_INT_ARRAY: {
- const PoolVector<int> *arr = reinterpret_cast<const PoolVector<int> *>(_data._mem);
+ case PACKED_INT32_ARRAY: {
+ const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array);
+ int32_t idx = r_iter;
+#ifdef DEBUG_ENABLED
+ if (idx < 0 || idx >= arr->size()) {
+ r_valid = false;
+ return Variant();
+ }
+#endif
+ return arr->get(idx);
+ } break;
+ case PACKED_INT64_ARRAY: {
+ const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array);
+ int64_t idx = r_iter;
+#ifdef DEBUG_ENABLED
+ if (idx < 0 || idx >= arr->size()) {
+ r_valid = false;
+ return Variant();
+ }
+#endif
+ return arr->get(idx);
+ } break;
+ case PACKED_FLOAT32_ARRAY: {
+ const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array);
int idx = r_iter;
#ifdef DEBUG_ENABLED
if (idx < 0 || idx >= arr->size()) {
@@ -3356,8 +3942,8 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
#endif
return arr->get(idx);
} break;
- case POOL_REAL_ARRAY: {
- const PoolVector<real_t> *arr = reinterpret_cast<const PoolVector<real_t> *>(_data._mem);
+ case PACKED_FLOAT64_ARRAY: {
+ const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array);
int idx = r_iter;
#ifdef DEBUG_ENABLED
if (idx < 0 || idx >= arr->size()) {
@@ -3367,8 +3953,8 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
#endif
return arr->get(idx);
} break;
- case POOL_STRING_ARRAY: {
- const PoolVector<String> *arr = reinterpret_cast<const PoolVector<String> *>(_data._mem);
+ case PACKED_STRING_ARRAY: {
+ const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array);
int idx = r_iter;
#ifdef DEBUG_ENABLED
if (idx < 0 || idx >= arr->size()) {
@@ -3378,9 +3964,9 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
#endif
return arr->get(idx);
} break;
- case POOL_VECTOR2_ARRAY: {
+ case PACKED_VECTOR2_ARRAY: {
- const PoolVector<Vector2> *arr = reinterpret_cast<const PoolVector<Vector2> *>(_data._mem);
+ const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array);
int idx = r_iter;
#ifdef DEBUG_ENABLED
if (idx < 0 || idx >= arr->size()) {
@@ -3390,9 +3976,9 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
#endif
return arr->get(idx);
} break;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
- const PoolVector<Vector3> *arr = reinterpret_cast<const PoolVector<Vector3> *>(_data._mem);
+ const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array);
int idx = r_iter;
#ifdef DEBUG_ENABLED
if (idx < 0 || idx >= arr->size()) {
@@ -3402,9 +3988,9 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
#endif
return arr->get(idx);
} break;
- case POOL_COLOR_ARRAY: {
+ case PACKED_COLOR_ARRAY: {
- const PoolVector<Color> *arr = reinterpret_cast<const PoolVector<Color> *>(_data._mem);
+ const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array);
int idx = r_iter;
#ifdef DEBUG_ENABLED
if (idx < 0 || idx >= arr->size()) {
@@ -3467,9 +4053,9 @@ void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst)
r_dst = int(va + vb * c + 0.5);
}
return;
- case REAL: {
- double ra = a._data._real;
- double rb = b._data._real;
+ case FLOAT: {
+ double ra = a._data._float;
+ double rb = b._data._float;
r_dst = ra + rb * c;
}
return;
@@ -3477,16 +4063,50 @@ void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst)
r_dst = *reinterpret_cast<const Vector2 *>(a._data._mem) + *reinterpret_cast<const Vector2 *>(b._data._mem) * c;
}
return;
+ case VECTOR2I: {
+ int32_t vax = reinterpret_cast<const Vector2i *>(a._data._mem)->x;
+ int32_t vbx = reinterpret_cast<const Vector2i *>(b._data._mem)->x;
+ int32_t vay = reinterpret_cast<const Vector2i *>(a._data._mem)->y;
+ int32_t vby = reinterpret_cast<const Vector2i *>(b._data._mem)->y;
+ r_dst = Vector2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5));
+ }
+ return;
case RECT2: {
const Rect2 *ra = reinterpret_cast<const Rect2 *>(a._data._mem);
const Rect2 *rb = reinterpret_cast<const Rect2 *>(b._data._mem);
r_dst = Rect2(ra->position + rb->position * c, ra->size + rb->size * c);
}
return;
+ case RECT2I: {
+ const Rect2i *ra = reinterpret_cast<const Rect2i *>(a._data._mem);
+ const Rect2i *rb = reinterpret_cast<const Rect2i *>(b._data._mem);
+
+ int32_t vax = ra->position.x;
+ int32_t vay = ra->position.y;
+ int32_t vbx = ra->size.x;
+ int32_t vby = ra->size.y;
+ int32_t vcx = rb->position.x;
+ int32_t vcy = rb->position.y;
+ int32_t vdx = rb->size.x;
+ int32_t vdy = rb->size.y;
+
+ r_dst = Rect2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vcx + vdx * c + 0.5), int32_t(vcy + vdy * c + 0.5));
+ }
+ return;
case VECTOR3: {
r_dst = *reinterpret_cast<const Vector3 *>(a._data._mem) + *reinterpret_cast<const Vector3 *>(b._data._mem) * c;
}
return;
+ case VECTOR3I: {
+ int32_t vax = reinterpret_cast<const Vector3i *>(a._data._mem)->x;
+ int32_t vbx = reinterpret_cast<const Vector3i *>(b._data._mem)->x;
+ int32_t vay = reinterpret_cast<const Vector3i *>(a._data._mem)->y;
+ int32_t vby = reinterpret_cast<const Vector3i *>(b._data._mem)->y;
+ int32_t vaz = reinterpret_cast<const Vector3i *>(a._data._mem)->z;
+ int32_t vbz = reinterpret_cast<const Vector3i *>(b._data._mem)->z;
+ r_dst = Vector3i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vaz + vbz * c + 0.5));
+ }
+ return;
case AABB: {
const ::AABB *ra = reinterpret_cast<const ::AABB *>(a._data._mem);
const ::AABB *rb = reinterpret_cast<const ::AABB *>(b._data._mem);
@@ -3552,9 +4172,9 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
r_dst = int(va + (vb - va) * c);
}
return;
- case REAL: {
- real_t va = a._data._real;
- real_t vb = b._data._real;
+ case FLOAT: {
+ real_t va = a._data._float;
+ real_t vb = b._data._float;
r_dst = va + (vb - va) * c;
}
return;
@@ -3603,14 +4223,51 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
r_dst = reinterpret_cast<const Vector2 *>(a._data._mem)->linear_interpolate(*reinterpret_cast<const Vector2 *>(b._data._mem), c);
}
return;
+ case VECTOR2I: {
+ int32_t vax = reinterpret_cast<const Vector2i *>(a._data._mem)->x;
+ int32_t vbx = reinterpret_cast<const Vector2i *>(b._data._mem)->x;
+ int32_t vay = reinterpret_cast<const Vector2i *>(a._data._mem)->y;
+ int32_t vby = reinterpret_cast<const Vector2i *>(b._data._mem)->y;
+ r_dst = Vector2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5));
+ }
+ return;
+
case RECT2: {
r_dst = Rect2(reinterpret_cast<const Rect2 *>(a._data._mem)->position.linear_interpolate(reinterpret_cast<const Rect2 *>(b._data._mem)->position, c), reinterpret_cast<const Rect2 *>(a._data._mem)->size.linear_interpolate(reinterpret_cast<const Rect2 *>(b._data._mem)->size, c));
}
return;
+ case RECT2I: {
+ const Rect2i *ra = reinterpret_cast<const Rect2i *>(a._data._mem);
+ const Rect2i *rb = reinterpret_cast<const Rect2i *>(b._data._mem);
+
+ int32_t vax = ra->position.x;
+ int32_t vay = ra->position.y;
+ int32_t vbx = ra->size.x;
+ int32_t vby = ra->size.y;
+ int32_t vcx = rb->position.x;
+ int32_t vcy = rb->position.y;
+ int32_t vdx = rb->size.x;
+ int32_t vdy = rb->size.y;
+
+ r_dst = Rect2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vcx + vdx * c + 0.5), int32_t(vcy + vdy * c + 0.5));
+ }
+ return;
+
case VECTOR3: {
r_dst = reinterpret_cast<const Vector3 *>(a._data._mem)->linear_interpolate(*reinterpret_cast<const Vector3 *>(b._data._mem), c);
}
return;
+ case VECTOR3I: {
+ int32_t vax = reinterpret_cast<const Vector3i *>(a._data._mem)->x;
+ int32_t vbx = reinterpret_cast<const Vector3i *>(b._data._mem)->x;
+ int32_t vay = reinterpret_cast<const Vector3i *>(a._data._mem)->y;
+ int32_t vby = reinterpret_cast<const Vector3i *>(b._data._mem)->y;
+ int32_t vaz = reinterpret_cast<const Vector3i *>(a._data._mem)->z;
+ int32_t vbz = reinterpret_cast<const Vector3i *>(b._data._mem)->z;
+ r_dst = Vector3i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vaz + vbz * c + 0.5));
+ }
+ return;
+
case TRANSFORM2D: {
r_dst = a._data._transform2d->interpolate_with(*b._data._transform2d, c);
}
@@ -3639,6 +4296,10 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
r_dst = reinterpret_cast<const Color *>(a._data._mem)->linear_interpolate(*reinterpret_cast<const Color *>(b._data._mem), c);
}
return;
+ case STRING_NAME: {
+ r_dst = a;
+ }
+ return;
case NODE_PATH: {
r_dst = a;
}
@@ -3658,25 +4319,77 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
r_dst = a;
}
return;
- case POOL_BYTE_ARRAY: {
+ case PACKED_BYTE_ARRAY: {
r_dst = a;
}
return;
- case POOL_INT_ARRAY: {
- const PoolVector<int> *arr_a = reinterpret_cast<const PoolVector<int> *>(a._data._mem);
- const PoolVector<int> *arr_b = reinterpret_cast<const PoolVector<int> *>(b._data._mem);
+ case PACKED_INT32_ARRAY: {
+ const Vector<int32_t> *arr_a = &PackedArrayRef<int32_t>::get_array(a._data.packed_array);
+ const Vector<int32_t> *arr_b = &PackedArrayRef<int32_t>::get_array(b._data.packed_array);
+ int32_t sz = arr_a->size();
+ if (sz == 0 || arr_b->size() != sz) {
+
+ r_dst = a;
+ } else {
+
+ Vector<int32_t> v;
+ v.resize(sz);
+ {
+ int32_t *vw = v.ptrw();
+ const int32_t *ar = arr_a->ptr();
+ const int32_t *br = arr_b->ptr();
+
+ Variant va;
+ for (int32_t i = 0; i < sz; i++) {
+ Variant::interpolate(ar[i], br[i], c, va);
+ vw[i] = va;
+ }
+ }
+ r_dst = v;
+ }
+ }
+ return;
+ case PACKED_INT64_ARRAY: {
+ const Vector<int64_t> *arr_a = &PackedArrayRef<int64_t>::get_array(a._data.packed_array);
+ const Vector<int64_t> *arr_b = &PackedArrayRef<int64_t>::get_array(b._data.packed_array);
+ int64_t sz = arr_a->size();
+ if (sz == 0 || arr_b->size() != sz) {
+
+ r_dst = a;
+ } else {
+
+ Vector<int64_t> v;
+ v.resize(sz);
+ {
+ int64_t *vw = v.ptrw();
+ const int64_t *ar = arr_a->ptr();
+ const int64_t *br = arr_b->ptr();
+
+ Variant va;
+ for (int64_t i = 0; i < sz; i++) {
+ Variant::interpolate(ar[i], br[i], c, va);
+ vw[i] = va;
+ }
+ }
+ r_dst = v;
+ }
+ }
+ return;
+ case PACKED_FLOAT32_ARRAY: {
+ const Vector<float> *arr_a = &PackedArrayRef<float>::get_array(a._data.packed_array);
+ const Vector<float> *arr_b = &PackedArrayRef<float>::get_array(b._data.packed_array);
int sz = arr_a->size();
if (sz == 0 || arr_b->size() != sz) {
r_dst = a;
} else {
- PoolVector<int> v;
+ Vector<float> v;
v.resize(sz);
{
- PoolVector<int>::Write vw = v.write();
- PoolVector<int>::Read ar = arr_a->read();
- PoolVector<int>::Read br = arr_b->read();
+ float *vw = v.ptrw();
+ const float *ar = arr_a->ptr();
+ const float *br = arr_b->ptr();
Variant va;
for (int i = 0; i < sz; i++) {
@@ -3688,21 +4401,21 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
}
return;
- case POOL_REAL_ARRAY: {
- const PoolVector<real_t> *arr_a = reinterpret_cast<const PoolVector<real_t> *>(a._data._mem);
- const PoolVector<real_t> *arr_b = reinterpret_cast<const PoolVector<real_t> *>(b._data._mem);
+ case PACKED_FLOAT64_ARRAY: {
+ const Vector<double> *arr_a = &PackedArrayRef<double>::get_array(a._data.packed_array);
+ const Vector<double> *arr_b = &PackedArrayRef<double>::get_array(b._data.packed_array);
int sz = arr_a->size();
if (sz == 0 || arr_b->size() != sz) {
r_dst = a;
} else {
- PoolVector<real_t> v;
+ Vector<double> v;
v.resize(sz);
{
- PoolVector<real_t>::Write vw = v.write();
- PoolVector<real_t>::Read ar = arr_a->read();
- PoolVector<real_t>::Read br = arr_b->read();
+ double *vw = v.ptrw();
+ const double *ar = arr_a->ptr();
+ const double *br = arr_b->ptr();
Variant va;
for (int i = 0; i < sz; i++) {
@@ -3714,25 +4427,25 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
}
return;
- case POOL_STRING_ARRAY: {
+ case PACKED_STRING_ARRAY: {
r_dst = a;
}
return;
- case POOL_VECTOR2_ARRAY: {
- const PoolVector<Vector2> *arr_a = reinterpret_cast<const PoolVector<Vector2> *>(a._data._mem);
- const PoolVector<Vector2> *arr_b = reinterpret_cast<const PoolVector<Vector2> *>(b._data._mem);
+ case PACKED_VECTOR2_ARRAY: {
+ const Vector<Vector2> *arr_a = &PackedArrayRef<Vector2>::get_array(a._data.packed_array);
+ const Vector<Vector2> *arr_b = &PackedArrayRef<Vector2>::get_array(b._data.packed_array);
int sz = arr_a->size();
if (sz == 0 || arr_b->size() != sz) {
r_dst = a;
} else {
- PoolVector<Vector2> v;
+ Vector<Vector2> v;
v.resize(sz);
{
- PoolVector<Vector2>::Write vw = v.write();
- PoolVector<Vector2>::Read ar = arr_a->read();
- PoolVector<Vector2>::Read br = arr_b->read();
+ Vector2 *vw = v.ptrw();
+ const Vector2 *ar = arr_a->ptr();
+ const Vector2 *br = arr_b->ptr();
for (int i = 0; i < sz; i++) {
vw[i] = ar[i].linear_interpolate(br[i], c);
@@ -3742,22 +4455,22 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
}
return;
- case POOL_VECTOR3_ARRAY: {
+ case PACKED_VECTOR3_ARRAY: {
- const PoolVector<Vector3> *arr_a = reinterpret_cast<const PoolVector<Vector3> *>(a._data._mem);
- const PoolVector<Vector3> *arr_b = reinterpret_cast<const PoolVector<Vector3> *>(b._data._mem);
+ const Vector<Vector3> *arr_a = &PackedArrayRef<Vector3>::get_array(a._data.packed_array);
+ const Vector<Vector3> *arr_b = &PackedArrayRef<Vector3>::get_array(b._data.packed_array);
int sz = arr_a->size();
if (sz == 0 || arr_b->size() != sz) {
r_dst = a;
} else {
- PoolVector<Vector3> v;
+ Vector<Vector3> v;
v.resize(sz);
{
- PoolVector<Vector3>::Write vw = v.write();
- PoolVector<Vector3>::Read ar = arr_a->read();
- PoolVector<Vector3>::Read br = arr_b->read();
+ Vector3 *vw = v.ptrw();
+ const Vector3 *ar = arr_a->ptr();
+ const Vector3 *br = arr_b->ptr();
for (int i = 0; i < sz; i++) {
vw[i] = ar[i].linear_interpolate(br[i], c);
@@ -3767,21 +4480,21 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
}
return;
- case POOL_COLOR_ARRAY: {
- const PoolVector<Color> *arr_a = reinterpret_cast<const PoolVector<Color> *>(a._data._mem);
- const PoolVector<Color> *arr_b = reinterpret_cast<const PoolVector<Color> *>(b._data._mem);
+ case PACKED_COLOR_ARRAY: {
+ const Vector<Color> *arr_a = &PackedArrayRef<Color>::get_array(a._data.packed_array);
+ const Vector<Color> *arr_b = &PackedArrayRef<Color>::get_array(b._data.packed_array);
int sz = arr_a->size();
if (sz == 0 || arr_b->size() != sz) {
r_dst = a;
} else {
- PoolVector<Color> v;
+ Vector<Color> v;
v.resize(sz);
{
- PoolVector<Color>::Write vw = v.write();
- PoolVector<Color>::Read ar = arr_a->read();
- PoolVector<Color>::Read br = arr_b->read();
+ Color *vw = v.ptrw();
+ const Color *ar = arr_a->ptr();
+ const Color *br = arr_b->ptr();
for (int i = 0; i < sz; i++) {
vw[i] = ar[i].linear_interpolate(br[i], c);
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index 996b25308e..d2ee0b71c9 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -81,6 +81,7 @@ const char *VariantParser::tk_name[TK_MAX] = {
"')'",
"identifier",
"string",
+ "string_name",
"number",
"color",
"':'",
@@ -93,6 +94,8 @@ const char *VariantParser::tk_name[TK_MAX] = {
Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, String &r_err_str) {
+ bool string_name = false;
+
while (true) {
CharType cchar;
@@ -204,6 +207,17 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
r_token.type = TK_COLOR;
return OK;
};
+ case '@': {
+ cchar = p_stream->get_char();
+ if (cchar != '"') {
+ r_err_str = "Expected '\"' after '@'";
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ }
+
+ string_name = true;
+ [[fallthrough]];
+ }
case '"': {
String str;
@@ -285,8 +299,14 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
if (p_stream->is_utf8()) {
str.parse_utf8(str.ascii(true).get_data());
}
- r_token.type = TK_STRING;
- r_token.value = str;
+ if (string_name) {
+ r_token.type = TK_STRING_NAME;
+ r_token.value = StringName(str);
+ string_name = false; //reset
+ } else {
+ r_token.type = TK_STRING;
+ r_token.value = str;
+ }
return OK;
} break;
@@ -512,6 +532,10 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = false;
else if (id == "null" || id == "nil")
value = Variant();
+ else if (id == "inf")
+ value = Math_INF;
+ else if (id == "nan")
+ value = Math_NAN;
else if (id == "Vector2") {
Vector<float> args;
@@ -525,6 +549,19 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = Vector2(args[0], args[1]);
return OK;
+ } else if (id == "Vector2i") {
+
+ Vector<int32_t> args;
+ Error err = _parse_construct<int32_t>(p_stream, args, line, r_err_str);
+ if (err)
+ return err;
+
+ if (args.size() != 2) {
+ r_err_str = "Expected 2 arguments for constructor";
+ }
+
+ value = Vector2i(args[0], args[1]);
+ return OK;
} else if (id == "Rect2") {
Vector<float> args;
@@ -538,6 +575,19 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = Rect2(args[0], args[1], args[2], args[3]);
return OK;
+ } else if (id == "Rect2i") {
+
+ Vector<int32_t> args;
+ Error err = _parse_construct<int32_t>(p_stream, args, line, r_err_str);
+ if (err)
+ return err;
+
+ if (args.size() != 4) {
+ r_err_str = "Expected 4 arguments for constructor";
+ }
+
+ value = Rect2i(args[0], args[1], args[2], args[3]);
+ return OK;
} else if (id == "Vector3") {
Vector<float> args;
@@ -551,6 +601,19 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = Vector3(args[0], args[1], args[2]);
return OK;
+ } else if (id == "Vector3i") {
+
+ Vector<int32_t> args;
+ Error err = _parse_construct<int32_t>(p_stream, args, line, r_err_str);
+ if (err)
+ return err;
+
+ if (args.size() != 3) {
+ r_err_str = "Expected 3 arguments for constructor";
+ }
+
+ value = Vector3i(args[0], args[1], args[2]);
+ return OK;
} else if (id == "Transform2D" || id == "Matrix32") { //compatibility
Vector<float> args;
@@ -861,18 +924,18 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
}
- } else if (id == "PoolByteArray" || id == "ByteArray") {
+ } else if (id == "PackedByteArray" || id == "PoolByteArray" || id == "ByteArray") {
Vector<uint8_t> args;
Error err = _parse_construct<uint8_t>(p_stream, args, line, r_err_str);
if (err)
return err;
- PoolVector<uint8_t> arr;
+ Vector<uint8_t> arr;
{
int len = args.size();
arr.resize(len);
- PoolVector<uint8_t>::Write w = arr.write();
+ uint8_t *w = arr.ptrw();
for (int i = 0; i < len; i++) {
w[i] = args[i];
}
@@ -882,20 +945,41 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
- } else if (id == "PoolIntArray" || id == "IntArray") {
+ } else if (id == "PackedInt32Array" || id == "PackedIntArray" || id == "PoolIntArray" || id == "IntArray") {
- Vector<int> args;
- Error err = _parse_construct<int>(p_stream, args, line, r_err_str);
+ Vector<int32_t> args;
+ Error err = _parse_construct<int32_t>(p_stream, args, line, r_err_str);
if (err)
return err;
- PoolVector<int> arr;
+ Vector<int32_t> arr;
{
- int len = args.size();
+ int32_t len = args.size();
arr.resize(len);
- PoolVector<int>::Write w = arr.write();
- for (int i = 0; i < len; i++) {
- w[i] = int(args[i]);
+ int32_t *w = arr.ptrw();
+ for (int32_t i = 0; i < len; i++) {
+ w[i] = int32_t(args[i]);
+ }
+ }
+
+ value = arr;
+
+ return OK;
+
+ } else if (id == "PackedInt64Array") {
+
+ Vector<int64_t> args;
+ Error err = _parse_construct<int64_t>(p_stream, args, line, r_err_str);
+ if (err)
+ return err;
+
+ Vector<int64_t> arr;
+ {
+ int64_t len = args.size();
+ arr.resize(len);
+ int64_t *w = arr.ptrw();
+ for (int64_t i = 0; i < len; i++) {
+ w[i] = int64_t(args[i]);
}
}
@@ -903,18 +987,18 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
- } else if (id == "PoolRealArray" || id == "FloatArray") {
+ } else if (id == "PackedFloat32Array" || id == "PackedRealArray" || id == "PoolRealArray" || id == "FloatArray") {
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
if (err)
return err;
- PoolVector<float> arr;
+ Vector<float> arr;
{
int len = args.size();
arr.resize(len);
- PoolVector<float>::Write w = arr.write();
+ float *w = arr.ptrw();
for (int i = 0; i < len; i++) {
w[i] = args[i];
}
@@ -923,7 +1007,27 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = arr;
return OK;
- } else if (id == "PoolStringArray" || id == "StringArray") {
+ } else if (id == "PackedFloat64Array") {
+
+ Vector<double> args;
+ Error err = _parse_construct<double>(p_stream, args, line, r_err_str);
+ if (err)
+ return err;
+
+ Vector<double> arr;
+ {
+ int len = args.size();
+ arr.resize(len);
+ double *w = arr.ptrw();
+ for (int i = 0; i < len; i++) {
+ w[i] = args[i];
+ }
+ }
+
+ value = arr;
+
+ return OK;
+ } else if (id == "PackedStringArray" || id == "PoolStringArray" || id == "StringArray") {
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_OPEN) {
@@ -960,11 +1064,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
cs.push_back(token.value);
}
- PoolVector<String> arr;
+ Vector<String> arr;
{
int len = cs.size();
arr.resize(len);
- PoolVector<String>::Write w = arr.write();
+ String *w = arr.ptrw();
for (int i = 0; i < len; i++) {
w[i] = cs[i];
}
@@ -974,18 +1078,18 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
- } else if (id == "PoolVector2Array" || id == "Vector2Array") {
+ } else if (id == "PackedVector2Array" || id == "PoolVector2Array" || id == "Vector2Array") {
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
if (err)
return err;
- PoolVector<Vector2> arr;
+ Vector<Vector2> arr;
{
int len = args.size() / 2;
arr.resize(len);
- PoolVector<Vector2>::Write w = arr.write();
+ Vector2 *w = arr.ptrw();
for (int i = 0; i < len; i++) {
w[i] = Vector2(args[i * 2 + 0], args[i * 2 + 1]);
}
@@ -995,18 +1099,18 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
- } else if (id == "PoolVector3Array" || id == "Vector3Array") {
+ } else if (id == "PackedVector3Array" || id == "PoolVector3Array" || id == "Vector3Array") {
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
if (err)
return err;
- PoolVector<Vector3> arr;
+ Vector<Vector3> arr;
{
int len = args.size() / 3;
arr.resize(len);
- PoolVector<Vector3>::Write w = arr.write();
+ Vector3 *w = arr.ptrw();
for (int i = 0; i < len; i++) {
w[i] = Vector3(args[i * 3 + 0], args[i * 3 + 1], args[i * 3 + 2]);
}
@@ -1016,18 +1120,18 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
- } else if (id == "PoolColorArray" || id == "ColorArray") {
+ } else if (id == "PackedColorArray" || id == "PoolColorArray" || id == "ColorArray") {
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
if (err)
return err;
- PoolVector<Color> arr;
+ Vector<Color> arr;
{
int len = args.size() / 4;
arr.resize(len);
- PoolVector<Color>::Write w = arr.write();
+ Color *w = arr.ptrw();
for (int i = 0; i < len; i++) {
w[i] = Color(args[i * 4 + 0], args[i * 4 + 1], args[i * 4 + 2], args[i * 4 + 3]);
}
@@ -1051,6 +1155,10 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = token.value;
return OK;
+ } else if (token.type == TK_STRING_NAME) {
+
+ value = token.value;
+ return OK;
} else if (token.type == TK_COLOR) {
value = token.value;
@@ -1392,11 +1500,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, itos(p_variant.operator int64_t()));
} break;
- case Variant::REAL: {
+ case Variant::FLOAT: {
String s = rtosfix(p_variant.operator real_t());
- if (s.find(".") == -1 && s.find("e") == -1)
- s += ".0";
+ if (s != "inf" && s != "nan") {
+ if (s.find(".") == -1 && s.find("e") == -1)
+ s += ".0";
+ }
p_store_string_func(p_store_string_ud, s);
} break;
case Variant::STRING: {
@@ -1411,17 +1521,33 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
Vector2 v = p_variant;
p_store_string_func(p_store_string_ud, "Vector2( " + rtosfix(v.x) + ", " + rtosfix(v.y) + " )");
} break;
+ case Variant::VECTOR2I: {
+
+ Vector2i v = p_variant;
+ p_store_string_func(p_store_string_ud, "Vector2i( " + itos(v.x) + ", " + itos(v.y) + " )");
+ } break;
case Variant::RECT2: {
Rect2 aabb = p_variant;
p_store_string_func(p_store_string_ud, "Rect2( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + " )");
} break;
+ case Variant::RECT2I: {
+
+ Rect2i aabb = p_variant;
+ p_store_string_func(p_store_string_ud, "Rect2i( " + itos(aabb.position.x) + ", " + itos(aabb.position.y) + ", " + itos(aabb.size.x) + ", " + itos(aabb.size.y) + " )");
+
+ } break;
case Variant::VECTOR3: {
Vector3 v = p_variant;
p_store_string_func(p_store_string_ud, "Vector3( " + rtosfix(v.x) + ", " + rtosfix(v.y) + ", " + rtosfix(v.z) + " )");
} break;
+ case Variant::VECTOR3I: {
+
+ Vector3i v = p_variant;
+ p_store_string_func(p_store_string_ud, "Vector3i( " + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + " )");
+ } break;
case Variant::PLANE: {
Plane p = p_variant;
@@ -1498,6 +1624,14 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, "Color( " + rtosfix(c.r) + ", " + rtosfix(c.g) + ", " + rtosfix(c.b) + ", " + rtosfix(c.a) + " )");
} break;
+ case Variant::STRING_NAME: {
+
+ String str = p_variant;
+
+ str = "@\"" + str.c_escape() + "\"";
+ p_store_string_func(p_store_string_ud, str);
+
+ } break;
case Variant::NODE_PATH: {
String str = p_variant;
@@ -1609,14 +1743,14 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
- case Variant::POOL_BYTE_ARRAY: {
+ case Variant::PACKED_BYTE_ARRAY: {
- p_store_string_func(p_store_string_ud, "PoolByteArray( ");
+ p_store_string_func(p_store_string_ud, "PackedByteArray( ");
String s;
- PoolVector<uint8_t> data = p_variant;
+ Vector<uint8_t> data = p_variant;
int len = data.size();
- PoolVector<uint8_t>::Read r = data.read();
- const uint8_t *ptr = r.ptr();
+ const uint8_t *ptr = data.ptr();
+
for (int i = 0; i < len; i++) {
if (i > 0)
@@ -1628,15 +1762,32 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, " )");
} break;
- case Variant::POOL_INT_ARRAY: {
+ case Variant::PACKED_INT32_ARRAY: {
- p_store_string_func(p_store_string_ud, "PoolIntArray( ");
- PoolVector<int> data = p_variant;
- int len = data.size();
- PoolVector<int>::Read r = data.read();
- const int *ptr = r.ptr();
+ p_store_string_func(p_store_string_ud, "PackedInt32Array( ");
+ Vector<int32_t> data = p_variant;
+ int32_t len = data.size();
+ const int32_t *ptr = data.ptr();
- for (int i = 0; i < len; i++) {
+ for (int32_t i = 0; i < len; i++) {
+
+ if (i > 0)
+ p_store_string_func(p_store_string_ud, ", ");
+
+ p_store_string_func(p_store_string_ud, itos(ptr[i]));
+ }
+
+ p_store_string_func(p_store_string_ud, " )");
+
+ } break;
+ case Variant::PACKED_INT64_ARRAY: {
+
+ p_store_string_func(p_store_string_ud, "PackedInt64Array( ");
+ Vector<int64_t> data = p_variant;
+ int64_t len = data.size();
+ const int64_t *ptr = data.ptr();
+
+ for (int64_t i = 0; i < len; i++) {
if (i > 0)
p_store_string_func(p_store_string_ud, ", ");
@@ -1647,13 +1798,12 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, " )");
} break;
- case Variant::POOL_REAL_ARRAY: {
+ case Variant::PACKED_FLOAT32_ARRAY: {
- p_store_string_func(p_store_string_ud, "PoolRealArray( ");
- PoolVector<real_t> data = p_variant;
+ p_store_string_func(p_store_string_ud, "PackedFloat32Array( ");
+ Vector<float> data = p_variant;
int len = data.size();
- PoolVector<real_t>::Read r = data.read();
- const real_t *ptr = r.ptr();
+ const float *ptr = data.ptr();
for (int i = 0; i < len; i++) {
@@ -1665,13 +1815,30 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, " )");
} break;
- case Variant::POOL_STRING_ARRAY: {
+ case Variant::PACKED_FLOAT64_ARRAY: {
- p_store_string_func(p_store_string_ud, "PoolStringArray( ");
- PoolVector<String> data = p_variant;
+ p_store_string_func(p_store_string_ud, "PackedFloat64Array( ");
+ Vector<double> data = p_variant;
int len = data.size();
- PoolVector<String>::Read r = data.read();
- const String *ptr = r.ptr();
+ const double *ptr = data.ptr();
+
+ for (int i = 0; i < len; i++) {
+
+ if (i > 0)
+ p_store_string_func(p_store_string_ud, ", ");
+ p_store_string_func(p_store_string_ud, rtosfix(ptr[i]));
+ }
+
+ p_store_string_func(p_store_string_ud, " )");
+
+ } break;
+ case Variant::PACKED_STRING_ARRAY: {
+
+ p_store_string_func(p_store_string_ud, "PackedStringArray( ");
+ Vector<String> data = p_variant;
+ int len = data.size();
+ const String *ptr = data.ptr();
+
String s;
//write_string("\n");
@@ -1686,13 +1853,12 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, " )");
} break;
- case Variant::POOL_VECTOR2_ARRAY: {
+ case Variant::PACKED_VECTOR2_ARRAY: {
- p_store_string_func(p_store_string_ud, "PoolVector2Array( ");
- PoolVector<Vector2> data = p_variant;
+ p_store_string_func(p_store_string_ud, "PackedVector2Array( ");
+ Vector<Vector2> data = p_variant;
int len = data.size();
- PoolVector<Vector2>::Read r = data.read();
- const Vector2 *ptr = r.ptr();
+ const Vector2 *ptr = data.ptr();
for (int i = 0; i < len; i++) {
@@ -1704,13 +1870,12 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, " )");
} break;
- case Variant::POOL_VECTOR3_ARRAY: {
+ case Variant::PACKED_VECTOR3_ARRAY: {
- p_store_string_func(p_store_string_ud, "PoolVector3Array( ");
- PoolVector<Vector3> data = p_variant;
+ p_store_string_func(p_store_string_ud, "PackedVector3Array( ");
+ Vector<Vector3> data = p_variant;
int len = data.size();
- PoolVector<Vector3>::Read r = data.read();
- const Vector3 *ptr = r.ptr();
+ const Vector3 *ptr = data.ptr();
for (int i = 0; i < len; i++) {
@@ -1722,14 +1887,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, " )");
} break;
- case Variant::POOL_COLOR_ARRAY: {
+ case Variant::PACKED_COLOR_ARRAY: {
- p_store_string_func(p_store_string_ud, "PoolColorArray( ");
+ p_store_string_func(p_store_string_ud, "PackedColorArray( ");
- PoolVector<Color> data = p_variant;
+ Vector<Color> data = p_variant;
int len = data.size();
- PoolVector<Color>::Read r = data.read();
- const Color *ptr = r.ptr();
+ const Color *ptr = data.ptr();
for (int i = 0; i < len; i++) {
diff --git a/core/variant_parser.h b/core/variant_parser.h
index 89db3ada0d..d50842145c 100644
--- a/core/variant_parser.h
+++ b/core/variant_parser.h
@@ -77,7 +77,7 @@ public:
struct ResourceParser {
- void *userdata;
+ void *userdata = nullptr;
ParseResourceFunc func;
ParseResourceFunc ext_func;
ParseResourceFunc sub_func;
@@ -92,6 +92,7 @@ public:
TK_PARENTHESIS_CLOSE,
TK_IDENTIFIER,
TK_STRING,
+ TK_STRING_NAME,
TK_NUMBER,
TK_COLOR,
TK_COLON,
diff --git a/core/vector.h b/core/vector.h
index 44add2c4d7..d3476679ff 100644
--- a/core/vector.h
+++ b/core/vector.h
@@ -34,7 +34,7 @@
/**
* @class Vector
* @author Juan Linietsky
- * Vector container. Regular Vector Container. Use with care and for smaller arrays when possible. Use PoolVector for large arrays.
+ * Vector container. Regular Vector Container. Use with care and for smaller arrays when possible. Use Vector for large arrays.
*/
#include "core/cowdata.h"
@@ -64,12 +64,13 @@ private:
public:
bool push_back(T p_elem);
+ _FORCE_INLINE_ bool append(const T &p_elem) { return push_back(p_elem); } //alias
void remove(int p_index) { _cowdata.remove(p_index); }
void erase(const T &p_val) {
int idx = find(p_val);
if (idx >= 0) remove(idx);
- };
+ }
void invert();
_FORCE_INLINE_ T *ptrw() { return _cowdata.ptrw(); }
@@ -123,6 +124,30 @@ public:
return *this;
}
+ Vector<T> subarray(int p_from, int p_to) const {
+
+ if (p_from < 0) {
+ p_from = size() + p_from;
+ }
+ if (p_to < 0) {
+ p_to = size() + p_to;
+ }
+
+ ERR_FAIL_INDEX_V(p_from, size(), Vector<T>());
+ ERR_FAIL_INDEX_V(p_to, size(), Vector<T>());
+
+ Vector<T> slice;
+ int span = 1 + p_to - p_from;
+ slice.resize(span);
+ const T *r = ptr();
+ T *w = slice.ptrw();
+ for (int i = 0; i < span; ++i) {
+ w[i] = r[p_from + i];
+ }
+
+ return slice;
+ }
+
_FORCE_INLINE_ ~Vector() {}
};