diff options
Diffstat (limited to 'core')
37 files changed, 3019 insertions, 2618 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..912c89a9d2 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -35,7 +35,6 @@ #include "core/debugger/engine_debugger.h" #include "core/io/file_access_compressed.h" #include "core/io/file_access_encrypted.h" -#include "core/io/json.h" #include "core/io/marshalls.h" #include "core/math/geometry_2d.h" #include "core/math/geometry_3d.h" @@ -426,6 +425,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 +532,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); @@ -2137,80 +2154,6 @@ void _Engine::_bind_methods() { _Engine *_Engine::singleton = nullptr; -////// _JSON ////// - -void JSONParseResult::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_error"), &JSONParseResult::get_error); - ClassDB::bind_method(D_METHOD("get_error_string"), &JSONParseResult::get_error_string); - ClassDB::bind_method(D_METHOD("get_error_line"), &JSONParseResult::get_error_line); - ClassDB::bind_method(D_METHOD("get_result"), &JSONParseResult::get_result); - - ClassDB::bind_method(D_METHOD("set_error", "error"), &JSONParseResult::set_error); - ClassDB::bind_method(D_METHOD("set_error_string", "error_string"), &JSONParseResult::set_error_string); - ClassDB::bind_method(D_METHOD("set_error_line", "error_line"), &JSONParseResult::set_error_line); - ClassDB::bind_method(D_METHOD("set_result", "result"), &JSONParseResult::set_result); - - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "error", PROPERTY_HINT_NONE, "Error", PROPERTY_USAGE_CLASS_IS_ENUM), "set_error", "get_error"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "error_string"), "set_error_string", "get_error_string"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "error_line"), "set_error_line", "get_error_line"); - ADD_PROPERTY(PropertyInfo(Variant::NIL, "result", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "set_result", "get_result"); -} - -void JSONParseResult::set_error(Error p_error) { - error = p_error; -} - -Error JSONParseResult::get_error() const { - return error; -} - -void JSONParseResult::set_error_string(const String &p_error_string) { - error_string = p_error_string; -} - -String JSONParseResult::get_error_string() const { - return error_string; -} - -void JSONParseResult::set_error_line(int p_error_line) { - error_line = p_error_line; -} - -int JSONParseResult::get_error_line() const { - return error_line; -} - -void JSONParseResult::set_result(const Variant &p_result) { - result = p_result; -} - -Variant JSONParseResult::get_result() const { - return result; -} - -void _JSON::_bind_methods() { - ClassDB::bind_method(D_METHOD("print", "value", "indent", "sort_keys", "full_precision"), &_JSON::print, DEFVAL(String()), DEFVAL(false), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("parse", "json"), &_JSON::parse); -} - -String _JSON::print(const Variant &p_value, const String &p_indent, bool p_sort_keys, bool p_full_precision) { - return JSON::print(p_value, p_indent, p_sort_keys, p_full_precision); -} - -Ref<JSONParseResult> _JSON::parse(const String &p_json) { - Ref<JSONParseResult> result; - result.instance(); - - result->error = JSON::parse(p_json, result->result, result->error_string, result->error_line); - - if (result->error != OK) { - ERR_PRINT(vformat("Error parsing JSON at line %s: %s", result->error_line, result->error_string)); - } - return result; -} - -_JSON *_JSON::singleton = nullptr; - ////// _EngineDebugger ////// void _EngineDebugger::_bind_methods() { diff --git a/core/core_bind.h b/core/core_bind.h index b161effe95..74b6a5b26f 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; @@ -656,54 +659,6 @@ public: _Engine() { singleton = this; } }; -class _JSON; - -class JSONParseResult : public RefCounted { - GDCLASS(JSONParseResult, RefCounted); - - friend class _JSON; - - Error error; - String error_string; - int error_line = -1; - - Variant result; - -protected: - static void _bind_methods(); - -public: - void set_error(Error p_error); - Error get_error() const; - - void set_error_string(const String &p_error_string); - String get_error_string() const; - - void set_error_line(int p_error_line); - int get_error_line() const; - - void set_result(const Variant &p_result); - Variant get_result() const; - - JSONParseResult() {} -}; - -class _JSON : public Object { - GDCLASS(_JSON, Object); - -protected: - static void _bind_methods(); - static _JSON *singleton; - -public: - static _JSON *get_singleton() { return singleton; } - - String print(const Variant &p_value, const String &p_indent = "", bool p_sort_keys = false, bool p_full_precision = false); - Ref<JSONParseResult> parse(const String &p_json); - - _JSON() { singleton = this; } -}; - class _EngineDebugger : public Object { GDCLASS(_EngineDebugger, Object); diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 9c1cf15342..72fb409b63 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -88,7 +88,7 @@ bool InputEvent::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, f return false; } -bool InputEvent::shortcut_match(const Ref<InputEvent> &p_event) const { +bool InputEvent::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) const { return false; } @@ -110,7 +110,7 @@ void InputEvent::_bind_methods() { ClassDB::bind_method(D_METHOD("as_text"), &InputEvent::as_text); - ClassDB::bind_method(D_METHOD("shortcut_match", "event"), &InputEvent::shortcut_match); + ClassDB::bind_method(D_METHOD("is_match", "event", "exact_match"), &InputEvent::is_match, DEFVAL(true)); ClassDB::bind_method(D_METHOD("is_action_type"), &InputEvent::is_action_type); @@ -194,6 +194,23 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif set_meta_pressed(event->is_meta_pressed()); } +uint32_t InputEventWithModifiers::get_modifiers_mask() const { + uint32_t mask = 0; + if (is_ctrl_pressed()) { + mask |= KEY_MASK_CTRL; + } + if (is_shift_pressed()) { + mask |= KEY_MASK_SHIFT; + } + if (is_alt_pressed()) { + mask |= KEY_MASK_ALT; + } + if (is_meta_pressed()) { + mask |= KEY_MASK_META; + } + return mask; +} + String InputEventWithModifiers::as_text() const { Vector<String> mod_names; @@ -313,39 +330,11 @@ bool InputEventKey::is_echo() const { } uint32_t InputEventKey::get_keycode_with_modifiers() const { - uint32_t sc = keycode; - if (is_ctrl_pressed()) { - sc |= KEY_MASK_CTRL; - } - if (is_alt_pressed()) { - sc |= KEY_MASK_ALT; - } - if (is_shift_pressed()) { - sc |= KEY_MASK_SHIFT; - } - if (is_meta_pressed()) { - sc |= KEY_MASK_META; - } - - return sc; + return keycode | get_modifiers_mask(); } uint32_t InputEventKey::get_physical_keycode_with_modifiers() const { - uint32_t sc = physical_keycode; - if (is_ctrl_pressed()) { - sc |= KEY_MASK_CTRL; - } - if (is_alt_pressed()) { - sc |= KEY_MASK_ALT; - } - if (is_shift_pressed()) { - sc |= KEY_MASK_SHIFT; - } - if (is_meta_pressed()) { - sc |= KEY_MASK_META; - } - - return sc; + return physical_keycode | get_modifiers_mask(); } String InputEventKey::as_text() const { @@ -442,16 +431,14 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed return match; } -bool InputEventKey::shortcut_match(const Ref<InputEvent> &p_event) const { +bool InputEventKey::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) const { Ref<InputEventKey> key = p_event; if (key.is_null()) { return false; } - uint32_t code = get_keycode_with_modifiers(); - uint32_t event_code = key->get_keycode_with_modifiers(); - - return code == event_code; + return keycode == key->keycode && + (!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask()); } void InputEventKey::_bind_methods() { @@ -599,6 +586,16 @@ bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p return match; } +bool InputEventMouseButton::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) const { + Ref<InputEventMouseButton> mb = p_event; + if (mb.is_null()) { + return false; + } + + return button_index == mb->button_index && + (!p_exact_match || get_modifiers_mask() == mb->get_modifiers_mask()); +} + static const char *_mouse_button_descriptions[9] = { TTRC("Left Mouse Button"), TTRC("Right Mouse Button"), @@ -904,6 +901,16 @@ bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool * return match; } +bool InputEventJoypadMotion::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) const { + Ref<InputEventJoypadMotion> jm = p_event; + if (jm.is_null()) { + return false; + } + + return axis == jm->axis && + (!p_exact_match || ((axis_value < 0) == (jm->axis_value < 0))); +} + static const char *_joy_axis_descriptions[JOY_AXIS_MAX] = { TTRC("Left Stick X-Axis, Joystick 0 X-Axis"), TTRC("Left Stick Y-Axis, Joystick 0 Y-Axis"), @@ -987,7 +994,7 @@ bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool * return match; } -bool InputEventJoypadButton::shortcut_match(const Ref<InputEvent> &p_event) const { +bool InputEventJoypadButton::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) const { Ref<InputEventJoypadButton> button = p_event; if (button.is_null()) { return false; @@ -1229,7 +1236,7 @@ float InputEventAction::get_strength() const { return strength; } -bool InputEventAction::shortcut_match(const Ref<InputEvent> &p_event) const { +bool InputEventAction::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) const { if (p_event.is_null()) { return false; } diff --git a/core/input/input_event.h b/core/input/input_event.h index eed0d79326..3ef135221d 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -142,7 +142,8 @@ public: virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const; - virtual bool shortcut_match(const Ref<InputEvent> &p_event) const; + virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const; + virtual bool is_action_type() const; virtual bool accumulate(const Ref<InputEvent> &p_event) { return false; } @@ -212,6 +213,8 @@ public: void set_modifiers_from_event(const InputEventWithModifiers *event); + uint32_t get_modifiers_mask() const; + virtual String as_text() const override; virtual String to_string() override; @@ -252,7 +255,7 @@ public: uint32_t get_physical_keycode_with_modifiers() const; virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; - virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override; + virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override; virtual bool is_action_type() const override { return true; } @@ -313,7 +316,9 @@ public: bool is_double_click() const; virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; + virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; + virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override; virtual bool is_action_type() const override { return true; } virtual String as_text() const override; @@ -373,6 +378,7 @@ public: virtual bool is_pressed() const override; virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; + virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override; virtual bool is_action_type() const override { return true; } virtual String as_text() const override; @@ -401,9 +407,10 @@ public: float get_pressure() const; virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; - virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override; + virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override; virtual bool is_action_type() const override { return true; } + virtual String as_text() const override; virtual String to_string() override; @@ -491,9 +498,10 @@ public: virtual bool is_action(const StringName &p_action) const; virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; + virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override; - virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override; virtual bool is_action_type() const override { return true; } + virtual String as_text() const override; virtual String to_string() override; diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 878ce820fb..52dc561546 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -130,12 +130,9 @@ List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Re for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) { const Ref<InputEvent> e = E->get(); - //if (e.type != Ref<InputEvent>::KEY && e.device != p_event.device) -- unsure about the KEY comparison, why is this here? - // continue; - int device = e->get_device(); if (device == ALL_DEVICES || device == p_event->get_device()) { - if (p_exact_match && e->shortcut_match(p_event)) { + if (p_exact_match && e->is_match(p_event, true)) { return E; } else if (!p_exact_match && e->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) { return E; @@ -353,8 +350,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") }, @@ -511,6 +509,7 @@ const OrderedHashMap<String, List<Ref<InputEvent>>> &InputMap::get_builtins() { // Text Backspace and Delete inputs = List<Ref<InputEvent>>(); inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE)); + inputs.push_back(InputEventKey::create_reference(KEY_BACKSPACE | KEY_MASK_SHIFT)); default_builtin_cache.insert("ui_text_backspace", inputs); inputs = List<Ref<InputEvent>>(); @@ -667,6 +666,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..b3a2498212 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -45,7 +45,7 @@ const char *JSON::tk_name[TK_MAX] = { "EOF", }; -static String _make_indent(const String &p_indent, int p_size) { +String JSON::_make_indent(const String &p_indent, int p_size) { String indent_text = ""; if (!p_indent.is_empty()) { for (int i = 0; i < p_size; i++) { @@ -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::_stringify(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) + _stringify(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) + _stringify(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 += _stringify(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: @@ -130,10 +140,6 @@ 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); -} - Error JSON::_get_token(const char32_t *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str) { while (p_len > 0) { switch (p_str[index]) { @@ -488,7 +494,7 @@ Error JSON::_parse_object(Dictionary &object, const char32_t *p_str, int &index, return ERR_PARSE_ERROR; } -Error JSON::parse(const String &p_json, Variant &r_ret, String &r_err_str, int &r_err_line) { +Error JSON::_parse_string(const String &p_json, Variant &r_ret, String &r_err_str, int &r_err_line) { const char32_t *str = p_json.ptr(); int idx = 0; int len = p_json.length(); @@ -519,34 +525,24 @@ Error JSON::parse(const String &p_json, Variant &r_ret, String &r_err_str, int & return err; } -Error JSONParser::parse_string(const String &p_json_string) { - return JSON::parse(p_json_string, data, err_text, err_line); -} -String JSONParser::get_error_text() const { - return err_text; -} -int JSONParser::get_error_line() const { - return err_line; -} -Variant JSONParser::get_data() const { - return data; +String JSON::stringify(const Variant &p_var, const String &p_indent, bool p_sort_keys, bool p_full_precision) { + Set<const void *> markers; + return _stringify(p_var, p_indent, 0, p_sort_keys, markers, p_full_precision); } -Error JSONParser::decode_data(const Variant &p_data, const String &p_indent, bool p_sort_keys) { - string = JSON::print(p_data, p_indent, p_sort_keys); - data = p_data; - return OK; +Error JSON::parse(const String &p_json_string) { + Error err = _parse_string(p_json_string, data, err_str, err_line); + if (err == Error::OK) { + err_line = 0; + } + return err; } -String JSONParser::get_string() const { - return string; -} +void JSON::_bind_methods() { + ClassDB::bind_method(D_METHOD("stringify", "data", "indent", "sort_keys", "full_precision"), &JSON::stringify, DEFVAL(""), DEFVAL(true), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("parse", "json_string"), &JSON::parse); -void JSONParser::_bind_methods() { - ClassDB::bind_method(D_METHOD("parse_string", "json_string"), &JSONParser::parse_string); - ClassDB::bind_method(D_METHOD("get_error_text"), &JSONParser::get_error_text); - ClassDB::bind_method(D_METHOD("get_error_line"), &JSONParser::get_error_line); - ClassDB::bind_method(D_METHOD("get_data"), &JSONParser::get_data); - ClassDB::bind_method(D_METHOD("decode_data", "data", "indent", "sort_keys"), &JSONParser::decode_data, DEFVAL(""), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("get_string"), &JSONParser::get_string); + ClassDB::bind_method(D_METHOD("get_data"), &JSON::get_data); + ClassDB::bind_method(D_METHOD("get_error_line"), &JSON::get_error_line); + ClassDB::bind_method(D_METHOD("get_error_message"), &JSON::get_error_message); } diff --git a/core/io/json.h b/core/io/json.h index bfd2347725..f20c97f540 100644 --- a/core/io/json.h +++ b/core/io/json.h @@ -33,7 +33,10 @@ #include "core/object/ref_counted.h" #include "core/variant/variant.h" -class JSON { + +class JSON : public RefCounted { + GDCLASS(JSON, RefCounted); + enum TokenType { TK_CURLY_BRACKET_OPEN, TK_CURLY_BRACKET_CLOSE, @@ -60,39 +63,30 @@ class JSON { Variant value; }; - static const char *tk_name[TK_MAX]; + Variant data; + String err_str; + int err_line = 0; - 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 const char *tk_name[]; + static String _make_indent(const String &p_indent, int p_size); + static String _stringify(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); static Error _parse_array(Array &array, const char32_t *p_str, int &index, int p_len, int &line, String &r_err_str); static Error _parse_object(Dictionary &object, const char32_t *p_str, int &index, int p_len, int &line, String &r_err_str); - -public: - static String print(const Variant &p_var, const String &p_indent = "", bool p_sort_keys = true, bool p_full_precision = false); - static Error parse(const String &p_json, Variant &r_ret, String &r_err_str, int &r_err_line); -}; - -class JSONParser : public RefCounted { - GDCLASS(JSONParser, RefCounted); - - Variant data; - String string; - String err_text; - int err_line = 0; + static Error _parse_string(const String &p_json, Variant &r_ret, String &r_err_str, int &r_err_line); protected: static void _bind_methods(); public: - Error parse_string(const String &p_json_string); - String get_error_text() const; - int get_error_line() const; - Variant get_data() const; + String stringify(const Variant &p_var, const String &p_indent = "", bool p_sort_keys = true, bool p_full_precision = false); + Error parse(const String &p_json_string); - Error decode_data(const Variant &p_data, const String &p_indent = "", bool p_sort_keys = true); - String get_string() const; + inline Variant get_data() const { return data; } + inline int get_error_line() const { return err_line; } + inline String get_error_message() const { return err_str; } }; #endif // JSON_H diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 4c58c84c14..c447e11ee7 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -111,6 +111,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = 4; } + // Note: We cannot use sizeof(real_t) for decoding, in case a different size is encoded. + // Decoding math types always checks for the encoded size, while encoding always uses compilation setting. + // This does lead to some code duplication for decoding, but compatibility is the priority. switch (type & ENCODE_MASK) { case Variant::NIL: { r_variant = Variant(); @@ -144,18 +147,18 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::FLOAT: { if (type & ENCODE_FLAG_64) { - ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA); + ERR_FAIL_COND_V((size_t)len < sizeof(double), ERR_INVALID_DATA); double val = decode_double(buf); r_variant = val; if (r_len) { - (*r_len) += 8; + (*r_len) += sizeof(double); } } else { - ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); + ERR_FAIL_COND_V((size_t)len < sizeof(float), ERR_INVALID_DATA); float val = decode_float(buf); r_variant = val; if (r_len) { - (*r_len) += 4; + (*r_len) += sizeof(float); } } @@ -172,15 +175,25 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int // math types case Variant::VECTOR2: { - ERR_FAIL_COND_V(len < 4 * 2, ERR_INVALID_DATA); Vector2 val; - val.x = decode_float(&buf[0]); - val.y = decode_float(&buf[4]); - r_variant = val; + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 2, ERR_INVALID_DATA); + val.x = decode_double(&buf[0]); + val.y = decode_double(&buf[sizeof(double)]); - if (r_len) { - (*r_len) += 4 * 2; + if (r_len) { + (*r_len) += sizeof(double) * 2; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 2, ERR_INVALID_DATA); + val.x = decode_float(&buf[0]); + val.y = decode_float(&buf[sizeof(float)]); + + if (r_len) { + (*r_len) += sizeof(float) * 2; + } } + r_variant = val; } break; case Variant::VECTOR2I: { @@ -196,17 +209,29 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::RECT2: { - ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA); Rect2 val; - val.position.x = decode_float(&buf[0]); - val.position.y = decode_float(&buf[4]); - val.size.x = decode_float(&buf[8]); - val.size.y = decode_float(&buf[12]); - r_variant = val; + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 4, ERR_INVALID_DATA); + val.position.x = decode_double(&buf[0]); + val.position.y = decode_double(&buf[sizeof(double)]); + val.size.x = decode_double(&buf[sizeof(double) * 2]); + val.size.y = decode_double(&buf[sizeof(double) * 3]); - if (r_len) { - (*r_len) += 4 * 4; + if (r_len) { + (*r_len) += sizeof(double) * 4; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 4, ERR_INVALID_DATA); + val.position.x = decode_float(&buf[0]); + val.position.y = decode_float(&buf[sizeof(float)]); + val.size.x = decode_float(&buf[sizeof(float) * 2]); + val.size.y = decode_float(&buf[sizeof(float) * 3]); + + if (r_len) { + (*r_len) += sizeof(float) * 4; + } } + r_variant = val; } break; case Variant::RECT2I: { @@ -224,16 +249,27 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::VECTOR3: { - ERR_FAIL_COND_V(len < 4 * 3, ERR_INVALID_DATA); Vector3 val; - val.x = decode_float(&buf[0]); - val.y = decode_float(&buf[4]); - val.z = decode_float(&buf[8]); - r_variant = val; + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 3, ERR_INVALID_DATA); + val.x = decode_double(&buf[0]); + val.y = decode_double(&buf[sizeof(double)]); + val.z = decode_double(&buf[sizeof(double) * 2]); - if (r_len) { - (*r_len) += 4 * 3; + if (r_len) { + (*r_len) += sizeof(double) * 3; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 3, ERR_INVALID_DATA); + val.x = decode_float(&buf[0]); + val.y = decode_float(&buf[sizeof(float)]); + val.z = decode_float(&buf[sizeof(float) * 2]); + + if (r_len) { + (*r_len) += sizeof(float) * 3; + } } + r_variant = val; } break; case Variant::VECTOR3I: { @@ -250,101 +286,177 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::TRANSFORM2D: { - ERR_FAIL_COND_V(len < 4 * 6, ERR_INVALID_DATA); Transform2D val; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 2; j++) { - val.elements[i][j] = decode_float(&buf[(i * 2 + j) * 4]); + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 6, ERR_INVALID_DATA); + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 2; j++) { + val.elements[i][j] = decode_double(&buf[(i * 2 + j) * sizeof(double)]); + } } - } - r_variant = val; + if (r_len) { + (*r_len) += sizeof(double) * 6; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 6, ERR_INVALID_DATA); + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 2; j++) { + val.elements[i][j] = decode_float(&buf[(i * 2 + j) * sizeof(float)]); + } + } - if (r_len) { - (*r_len) += 4 * 6; + if (r_len) { + (*r_len) += sizeof(float) * 6; + } } + r_variant = val; } break; case Variant::PLANE: { - ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA); Plane val; - val.normal.x = decode_float(&buf[0]); - val.normal.y = decode_float(&buf[4]); - val.normal.z = decode_float(&buf[8]); - val.d = decode_float(&buf[12]); - r_variant = val; + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 4, ERR_INVALID_DATA); + val.normal.x = decode_double(&buf[0]); + val.normal.y = decode_double(&buf[sizeof(double)]); + val.normal.z = decode_double(&buf[sizeof(double) * 2]); + val.d = decode_double(&buf[sizeof(double) * 3]); - if (r_len) { - (*r_len) += 4 * 4; + if (r_len) { + (*r_len) += sizeof(double) * 4; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 4, ERR_INVALID_DATA); + val.normal.x = decode_float(&buf[0]); + val.normal.y = decode_float(&buf[sizeof(float)]); + val.normal.z = decode_float(&buf[sizeof(float) * 2]); + val.d = decode_float(&buf[sizeof(float) * 3]); + + if (r_len) { + (*r_len) += sizeof(float) * 4; + } } + r_variant = val; } break; case Variant::QUATERNION: { - ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA); Quaternion val; - val.x = decode_float(&buf[0]); - val.y = decode_float(&buf[4]); - val.z = decode_float(&buf[8]); - val.w = decode_float(&buf[12]); - r_variant = val; + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 4, ERR_INVALID_DATA); + val.x = decode_double(&buf[0]); + val.y = decode_double(&buf[sizeof(double)]); + val.z = decode_double(&buf[sizeof(double) * 2]); + val.w = decode_double(&buf[sizeof(double) * 3]); - if (r_len) { - (*r_len) += 4 * 4; + if (r_len) { + (*r_len) += sizeof(double) * 4; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 4, ERR_INVALID_DATA); + val.x = decode_float(&buf[0]); + val.y = decode_float(&buf[sizeof(float)]); + val.z = decode_float(&buf[sizeof(float) * 2]); + val.w = decode_float(&buf[sizeof(float) * 3]); + + if (r_len) { + (*r_len) += sizeof(float) * 4; + } } + r_variant = val; } break; case Variant::AABB: { - ERR_FAIL_COND_V(len < 4 * 6, ERR_INVALID_DATA); AABB val; - val.position.x = decode_float(&buf[0]); - val.position.y = decode_float(&buf[4]); - val.position.z = decode_float(&buf[8]); - val.size.x = decode_float(&buf[12]); - val.size.y = decode_float(&buf[16]); - val.size.z = decode_float(&buf[20]); - r_variant = val; + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 6, ERR_INVALID_DATA); + val.position.x = decode_double(&buf[0]); + val.position.y = decode_double(&buf[sizeof(double)]); + val.position.z = decode_double(&buf[sizeof(double) * 2]); + val.size.x = decode_double(&buf[sizeof(double) * 3]); + val.size.y = decode_double(&buf[sizeof(double) * 4]); + val.size.z = decode_double(&buf[sizeof(double) * 5]); - if (r_len) { - (*r_len) += 4 * 6; + if (r_len) { + (*r_len) += sizeof(double) * 6; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 6, ERR_INVALID_DATA); + val.position.x = decode_float(&buf[0]); + val.position.y = decode_float(&buf[sizeof(float)]); + val.position.z = decode_float(&buf[sizeof(float) * 2]); + val.size.x = decode_float(&buf[sizeof(float) * 3]); + val.size.y = decode_float(&buf[sizeof(float) * 4]); + val.size.z = decode_float(&buf[sizeof(float) * 5]); + + if (r_len) { + (*r_len) += sizeof(float) * 6; + } } + r_variant = val; } break; case Variant::BASIS: { - ERR_FAIL_COND_V(len < 4 * 9, ERR_INVALID_DATA); Basis val; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - val.elements[i][j] = decode_float(&buf[(i * 3 + j) * 4]); + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 9, ERR_INVALID_DATA); + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + val.elements[i][j] = decode_double(&buf[(i * 3 + j) * sizeof(double)]); + } } - } - r_variant = val; + if (r_len) { + (*r_len) += sizeof(double) * 9; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 9, ERR_INVALID_DATA); + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + val.elements[i][j] = decode_float(&buf[(i * 3 + j) * sizeof(float)]); + } + } - if (r_len) { - (*r_len) += 4 * 9; + if (r_len) { + (*r_len) += sizeof(float) * 9; + } } + r_variant = val; } break; case Variant::TRANSFORM3D: { - ERR_FAIL_COND_V(len < 4 * 12, ERR_INVALID_DATA); Transform3D val; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - val.basis.elements[i][j] = decode_float(&buf[(i * 3 + j) * 4]); + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 12, ERR_INVALID_DATA); + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + val.basis.elements[i][j] = decode_double(&buf[(i * 3 + j) * sizeof(double)]); + } } - } - val.origin[0] = decode_float(&buf[36]); - val.origin[1] = decode_float(&buf[40]); - val.origin[2] = decode_float(&buf[44]); + val.origin[0] = decode_double(&buf[sizeof(double) * 9]); + val.origin[1] = decode_double(&buf[sizeof(double) * 10]); + val.origin[2] = decode_double(&buf[sizeof(double) * 11]); - r_variant = val; + if (r_len) { + (*r_len) += sizeof(double) * 12; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 12, ERR_INVALID_DATA); + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + val.basis.elements[i][j] = decode_float(&buf[(i * 3 + j) * sizeof(float)]); + } + } + val.origin[0] = decode_float(&buf[sizeof(float) * 9]); + val.origin[1] = decode_float(&buf[sizeof(float) * 10]); + val.origin[2] = decode_float(&buf[sizeof(float) * 11]); - if (r_len) { - (*r_len) += 4 * 12; + if (r_len) { + (*r_len) += sizeof(float) * 12; + } } + r_variant = val; } break; - // misc types case Variant::COLOR: { ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA); @@ -356,9 +468,8 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int r_variant = val; if (r_len) { - (*r_len) += 4 * 4; + (*r_len) += 4 * 4; // Colors should always be in single-precision. } - } break; case Variant::STRING_NAME: { String str; @@ -463,7 +574,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int buf += 4; len -= 4; if (r_len) { - (*r_len) += 4; + (*r_len) += 4; // Size of count number. } for (int i = 0; i < count; i++) { @@ -516,7 +627,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int len -= 4; if (r_len) { - (*r_len) += 4; + (*r_len) += 4; // Size of count number. } Dictionary d; @@ -559,7 +670,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int len -= 4; if (r_len) { - (*r_len) += 4; + (*r_len) += 4; // Size of count number. } Array varr; @@ -716,9 +827,8 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int len -= 4; if (r_len) { - (*r_len) += 4; + (*r_len) += 4; // Size of count number. } - //printf("string count: %i\n",count); for (int32_t i = 0; i < count; i++) { String str; @@ -739,30 +849,57 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int buf += 4; len -= 4; - ERR_FAIL_MUL_OF(count, 4 * 2, ERR_INVALID_DATA); - ERR_FAIL_COND_V(count < 0 || count * 4 * 2 > len, ERR_INVALID_DATA); Vector<Vector2> varray; - if (r_len) { - (*r_len) += 4; - } - - if (count) { - varray.resize(count); - Vector2 *w = varray.ptrw(); + if (type & ENCODE_FLAG_64) { + ERR_FAIL_MUL_OF(count, sizeof(double) * 2, ERR_INVALID_DATA); + ERR_FAIL_COND_V(count < 0 || count * sizeof(double) * 2 > (size_t)len, ERR_INVALID_DATA); - for (int32_t i = 0; i < count; i++) { - w[i].x = decode_float(buf + i * 4 * 2 + 4 * 0); - w[i].y = decode_float(buf + i * 4 * 2 + 4 * 1); + if (r_len) { + (*r_len) += 4; // Size of count number. } - int adv = 4 * 2 * count; + if (count) { + varray.resize(count); + Vector2 *w = varray.ptrw(); + + for (int32_t i = 0; i < count; i++) { + w[i].x = decode_double(buf + i * sizeof(double) * 2 + sizeof(double) * 0); + w[i].y = decode_double(buf + i * sizeof(double) * 2 + sizeof(double) * 1); + } + + int adv = sizeof(double) * 2 * count; + + if (r_len) { + (*r_len) += adv; + } + len -= adv; + buf += adv; + } + } else { + ERR_FAIL_MUL_OF(count, sizeof(float) * 2, ERR_INVALID_DATA); + ERR_FAIL_COND_V(count < 0 || count * sizeof(float) * 2 > (size_t)len, ERR_INVALID_DATA); if (r_len) { - (*r_len) += adv; + (*r_len) += 4; // Size of count number. } - } + if (count) { + varray.resize(count); + Vector2 *w = varray.ptrw(); + + for (int32_t i = 0; i < count; i++) { + w[i].x = decode_float(buf + i * sizeof(float) * 2 + sizeof(float) * 0); + w[i].y = decode_float(buf + i * sizeof(float) * 2 + sizeof(float) * 1); + } + + int adv = sizeof(float) * 2 * count; + + if (r_len) { + (*r_len) += adv; + } + } + } r_variant = varray; } break; @@ -772,32 +909,61 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int buf += 4; len -= 4; - ERR_FAIL_MUL_OF(count, 4 * 3, ERR_INVALID_DATA); - ERR_FAIL_COND_V(count < 0 || count * 4 * 3 > len, ERR_INVALID_DATA); - Vector<Vector3> varray; - if (r_len) { - (*r_len) += 4; - } - - if (count) { - varray.resize(count); - Vector3 *w = varray.ptrw(); + if (type & ENCODE_FLAG_64) { + ERR_FAIL_MUL_OF(count, sizeof(double) * 3, ERR_INVALID_DATA); + ERR_FAIL_COND_V(count < 0 || count * sizeof(double) * 3 > (size_t)len, ERR_INVALID_DATA); - for (int32_t i = 0; i < count; i++) { - w[i].x = decode_float(buf + i * 4 * 3 + 4 * 0); - w[i].y = decode_float(buf + i * 4 * 3 + 4 * 1); - w[i].z = decode_float(buf + i * 4 * 3 + 4 * 2); + if (r_len) { + (*r_len) += 4; // Size of count number. } - int adv = 4 * 3 * count; + if (count) { + varray.resize(count); + Vector3 *w = varray.ptrw(); + + for (int32_t i = 0; i < count; i++) { + w[i].x = decode_double(buf + i * sizeof(double) * 3 + sizeof(double) * 0); + w[i].y = decode_double(buf + i * sizeof(double) * 3 + sizeof(double) * 1); + w[i].z = decode_double(buf + i * sizeof(double) * 3 + sizeof(double) * 2); + } + + int adv = sizeof(double) * 3 * count; + + if (r_len) { + (*r_len) += adv; + } + len -= adv; + buf += adv; + } + } else { + ERR_FAIL_MUL_OF(count, sizeof(float) * 3, ERR_INVALID_DATA); + ERR_FAIL_COND_V(count < 0 || count * sizeof(float) * 3 > (size_t)len, ERR_INVALID_DATA); if (r_len) { - (*r_len) += adv; + (*r_len) += 4; // Size of count number. } - } + if (count) { + varray.resize(count); + Vector3 *w = varray.ptrw(); + + for (int32_t i = 0; i < count; i++) { + w[i].x = decode_float(buf + i * sizeof(float) * 3 + sizeof(float) * 0); + w[i].y = decode_float(buf + i * sizeof(float) * 3 + sizeof(float) * 1); + w[i].z = decode_float(buf + i * sizeof(float) * 3 + sizeof(float) * 2); + } + + int adv = sizeof(float) * 3 * count; + + if (r_len) { + (*r_len) += adv; + } + len -= adv; + buf += adv; + } + } r_variant = varray; } break; @@ -813,7 +979,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int Vector<Color> carray; if (r_len) { - (*r_len) += 4; + (*r_len) += 4; // Size of count number. } if (count) { @@ -821,6 +987,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int Color *w = carray.ptrw(); for (int32_t i = 0; i < count; i++) { + // Colors should always be in single-precision. w[i].r = decode_float(buf + i * 4 * 4 + 4 * 0); w[i].g = decode_float(buf + i * 4 * 4 + 4 * 1); w[i].b = decode_float(buf + i * 4 * 4 + 4 * 2); @@ -882,7 +1049,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo double d = p_variant; float f = d; if (double(f) != d) { - flags |= ENCODE_FLAG_64; //always encode real as double + flags |= ENCODE_FLAG_64; } } break; case Variant::OBJECT: { @@ -1013,11 +1180,11 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo case Variant::VECTOR2: { if (buf) { Vector2 v2 = p_variant; - encode_float(v2.x, &buf[0]); - encode_float(v2.y, &buf[4]); + encode_real(v2.x, &buf[0]); + encode_real(v2.y, &buf[sizeof(real_t)]); } - r_len += 2 * 4; + r_len += 2 * sizeof(real_t); } break; case Variant::VECTOR2I: { @@ -1033,12 +1200,12 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo case Variant::RECT2: { if (buf) { Rect2 r2 = p_variant; - encode_float(r2.position.x, &buf[0]); - encode_float(r2.position.y, &buf[4]); - encode_float(r2.size.x, &buf[8]); - encode_float(r2.size.y, &buf[12]); + encode_real(r2.position.x, &buf[0]); + encode_real(r2.position.y, &buf[sizeof(real_t)]); + encode_real(r2.size.x, &buf[sizeof(real_t) * 2]); + encode_real(r2.size.y, &buf[sizeof(real_t) * 3]); } - r_len += 4 * 4; + r_len += 4 * sizeof(real_t); } break; case Variant::RECT2I: { @@ -1055,12 +1222,12 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo case Variant::VECTOR3: { if (buf) { Vector3 v3 = p_variant; - encode_float(v3.x, &buf[0]); - encode_float(v3.y, &buf[4]); - encode_float(v3.z, &buf[8]); + encode_real(v3.x, &buf[0]); + encode_real(v3.y, &buf[sizeof(real_t)]); + encode_real(v3.z, &buf[sizeof(real_t) * 2]); } - r_len += 3 * 4; + r_len += 3 * sizeof(real_t); } break; case Variant::VECTOR3I: { @@ -1079,50 +1246,50 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo Transform2D val = p_variant; for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { - memcpy(&buf[(i * 2 + j) * 4], &val.elements[i][j], sizeof(float)); + memcpy(&buf[(i * 2 + j) * sizeof(real_t)], &val.elements[i][j], sizeof(real_t)); } } } - r_len += 6 * 4; + r_len += 6 * sizeof(real_t); } break; case Variant::PLANE: { if (buf) { Plane p = p_variant; - encode_float(p.normal.x, &buf[0]); - encode_float(p.normal.y, &buf[4]); - encode_float(p.normal.z, &buf[8]); - encode_float(p.d, &buf[12]); + encode_real(p.normal.x, &buf[0]); + encode_real(p.normal.y, &buf[sizeof(real_t)]); + encode_real(p.normal.z, &buf[sizeof(real_t) * 2]); + encode_real(p.d, &buf[sizeof(real_t) * 3]); } - r_len += 4 * 4; + r_len += 4 * sizeof(real_t); } break; case Variant::QUATERNION: { if (buf) { Quaternion q = p_variant; - encode_float(q.x, &buf[0]); - encode_float(q.y, &buf[4]); - encode_float(q.z, &buf[8]); - encode_float(q.w, &buf[12]); + encode_real(q.x, &buf[0]); + encode_real(q.y, &buf[sizeof(real_t)]); + encode_real(q.z, &buf[sizeof(real_t) * 2]); + encode_real(q.w, &buf[sizeof(real_t) * 3]); } - r_len += 4 * 4; + r_len += 4 * sizeof(real_t); } break; case Variant::AABB: { if (buf) { AABB aabb = p_variant; - encode_float(aabb.position.x, &buf[0]); - encode_float(aabb.position.y, &buf[4]); - encode_float(aabb.position.z, &buf[8]); - encode_float(aabb.size.x, &buf[12]); - encode_float(aabb.size.y, &buf[16]); - encode_float(aabb.size.z, &buf[20]); + encode_real(aabb.position.x, &buf[0]); + encode_real(aabb.position.y, &buf[sizeof(real_t)]); + encode_real(aabb.position.z, &buf[sizeof(real_t) * 2]); + encode_real(aabb.size.x, &buf[sizeof(real_t) * 3]); + encode_real(aabb.size.y, &buf[sizeof(real_t) * 4]); + encode_real(aabb.size.z, &buf[sizeof(real_t) * 5]); } - r_len += 6 * 4; + r_len += 6 * sizeof(real_t); } break; case Variant::BASIS: { @@ -1130,12 +1297,12 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo Basis val = p_variant; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { - memcpy(&buf[(i * 3 + j) * 4], &val.elements[i][j], sizeof(float)); + memcpy(&buf[(i * 3 + j) * sizeof(real_t)], &val.elements[i][j], sizeof(real_t)); } } } - r_len += 9 * 4; + r_len += 9 * sizeof(real_t); } break; case Variant::TRANSFORM3D: { @@ -1143,16 +1310,16 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo Transform3D val = p_variant; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { - memcpy(&buf[(i * 3 + j) * 4], &val.basis.elements[i][j], sizeof(float)); + memcpy(&buf[(i * 3 + j) * sizeof(real_t)], &val.basis.elements[i][j], sizeof(real_t)); } } - encode_float(val.origin.x, &buf[36]); - encode_float(val.origin.y, &buf[40]); - encode_float(val.origin.z, &buf[44]); + encode_real(val.origin.x, &buf[sizeof(real_t) * 9]); + encode_real(val.origin.y, &buf[sizeof(real_t) * 10]); + encode_real(val.origin.z, &buf[sizeof(real_t) * 11]); } - r_len += 12 * 4; + r_len += 12 * sizeof(real_t); } break; @@ -1166,7 +1333,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo encode_float(c.a, &buf[12]); } - r_len += 4 * 4; + r_len += 4 * 4; // Colors should always be in single-precision. } break; case Variant::RID: { @@ -1441,13 +1608,13 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo for (int i = 0; i < len; i++) { Vector2 v = data.get(i); - encode_float(v.x, &buf[0]); - encode_float(v.y, &buf[4]); - buf += 4 * 2; + encode_real(v.x, &buf[0]); + encode_real(v.y, &buf[sizeof(real_t)]); + buf += sizeof(real_t) * 2; } } - r_len += 4 * 2 * len; + r_len += sizeof(real_t) * 2 * len; } break; case Variant::PACKED_VECTOR3_ARRAY: { @@ -1465,14 +1632,14 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo for (int i = 0; i < len; i++) { Vector3 v = data.get(i); - encode_float(v.x, &buf[0]); - encode_float(v.y, &buf[4]); - encode_float(v.z, &buf[8]); - buf += 4 * 3; + encode_real(v.x, &buf[0]); + encode_real(v.y, &buf[sizeof(real_t)]); + encode_real(v.z, &buf[sizeof(real_t) * 2]); + buf += sizeof(real_t) * 3; } } - r_len += 4 * 3 * len; + r_len += sizeof(real_t) * 3 * len; } break; case Variant::PACKED_COLOR_ARRAY: { @@ -1494,7 +1661,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo encode_float(c.g, &buf[4]); encode_float(c.b, &buf[8]); encode_float(c.a, &buf[12]); - buf += 4 * 4; + buf += 4 * 4; // Colors should always be in single-precision. } } diff --git a/core/io/marshalls.h b/core/io/marshalls.h index 7fac708f97..3ebed914a3 100644 --- a/core/io/marshalls.h +++ b/core/io/marshalls.h @@ -31,10 +31,18 @@ #ifndef MARSHALLS_H #define MARSHALLS_H +#include "core/math/math_defs.h" #include "core/object/ref_counted.h" #include "core/typedefs.h" #include "core/variant/variant.h" +// uintr_t is only for pairing with real_t, and we only need it in here. +#ifdef REAL_T_IS_DOUBLE +typedef uint64_t uintr_t; +#else +typedef uint32_t uintr_t; +#endif + /** * Miscellaneous helpers for marshalling data types, and encoding * in an endian independent way @@ -50,6 +58,12 @@ union MarshallDouble { double d; ///< double }; +// Behaves like one of the above, depending on compilation setting. +union MarshallReal { + uintr_t i; + real_t r; +}; + static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) { for (int i = 0; i < 2; i++) { *p_arr = p_uint & 0xFF; @@ -96,6 +110,24 @@ static inline unsigned int encode_double(double p_double, uint8_t *p_arr) { return sizeof(uint64_t); } +static inline unsigned int encode_uintr(uintr_t p_uint, uint8_t *p_arr) { + for (size_t i = 0; i < sizeof(uintr_t); i++) { + *p_arr = p_uint & 0xFF; + p_arr++; + p_uint >>= 8; + } + + return sizeof(uintr_t); +} + +static inline unsigned int encode_real(real_t p_real, uint8_t *p_arr) { + MarshallReal mr; + mr.r = p_real; + encode_uintr(mr.i, p_arr); + + return sizeof(uintr_t); +} + static inline int encode_cstring(const char *p_string, uint8_t *p_data) { int len = 0; 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/register_core_types.cpp b/core/register_core_types.cpp index f67d615418..fc8ab72e1a 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -86,7 +86,6 @@ static _OS *_os = nullptr; static _Engine *_engine = nullptr; static _ClassDB *_classdb = nullptr; static _Marshalls *_marshalls = nullptr; -static _JSON *_json = nullptr; static _EngineDebugger *_engine_debugger = nullptr; static IP *ip = nullptr; @@ -199,7 +198,7 @@ void register_core_types() { ClassDB::register_class<_Semaphore>(); ClassDB::register_class<XMLParser>(); - ClassDB::register_class<JSONParser>(); + ClassDB::register_class<JSON>(); ClassDB::register_class<ConfigFile>(); @@ -212,8 +211,6 @@ void register_core_types() { ClassDB::register_class<EncodedObjectAsID>(); ClassDB::register_class<RandomNumberGenerator>(); - ClassDB::register_class<JSONParseResult>(); - ClassDB::register_virtual_class<ResourceImporter>(); ip = IP::create(); @@ -227,7 +224,6 @@ void register_core_types() { _engine = memnew(_Engine); _classdb = memnew(_ClassDB); _marshalls = memnew(_Marshalls); - _json = memnew(_JSON); _engine_debugger = memnew(_EngineDebugger); } @@ -256,7 +252,6 @@ void register_core_singletons() { ClassDB::register_class<TranslationServer>(); ClassDB::register_virtual_class<Input>(); ClassDB::register_class<InputMap>(); - ClassDB::register_class<_JSON>(); ClassDB::register_class<Expression>(); ClassDB::register_class<_EngineDebugger>(); ClassDB::register_class<Time>(); @@ -274,7 +269,6 @@ void register_core_singletons() { Engine::get_singleton()->add_singleton(Engine::Singleton("TranslationServer", TranslationServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("Input", Input::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("InputMap", InputMap::get_singleton())); - Engine::get_singleton()->add_singleton(Engine::Singleton("JSON", _JSON::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("EngineDebugger", _EngineDebugger::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("Time", Time::get_singleton())); } @@ -286,7 +280,6 @@ void unregister_core_types() { memdelete(_engine); memdelete(_classdb); memdelete(_marshalls); - memdelete(_json); memdelete(_engine_debugger); memdelete(_geometry_2d); 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/bin_sorted_array.h b/core/templates/bin_sorted_array.h new file mode 100644 index 0000000000..be9d0b5475 --- /dev/null +++ b/core/templates/bin_sorted_array.h @@ -0,0 +1,181 @@ +/*************************************************************************/ +/* bin_sorted_array.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 BIN_SORTED_ARRAY_H +#define BIN_SORTED_ARRAY_H + +#include "core/templates/local_vector.h" +#include "core/templates/paged_array.h" + +template <class T> +class BinSortedArray { + PagedArray<T> array; + LocalVector<uint64_t> bin_limits; + + // Implement if elements need to keep track of their own index in the array. + _FORCE_INLINE_ virtual void _update_idx(T &r_element, uint64_t p_idx) {} + + _FORCE_INLINE_ void _swap(uint64_t p_a, uint64_t p_b) { + SWAP(array[p_a], array[p_b]); + _update_idx(array[p_a], p_a); + _update_idx(array[p_b], p_b); + } + +public: + uint64_t insert(T &p_element, uint64_t p_bin) { + array.push_back(p_element); + uint64_t new_idx = array.size() - 1; + _update_idx(p_element, new_idx); + bin_limits[0] = new_idx; + if (p_bin != 0) { + new_idx = move(new_idx, p_bin); + } + return new_idx; + } + + uint64_t move(uint64_t p_idx, uint64_t p_bin) { + ERR_FAIL_COND_V(p_idx >= array.size(), -1); + + uint64_t current_bin = bin_limits.size() - 1; + while (p_idx > bin_limits[current_bin]) { + current_bin--; + } + + if (p_bin == current_bin) { + return p_idx; + } + + uint64_t current_idx = p_idx; + if (p_bin > current_bin) { + while (p_bin > current_bin) { + uint64_t swap_idx = 0; + + if (current_bin == bin_limits.size() - 1) { + bin_limits.push_back(0); + } else { + bin_limits[current_bin + 1]++; + swap_idx = bin_limits[current_bin + 1]; + } + + if (current_idx != swap_idx) { + _swap(current_idx, swap_idx); + current_idx = swap_idx; + } + + current_bin++; + } + } else { + while (p_bin < current_bin) { + uint64_t swap_idx = bin_limits[current_bin]; + + if (current_idx != swap_idx) { + _swap(current_idx, swap_idx); + } + + if (current_bin == bin_limits.size() - 1 && bin_limits[current_bin] == 0) { + bin_limits.resize(bin_limits.size() - 1); + } else { + bin_limits[current_bin]--; + } + current_idx = swap_idx; + current_bin--; + } + } + + return current_idx; + } + + void remove(uint64_t p_idx) { + ERR_FAIL_COND(p_idx >= array.size()); + uint64_t new_idx = move(p_idx, 0); + uint64_t swap_idx = array.size() - 1; + + if (new_idx != swap_idx) { + _swap(new_idx, swap_idx); + } + + if (bin_limits[0] > 0) { + bin_limits[0]--; + } + + array.pop_back(); + } + + void set_page_pool(PagedArrayPool<T> *p_page_pool) { + array.set_page_pool(p_page_pool); + } + + _FORCE_INLINE_ const T &operator[](uint64_t p_index) const { + return array[p_index]; + } + + _FORCE_INLINE_ T &operator[](uint64_t p_index) { + return array[p_index]; + } + + int get_bin_count() { + if (array.size() == 0) { + return 0; + } + return bin_limits.size(); + } + + int get_bin_start(int p_bin) { + ERR_FAIL_COND_V(p_bin >= get_bin_count(), ~0U); + if ((unsigned int)p_bin == bin_limits.size() - 1) { + return 0; + } + return bin_limits[p_bin + 1] + 1; + } + + int get_bin_size(int p_bin) { + ERR_FAIL_COND_V(p_bin >= get_bin_count(), 0); + if ((unsigned int)p_bin == bin_limits.size() - 1) { + return bin_limits[p_bin] + 1; + } + return bin_limits[p_bin] - bin_limits[p_bin + 1]; + } + + void reset() { + array.reset(); + bin_limits.clear(); + bin_limits.push_back(0); + } + + BinSortedArray() { + bin_limits.push_back(0); + } + + virtual ~BinSortedArray() { + reset(); + } +}; + +#endif //BIN_SORTED_ARRAY_H 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..badb5ba103 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -32,6 +32,7 @@ #include "core/core_string_names.h" #include "core/debugger/engine_debugger.h" +#include "core/io/json.h" #include "core/io/marshalls.h" #include "core/io/resource.h" #include "core/math/math_funcs.h" @@ -1698,6 +1699,7 @@ String Variant::stringify(List<const void *> &stack) const { } str += "}"; + stack.erase(d.id()); return str; } break; case PACKED_VECTOR2_ARRAY: { @@ -1801,6 +1803,7 @@ String Variant::stringify(List<const void *> &stack) const { } str += "]"; + stack.erase(arr.id()); return str; } break; @@ -1836,6 +1839,11 @@ String Variant::stringify(List<const void *> &stack) const { return ""; } +String Variant::to_json_string() const { + JSON json; + return json.stringify(*this); +} + Variant::operator Vector2() const { if (type == VECTOR2) { return *reinterpret_cast<const Vector2 *>(_data._mem); diff --git a/core/variant/variant.h b/core/variant/variant.h index 75316da63f..125173ea5c 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -645,6 +645,7 @@ public: bool hash_compare(const Variant &p_variant) const; bool booleanize() const; String stringify(List<const void *> &stack) const; + String to_json_string() const; void static_assign(const Variant &p_variant); static void get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants); 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 |