diff options
Diffstat (limited to 'core')
30 files changed, 2372 insertions, 2220 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 590c3ff50e..74ef05b797 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -711,8 +711,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str file->store_32(count + 1); //store how many properties are saved, add one for custom featuers, which must always go first String key = CoreStringNames::get_singleton()->_custom_features; - file->store_32(key.length()); - file->store_string(key); + file->store_pascal_string(key); int len; err = encode_variant(p_custom_features, nullptr, len, false); @@ -749,8 +748,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str value = get(key); } - file->store_32(key.length()); - file->store_string(key); + file->store_pascal_string(key); int len; err = encode_variant(value, nullptr, len, true); diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 60759cd71c..912512d993 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -426,6 +426,21 @@ String _OS::get_external_data_dir() const { return OS::get_singleton()->get_external_data_dir(); } +String _OS::get_config_dir() const { + // Exposed as `get_config_dir()` instead of `get_config_path()` for consistency with other exposed OS methods. + return OS::get_singleton()->get_config_path(); +} + +String _OS::get_data_dir() const { + // Exposed as `get_data_dir()` instead of `get_data_path()` for consistency with other exposed OS methods. + return OS::get_singleton()->get_data_path(); +} + +String _OS::get_cache_dir() const { + // Exposed as `get_cache_dir()` instead of `get_cache_path()` for consistency with other exposed OS methods. + return OS::get_singleton()->get_cache_path(); +} + bool _OS::is_debug_build() const { #ifdef DEBUG_ENABLED return true; @@ -518,6 +533,9 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_user_data_dir"), &_OS::get_user_data_dir); ClassDB::bind_method(D_METHOD("get_external_data_dir"), &_OS::get_external_data_dir); ClassDB::bind_method(D_METHOD("get_system_dir", "dir"), &_OS::get_system_dir); + ClassDB::bind_method(D_METHOD("get_config_dir"), &_OS::get_config_dir); + ClassDB::bind_method(D_METHOD("get_data_dir"), &_OS::get_data_dir); + ClassDB::bind_method(D_METHOD("get_cache_dir"), &_OS::get_cache_dir); ClassDB::bind_method(D_METHOD("get_unique_id"), &_OS::get_unique_id); ClassDB::bind_method(D_METHOD("print_all_textures_by_size"), &_OS::print_all_textures_by_size); diff --git a/core/core_bind.h b/core/core_bind.h index b161effe95..5ab81547d7 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -230,6 +230,9 @@ public: String get_user_data_dir() const; String get_external_data_dir() const; + String get_config_dir() const; + String get_data_dir() const; + String get_cache_dir() const; Error set_thread_name(const String &p_name); Thread::ID get_thread_caller_id() const; diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 5b96babe44..c43fd64561 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -353,8 +353,9 @@ static const _BuiltinActionDisplayName _builtin_action_display_names[] = { { "ui_text_scroll_down", TTRC("Scroll Down") }, { "ui_text_scroll_down.OSX", TTRC("Scroll Down") }, { "ui_text_select_all", TTRC("Select All") }, - { "ui_text_select_word_under_caret", TTRC("Select Word Under Caret") }, + { "ui_text_select_word_under_caret", TTRC("Select Word Under Caret") }, { "ui_text_toggle_insert_mode", TTRC("Toggle Insert Mode") }, + { "ui_text_submit", TTRC("Text Submitted") }, { "ui_graph_duplicate", TTRC("Duplicate Nodes") }, { "ui_graph_delete", TTRC("Delete Nodes") }, { "ui_filedialog_up_one_level", TTRC("Go Up One Level") }, @@ -668,6 +669,11 @@ const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() { inputs.push_back(InputEventKey::create_reference(KEY_MENU)); default_builtin_cache.insert("ui_menu", inputs); + inputs = List<Ref<InputEvent>>(); + inputs.push_back(InputEventKey::create_reference(KEY_ENTER)); + inputs.push_back(InputEventKey::create_reference(KEY_KP_ENTER)); + default_builtin_cache.insert("ui_text_submit", inputs); + // ///// UI Graph Shortcuts ///// inputs = List<Ref<InputEvent>>(); diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 0cf870e7e7..449ebaa6ee 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -825,7 +825,7 @@ void HTTPClient::_bind_methods() { ClassDB::bind_method(D_METHOD("query_string_from_dict", "fields"), &HTTPClient::query_string_from_dict); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "blocking_mode_enabled"), "set_blocking_mode", "is_blocking_mode_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "connection", PROPERTY_HINT_RESOURCE_TYPE, "StreamPeer", 0), "set_connection", "get_connection"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "connection", PROPERTY_HINT_RESOURCE_TYPE, "StreamPeer", PROPERTY_USAGE_NONE), "set_connection", "get_connection"); ADD_PROPERTY(PropertyInfo(Variant::INT, "read_chunk_size", PROPERTY_HINT_RANGE, "256,16777216"), "set_read_chunk_size", "get_read_chunk_size"); BIND_ENUM_CONSTANT(METHOD_GET); diff --git a/core/io/json.cpp b/core/io/json.cpp index e3e9d6158b..82ef2a6894 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -55,7 +55,7 @@ static String _make_indent(const String &p_indent, int p_size) { return indent_text; } -String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_indent, bool p_sort_keys, bool p_full_precision) { +String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_indent, bool p_sort_keys, Set<const void *> &p_markers, bool p_full_precision) { String colon = ":"; String end_statement = ""; @@ -91,20 +91,29 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_ String s = "["; s += end_statement; Array a = p_var; + + ERR_FAIL_COND_V_MSG(p_markers.has(a.id()), "\"[...]\"", "Converting circular structure to JSON."); + p_markers.insert(a.id()); + for (int i = 0; i < a.size(); i++) { if (i > 0) { s += ","; s += end_statement; } - s += _make_indent(p_indent, p_cur_indent + 1) + _print_var(a[i], p_indent, p_cur_indent + 1, p_sort_keys); + s += _make_indent(p_indent, p_cur_indent + 1) + _print_var(a[i], p_indent, p_cur_indent + 1, p_sort_keys, p_markers); } s += end_statement + _make_indent(p_indent, p_cur_indent) + "]"; + p_markers.erase(a.id()); return s; } case Variant::DICTIONARY: { String s = "{"; s += end_statement; Dictionary d = p_var; + + ERR_FAIL_COND_V_MSG(p_markers.has(d.id()), "\"{...}\"", "Converting circular structure to JSON."); + p_markers.insert(d.id()); + List<Variant> keys; d.get_key_list(&keys); @@ -117,12 +126,13 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_ s += ","; s += end_statement; } - s += _make_indent(p_indent, p_cur_indent + 1) + _print_var(String(E->get()), p_indent, p_cur_indent + 1, p_sort_keys); + s += _make_indent(p_indent, p_cur_indent + 1) + _print_var(String(E->get()), p_indent, p_cur_indent + 1, p_sort_keys, p_markers); s += colon; - s += _print_var(d[E->get()], p_indent, p_cur_indent + 1, p_sort_keys); + s += _print_var(d[E->get()], p_indent, p_cur_indent + 1, p_sort_keys, p_markers); } s += end_statement + _make_indent(p_indent, p_cur_indent) + "}"; + p_markers.erase(d.id()); return s; } default: @@ -131,7 +141,8 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_ } String JSON::print(const Variant &p_var, const String &p_indent, bool p_sort_keys, bool p_full_precision) { - return _print_var(p_var, p_indent, 0, p_sort_keys, p_full_precision); + Set<const void *> markers; + return _print_var(p_var, p_indent, 0, p_sort_keys, markers, p_full_precision); } Error JSON::_get_token(const char32_t *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str) { diff --git a/core/io/json.h b/core/io/json.h index bfd2347725..5be8cc1e86 100644 --- a/core/io/json.h +++ b/core/io/json.h @@ -62,7 +62,7 @@ class JSON { static const char *tk_name[TK_MAX]; - static String _print_var(const Variant &p_var, const String &p_indent, int p_cur_indent, bool p_sort_keys, bool p_full_precision = false); + static String _print_var(const Variant &p_var, const String &p_indent, int p_cur_indent, bool p_sort_keys, Set<const void *> &p_markers, bool p_full_precision = false); static Error _get_token(const char32_t *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str); static Error _parse_value(Variant &value, Token &token, const char32_t *p_str, int &index, int p_len, int &line, String &r_err_str); diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 78ec7ea21a..51ba8800e4 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -1123,8 +1123,8 @@ void MultiplayerAPI::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_object_decoding"), "set_allow_object_decoding", "is_object_decoding_allowed"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "refuse_new_network_connections"), "set_refuse_new_network_connections", "is_refusing_new_network_connections"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "network_peer", PROPERTY_HINT_RESOURCE_TYPE, "NetworkedMultiplayerPeer", 0), "set_network_peer", "get_network_peer"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "root_node", PROPERTY_HINT_RESOURCE_TYPE, "Node", 0), "set_root_node", "get_root_node"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "network_peer", PROPERTY_HINT_RESOURCE_TYPE, "NetworkedMultiplayerPeer", PROPERTY_USAGE_NONE), "set_network_peer", "get_network_peer"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "root_node", PROPERTY_HINT_RESOURCE_TYPE, "Node", PROPERTY_USAGE_NONE), "set_root_node", "get_root_node"); ADD_PROPERTY_DEFAULT("refuse_new_network_connections", false); ADD_SIGNAL(MethodInfo("network_peer_connected", PropertyInfo(Variant::INT, "id"))); diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index 318fd10243..8da44fd290 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -161,7 +161,7 @@ void PacketPeerStream::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "input_buffer_max_size"), "set_input_buffer_max_size", "get_input_buffer_max_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "output_buffer_max_size"), "set_output_buffer_max_size", "get_output_buffer_max_size"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream_peer", PROPERTY_HINT_RESOURCE_TYPE, "StreamPeer", 0), "set_stream_peer", "get_stream_peer"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream_peer", PROPERTY_HINT_RESOURCE_TYPE, "StreamPeer", PROPERTY_USAGE_NONE), "set_stream_peer", "get_stream_peer"); } Error PacketPeerStream::_poll_buffer() const { diff --git a/core/math/basis.h b/core/math/basis.h index 3736047dd3..2889a4aa5e 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -158,8 +158,8 @@ public: _FORCE_INLINE_ Basis operator+(const Basis &p_matrix) const; _FORCE_INLINE_ void operator-=(const Basis &p_matrix); _FORCE_INLINE_ Basis operator-(const Basis &p_matrix) const; - _FORCE_INLINE_ void operator*=(real_t p_val); - _FORCE_INLINE_ Basis operator*(real_t p_val) const; + _FORCE_INLINE_ void operator*=(const real_t p_val); + _FORCE_INLINE_ Basis operator*(const real_t p_val) const; int get_orthogonal_index() const; void set_orthogonal_index(int p_index); @@ -298,13 +298,13 @@ _FORCE_INLINE_ Basis Basis::operator-(const Basis &p_matrix) const { return ret; } -_FORCE_INLINE_ void Basis::operator*=(real_t p_val) { +_FORCE_INLINE_ void Basis::operator*=(const real_t p_val) { elements[0] *= p_val; elements[1] *= p_val; elements[2] *= p_val; } -_FORCE_INLINE_ Basis Basis::operator*(real_t p_val) const { +_FORCE_INLINE_ Basis Basis::operator*(const real_t p_val) const { Basis ret(*this); ret *= p_val; return ret; diff --git a/core/math/quaternion.cpp b/core/math/quaternion.cpp index 7037db7112..3f1d2c58e5 100644 --- a/core/math/quaternion.cpp +++ b/core/math/quaternion.cpp @@ -33,6 +33,11 @@ #include "core/math/basis.h" #include "core/string/print_string.h" +real_t Quaternion::angle_to(const Quaternion &p_to) const { + real_t d = dot(p_to); + return Math::acos(CLAMP(d * d * 2 - 1, -1, 1)); +} + // get_euler_xyz returns a vector containing the Euler angles in the format // (ax,ay,az), where ax is the angle of rotation around x axis, // and similar for other axes. diff --git a/core/math/quaternion.h b/core/math/quaternion.h index 796214b79e..35324323b3 100644 --- a/core/math/quaternion.h +++ b/core/math/quaternion.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef QUAT_H -#define QUAT_H +#ifndef QUATERNION_H +#define QUATERNION_H #include "core/math/math_defs.h" #include "core/math/math_funcs.h" @@ -62,6 +62,7 @@ public: bool is_normalized() const; Quaternion inverse() const; _FORCE_INLINE_ real_t dot(const Quaternion &p_q) const; + real_t angle_to(const Quaternion &p_to) const; Vector3 get_euler_xyz() const; Vector3 get_euler_yxz() const; @@ -235,4 +236,4 @@ _FORCE_INLINE_ Quaternion operator*(const real_t &p_real, const Quaternion &p_qu return p_quaternion * p_real; } -#endif // QUAT_H +#endif // QUATERNION_H diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index 0140f31b8a..16934d67df 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -276,6 +276,18 @@ Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t return res; } +void Transform2D::operator*=(const real_t p_val) { + elements[0] *= p_val; + elements[1] *= p_val; + elements[2] *= p_val; +} + +Transform2D Transform2D::operator*(const real_t p_val) const { + Transform2D ret(*this); + ret *= p_val; + return ret; +} + Transform2D::operator String() const { return "[X: " + elements[0].operator String() + ", Y: " + elements[1].operator String() + diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 715f013701..34cfd0c1a9 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -107,6 +107,8 @@ struct Transform2D { void operator*=(const Transform2D &p_transform); Transform2D operator*(const Transform2D &p_transform) const; + void operator*=(const real_t p_val); + Transform2D operator*(const real_t p_val) const; Transform2D interpolate_with(const Transform2D &p_transform, real_t p_c) const; diff --git a/core/math/transform_3d.cpp b/core/math/transform_3d.cpp index a34d998dde..51766b39f4 100644 --- a/core/math/transform_3d.cpp +++ b/core/math/transform_3d.cpp @@ -190,6 +190,17 @@ Transform3D Transform3D::operator*(const Transform3D &p_transform) const { return t; } +void Transform3D::operator*=(const real_t p_val) { + origin *= p_val; + basis *= p_val; +} + +Transform3D Transform3D::operator*(const real_t p_val) const { + Transform3D ret(*this); + ret *= p_val; + return ret; +} + Transform3D::operator String() const { return "[X: " + basis.get_axis(0).operator String() + ", Y: " + basis.get_axis(1).operator String() + diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h index 078a2ca11a..3d8e70cec7 100644 --- a/core/math/transform_3d.h +++ b/core/math/transform_3d.h @@ -88,6 +88,8 @@ public: void operator*=(const Transform3D &p_transform); Transform3D operator*(const Transform3D &p_transform) const; + void operator*=(const real_t p_val); + Transform3D operator*(const real_t p_val) const; Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const; diff --git a/core/object/object.h b/core/object/object.h index 37b2e61dfe..65621a47ca 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -101,6 +101,7 @@ enum PropertyHint { }; enum PropertyUsageFlags { + PROPERTY_USAGE_NONE = 0, PROPERTY_USAGE_STORAGE = 1, PROPERTY_USAGE_EDITOR = 2, PROPERTY_USAGE_NETWORK = 4, diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index aa91c6cbf7..dd6bc09abb 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -120,7 +120,7 @@ void Script::_bind_methods() { ClassDB::bind_method(D_METHOD("is_tool"), &Script::is_tool); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "source_code", PROPERTY_HINT_NONE, "", 0), "set_source_code", "get_source_code"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "source_code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_source_code", "get_source_code"); } void ScriptServer::set_scripting_enabled(bool p_enabled) { @@ -353,10 +353,10 @@ void ScriptLanguage::get_core_type_words(List<String> *p_core_type_words) const p_core_type_words->push_back("Vector3i"); p_core_type_words->push_back("Transform2D"); p_core_type_words->push_back("Plane"); - p_core_type_words->push_back("Quat"); + p_core_type_words->push_back("Quaternion"); p_core_type_words->push_back("AABB"); p_core_type_words->push_back("Basis"); - p_core_type_words->push_back("Transform"); + p_core_type_words->push_back("Transform3D"); p_core_type_words->push_back("Color"); p_core_type_words->push_back("StringName"); p_core_type_words->push_back("NodePath"); diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 83ede0b11b..16ecd2b985 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -275,7 +275,7 @@ Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r base = base.substr(pos + 1, base.length() - pos - 1); } else { // Anything else - if (base.get_slice_count(":") > 1) { + if (base.get_slice_count(":") > 2) { return ERR_INVALID_PARAMETER; } pos = base.rfind(":"); @@ -294,7 +294,7 @@ Error String::parse_url(String &r_scheme, String &r_host, int &r_port, String &r // Port if (base.begins_with(":")) { base = base.substr(1, base.length() - 1); - if (!base.is_valid_integer()) { + if (!base.is_valid_int()) { return ERR_INVALID_PARAMETER; } r_port = base.to_int(); @@ -4168,7 +4168,7 @@ String String::trim_suffix(const String &p_suffix) const { return s; } -bool String::is_valid_integer() const { +bool String::is_valid_int() const { int len = length(); if (len == 0) { @@ -4393,7 +4393,7 @@ bool String::is_valid_ip_address() const { } for (int i = 0; i < ip.size(); i++) { String n = ip[i]; - if (!n.is_valid_integer()) { + if (!n.is_valid_int()) { return false; } int val = n.to_int(); diff --git a/core/string/ustring.h b/core/string/ustring.h index 82cd3e1667..ffb354d6e1 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -425,7 +425,7 @@ public: String validate_node_name() const; bool is_valid_identifier() const; - bool is_valid_integer() const; + bool is_valid_int() const; bool is_valid_float() const; bool is_valid_hex_number(bool p_with_prefix) const; bool is_valid_html_color() const; diff --git a/core/templates/thread_work_pool.h b/core/templates/thread_work_pool.h index 9f7a692cc5..b242648bc8 100644 --- a/core/templates/thread_work_pool.h +++ b/core/templates/thread_work_pool.h @@ -105,7 +105,7 @@ public: } bool is_done_dispatching() const { - ERR_FAIL_COND_V(current_work == nullptr, false); + ERR_FAIL_COND_V(current_work == nullptr, true); return index.load(std::memory_order_acquire) >= current_work->max_elements; } diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index d10f41b833..4e45862fd3 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -1698,6 +1698,7 @@ String Variant::stringify(List<const void *> &stack) const { } str += "}"; + stack.erase(d.id()); return str; } break; case PACKED_VECTOR2_ARRAY: { @@ -1801,6 +1802,7 @@ String Variant::stringify(List<const void *> &stack) const { } str += "]"; + stack.erase(arr.id()); return str; } break; diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 05ed35c760..9c7cd23d72 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1380,7 +1380,7 @@ static void _register_variant_builtin_methods() { bind_method(String, validate_node_name, sarray(), varray()); bind_method(String, is_valid_identifier, sarray(), varray()); - bind_method(String, is_valid_integer, sarray(), varray()); + bind_method(String, is_valid_int, sarray(), varray()); bind_method(String, is_valid_float, sarray(), varray()); bind_method(String, is_valid_hex_number, sarray("with_prefix"), varray(false)); bind_method(String, is_valid_html_color, sarray(), varray()); @@ -1552,6 +1552,7 @@ static void _register_variant_builtin_methods() { bind_method(Quaternion, is_normalized, sarray(), varray()); bind_method(Quaternion, is_equal_approx, sarray("to"), varray()); bind_method(Quaternion, inverse, sarray(), varray()); + bind_method(Quaternion, angle_to, sarray("to"), varray()); bind_method(Quaternion, dot, sarray("with"), varray()); bind_method(Quaternion, slerp, sarray("to", "weight"), varray()); bind_method(Quaternion, slerpni, sarray("to", "weight"), varray()); diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index 9e3ab5897b..a1a2bec369 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -28,543 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "variant.h" - -#include "core/core_string_names.h" -#include "core/crypto/crypto_core.h" -#include "core/debugger/engine_debugger.h" -#include "core/io/compression.h" -#include "core/object/class_db.h" -#include "core/os/os.h" -#include "core/templates/local_vector.h" -#include "core/templates/oa_hash_map.h" - -template <class T> -struct PtrConstruct {}; - -#define MAKE_PTRCONSTRUCT(m_type) \ - template <> \ - struct PtrConstruct<m_type> { \ - _FORCE_INLINE_ static void construct(const m_type &p_value, void *p_ptr) { \ - memnew_placement(p_ptr, m_type(p_value)); \ - } \ - }; - -MAKE_PTRCONSTRUCT(bool); -MAKE_PTRCONSTRUCT(int64_t); -MAKE_PTRCONSTRUCT(double); -MAKE_PTRCONSTRUCT(String); -MAKE_PTRCONSTRUCT(Vector2); -MAKE_PTRCONSTRUCT(Vector2i); -MAKE_PTRCONSTRUCT(Rect2); -MAKE_PTRCONSTRUCT(Rect2i); -MAKE_PTRCONSTRUCT(Vector3); -MAKE_PTRCONSTRUCT(Vector3i); -MAKE_PTRCONSTRUCT(Transform2D); -MAKE_PTRCONSTRUCT(Plane); -MAKE_PTRCONSTRUCT(Quaternion); -MAKE_PTRCONSTRUCT(AABB); -MAKE_PTRCONSTRUCT(Basis); -MAKE_PTRCONSTRUCT(Transform3D); -MAKE_PTRCONSTRUCT(Color); -MAKE_PTRCONSTRUCT(StringName); -MAKE_PTRCONSTRUCT(NodePath); -MAKE_PTRCONSTRUCT(RID); - -template <> -struct PtrConstruct<Object *> { - _FORCE_INLINE_ static void construct(Object *p_value, void *p_ptr) { - *((Object **)p_ptr) = p_value; - } -}; - -MAKE_PTRCONSTRUCT(Callable); -MAKE_PTRCONSTRUCT(Signal); -MAKE_PTRCONSTRUCT(Dictionary); -MAKE_PTRCONSTRUCT(Array); -MAKE_PTRCONSTRUCT(PackedByteArray); -MAKE_PTRCONSTRUCT(PackedInt32Array); -MAKE_PTRCONSTRUCT(PackedInt64Array); -MAKE_PTRCONSTRUCT(PackedFloat32Array); -MAKE_PTRCONSTRUCT(PackedFloat64Array); -MAKE_PTRCONSTRUCT(PackedStringArray); -MAKE_PTRCONSTRUCT(PackedVector2Array); -MAKE_PTRCONSTRUCT(PackedVector3Array); -MAKE_PTRCONSTRUCT(PackedColorArray); -MAKE_PTRCONSTRUCT(Variant); - -template <class T, class... P> -class VariantConstructor { - template <size_t... Is> - static _FORCE_INLINE_ void construct_helper(T &base, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) { - r_error.error = Callable::CallError::CALL_OK; - -#ifdef DEBUG_METHODS_ENABLED - base = T(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); -#else - base = T(VariantCaster<P>::cast(*p_args[Is])...); -#endif - } - - template <size_t... Is> - static _FORCE_INLINE_ void validated_construct_helper(T &base, const Variant **p_args, IndexSequence<Is...>) { - base = T((*VariantGetInternalPtr<P>::get_ptr(p_args[Is]))...); - } - - template <size_t... Is> - static _FORCE_INLINE_ void ptr_construct_helper(void *base, const void **p_args, IndexSequence<Is...>) { - PtrConstruct<T>::construct(T(PtrToArg<P>::convert(p_args[Is])...), base); - } - -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - r_error.error = Callable::CallError::CALL_OK; - VariantTypeChanger<T>::change(&r_ret); - construct_helper(*VariantGetInternalPtr<T>::get_ptr(&r_ret), p_args, r_error, BuildIndexSequence<sizeof...(P)>{}); - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantTypeChanger<T>::change(r_ret); - validated_construct_helper(*VariantGetInternalPtr<T>::get_ptr(r_ret), p_args, BuildIndexSequence<sizeof...(P)>{}); - } - static void ptr_construct(void *base, const void **p_args) { - ptr_construct_helper(base, p_args, BuildIndexSequence<sizeof...(P)>{}); - } - - static int get_argument_count() { - return sizeof...(P); - } - - static Variant::Type get_argument_type(int p_arg) { - return call_get_argument_type<P...>(p_arg); - } - - static Variant::Type get_base_type() { - return GetTypeInfo<T>::VARIANT_TYPE; - } -}; - -class VariantConstructorObject { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - VariantInternal::clear(&r_ret); - if (p_args[0]->get_type() == Variant::NIL) { - VariantInternal::object_assign_null(&r_ret); - r_error.error = Callable::CallError::CALL_OK; - } else if (p_args[0]->get_type() == Variant::OBJECT) { - VariantInternal::object_assign(&r_ret, p_args[0]); - r_error.error = Callable::CallError::CALL_OK; - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::OBJECT; - } - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantInternal::clear(r_ret); - VariantInternal::object_assign(r_ret, p_args[0]); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<Object *>::construct(PtrToArg<Object *>::convert(p_args[0]), base); - } - - static int get_argument_count() { - return 1; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::OBJECT; - } - - static Variant::Type get_base_type() { - return Variant::OBJECT; - } -}; - -class VariantConstructorNilObject { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - if (p_args[0]->get_type() != Variant::NIL) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::NIL; - } - - VariantInternal::clear(&r_ret); - VariantInternal::object_assign_null(&r_ret); - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantInternal::clear(r_ret); - VariantInternal::object_assign_null(r_ret); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<Object *>::construct(nullptr, base); - } - - static int get_argument_count() { - return 1; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::NIL; - } - - static Variant::Type get_base_type() { - return Variant::OBJECT; - } -}; - -class VariantConstructorCallableArgs { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - ObjectID object_id; - StringName method; - - if (p_args[0]->get_type() == Variant::NIL) { - // leave as is - } else if (p_args[0]->get_type() == Variant::OBJECT) { - object_id = VariantInternal::get_object_id(p_args[0]); - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::OBJECT; - return; - } - - if (p_args[1]->get_type() == Variant::STRING_NAME) { - method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]); - } else if (p_args[1]->get_type() == Variant::STRING) { - method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]); - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 1; - r_error.expected = Variant::STRING_NAME; - return; - } - - VariantTypeChanger<Callable>::change(&r_ret); - *VariantGetInternalPtr<Callable>::get_ptr(&r_ret) = Callable(object_id, method); - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantTypeChanger<Callable>::change(r_ret); - *VariantGetInternalPtr<Callable>::get_ptr(r_ret) = Callable(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1])); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<Callable>::construct(Callable(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base); - } - - static int get_argument_count() { - return 2; - } - - static Variant::Type get_argument_type(int p_arg) { - if (p_arg == 0) { - return Variant::OBJECT; - } else { - return Variant::STRING_NAME; - } - } - - static Variant::Type get_base_type() { - return Variant::CALLABLE; - } -}; - -class VariantConstructorSignalArgs { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - ObjectID object_id; - StringName method; - - if (p_args[0]->get_type() == Variant::NIL) { - // leave as is - } else if (p_args[0]->get_type() == Variant::OBJECT) { - object_id = VariantInternal::get_object_id(p_args[0]); - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::OBJECT; - return; - } - - if (p_args[1]->get_type() == Variant::STRING_NAME) { - method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]); - } else if (p_args[1]->get_type() == Variant::STRING) { - method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]); - } else { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 1; - r_error.expected = Variant::STRING_NAME; - return; - } - - VariantTypeChanger<Signal>::change(&r_ret); - *VariantGetInternalPtr<Signal>::get_ptr(&r_ret) = Signal(object_id, method); - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantTypeChanger<Signal>::change(r_ret); - *VariantGetInternalPtr<Signal>::get_ptr(r_ret) = Signal(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1])); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<Signal>::construct(Signal(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base); - } - - static int get_argument_count() { - return 2; - } - - static Variant::Type get_argument_type(int p_arg) { - if (p_arg == 0) { - return Variant::OBJECT; - } else { - return Variant::STRING_NAME; - } - } - - static Variant::Type get_base_type() { - return Variant::SIGNAL; - } -}; - -template <class T> -class VariantConstructorToArray { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - if (p_args[0]->get_type() != GetTypeInfo<T>::VARIANT_TYPE) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = GetTypeInfo<T>::VARIANT_TYPE; - return; - } - - VariantTypeChanger<Array>::change(&r_ret); - Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(&r_ret); - const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]); - - int size = src_arr.size(); - dst_arr.resize(size); - for (int i = 0; i < size; i++) { - dst_arr[i] = src_arr[i]; - } - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantTypeChanger<Array>::change(r_ret); - Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(r_ret); - const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]); - - int size = src_arr.size(); - dst_arr.resize(size); - for (int i = 0; i < size; i++) { - dst_arr[i] = src_arr[i]; - } - } - static void ptr_construct(void *base, const void **p_args) { - Array dst_arr; - T src_arr = PtrToArg<T>::convert(p_args[0]); - - int size = src_arr.size(); - dst_arr.resize(size); - for (int i = 0; i < size; i++) { - dst_arr[i] = src_arr[i]; - } - - PtrConstruct<Array>::construct(dst_arr, base); - } - - static int get_argument_count() { - return 1; - } - - static Variant::Type get_argument_type(int p_arg) { - return GetTypeInfo<T>::VARIANT_TYPE; - } - - static Variant::Type get_base_type() { - return Variant::ARRAY; - } -}; - -template <class T> -class VariantConstructorFromArray { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - if (p_args[0]->get_type() != Variant::ARRAY) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::ARRAY; - return; - } - - VariantTypeChanger<T>::change(&r_ret); - const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]); - T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(&r_ret); - - int size = src_arr.size(); - dst_arr.resize(size); - for (int i = 0; i < size; i++) { - dst_arr.write[i] = src_arr[i]; - } - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantTypeChanger<T>::change(r_ret); - const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]); - T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(r_ret); - - int size = src_arr.size(); - dst_arr.resize(size); - for (int i = 0; i < size; i++) { - dst_arr.write[i] = src_arr[i]; - } - } - static void ptr_construct(void *base, const void **p_args) { - Array src_arr = PtrToArg<Array>::convert(p_args[0]); - T dst_arr; - - int size = src_arr.size(); - dst_arr.resize(size); - for (int i = 0; i < size; i++) { - dst_arr.write[i] = src_arr[i]; - } - - PtrConstruct<T>::construct(dst_arr, base); - } - - static int get_argument_count() { - return 1; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::ARRAY; - } - - static Variant::Type get_base_type() { - return GetTypeInfo<T>::VARIANT_TYPE; - } -}; - -class VariantConstructorNil { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - if (p_args[0]->get_type() != Variant::NIL) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::NIL; - return; - } - - r_error.error = Callable::CallError::CALL_OK; - VariantInternal::clear(&r_ret); - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantInternal::clear(r_ret); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<Variant>::construct(Variant(), base); - } - - static int get_argument_count() { - return 1; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::NIL; - } - - static Variant::Type get_base_type() { - return Variant::NIL; - } -}; - -template <class T> -class VariantConstructNoArgs { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - VariantTypeChanger<T>::change_and_reset(&r_ret); - r_error.error = Callable::CallError::CALL_OK; - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantTypeChanger<T>::change_and_reset(r_ret); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<T>::construct(T(), base); - } - - static int get_argument_count() { - return 0; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::NIL; - } - - static Variant::Type get_base_type() { - return GetTypeInfo<T>::VARIANT_TYPE; - } -}; - -class VariantConstructNoArgsNil { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - VariantInternal::clear(&r_ret); - r_error.error = Callable::CallError::CALL_OK; - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantInternal::clear(r_ret); - } - static void ptr_construct(void *base, const void **p_args) { - ERR_FAIL_MSG("can't ptrcall nil constructor"); - } - - static int get_argument_count() { - return 0; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::NIL; - } - - static Variant::Type get_base_type() { - return Variant::NIL; - } -}; - -class VariantConstructNoArgsObject { -public: - static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - VariantInternal::clear(&r_ret); - VariantInternal::object_assign_null(&r_ret); - r_error.error = Callable::CallError::CALL_OK; - } - - static void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantInternal::clear(r_ret); - VariantInternal::object_assign_null(r_ret); - } - static void ptr_construct(void *base, const void **p_args) { - PtrConstruct<Object *>::construct(nullptr, base); - } - - static int get_argument_count() { - return 0; - } - - static Variant::Type get_argument_type(int p_arg) { - return Variant::NIL; - } - - static Variant::Type get_base_type() { - return Variant::OBJECT; - } -}; +#include "variant_construct.h" struct VariantConstructData { void (*construct)(Variant &r_base, const Variant **p_args, Callable::CallError &r_error); diff --git a/core/variant/variant_construct.h b/core/variant/variant_construct.h new file mode 100644 index 0000000000..b03f4a8d3b --- /dev/null +++ b/core/variant/variant_construct.h @@ -0,0 +1,572 @@ +/*************************************************************************/ +/* variant_construct.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 VARIANT_CONSTRUCT_H +#define VARIANT_CONSTRUCT_H + +#include "variant.h" + +#include "core/core_string_names.h" +#include "core/crypto/crypto_core.h" +#include "core/debugger/engine_debugger.h" +#include "core/io/compression.h" +#include "core/object/class_db.h" +#include "core/os/os.h" +#include "core/templates/local_vector.h" +#include "core/templates/oa_hash_map.h" + +template <class T> +struct PtrConstruct {}; + +#define MAKE_PTRCONSTRUCT(m_type) \ + template <> \ + struct PtrConstruct<m_type> { \ + _FORCE_INLINE_ static void construct(const m_type &p_value, void *p_ptr) { \ + memnew_placement(p_ptr, m_type(p_value)); \ + } \ + }; + +MAKE_PTRCONSTRUCT(bool); +MAKE_PTRCONSTRUCT(int64_t); +MAKE_PTRCONSTRUCT(double); +MAKE_PTRCONSTRUCT(String); +MAKE_PTRCONSTRUCT(Vector2); +MAKE_PTRCONSTRUCT(Vector2i); +MAKE_PTRCONSTRUCT(Rect2); +MAKE_PTRCONSTRUCT(Rect2i); +MAKE_PTRCONSTRUCT(Vector3); +MAKE_PTRCONSTRUCT(Vector3i); +MAKE_PTRCONSTRUCT(Transform2D); +MAKE_PTRCONSTRUCT(Plane); +MAKE_PTRCONSTRUCT(Quaternion); +MAKE_PTRCONSTRUCT(AABB); +MAKE_PTRCONSTRUCT(Basis); +MAKE_PTRCONSTRUCT(Transform3D); +MAKE_PTRCONSTRUCT(Color); +MAKE_PTRCONSTRUCT(StringName); +MAKE_PTRCONSTRUCT(NodePath); +MAKE_PTRCONSTRUCT(RID); + +template <> +struct PtrConstruct<Object *> { + _FORCE_INLINE_ static void construct(Object *p_value, void *p_ptr) { + *((Object **)p_ptr) = p_value; + } +}; + +MAKE_PTRCONSTRUCT(Callable); +MAKE_PTRCONSTRUCT(Signal); +MAKE_PTRCONSTRUCT(Dictionary); +MAKE_PTRCONSTRUCT(Array); +MAKE_PTRCONSTRUCT(PackedByteArray); +MAKE_PTRCONSTRUCT(PackedInt32Array); +MAKE_PTRCONSTRUCT(PackedInt64Array); +MAKE_PTRCONSTRUCT(PackedFloat32Array); +MAKE_PTRCONSTRUCT(PackedFloat64Array); +MAKE_PTRCONSTRUCT(PackedStringArray); +MAKE_PTRCONSTRUCT(PackedVector2Array); +MAKE_PTRCONSTRUCT(PackedVector3Array); +MAKE_PTRCONSTRUCT(PackedColorArray); +MAKE_PTRCONSTRUCT(Variant); + +template <class T, class... P> +class VariantConstructor { + template <size_t... Is> + static _FORCE_INLINE_ void construct_helper(T &base, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) { + r_error.error = Callable::CallError::CALL_OK; + +#ifdef DEBUG_METHODS_ENABLED + base = T(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); +#else + base = T(VariantCaster<P>::cast(*p_args[Is])...); +#endif + } + + template <size_t... Is> + static _FORCE_INLINE_ void validated_construct_helper(T &base, const Variant **p_args, IndexSequence<Is...>) { + base = T((*VariantGetInternalPtr<P>::get_ptr(p_args[Is]))...); + } + + template <size_t... Is> + static _FORCE_INLINE_ void ptr_construct_helper(void *base, const void **p_args, IndexSequence<Is...>) { + PtrConstruct<T>::construct(T(PtrToArg<P>::convert(p_args[Is])...), base); + } + +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + VariantTypeChanger<T>::change(&r_ret); + construct_helper(*VariantGetInternalPtr<T>::get_ptr(&r_ret), p_args, r_error, BuildIndexSequence<sizeof...(P)>{}); + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantTypeChanger<T>::change(r_ret); + validated_construct_helper(*VariantGetInternalPtr<T>::get_ptr(r_ret), p_args, BuildIndexSequence<sizeof...(P)>{}); + } + static void ptr_construct(void *base, const void **p_args) { + ptr_construct_helper(base, p_args, BuildIndexSequence<sizeof...(P)>{}); + } + + static int get_argument_count() { + return sizeof...(P); + } + + static Variant::Type get_argument_type(int p_arg) { + return call_get_argument_type<P...>(p_arg); + } + + static Variant::Type get_base_type() { + return GetTypeInfo<T>::VARIANT_TYPE; + } +}; + +class VariantConstructorObject { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); + if (p_args[0]->get_type() == Variant::NIL) { + VariantInternal::object_assign_null(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } else if (p_args[0]->get_type() == Variant::OBJECT) { + VariantInternal::object_assign(&r_ret, p_args[0]); + r_error.error = Callable::CallError::CALL_OK; + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + } + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantInternal::clear(r_ret); + VariantInternal::object_assign(r_ret, p_args[0]); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<Object *>::construct(PtrToArg<Object *>::convert(p_args[0]), base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::OBJECT; + } + + static Variant::Type get_base_type() { + return Variant::OBJECT; + } +}; + +class VariantConstructorNilObject { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::NIL) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::NIL; + } + + VariantInternal::clear(&r_ret); + VariantInternal::object_assign_null(&r_ret); + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantInternal::clear(r_ret); + VariantInternal::object_assign_null(r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<Object *>::construct(nullptr, base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::OBJECT; + } +}; + +class VariantConstructorCallableArgs { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + ObjectID object_id; + StringName method; + + if (p_args[0]->get_type() == Variant::NIL) { + // leave as is + } else if (p_args[0]->get_type() == Variant::OBJECT) { + object_id = VariantInternal::get_object_id(p_args[0]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + return; + } + + if (p_args[1]->get_type() == Variant::STRING_NAME) { + method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]); + } else if (p_args[1]->get_type() == Variant::STRING) { + method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 1; + r_error.expected = Variant::STRING_NAME; + return; + } + + VariantTypeChanger<Callable>::change(&r_ret); + *VariantGetInternalPtr<Callable>::get_ptr(&r_ret) = Callable(object_id, method); + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantTypeChanger<Callable>::change(r_ret); + *VariantGetInternalPtr<Callable>::get_ptr(r_ret) = Callable(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1])); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<Callable>::construct(Callable(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base); + } + + static int get_argument_count() { + return 2; + } + + static Variant::Type get_argument_type(int p_arg) { + if (p_arg == 0) { + return Variant::OBJECT; + } else { + return Variant::STRING_NAME; + } + } + + static Variant::Type get_base_type() { + return Variant::CALLABLE; + } +}; + +class VariantConstructorSignalArgs { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + ObjectID object_id; + StringName method; + + if (p_args[0]->get_type() == Variant::NIL) { + // leave as is + } else if (p_args[0]->get_type() == Variant::OBJECT) { + object_id = VariantInternal::get_object_id(p_args[0]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + return; + } + + if (p_args[1]->get_type() == Variant::STRING_NAME) { + method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]); + } else if (p_args[1]->get_type() == Variant::STRING) { + method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 1; + r_error.expected = Variant::STRING_NAME; + return; + } + + VariantTypeChanger<Signal>::change(&r_ret); + *VariantGetInternalPtr<Signal>::get_ptr(&r_ret) = Signal(object_id, method); + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantTypeChanger<Signal>::change(r_ret); + *VariantGetInternalPtr<Signal>::get_ptr(r_ret) = Signal(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1])); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<Signal>::construct(Signal(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base); + } + + static int get_argument_count() { + return 2; + } + + static Variant::Type get_argument_type(int p_arg) { + if (p_arg == 0) { + return Variant::OBJECT; + } else { + return Variant::STRING_NAME; + } + } + + static Variant::Type get_base_type() { + return Variant::SIGNAL; + } +}; + +template <class T> +class VariantConstructorToArray { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != GetTypeInfo<T>::VARIANT_TYPE) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = GetTypeInfo<T>::VARIANT_TYPE; + return; + } + + VariantTypeChanger<Array>::change(&r_ret); + Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(&r_ret); + const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr[i] = src_arr[i]; + } + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantTypeChanger<Array>::change(r_ret); + Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(r_ret); + const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr[i] = src_arr[i]; + } + } + static void ptr_construct(void *base, const void **p_args) { + Array dst_arr; + T src_arr = PtrToArg<T>::convert(p_args[0]); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr[i] = src_arr[i]; + } + + PtrConstruct<Array>::construct(dst_arr, base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return GetTypeInfo<T>::VARIANT_TYPE; + } + + static Variant::Type get_base_type() { + return Variant::ARRAY; + } +}; + +template <class T> +class VariantConstructorFromArray { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::ARRAY) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::ARRAY; + return; + } + + VariantTypeChanger<T>::change(&r_ret); + const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]); + T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(&r_ret); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr.write[i] = src_arr[i]; + } + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantTypeChanger<T>::change(r_ret); + const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]); + T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(r_ret); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr.write[i] = src_arr[i]; + } + } + static void ptr_construct(void *base, const void **p_args) { + Array src_arr = PtrToArg<Array>::convert(p_args[0]); + T dst_arr; + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr.write[i] = src_arr[i]; + } + + PtrConstruct<T>::construct(dst_arr, base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::ARRAY; + } + + static Variant::Type get_base_type() { + return GetTypeInfo<T>::VARIANT_TYPE; + } +}; + +class VariantConstructorNil { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::NIL) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::NIL; + return; + } + + r_error.error = Callable::CallError::CALL_OK; + VariantInternal::clear(&r_ret); + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantInternal::clear(r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<Variant>::construct(Variant(), base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::NIL; + } +}; + +template <class T> +class VariantConstructNoArgs { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantTypeChanger<T>::change_and_reset(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantTypeChanger<T>::change_and_reset(r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<T>::construct(T(), base); + } + + static int get_argument_count() { + return 0; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return GetTypeInfo<T>::VARIANT_TYPE; + } +}; + +class VariantConstructNoArgsNil { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantInternal::clear(r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + ERR_FAIL_MSG("can't ptrcall nil constructor"); + } + + static int get_argument_count() { + return 0; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::NIL; + } +}; + +class VariantConstructNoArgsObject { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); + VariantInternal::object_assign_null(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } + + static inline void validated_construct(Variant *r_ret, const Variant **p_args) { + VariantInternal::clear(r_ret); + VariantInternal::object_assign_null(r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrConstruct<Object *>::construct(nullptr, base); + } + + static int get_argument_count() { + return 0; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::OBJECT; + } +}; + +#endif // VARIANT_CONSTRUCT_H diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index 10d0a83014..4a1950c9bf 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -28,1342 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "variant.h" - -#include "core/core_string_names.h" -#include "core/debugger/engine_debugger.h" -#include "core/object/class_db.h" - -template <class R, class A, class B> -class OperatorEvaluatorAdd { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a + b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) + *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) + PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorSub { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a - b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) - *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) - PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorMul { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a * b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) * *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) * PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorXForm { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a.xform(b); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = VariantGetInternalPtr<A>::get_ptr(left)->xform(*VariantGetInternalPtr<B>::get_ptr(right)); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left).xform(PtrToArg<B>::convert(right)), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorXFormInv { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = b.xform_inv(a); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = VariantGetInternalPtr<B>::get_ptr(right)->xform_inv(*VariantGetInternalPtr<A>::get_ptr(left)); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<B>::convert(right).xform_inv(PtrToArg<A>::convert(left)), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorDiv { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a / b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) / *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) / PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorDivNZ { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - if (b == 0) { - r_valid = false; - *r_ret = "Division by zero error"; - return; - } - *r_ret = a / b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) / *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) / PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorMod { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a % b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) % *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) % PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorModNZ { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - if (b == 0) { - r_valid = false; - *r_ret = "Module by zero error"; - return; - } - *r_ret = a % b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) % *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) % PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A> -class OperatorEvaluatorNeg { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - *r_ret = -a; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = -*VariantGetInternalPtr<A>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(-PtrToArg<A>::convert(left), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A> -class OperatorEvaluatorPos { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - *r_ret = a; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorShiftLeft { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - -#if defined(DEBUG_ENABLED) - if (b < 0 || a < 0) { - *r_ret = "Invalid operands for bit shifting. Only positive operands are supported."; - r_valid = false; - return; - } -#endif - *r_ret = a << b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) << *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) << PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorShiftRight { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - -#if defined(DEBUG_ENABLED) - if (b < 0 || a < 0) { - *r_ret = "Invalid operands for bit shifting. Only positive operands are supported."; - r_valid = false; - return; - } -#endif - *r_ret = a >> b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) >> *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) >> PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorBitOr { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a | b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) | *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) | PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorBitAnd { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a & b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) & *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) & PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A, class B> -class OperatorEvaluatorBitXor { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a ^ b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) ^ *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(PtrToArg<A>::convert(left) ^ PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class R, class A> -class OperatorEvaluatorBitNeg { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - *r_ret = ~a; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<R>::change(r_ret); - *VariantGetInternalPtr<R>::get_ptr(r_ret) = ~*VariantGetInternalPtr<A>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<R>::encode(~PtrToArg<A>::convert(left), r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } -}; - -template <class A, class B> -class OperatorEvaluatorEqual { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a == b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) == *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) == PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorEqualObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Object *a = p_left.get_validated_object(); - const Object *b = p_right.get_validated_object(); - *r_ret = a == b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Object *a = left->get_validated_object(); - const Object *b = right->get_validated_object(); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == b; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == PtrToArg<Object *>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorEqualObjectNil { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Object *a = p_left.get_validated_object(); - *r_ret = a == nullptr; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Object *a = left->get_validated_object(); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == nullptr; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == nullptr, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorEqualNilObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Object *b = p_right.get_validated_object(); - *r_ret = nullptr == b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Object *b = right->get_validated_object(); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr == b; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(nullptr == PtrToArg<Object *>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorNotEqual { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a != b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) != *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) != PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorNotEqualObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - Object *a = p_left.get_validated_object(); - Object *b = p_right.get_validated_object(); - *r_ret = a != b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - Object *a = left->get_validated_object(); - Object *b = right->get_validated_object(); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != b; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) != PtrToArg<Object *>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorNotEqualObjectNil { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - Object *a = p_left.get_validated_object(); - *r_ret = a != nullptr; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - Object *a = left->get_validated_object(); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != nullptr; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) != nullptr, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorNotEqualNilObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - Object *b = p_right.get_validated_object(); - *r_ret = nullptr != b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - Object *b = right->get_validated_object(); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr != b; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(nullptr != PtrToArg<Object *>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorLess { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a < b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) < *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) < PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorLessEqual { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a <= b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) <= *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) <= PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorGreater { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a > b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) > *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) > PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorGreaterEqual { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a >= b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) >= *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) >= PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorAnd { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a && b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) && *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) && PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorOr { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = a || b; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) || *VariantGetInternalPtr<B>::get_ptr(right); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<A>::convert(left) || PtrToArg<B>::convert(right), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -#define XOR_OP(m_a, m_b) (((m_a) || (m_b)) && !((m_a) && (m_b))) -template <class A, class B> -class OperatorEvaluatorXor { -public: - _FORCE_INLINE_ static bool xor_op(const A &a, const B &b) { - return ((a) || (b)) && !((a) && (b)); - } - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - *r_ret = xor_op(a, b); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = xor_op(*VariantGetInternalPtr<A>::get_ptr(left), *VariantGetInternalPtr<B>::get_ptr(right)); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(xor_op(PtrToArg<A>::convert(left), PtrToArg<B>::convert(right)), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A> -class OperatorEvaluatorNot { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - *r_ret = !a; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<A>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(!PtrToArg<A>::convert(left)); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -//// CUSTOM //// - -class OperatorEvaluatorAddArray { -public: - _FORCE_INLINE_ static void _add_arrays(Array &sum, const Array &array_a, const Array &array_b) { - int asize = array_a.size(); - int bsize = array_b.size(); - sum.resize(asize + bsize); - for (int i = 0; i < asize; i++) { - sum[i] = array_a[i]; - } - for (int i = 0; i < bsize; i++) { - sum[i + asize] = array_b[i]; - } - } - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Array &array_a = *VariantGetInternalPtr<Array>::get_ptr(&p_left); - const Array &array_b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); - Array sum; - _add_arrays(sum, array_a, array_b); - *r_ret = sum; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<Array>::change(r_ret); - _add_arrays(*VariantGetInternalPtr<Array>::get_ptr(r_ret), *VariantGetInternalPtr<Array>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right)); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - Array ret; - _add_arrays(ret, PtrToArg<Array>::convert(left), PtrToArg<Array>::convert(right)); - PtrToArg<Array>::encode(ret, r_ret); - } - static Variant::Type get_return_type() { return Variant::ARRAY; } -}; - -template <class T> -class OperatorEvaluatorAppendArray { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Vector<T> &array_a = *VariantGetInternalPtr<Vector<T>>::get_ptr(&p_left); - const Vector<T> &array_b = *VariantGetInternalPtr<Vector<T>>::get_ptr(&p_right); - Vector<T> sum = array_a; - sum.append_array(array_b); - *r_ret = sum; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<Vector<T>>::change(r_ret); - *VariantGetInternalPtr<Vector<T>>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector<T>>::get_ptr(left); - VariantGetInternalPtr<Vector<T>>::get_ptr(r_ret)->append_array(*VariantGetInternalPtr<Vector<T>>::get_ptr(right)); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - Vector<T> sum = PtrToArg<Vector<T>>::convert(left); - sum.append_array(PtrToArg<Vector<T>>::convert(right)); - PtrToArg<Vector<T>>::encode(sum, r_ret); - } - static Variant::Type get_return_type() { return GetTypeInfo<Vector<T>>::VARIANT_TYPE; } -}; - -class OperatorEvaluatorStringModNil { -public: - _FORCE_INLINE_ static String do_mod(const String &s, bool *r_valid) { - Array values; - values.push_back(Variant()); - - String a = s.sprintf(values, r_valid); - if (r_valid) { - *r_valid = !*r_valid; - } - return a; - } - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - *r_ret = do_mod(a, &r_valid); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<String>::change(r_ret); - *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), nullptr); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), nullptr), r_ret); - } - static Variant::Type get_return_type() { return Variant::STRING; } -}; - -class OperatorEvaluatorStringModArray { -public: - _FORCE_INLINE_ static String do_mod(const String &s, const Array &p_values, bool *r_valid) { - String a = s.sprintf(p_values, r_valid); - if (r_valid) { - *r_valid = !*r_valid; - } - return a; - } - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - *r_ret = do_mod(a, *VariantGetInternalPtr<Array>::get_ptr(&p_right), &r_valid); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<String>::change(r_ret); - *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right), nullptr); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Array>::convert(right), nullptr), r_ret); - } - static Variant::Type get_return_type() { return Variant::STRING; } -}; - -class OperatorEvaluatorStringModObject { -public: - _FORCE_INLINE_ static String do_mod(const String &s, const Object *p_object, bool *r_valid) { - Array values; - values.push_back(p_object); - String a = s.sprintf(values, r_valid); - if (r_valid) { - *r_valid = !*r_valid; - } - - return a; - } - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - *r_ret = do_mod(a, p_right.get_validated_object(), &r_valid); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<String>::change(r_ret); - *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), right->get_validated_object(), nullptr); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Object *>::convert(right), nullptr), r_ret); - } - static Variant::Type get_return_type() { return Variant::STRING; } -}; - -template <class T> -class OperatorEvaluatorStringModT { -public: - _FORCE_INLINE_ static String do_mod(const String &s, const T &p_value, bool *r_valid) { - Array values; - values.push_back(p_value); - String a = s.sprintf(values, r_valid); - if (r_valid) { - *r_valid = !*r_valid; - } - return a; - } - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - *r_ret = do_mod(a, *VariantGetInternalPtr<T>::get_ptr(&p_right), &r_valid); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<String>::change(r_ret); - *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<T>::get_ptr(right), nullptr); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<T>::convert(right), nullptr), r_ret); - } - static Variant::Type get_return_type() { return Variant::STRING; } -}; - -template <Variant::Operator op, Variant::Type type_left, Variant::Type type_right> -class OperatorEvaluatorAlwaysTrue { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - *r_ret = true; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = true; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(true, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <Variant::Operator op, Variant::Type type_left, Variant::Type type_right> -class OperatorEvaluatorAlwaysFalse { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - *r_ret = false; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = false; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(false, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -///// OR /////// - -_FORCE_INLINE_ static bool _operate_or(bool p_left, bool p_right) { - return p_left || p_right; -} - -_FORCE_INLINE_ static bool _operate_and(bool p_left, bool p_right) { - return p_left && p_right; -} - -_FORCE_INLINE_ static bool _operate_xor(bool p_left, bool p_right) { - return (p_left || p_right) && !(p_left && p_right); -} - -_FORCE_INLINE_ static bool _operate_get_nil(const Variant *p_ptr) { - return p_ptr->get_validated_object() != nullptr; -} - -_FORCE_INLINE_ static bool _operate_get_bool(const Variant *p_ptr) { - return *VariantGetInternalPtr<bool>::get_ptr(p_ptr); -} - -_FORCE_INLINE_ static bool _operate_get_int(const Variant *p_ptr) { - return *VariantGetInternalPtr<int64_t>::get_ptr(p_ptr) != 0; -} - -_FORCE_INLINE_ static bool _operate_get_float(const Variant *p_ptr) { - return *VariantGetInternalPtr<double>::get_ptr(p_ptr) != 0.0; -} - -_FORCE_INLINE_ static bool _operate_get_object(const Variant *p_ptr) { - return p_ptr->get_validated_object() != nullptr; -} - -_FORCE_INLINE_ static bool _operate_get_ptr_nil(const void *p_ptr) { - return false; -} - -_FORCE_INLINE_ static bool _operate_get_ptr_bool(const void *p_ptr) { - return PtrToArg<bool>::convert(p_ptr); -} - -_FORCE_INLINE_ static bool _operate_get_ptr_int(const void *p_ptr) { - return PtrToArg<int64_t>::convert(p_ptr) != 0; -} - -_FORCE_INLINE_ static bool _operate_get_ptr_float(const void *p_ptr) { - return PtrToArg<double>::convert(p_ptr) != 0.0; -} - -_FORCE_INLINE_ static bool _operate_get_ptr_object(const void *p_ptr) { - return PtrToArg<Object *>::convert(p_ptr) != nullptr; -} - -#define OP_EVALUATOR(m_class_name, m_left, m_right, m_op) \ - class m_class_name { \ - public: \ - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { \ - *r_ret = m_op(_operate_get_##m_left(&p_left), _operate_get_##m_right(&p_right)); \ - r_valid = true; \ - } \ - \ - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { \ - VariantTypeChanger<bool>::change(r_ret); \ - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = m_op(_operate_get_##m_left(left), _operate_get_##m_right(right)); \ - } \ - \ - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { \ - PtrToArg<bool>::encode(m_op(_operate_get_ptr_##m_left(left), _operate_get_ptr_##m_right(right)), r_ret); \ - } \ - \ - static Variant::Type get_return_type() { \ - return Variant::BOOL; \ - } \ - }; - -// OR - -// nil -OP_EVALUATOR(OperatorEvaluatorNilXBoolOr, nil, bool, _operate_or) -OP_EVALUATOR(OperatorEvaluatorBoolXNilOr, bool, nil, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorNilXIntOr, nil, int, _operate_or) -OP_EVALUATOR(OperatorEvaluatorIntXNilOr, int, nil, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorNilXFloatOr, nil, float, _operate_or) -OP_EVALUATOR(OperatorEvaluatorFloatXNilOr, float, nil, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorObjectXNilOr, object, nil, _operate_or) -OP_EVALUATOR(OperatorEvaluatorNilXObjectOr, nil, object, _operate_or) - -// bool -OP_EVALUATOR(OperatorEvaluatorBoolXBoolOr, bool, bool, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorBoolXIntOr, bool, int, _operate_or) -OP_EVALUATOR(OperatorEvaluatorIntXBoolOr, int, bool, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorBoolXFloatOr, bool, float, _operate_or) -OP_EVALUATOR(OperatorEvaluatorFloatXBoolOr, float, bool, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorBoolXObjectOr, bool, object, _operate_or) -OP_EVALUATOR(OperatorEvaluatorObjectXBoolOr, object, bool, _operate_or) - -// int -OP_EVALUATOR(OperatorEvaluatorIntXIntOr, int, int, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorIntXFloatOr, int, float, _operate_or) -OP_EVALUATOR(OperatorEvaluatorFloatXIntOr, float, int, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorIntXObjectOr, int, object, _operate_or) -OP_EVALUATOR(OperatorEvaluatorObjectXIntOr, object, int, _operate_or) - -// float -OP_EVALUATOR(OperatorEvaluatorFloatXFloatOr, float, float, _operate_or) - -OP_EVALUATOR(OperatorEvaluatorFloatXObjectOr, float, object, _operate_or) -OP_EVALUATOR(OperatorEvaluatorObjectXFloatOr, object, float, _operate_or) - -// object -OP_EVALUATOR(OperatorEvaluatorObjectXObjectOr, object, object, _operate_or) - -// AND - -// nil -OP_EVALUATOR(OperatorEvaluatorNilXBoolAnd, nil, bool, _operate_and) -OP_EVALUATOR(OperatorEvaluatorBoolXNilAnd, bool, nil, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorNilXIntAnd, nil, int, _operate_and) -OP_EVALUATOR(OperatorEvaluatorIntXNilAnd, int, nil, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorNilXFloatAnd, nil, float, _operate_and) -OP_EVALUATOR(OperatorEvaluatorFloatXNilAnd, float, nil, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorObjectXNilAnd, object, nil, _operate_and) -OP_EVALUATOR(OperatorEvaluatorNilXObjectAnd, nil, object, _operate_and) - -// bool -OP_EVALUATOR(OperatorEvaluatorBoolXBoolAnd, bool, bool, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorBoolXIntAnd, bool, int, _operate_and) -OP_EVALUATOR(OperatorEvaluatorIntXBoolAnd, int, bool, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorBoolXFloatAnd, bool, float, _operate_and) -OP_EVALUATOR(OperatorEvaluatorFloatXBoolAnd, float, bool, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorBoolXObjectAnd, bool, object, _operate_and) -OP_EVALUATOR(OperatorEvaluatorObjectXBoolAnd, object, bool, _operate_and) - -// int -OP_EVALUATOR(OperatorEvaluatorIntXIntAnd, int, int, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorIntXFloatAnd, int, float, _operate_and) -OP_EVALUATOR(OperatorEvaluatorFloatXIntAnd, float, int, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorIntXObjectAnd, int, object, _operate_and) -OP_EVALUATOR(OperatorEvaluatorObjectXIntAnd, object, int, _operate_and) - -// float -OP_EVALUATOR(OperatorEvaluatorFloatXFloatAnd, float, float, _operate_and) - -OP_EVALUATOR(OperatorEvaluatorFloatXObjectAnd, float, object, _operate_and) -OP_EVALUATOR(OperatorEvaluatorObjectXFloatAnd, object, float, _operate_and) - -// object -OP_EVALUATOR(OperatorEvaluatorObjectXObjectAnd, object, object, _operate_and) - -// XOR - -// nil -OP_EVALUATOR(OperatorEvaluatorNilXBoolXor, nil, bool, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorBoolXNilXor, bool, nil, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorNilXIntXor, nil, int, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorIntXNilXor, int, nil, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorNilXFloatXor, nil, float, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorFloatXNilXor, float, nil, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorObjectXNilXor, object, nil, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorNilXObjectXor, nil, object, _operate_xor) - -// bool -OP_EVALUATOR(OperatorEvaluatorBoolXBoolXor, bool, bool, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorBoolXIntXor, bool, int, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorIntXBoolXor, int, bool, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorBoolXFloatXor, bool, float, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorFloatXBoolXor, float, bool, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorBoolXObjectXor, bool, object, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorObjectXBoolXor, object, bool, _operate_xor) - -// int -OP_EVALUATOR(OperatorEvaluatorIntXIntXor, int, int, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorIntXFloatXor, int, float, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorFloatXIntXor, float, int, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorIntXObjectXor, int, object, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorObjectXIntXor, object, int, _operate_xor) - -// float -OP_EVALUATOR(OperatorEvaluatorFloatXFloatXor, float, float, _operate_xor) - -OP_EVALUATOR(OperatorEvaluatorFloatXObjectXor, float, object, _operate_xor) -OP_EVALUATOR(OperatorEvaluatorObjectXFloatXor, object, float, _operate_xor) - -// object -OP_EVALUATOR(OperatorEvaluatorObjectXObjectXor, object, object, _operate_xor) - -class OperatorEvaluatorNotBool { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - *r_ret = !*VariantGetInternalPtr<bool>::get_ptr(&p_left); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<bool>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(!PtrToArg<bool>::convert(left), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorNotInt { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - *r_ret = !*VariantGetInternalPtr<int64_t>::get_ptr(&p_left); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<int64_t>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(!PtrToArg<int64_t>::convert(left), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorNotFloat { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - *r_ret = !*VariantGetInternalPtr<double>::get_ptr(&p_left); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<double>::get_ptr(left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(!PtrToArg<double>::convert(left), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorNotObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - *r_ret = p_left.get_validated_object() == nullptr; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = left->get_validated_object() == nullptr; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == nullptr, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -//// - -class OperatorEvaluatorInStringFind { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const String &str_a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - const String &str_b = *VariantGetInternalPtr<String>::get_ptr(&p_right); - - *r_ret = str_b.find(str_a) != -1; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const String &str_a = *VariantGetInternalPtr<String>::get_ptr(left); - const String &str_b = *VariantGetInternalPtr<String>::get_ptr(right); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = str_b.find(str_a) != -1; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<String>::convert(right).find(PtrToArg<String>::convert(left)) != -1, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A, class B> -class OperatorEvaluatorInArrayFind { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); - - *r_ret = b.find(a) != -1; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const A &a = *VariantGetInternalPtr<A>::get_ptr(left); - const B &b = *VariantGetInternalPtr<B>::get_ptr(right); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(a) != -1; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<B>::convert(right).find(PtrToArg<A>::convert(left)) != -1, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorInArrayFindNil { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Array &b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); - *r_ret = b.find(Variant()) != -1; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Array &b = *VariantGetInternalPtr<Array>::get_ptr(right); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(Variant()) != -1; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Array>::convert(right).find(Variant()) != -1, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorInArrayFindObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Array &b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); - *r_ret = b.find(p_left) != -1; - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Array &b = *VariantGetInternalPtr<Array>::get_ptr(right); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(*left) != -1; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Array>::convert(right).find(PtrToArg<Object *>::convert(left)) != -1, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -template <class A> -class OperatorEvaluatorInDictionaryHas { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); - const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); - - *r_ret = b.has(a); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); - const A &a = *VariantGetInternalPtr<A>::get_ptr(left); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(a); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(PtrToArg<A>::convert(left)), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorInDictionaryHasNil { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); - - *r_ret = b.has(Variant()); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(Variant()); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(Variant()), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorInDictionaryHasObject { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); - - *r_ret = b.has(p_left); - r_valid = true; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(*left); - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(PtrToArg<Object *>::convert(left)), r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorObjectHasPropertyString { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - Object *b = p_right.get_validated_object(); - if (!b) { - *r_ret = "Invalid base object for 'in'"; - r_valid = false; - return; - } - - const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); - - b->get(a, &r_valid); - *r_ret = r_valid; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - Object *l = right->get_validated_object(); - ERR_FAIL_COND(l == nullptr); - const String &a = *VariantGetInternalPtr<String>::get_ptr(left); - - bool valid; - l->get(a, &valid); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - bool valid; - PtrToArg<Object *>::convert(right)->get(PtrToArg<String>::convert(left), &valid); - PtrToArg<bool>::encode(valid, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; - -class OperatorEvaluatorObjectHasPropertyStringName { -public: - static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { - Object *b = p_right.get_validated_object(); - if (!b) { - *r_ret = "Invalid base object for 'in'"; - r_valid = false; - return; - } - - const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(&p_left); - - b->get(a, &r_valid); - *r_ret = r_valid; - } - static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { - Object *l = right->get_validated_object(); - ERR_FAIL_COND(l == nullptr); - const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(left); - - bool valid; - l->get(a, &valid); - VariantTypeChanger<bool>::change(r_ret); - *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid; - } - static void ptr_evaluate(const void *left, const void *right, void *r_ret) { - bool valid; - PtrToArg<Object *>::convert(right)->get(PtrToArg<StringName>::convert(left), &valid); - PtrToArg<bool>::encode(valid, r_ret); - } - static Variant::Type get_return_type() { return Variant::BOOL; } -}; +#include "variant_op.h" typedef void (*VariantEvaluatorFunction)(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid); @@ -1458,6 +123,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorMul<Color, Color, double>>(Variant::OP_MULTIPLY, Variant::COLOR, Variant::FLOAT); register_op<OperatorEvaluatorMul<Transform2D, Transform2D, Transform2D>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::TRANSFORM2D); + register_op<OperatorEvaluatorMul<Transform2D, Transform2D, int64_t>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::INT); + register_op<OperatorEvaluatorMul<Transform2D, Transform2D, double>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::FLOAT); register_op<OperatorEvaluatorXForm<Vector2, Transform2D, Vector2>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::VECTOR2); register_op<OperatorEvaluatorXFormInv<Vector2, Vector2, Transform2D>>(Variant::OP_MULTIPLY, Variant::VECTOR2, Variant::TRANSFORM2D); register_op<OperatorEvaluatorXForm<Rect2, Transform2D, Rect2>>(Variant::OP_MULTIPLY, Variant::TRANSFORM2D, Variant::RECT2); @@ -1466,6 +133,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorXFormInv<Vector<Vector2>, Vector<Vector2>, Transform2D>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR2_ARRAY, Variant::TRANSFORM2D); register_op<OperatorEvaluatorMul<Transform3D, Transform3D, Transform3D>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorMul<Transform3D, Transform3D, int64_t>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::INT); + register_op<OperatorEvaluatorMul<Transform3D, Transform3D, double>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::FLOAT); register_op<OperatorEvaluatorXForm<Vector3, Transform3D, Vector3>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::VECTOR3); register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Transform3D>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::TRANSFORM3D); register_op<OperatorEvaluatorXForm<::AABB, Transform3D, ::AABB>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::AABB); @@ -1474,6 +143,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorXFormInv<Vector<Vector3>, Vector<Vector3>, Transform3D>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR3_ARRAY, Variant::TRANSFORM3D); register_op<OperatorEvaluatorMul<Basis, Basis, Basis>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::BASIS); + register_op<OperatorEvaluatorMul<Basis, Basis, int64_t>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::INT); + register_op<OperatorEvaluatorMul<Basis, Basis, double>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::FLOAT); register_op<OperatorEvaluatorXForm<Vector3, Basis, Vector3>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::VECTOR3); register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Basis>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::BASIS); diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h new file mode 100644 index 0000000000..e744e76ea3 --- /dev/null +++ b/core/variant/variant_op.h @@ -0,0 +1,1316 @@ +/*************************************************************************/ +/* variant_op.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 VARIANT_OP_H +#define VARIANT_OP_H + +#include "variant.h" + +#include "core/core_string_names.h" +#include "core/debugger/engine_debugger.h" +#include "core/object/class_db.h" + +template <class R, class A, class B> +class OperatorEvaluatorAdd { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a + b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) + *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) + PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorSub { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a - b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) - *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) - PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorMul { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a * b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) * *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) * PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorXForm { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a.xform(b); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = VariantGetInternalPtr<A>::get_ptr(left)->xform(*VariantGetInternalPtr<B>::get_ptr(right)); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left).xform(PtrToArg<B>::convert(right)), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorXFormInv { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = b.xform_inv(a); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = VariantGetInternalPtr<B>::get_ptr(right)->xform_inv(*VariantGetInternalPtr<A>::get_ptr(left)); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<B>::convert(right).xform_inv(PtrToArg<A>::convert(left)), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorDiv { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a / b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) / *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) / PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorDivNZ { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + if (b == 0) { + r_valid = false; + *r_ret = "Division by zero error"; + return; + } + *r_ret = a / b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) / *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) / PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorMod { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a % b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) % *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) % PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorModNZ { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + if (b == 0) { + r_valid = false; + *r_ret = "Module by zero error"; + return; + } + *r_ret = a % b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) % *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) % PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A> +class OperatorEvaluatorNeg { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + *r_ret = -a; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = -*VariantGetInternalPtr<A>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(-PtrToArg<A>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A> +class OperatorEvaluatorPos { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + *r_ret = a; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorShiftLeft { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + +#if defined(DEBUG_ENABLED) + if (b < 0 || a < 0) { + *r_ret = "Invalid operands for bit shifting. Only positive operands are supported."; + r_valid = false; + return; + } +#endif + *r_ret = a << b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) << *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) << PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorShiftRight { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + +#if defined(DEBUG_ENABLED) + if (b < 0 || a < 0) { + *r_ret = "Invalid operands for bit shifting. Only positive operands are supported."; + r_valid = false; + return; + } +#endif + *r_ret = a >> b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) >> *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) >> PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorBitOr { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a | b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) | *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) | PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorBitAnd { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a & b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) & *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) & PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A, class B> +class OperatorEvaluatorBitXor { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a ^ b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) ^ *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(PtrToArg<A>::convert(left) ^ PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class R, class A> +class OperatorEvaluatorBitNeg { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + *r_ret = ~a; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<R>::get_ptr(r_ret) = ~*VariantGetInternalPtr<A>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<R>::encode(~PtrToArg<A>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; } +}; + +template <class A, class B> +class OperatorEvaluatorEqual { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a == b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) == *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) == PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorEqualObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Object *a = p_left.get_validated_object(); + const Object *b = p_right.get_validated_object(); + *r_ret = a == b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Object *a = left->get_validated_object(); + const Object *b = right->get_validated_object(); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == b; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == PtrToArg<Object *>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorEqualObjectNil { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Object *a = p_left.get_validated_object(); + *r_ret = a == nullptr; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Object *a = left->get_validated_object(); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == nullptr; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == nullptr, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorEqualNilObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Object *b = p_right.get_validated_object(); + *r_ret = nullptr == b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Object *b = right->get_validated_object(); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr == b; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(nullptr == PtrToArg<Object *>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorNotEqual { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a != b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) != *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) != PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotEqualObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *a = p_left.get_validated_object(); + Object *b = p_right.get_validated_object(); + *r_ret = a != b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *a = left->get_validated_object(); + Object *b = right->get_validated_object(); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != b; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) != PtrToArg<Object *>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotEqualObjectNil { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *a = p_left.get_validated_object(); + *r_ret = a != nullptr; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *a = left->get_validated_object(); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != nullptr; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) != nullptr, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotEqualNilObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *b = p_right.get_validated_object(); + *r_ret = nullptr != b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *b = right->get_validated_object(); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr != b; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(nullptr != PtrToArg<Object *>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorLess { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a < b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) < *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) < PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorLessEqual { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a <= b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) <= *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) <= PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorGreater { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a > b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) > *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) > PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorGreaterEqual { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a >= b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) >= *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) >= PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorAnd { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a && b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) && *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) && PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorOr { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = a || b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) || *VariantGetInternalPtr<B>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<A>::convert(left) || PtrToArg<B>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +#define XOR_OP(m_a, m_b) (((m_a) || (m_b)) && !((m_a) && (m_b))) +template <class A, class B> +class OperatorEvaluatorXor { +public: + _FORCE_INLINE_ static bool xor_op(const A &a, const B &b) { + return ((a) || (b)) && !((a) && (b)); + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + *r_ret = xor_op(a, b); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = xor_op(*VariantGetInternalPtr<A>::get_ptr(left), *VariantGetInternalPtr<B>::get_ptr(right)); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(xor_op(PtrToArg<A>::convert(left), PtrToArg<B>::convert(right)), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A> +class OperatorEvaluatorNot { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + *r_ret = !a; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<A>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(!PtrToArg<A>::convert(left)); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +//// CUSTOM //// + +class OperatorEvaluatorAddArray { +public: + _FORCE_INLINE_ static void _add_arrays(Array &sum, const Array &array_a, const Array &array_b) { + int asize = array_a.size(); + int bsize = array_b.size(); + sum.resize(asize + bsize); + for (int i = 0; i < asize; i++) { + sum[i] = array_a[i]; + } + for (int i = 0; i < bsize; i++) { + sum[i + asize] = array_b[i]; + } + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Array &array_a = *VariantGetInternalPtr<Array>::get_ptr(&p_left); + const Array &array_b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); + Array sum; + _add_arrays(sum, array_a, array_b); + *r_ret = sum; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + _add_arrays(*VariantGetInternalPtr<Array>::get_ptr(r_ret), *VariantGetInternalPtr<Array>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right)); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + Array ret; + _add_arrays(ret, PtrToArg<Array>::convert(left), PtrToArg<Array>::convert(right)); + PtrToArg<Array>::encode(ret, r_ret); + } + static Variant::Type get_return_type() { return Variant::ARRAY; } +}; + +template <class T> +class OperatorEvaluatorAppendArray { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector<T> &array_a = *VariantGetInternalPtr<Vector<T>>::get_ptr(&p_left); + const Vector<T> &array_b = *VariantGetInternalPtr<Vector<T>>::get_ptr(&p_right); + Vector<T> sum = array_a; + sum.append_array(array_b); + *r_ret = sum; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<Vector<T>>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector<T>>::get_ptr(left); + VariantGetInternalPtr<Vector<T>>::get_ptr(r_ret)->append_array(*VariantGetInternalPtr<Vector<T>>::get_ptr(right)); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + Vector<T> sum = PtrToArg<Vector<T>>::convert(left); + sum.append_array(PtrToArg<Vector<T>>::convert(right)); + PtrToArg<Vector<T>>::encode(sum, r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector<T>>::VARIANT_TYPE; } +}; + +class OperatorEvaluatorStringModNil { +public: + _FORCE_INLINE_ static String do_mod(const String &s, bool *r_valid) { + Array values; + values.push_back(Variant()); + + String a = s.sprintf(values, r_valid); + if (r_valid) { + *r_valid = !*r_valid; + } + return a; + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + *r_ret = do_mod(a, &r_valid); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), nullptr); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), nullptr), r_ret); + } + static Variant::Type get_return_type() { return Variant::STRING; } +}; + +class OperatorEvaluatorStringModArray { +public: + _FORCE_INLINE_ static String do_mod(const String &s, const Array &p_values, bool *r_valid) { + String a = s.sprintf(p_values, r_valid); + if (r_valid) { + *r_valid = !*r_valid; + } + return a; + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + *r_ret = do_mod(a, *VariantGetInternalPtr<Array>::get_ptr(&p_right), &r_valid); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right), nullptr); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Array>::convert(right), nullptr), r_ret); + } + static Variant::Type get_return_type() { return Variant::STRING; } +}; + +class OperatorEvaluatorStringModObject { +public: + _FORCE_INLINE_ static String do_mod(const String &s, const Object *p_object, bool *r_valid) { + Array values; + values.push_back(p_object); + String a = s.sprintf(values, r_valid); + if (r_valid) { + *r_valid = !*r_valid; + } + + return a; + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + *r_ret = do_mod(a, p_right.get_validated_object(), &r_valid); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), right->get_validated_object(), nullptr); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<Object *>::convert(right), nullptr), r_ret); + } + static Variant::Type get_return_type() { return Variant::STRING; } +}; + +template <class T> +class OperatorEvaluatorStringModT { +public: + _FORCE_INLINE_ static String do_mod(const String &s, const T &p_value, bool *r_valid) { + Array values; + values.push_back(p_value); + String a = s.sprintf(values, r_valid); + if (r_valid) { + *r_valid = !*r_valid; + } + return a; + } + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + *r_ret = do_mod(a, *VariantGetInternalPtr<T>::get_ptr(&p_right), &r_valid); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<T>::get_ptr(right), nullptr); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<String>::encode(do_mod(PtrToArg<String>::convert(left), PtrToArg<T>::convert(right), nullptr), r_ret); + } + static Variant::Type get_return_type() { return Variant::STRING; } +}; + +template <Variant::Operator op, Variant::Type type_left, Variant::Type type_right> +class OperatorEvaluatorAlwaysTrue { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = true; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = true; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(true, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <Variant::Operator op, Variant::Type type_left, Variant::Type type_right> +class OperatorEvaluatorAlwaysFalse { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = false; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = false; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(false, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +///// OR /////// + +_FORCE_INLINE_ static bool _operate_or(bool p_left, bool p_right) { + return p_left || p_right; +} + +_FORCE_INLINE_ static bool _operate_and(bool p_left, bool p_right) { + return p_left && p_right; +} + +_FORCE_INLINE_ static bool _operate_xor(bool p_left, bool p_right) { + return (p_left || p_right) && !(p_left && p_right); +} + +_FORCE_INLINE_ static bool _operate_get_nil(const Variant *p_ptr) { + return p_ptr->get_validated_object() != nullptr; +} + +_FORCE_INLINE_ static bool _operate_get_bool(const Variant *p_ptr) { + return *VariantGetInternalPtr<bool>::get_ptr(p_ptr); +} + +_FORCE_INLINE_ static bool _operate_get_int(const Variant *p_ptr) { + return *VariantGetInternalPtr<int64_t>::get_ptr(p_ptr) != 0; +} + +_FORCE_INLINE_ static bool _operate_get_float(const Variant *p_ptr) { + return *VariantGetInternalPtr<double>::get_ptr(p_ptr) != 0.0; +} + +_FORCE_INLINE_ static bool _operate_get_object(const Variant *p_ptr) { + return p_ptr->get_validated_object() != nullptr; +} + +_FORCE_INLINE_ static bool _operate_get_ptr_nil(const void *p_ptr) { + return false; +} + +_FORCE_INLINE_ static bool _operate_get_ptr_bool(const void *p_ptr) { + return PtrToArg<bool>::convert(p_ptr); +} + +_FORCE_INLINE_ static bool _operate_get_ptr_int(const void *p_ptr) { + return PtrToArg<int64_t>::convert(p_ptr) != 0; +} + +_FORCE_INLINE_ static bool _operate_get_ptr_float(const void *p_ptr) { + return PtrToArg<double>::convert(p_ptr) != 0.0; +} + +_FORCE_INLINE_ static bool _operate_get_ptr_object(const void *p_ptr) { + return PtrToArg<Object *>::convert(p_ptr) != nullptr; +} + +#define OP_EVALUATOR(m_class_name, m_left, m_right, m_op) \ + class m_class_name { \ + public: \ + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { \ + *r_ret = m_op(_operate_get_##m_left(&p_left), _operate_get_##m_right(&p_right)); \ + r_valid = true; \ + } \ + \ + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { \ + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = m_op(_operate_get_##m_left(left), _operate_get_##m_right(right)); \ + } \ + \ + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { \ + PtrToArg<bool>::encode(m_op(_operate_get_ptr_##m_left(left), _operate_get_ptr_##m_right(right)), r_ret); \ + } \ + \ + static Variant::Type get_return_type() { \ + return Variant::BOOL; \ + } \ + }; + +// OR + +// nil +OP_EVALUATOR(OperatorEvaluatorNilXBoolOr, nil, bool, _operate_or) +OP_EVALUATOR(OperatorEvaluatorBoolXNilOr, bool, nil, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorNilXIntOr, nil, int, _operate_or) +OP_EVALUATOR(OperatorEvaluatorIntXNilOr, int, nil, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorNilXFloatOr, nil, float, _operate_or) +OP_EVALUATOR(OperatorEvaluatorFloatXNilOr, float, nil, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorObjectXNilOr, object, nil, _operate_or) +OP_EVALUATOR(OperatorEvaluatorNilXObjectOr, nil, object, _operate_or) + +// bool +OP_EVALUATOR(OperatorEvaluatorBoolXBoolOr, bool, bool, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorBoolXIntOr, bool, int, _operate_or) +OP_EVALUATOR(OperatorEvaluatorIntXBoolOr, int, bool, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorBoolXFloatOr, bool, float, _operate_or) +OP_EVALUATOR(OperatorEvaluatorFloatXBoolOr, float, bool, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorBoolXObjectOr, bool, object, _operate_or) +OP_EVALUATOR(OperatorEvaluatorObjectXBoolOr, object, bool, _operate_or) + +// int +OP_EVALUATOR(OperatorEvaluatorIntXIntOr, int, int, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorIntXFloatOr, int, float, _operate_or) +OP_EVALUATOR(OperatorEvaluatorFloatXIntOr, float, int, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorIntXObjectOr, int, object, _operate_or) +OP_EVALUATOR(OperatorEvaluatorObjectXIntOr, object, int, _operate_or) + +// float +OP_EVALUATOR(OperatorEvaluatorFloatXFloatOr, float, float, _operate_or) + +OP_EVALUATOR(OperatorEvaluatorFloatXObjectOr, float, object, _operate_or) +OP_EVALUATOR(OperatorEvaluatorObjectXFloatOr, object, float, _operate_or) + +// object +OP_EVALUATOR(OperatorEvaluatorObjectXObjectOr, object, object, _operate_or) + +// AND + +// nil +OP_EVALUATOR(OperatorEvaluatorNilXBoolAnd, nil, bool, _operate_and) +OP_EVALUATOR(OperatorEvaluatorBoolXNilAnd, bool, nil, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorNilXIntAnd, nil, int, _operate_and) +OP_EVALUATOR(OperatorEvaluatorIntXNilAnd, int, nil, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorNilXFloatAnd, nil, float, _operate_and) +OP_EVALUATOR(OperatorEvaluatorFloatXNilAnd, float, nil, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorObjectXNilAnd, object, nil, _operate_and) +OP_EVALUATOR(OperatorEvaluatorNilXObjectAnd, nil, object, _operate_and) + +// bool +OP_EVALUATOR(OperatorEvaluatorBoolXBoolAnd, bool, bool, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorBoolXIntAnd, bool, int, _operate_and) +OP_EVALUATOR(OperatorEvaluatorIntXBoolAnd, int, bool, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorBoolXFloatAnd, bool, float, _operate_and) +OP_EVALUATOR(OperatorEvaluatorFloatXBoolAnd, float, bool, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorBoolXObjectAnd, bool, object, _operate_and) +OP_EVALUATOR(OperatorEvaluatorObjectXBoolAnd, object, bool, _operate_and) + +// int +OP_EVALUATOR(OperatorEvaluatorIntXIntAnd, int, int, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorIntXFloatAnd, int, float, _operate_and) +OP_EVALUATOR(OperatorEvaluatorFloatXIntAnd, float, int, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorIntXObjectAnd, int, object, _operate_and) +OP_EVALUATOR(OperatorEvaluatorObjectXIntAnd, object, int, _operate_and) + +// float +OP_EVALUATOR(OperatorEvaluatorFloatXFloatAnd, float, float, _operate_and) + +OP_EVALUATOR(OperatorEvaluatorFloatXObjectAnd, float, object, _operate_and) +OP_EVALUATOR(OperatorEvaluatorObjectXFloatAnd, object, float, _operate_and) + +// object +OP_EVALUATOR(OperatorEvaluatorObjectXObjectAnd, object, object, _operate_and) + +// XOR + +// nil +OP_EVALUATOR(OperatorEvaluatorNilXBoolXor, nil, bool, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorBoolXNilXor, bool, nil, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorNilXIntXor, nil, int, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorIntXNilXor, int, nil, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorNilXFloatXor, nil, float, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorFloatXNilXor, float, nil, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorObjectXNilXor, object, nil, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorNilXObjectXor, nil, object, _operate_xor) + +// bool +OP_EVALUATOR(OperatorEvaluatorBoolXBoolXor, bool, bool, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorBoolXIntXor, bool, int, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorIntXBoolXor, int, bool, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorBoolXFloatXor, bool, float, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorFloatXBoolXor, float, bool, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorBoolXObjectXor, bool, object, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorObjectXBoolXor, object, bool, _operate_xor) + +// int +OP_EVALUATOR(OperatorEvaluatorIntXIntXor, int, int, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorIntXFloatXor, int, float, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorFloatXIntXor, float, int, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorIntXObjectXor, int, object, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorObjectXIntXor, object, int, _operate_xor) + +// float +OP_EVALUATOR(OperatorEvaluatorFloatXFloatXor, float, float, _operate_xor) + +OP_EVALUATOR(OperatorEvaluatorFloatXObjectXor, float, object, _operate_xor) +OP_EVALUATOR(OperatorEvaluatorObjectXFloatXor, object, float, _operate_xor) + +// object +OP_EVALUATOR(OperatorEvaluatorObjectXObjectXor, object, object, _operate_xor) + +class OperatorEvaluatorNotBool { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = !*VariantGetInternalPtr<bool>::get_ptr(&p_left); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<bool>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(!PtrToArg<bool>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotInt { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = !*VariantGetInternalPtr<int64_t>::get_ptr(&p_left); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<int64_t>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(!PtrToArg<int64_t>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotFloat { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = !*VariantGetInternalPtr<double>::get_ptr(&p_left); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<double>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(!PtrToArg<double>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorNotObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + *r_ret = p_left.get_validated_object() == nullptr; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = left->get_validated_object() == nullptr; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Object *>::convert(left) == nullptr, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +//// + +class OperatorEvaluatorInStringFind { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const String &str_a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + const String &str_b = *VariantGetInternalPtr<String>::get_ptr(&p_right); + + *r_ret = str_b.find(str_a) != -1; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const String &str_a = *VariantGetInternalPtr<String>::get_ptr(left); + const String &str_b = *VariantGetInternalPtr<String>::get_ptr(right); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = str_b.find(str_a) != -1; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<String>::convert(right).find(PtrToArg<String>::convert(left)) != -1, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A, class B> +class OperatorEvaluatorInArrayFind { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right); + + *r_ret = b.find(a) != -1; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const A &a = *VariantGetInternalPtr<A>::get_ptr(left); + const B &b = *VariantGetInternalPtr<B>::get_ptr(right); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(a) != -1; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<B>::convert(right).find(PtrToArg<A>::convert(left)) != -1, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorInArrayFindNil { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Array &b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); + *r_ret = b.find(Variant()) != -1; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Array &b = *VariantGetInternalPtr<Array>::get_ptr(right); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(Variant()) != -1; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Array>::convert(right).find(Variant()) != -1, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorInArrayFindObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Array &b = *VariantGetInternalPtr<Array>::get_ptr(&p_right); + *r_ret = b.find(p_left) != -1; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Array &b = *VariantGetInternalPtr<Array>::get_ptr(right); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(*left) != -1; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Array>::convert(right).find(PtrToArg<Object *>::convert(left)) != -1, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +template <class A> +class OperatorEvaluatorInDictionaryHas { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); + const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left); + + *r_ret = b.has(a); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); + const A &a = *VariantGetInternalPtr<A>::get_ptr(left); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(a); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(PtrToArg<A>::convert(left)), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorInDictionaryHasNil { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); + + *r_ret = b.has(Variant()); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(Variant()); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(Variant()), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorInDictionaryHasObject { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(&p_right); + + *r_ret = b.has(p_left); + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(*left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<bool>::encode(PtrToArg<Dictionary>::convert(right).has(PtrToArg<Object *>::convert(left)), r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorObjectHasPropertyString { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *b = p_right.get_validated_object(); + if (!b) { + *r_ret = "Invalid base object for 'in'"; + r_valid = false; + return; + } + + const String &a = *VariantGetInternalPtr<String>::get_ptr(&p_left); + + b->get(a, &r_valid); + *r_ret = r_valid; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *l = right->get_validated_object(); + ERR_FAIL_COND(l == nullptr); + const String &a = *VariantGetInternalPtr<String>::get_ptr(left); + + bool valid; + l->get(a, &valid); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + bool valid; + PtrToArg<Object *>::convert(right)->get(PtrToArg<String>::convert(left), &valid); + PtrToArg<bool>::encode(valid, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +class OperatorEvaluatorObjectHasPropertyStringName { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + Object *b = p_right.get_validated_object(); + if (!b) { + *r_ret = "Invalid base object for 'in'"; + r_valid = false; + return; + } + + const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(&p_left); + + b->get(a, &r_valid); + *r_ret = r_valid; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + Object *l = right->get_validated_object(); + ERR_FAIL_COND(l == nullptr); + const StringName &a = *VariantGetInternalPtr<StringName>::get_ptr(left); + + bool valid; + l->get(a, &valid); + *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid; + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + bool valid; + PtrToArg<Object *>::convert(right)->get(PtrToArg<StringName>::convert(left), &valid); + PtrToArg<bool>::encode(valid, r_ret); + } + static Variant::Type get_return_type() { return Variant::BOOL; } +}; + +#endif // VARIANT_OP_H diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index 751cb64c62..28930a19e2 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -1423,47 +1423,47 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; case Variant::VECTOR2: { Vector2 v = p_variant; - p_store_string_func(p_store_string_ud, "Vector2( " + rtosfix(v.x) + ", " + rtosfix(v.y) + " )"); + 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) + " )"); + 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) + " )"); + 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) + " )"); + 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) + " )"); + 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) + " )"); + 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; - p_store_string_func(p_store_string_ud, "Plane( " + rtosfix(p.normal.x) + ", " + rtosfix(p.normal.y) + ", " + rtosfix(p.normal.z) + ", " + rtosfix(p.d) + " )"); + p_store_string_func(p_store_string_ud, "Plane(" + rtosfix(p.normal.x) + ", " + rtosfix(p.normal.y) + ", " + rtosfix(p.normal.z) + ", " + rtosfix(p.d) + ")"); } break; case Variant::AABB: { AABB aabb = p_variant; - p_store_string_func(p_store_string_ud, "AABB( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + " )"); + p_store_string_func(p_store_string_ud, "AABB(" + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + ")"); } break; case Variant::QUATERNION: { Quaternion quaternion = p_variant; - p_store_string_func(p_store_string_ud, "Quaternion( " + rtosfix(quaternion.x) + ", " + rtosfix(quaternion.y) + ", " + rtosfix(quaternion.z) + ", " + rtosfix(quaternion.w) + " )"); + p_store_string_func(p_store_string_ud, "Quaternion(" + rtosfix(quaternion.x) + ", " + rtosfix(quaternion.y) + ", " + rtosfix(quaternion.z) + ", " + rtosfix(quaternion.w) + ")"); } break; case Variant::TRANSFORM2D: { - String s = "Transform2D( "; + String s = "Transform2D("; Transform2D m3 = p_variant; for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { @@ -1474,11 +1474,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } } - p_store_string_func(p_store_string_ud, s + " )"); + p_store_string_func(p_store_string_ud, s + ")"); } break; case Variant::BASIS: { - String s = "Basis( "; + String s = "Basis("; Basis m3 = p_variant; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { @@ -1489,11 +1489,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } } - p_store_string_func(p_store_string_ud, s + " )"); + p_store_string_func(p_store_string_ud, s + ")"); } break; case Variant::TRANSFORM3D: { - String s = "Transform3D( "; + String s = "Transform3D("; Transform3D t = p_variant; Basis &m3 = t.basis; for (int i = 0; i < 3; i++) { @@ -1507,13 +1507,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str s = s + ", " + rtosfix(t.origin.x) + ", " + rtosfix(t.origin.y) + ", " + rtosfix(t.origin.z); - p_store_string_func(p_store_string_ud, s + " )"); + p_store_string_func(p_store_string_ud, s + ")"); } break; // misc types case Variant::COLOR: { Color c = p_variant; - p_store_string_func(p_store_string_ud, "Color( " + rtosfix(c.r) + ", " + rtosfix(c.g) + ", " + rtosfix(c.b) + ", " + rtosfix(c.a) + " )"); + 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: { @@ -1553,7 +1553,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (res_text == String() && res->get_path().is_resource_file()) { //external resource String path = res->get_path(); - res_text = "Resource( \"" + path + "\")"; + res_text = "Resource(\"" + path + "\")"; } //could come up with some sort of text @@ -1616,7 +1616,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; case Variant::ARRAY: { - p_store_string_func(p_store_string_ud, "[ "); + p_store_string_func(p_store_string_ud, "["); Array array = p_variant; int len = array.size(); for (int i = 0; i < len; i++) { @@ -1625,12 +1625,12 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud); } - p_store_string_func(p_store_string_ud, " ]"); + p_store_string_func(p_store_string_ud, "]"); } break; case Variant::PACKED_BYTE_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedByteArray( "); + p_store_string_func(p_store_string_ud, "PackedByteArray("); String s; Vector<uint8_t> data = p_variant; int len = data.size(); @@ -1644,11 +1644,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, itos(ptr[i])); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_INT32_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedInt32Array( "); + 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(); @@ -1661,11 +1661,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, itos(ptr[i])); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_INT64_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedInt64Array( "); + 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(); @@ -1678,11 +1678,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, itos(ptr[i])); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_FLOAT32_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedFloat32Array( "); + p_store_string_func(p_store_string_ud, "PackedFloat32Array("); Vector<float> data = p_variant; int len = data.size(); const float *ptr = data.ptr(); @@ -1694,11 +1694,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, rtosfix(ptr[i])); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_FLOAT64_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedFloat64Array( "); + p_store_string_func(p_store_string_ud, "PackedFloat64Array("); Vector<double> data = p_variant; int len = data.size(); const double *ptr = data.ptr(); @@ -1710,11 +1710,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, rtosfix(ptr[i])); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_STRING_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedStringArray( "); + p_store_string_func(p_store_string_ud, "PackedStringArray("); Vector<String> data = p_variant; int len = data.size(); const String *ptr = data.ptr(); @@ -1730,11 +1730,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, "\"" + str.c_escape() + "\""); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_VECTOR2_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedVector2Array( "); + p_store_string_func(p_store_string_ud, "PackedVector2Array("); Vector<Vector2> data = p_variant; int len = data.size(); const Vector2 *ptr = data.ptr(); @@ -1746,11 +1746,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, rtosfix(ptr[i].x) + ", " + rtosfix(ptr[i].y)); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_VECTOR3_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedVector3Array( "); + p_store_string_func(p_store_string_ud, "PackedVector3Array("); Vector<Vector3> data = p_variant; int len = data.size(); const Vector3 *ptr = data.ptr(); @@ -1762,12 +1762,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, rtosfix(ptr[i].x) + ", " + rtosfix(ptr[i].y) + ", " + rtosfix(ptr[i].z)); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; case Variant::PACKED_COLOR_ARRAY: { - p_store_string_func(p_store_string_ud, "PackedColorArray( "); - + p_store_string_func(p_store_string_ud, "PackedColorArray("); Vector<Color> data = p_variant; int len = data.size(); const Color *ptr = data.ptr(); @@ -1779,7 +1778,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, rtosfix(ptr[i].r) + ", " + rtosfix(ptr[i].g) + ", " + rtosfix(ptr[i].b) + ", " + rtosfix(ptr[i].a)); } - p_store_string_func(p_store_string_ud, " )"); + p_store_string_func(p_store_string_ud, ")"); } break; default: { diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index ae2795f2fd..5cb329e69a 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -28,282 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "variant.h" - -#include "core/core_string_names.h" -#include "core/debugger/engine_debugger.h" -#include "core/object/class_db.h" -#include "core/templates/local_vector.h" -#include "core/variant/variant_internal.h" - -/**** NAMED SETTERS AND GETTERS ****/ - -#define SETGET_STRUCT(m_base_type, m_member_type, m_member) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_member = PtrToArg<m_member_type>::convert(member); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -#define SETGET_NUMBER_STRUCT(m_base_type, m_member_type, m_member) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == Variant::FLOAT) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<double>::get_ptr(value); \ - valid = true; \ - } else if (value->get_type() == Variant::INT) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<int64_t>::get_ptr(value); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_member = PtrToArg<m_member_type>::convert(member); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -#define SETGET_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_custom = PtrToArg<m_member_type>::convert(member); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -#define SETGET_NUMBER_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == Variant::FLOAT) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<double>::get_ptr(value); \ - valid = true; \ - } else if (value->get_type() == Variant::INT) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<int64_t>::get_ptr(value); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_custom = PtrToArg<m_member_type>::convert(member); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -#define SETGET_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_setter(PtrToArg<m_member_type>::convert(member)); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -#define SETGET_NUMBER_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == Variant::FLOAT) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<double>::get_ptr(value)); \ - valid = true; \ - } else if (value->get_type() == Variant::INT) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<int64_t>::get_ptr(value)); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_setter(PtrToArg<m_member_type>::convert(member)); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -#define SETGET_STRUCT_FUNC_INDEX(m_base_type, m_member_type, m_member, m_setter, m_getter, m_index) \ - struct VariantSetGet_##m_base_type##_##m_member { \ - static void get(const Variant *base, Variant *member) { \ - VariantTypeAdjust<m_member_type>::adjust(member); \ - *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \ - } \ - static void ptr_get(const void *base, void *member) { \ - PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(m_index), member); \ - } \ - static void set(Variant *base, const Variant *value, bool &valid) { \ - if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ - valid = true; \ - } else { \ - valid = false; \ - } \ - } \ - static void validated_set(Variant *base, const Variant *value) { \ - VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ - } \ - static void ptr_set(void *base, const void *member) { \ - m_base_type b = PtrToArg<m_base_type>::convert(base); \ - b.m_setter(m_index, PtrToArg<m_member_type>::convert(member)); \ - PtrToArg<m_base_type>::encode(b, base); \ - } \ - static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ - }; - -SETGET_NUMBER_STRUCT(Vector2, double, x) -SETGET_NUMBER_STRUCT(Vector2, double, y) - -SETGET_NUMBER_STRUCT(Vector2i, int64_t, x) -SETGET_NUMBER_STRUCT(Vector2i, int64_t, y) - -SETGET_NUMBER_STRUCT(Vector3, double, x) -SETGET_NUMBER_STRUCT(Vector3, double, y) -SETGET_NUMBER_STRUCT(Vector3, double, z) - -SETGET_NUMBER_STRUCT(Vector3i, int64_t, x) -SETGET_NUMBER_STRUCT(Vector3i, int64_t, y) -SETGET_NUMBER_STRUCT(Vector3i, int64_t, z) - -SETGET_STRUCT(Rect2, Vector2, position) -SETGET_STRUCT(Rect2, Vector2, size) -SETGET_STRUCT_FUNC(Rect2, Vector2, end, set_end, get_end) - -SETGET_STRUCT(Rect2i, Vector2i, position) -SETGET_STRUCT(Rect2i, Vector2i, size) -SETGET_STRUCT_FUNC(Rect2i, Vector2i, end, set_end, get_end) - -SETGET_STRUCT(AABB, Vector3, position) -SETGET_STRUCT(AABB, Vector3, size) -SETGET_STRUCT_FUNC(AABB, Vector3, end, set_end, get_end) - -SETGET_STRUCT_CUSTOM(Transform2D, Vector2, x, elements[0]) -SETGET_STRUCT_CUSTOM(Transform2D, Vector2, y, elements[1]) -SETGET_STRUCT_CUSTOM(Transform2D, Vector2, origin, elements[2]) - -SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, x, normal.x) -SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, y, normal.y) -SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, z, normal.z) -SETGET_STRUCT(Plane, Vector3, normal) -SETGET_NUMBER_STRUCT(Plane, double, d) - -SETGET_NUMBER_STRUCT(Quaternion, double, x) -SETGET_NUMBER_STRUCT(Quaternion, double, y) -SETGET_NUMBER_STRUCT(Quaternion, double, z) -SETGET_NUMBER_STRUCT(Quaternion, double, w) - -SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, x, set_axis, get_axis, 0) -SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, y, set_axis, get_axis, 1) -SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_axis, get_axis, 2) - -SETGET_STRUCT(Transform3D, Basis, basis) -SETGET_STRUCT(Transform3D, Vector3, origin) - -SETGET_NUMBER_STRUCT(Color, double, r) -SETGET_NUMBER_STRUCT(Color, double, g) -SETGET_NUMBER_STRUCT(Color, double, b) -SETGET_NUMBER_STRUCT(Color, double, a) - -SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, r8, set_r8, get_r8) -SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, g8, set_g8, get_g8) -SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, b8, set_b8, get_b8) -SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, a8, set_a8, get_a8) - -SETGET_NUMBER_STRUCT_FUNC(Color, double, h, set_h, get_h) -SETGET_NUMBER_STRUCT_FUNC(Color, double, s, set_s, get_s) -SETGET_NUMBER_STRUCT_FUNC(Color, double, v, set_v, get_v) +#include "variant_setget.h" struct VariantSetterGetterInfo { void (*setter)(Variant *base, const Variant *value, bool &valid); @@ -326,7 +51,7 @@ static void register_member(Variant::Type p_type, const StringName &p_member) { sgi.ptr_setter = T::ptr_set; sgi.getter = T::get; - sgi.validated_getter = T::get; + sgi.validated_getter = T::validated_get; sgi.ptr_getter = T::ptr_get; sgi.member_type = T::get_type(); diff --git a/core/variant/variant_setget.h b/core/variant/variant_setget.h new file mode 100644 index 0000000000..dbf24ab3e3 --- /dev/null +++ b/core/variant/variant_setget.h @@ -0,0 +1,332 @@ +/*************************************************************************/ +/* variant_setget.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 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 VARIANT_SETGET_H +#define VARIANT_SETGET_H + +#include "variant.h" + +#include "core/core_string_names.h" +#include "core/debugger/engine_debugger.h" +#include "core/object/class_db.h" +#include "core/templates/local_vector.h" +#include "core/variant/variant_internal.h" + +/**** NAMED SETTERS AND GETTERS ****/ + +#define SETGET_STRUCT(m_base_type, m_member_type, m_member) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_member = PtrToArg<m_member_type>::convert(member); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_NUMBER_STRUCT(m_base_type, m_member_type, m_member) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_member, member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == Variant::FLOAT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<double>::get_ptr(value); \ + valid = true; \ + } else if (value->get_type() == Variant::INT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<int64_t>::get_ptr(value); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_member = PtrToArg<m_member_type>::convert(member); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_custom = PtrToArg<m_member_type>::convert(member); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_NUMBER_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_custom, member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == Variant::FLOAT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<double>::get_ptr(value); \ + valid = true; \ + } else if (value->get_type() == Variant::INT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<int64_t>::get_ptr(value); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom = *VariantGetInternalPtr<m_member_type>::get_ptr(value); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_custom = PtrToArg<m_member_type>::convert(member); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_setter(PtrToArg<m_member_type>::convert(member)); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_NUMBER_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(), member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == Variant::FLOAT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<double>::get_ptr(value)); \ + valid = true; \ + } else if (value->get_type() == Variant::INT) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<int64_t>::get_ptr(value)); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(*VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_setter(PtrToArg<m_member_type>::convert(member)); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +#define SETGET_STRUCT_FUNC_INDEX(m_base_type, m_member_type, m_member, m_setter, m_getter, m_index) \ + struct VariantSetGet_##m_base_type##_##m_member { \ + static void get(const Variant *base, Variant *member) { \ + VariantTypeAdjust<m_member_type>::adjust(member); \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \ + } \ + static inline void validated_get(const Variant *base, Variant *member) { \ + *VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \ + } \ + static void ptr_get(const void *base, void *member) { \ + PtrToArg<m_member_type>::encode(PtrToArg<m_base_type>::convert(base).m_getter(m_index), member); \ + } \ + static void set(Variant *base, const Variant *value, bool &valid) { \ + if (value->get_type() == GetTypeInfo<m_member_type>::VARIANT_TYPE) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + valid = true; \ + } else { \ + valid = false; \ + } \ + } \ + static inline void validated_set(Variant *base, const Variant *value) { \ + VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_setter(m_index, *VariantGetInternalPtr<m_member_type>::get_ptr(value)); \ + } \ + static void ptr_set(void *base, const void *member) { \ + m_base_type b = PtrToArg<m_base_type>::convert(base); \ + b.m_setter(m_index, PtrToArg<m_member_type>::convert(member)); \ + PtrToArg<m_base_type>::encode(b, base); \ + } \ + static Variant::Type get_type() { return GetTypeInfo<m_member_type>::VARIANT_TYPE; } \ + }; + +SETGET_NUMBER_STRUCT(Vector2, double, x) +SETGET_NUMBER_STRUCT(Vector2, double, y) + +SETGET_NUMBER_STRUCT(Vector2i, int64_t, x) +SETGET_NUMBER_STRUCT(Vector2i, int64_t, y) + +SETGET_NUMBER_STRUCT(Vector3, double, x) +SETGET_NUMBER_STRUCT(Vector3, double, y) +SETGET_NUMBER_STRUCT(Vector3, double, z) + +SETGET_NUMBER_STRUCT(Vector3i, int64_t, x) +SETGET_NUMBER_STRUCT(Vector3i, int64_t, y) +SETGET_NUMBER_STRUCT(Vector3i, int64_t, z) + +SETGET_STRUCT(Rect2, Vector2, position) +SETGET_STRUCT(Rect2, Vector2, size) +SETGET_STRUCT_FUNC(Rect2, Vector2, end, set_end, get_end) + +SETGET_STRUCT(Rect2i, Vector2i, position) +SETGET_STRUCT(Rect2i, Vector2i, size) +SETGET_STRUCT_FUNC(Rect2i, Vector2i, end, set_end, get_end) + +SETGET_STRUCT(AABB, Vector3, position) +SETGET_STRUCT(AABB, Vector3, size) +SETGET_STRUCT_FUNC(AABB, Vector3, end, set_end, get_end) + +SETGET_STRUCT_CUSTOM(Transform2D, Vector2, x, elements[0]) +SETGET_STRUCT_CUSTOM(Transform2D, Vector2, y, elements[1]) +SETGET_STRUCT_CUSTOM(Transform2D, Vector2, origin, elements[2]) + +SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, x, normal.x) +SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, y, normal.y) +SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, z, normal.z) +SETGET_STRUCT(Plane, Vector3, normal) +SETGET_NUMBER_STRUCT(Plane, double, d) + +SETGET_NUMBER_STRUCT(Quaternion, double, x) +SETGET_NUMBER_STRUCT(Quaternion, double, y) +SETGET_NUMBER_STRUCT(Quaternion, double, z) +SETGET_NUMBER_STRUCT(Quaternion, double, w) + +SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, x, set_axis, get_axis, 0) +SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, y, set_axis, get_axis, 1) +SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_axis, get_axis, 2) + +SETGET_STRUCT(Transform3D, Basis, basis) +SETGET_STRUCT(Transform3D, Vector3, origin) + +SETGET_NUMBER_STRUCT(Color, double, r) +SETGET_NUMBER_STRUCT(Color, double, g) +SETGET_NUMBER_STRUCT(Color, double, b) +SETGET_NUMBER_STRUCT(Color, double, a) + +SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, r8, set_r8, get_r8) +SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, g8, set_g8, get_g8) +SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, b8, set_b8, get_b8) +SETGET_NUMBER_STRUCT_FUNC(Color, int64_t, a8, set_a8, get_a8) + +SETGET_NUMBER_STRUCT_FUNC(Color, double, h, set_h, get_h) +SETGET_NUMBER_STRUCT_FUNC(Color, double, s, set_s, get_s) +SETGET_NUMBER_STRUCT_FUNC(Color, double, v, set_v, get_v) + +#endif // VARIANT_SETGET_H |