diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/config/project_settings.cpp | 1 | ||||
-rw-r--r-- | core/extension/gdnative_interface.cpp | 6 | ||||
-rw-r--r-- | core/extension/gdnative_interface.h | 11 | ||||
-rw-r--r-- | core/input/input_event.cpp | 18 | ||||
-rw-r--r-- | core/io/compression.cpp | 5 | ||||
-rw-r--r-- | core/io/http_client_tcp.cpp | 1 | ||||
-rw-r--r-- | core/io/multiplayer_api.cpp | 2 | ||||
-rw-r--r-- | core/object/object.cpp | 61 | ||||
-rw-r--r-- | core/object/object.h | 35 | ||||
-rw-r--r-- | core/object/ref_counted.cpp | 19 | ||||
-rw-r--r-- | core/os/os.h | 2 | ||||
-rw-r--r-- | core/templates/list.h | 77 | ||||
-rw-r--r-- | core/templates/map.h | 133 | ||||
-rw-r--r-- | core/templates/pair.h | 35 | ||||
-rw-r--r-- | core/templates/rid_owner.h | 2 | ||||
-rw-r--r-- | core/templates/set.h | 79 | ||||
-rw-r--r-- | core/templates/vector.h | 64 | ||||
-rw-r--r-- | core/variant/variant_parser.cpp | 32 |
18 files changed, 491 insertions, 92 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 25506e8db3..29f53482fa 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1114,6 +1114,7 @@ ProjectSettings::ProjectSettings() { // Keep the enum values in sync with the `DisplayServer::ScreenOrientation` enum. custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::INT, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "Landscape,Portrait,Reverse Landscape,Reverse Portrait,Sensor Landscape,Sensor Portrait,Sensor"); + custom_prop_info["display/window/vsync/vsync_mode"] = PropertyInfo(Variant::STRING, "display/window/vsync/vsync_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Adaptive,Mailbox"); custom_prop_info["rendering/driver/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/driver/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded"); GLOBAL_DEF("physics/2d/run_on_thread", false); GLOBAL_DEF("physics/3d/run_on_thread", false); diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp index 324933d7b7..8f68b8d848 100644 --- a/core/extension/gdnative_interface.cpp +++ b/core/extension/gdnative_interface.cpp @@ -520,6 +520,11 @@ static GDNativeObjectPtr gdnative_global_get_singleton(const char *p_name) { return (GDNativeObjectPtr)Engine::get_singleton()->get_singleton_object(String(p_name)); } +static void *gdnative_object_get_instance_binding(GDNativeObjectPtr p_instance, void *p_token, GDNativeInstanceBindingCallbacks *p_callbacks) { + Object *o = (Object *)p_instance; + return o->get_instance_binding(p_token, p_callbacks); +} + static GDNativeObjectPtr gdnative_object_get_instance_from_id(GDObjectInstanceID p_instance_id) { return (GDNativeObjectPtr)ObjectDB::get_instance(ObjectID(p_instance_id)); } @@ -665,6 +670,7 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) { gdni.object_method_bind_ptrcall = gdnative_object_method_bind_ptrcall; gdni.object_destroy = gdnative_object_destroy; gdni.global_get_singleton = gdnative_global_get_singleton; + gdni.object_get_instance_binding = gdnative_object_get_instance_binding; gdni.object_cast_to = gdnative_object_cast_to; gdni.object_get_instance_from_id = gdnative_object_get_instance_from_id; diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h index 318912e889..c1ebb3e76a 100644 --- a/core/extension/gdnative_interface.h +++ b/core/extension/gdnative_interface.h @@ -171,6 +171,16 @@ typedef void (*GDNativePtrUtilityFunction)(GDNativeTypePtr r_return, const GDNat typedef GDNativeObjectPtr (*GDNativeClassConstructor)(); +typedef void *(*GDNativeInstanceBindingCreateCallback)(void *p_token, void *p_instance); +typedef void (*GDNativeInstanceBindingFreeCallback)(void *p_token, void *p_instance, void *p_binding); +typedef GDNativeBool (*GDNativeInstanceBindingReferenceCallback)(void *p_token, void *p_instance, GDNativeBool p_reference); + +struct GDNativeInstanceBindingCallbacks { + GDNativeInstanceBindingCreateCallback create_callback; + GDNativeInstanceBindingFreeCallback free_callback; + GDNativeInstanceBindingReferenceCallback reference_callback; +}; + /* EXTENSION CLASSES */ typedef void *GDExtensionClassInstancePtr; @@ -373,6 +383,7 @@ typedef struct { void (*object_method_bind_ptrcall)(GDNativeMethodBindPtr p_method_bind, GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_ret); void (*object_destroy)(GDNativeObjectPtr p_o); GDNativeObjectPtr (*global_get_singleton)(const char *p_name); + void *(*object_get_instance_binding)(GDNativeObjectPtr p_o, void *p_token, GDNativeInstanceBindingCallbacks *p_callbacks); GDNativeObjectPtr (*object_cast_to)(const GDNativeObjectPtr p_object, void *p_class_tag); GDNativeObjectPtr (*object_get_instance_from_id)(GDObjectInstanceID p_instance_id); diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 52a6c5d64f..4a2abffae8 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -38,6 +38,7 @@ const int InputEvent::DEVICE_ID_INTERNAL = -2; void InputEvent::set_device(int p_device) { device = p_device; + emit_changed(); } int InputEvent::get_device() const { @@ -131,6 +132,7 @@ void InputEventFromWindow::_bind_methods() { void InputEventFromWindow::set_window_id(int64_t p_id) { window_id = p_id; + emit_changed(); } int64_t InputEventFromWindow::get_window_id() const { @@ -141,6 +143,7 @@ int64_t InputEventFromWindow::get_window_id() const { void InputEventWithModifiers::set_store_command(bool p_enabled) { store_command = p_enabled; + emit_changed(); } bool InputEventWithModifiers::is_storing_command() const { @@ -149,6 +152,7 @@ bool InputEventWithModifiers::is_storing_command() const { void InputEventWithModifiers::set_shift_pressed(bool p_enabled) { shift_pressed = p_enabled; + emit_changed(); } bool InputEventWithModifiers::is_shift_pressed() const { @@ -157,6 +161,7 @@ bool InputEventWithModifiers::is_shift_pressed() const { void InputEventWithModifiers::set_alt_pressed(bool p_enabled) { alt_pressed = p_enabled; + emit_changed(); } bool InputEventWithModifiers::is_alt_pressed() const { @@ -165,6 +170,7 @@ bool InputEventWithModifiers::is_alt_pressed() const { void InputEventWithModifiers::set_ctrl_pressed(bool p_enabled) { ctrl_pressed = p_enabled; + emit_changed(); } bool InputEventWithModifiers::is_ctrl_pressed() const { @@ -173,6 +179,7 @@ bool InputEventWithModifiers::is_ctrl_pressed() const { void InputEventWithModifiers::set_meta_pressed(bool p_enabled) { meta_pressed = p_enabled; + emit_changed(); } bool InputEventWithModifiers::is_meta_pressed() const { @@ -181,6 +188,7 @@ bool InputEventWithModifiers::is_meta_pressed() const { void InputEventWithModifiers::set_command_pressed(bool p_enabled) { command_pressed = p_enabled; + emit_changed(); } bool InputEventWithModifiers::is_command_pressed() const { @@ -291,6 +299,7 @@ void InputEventWithModifiers::_validate_property(PropertyInfo &property) const { void InputEventKey::set_pressed(bool p_pressed) { pressed = p_pressed; + emit_changed(); } bool InputEventKey::is_pressed() const { @@ -299,6 +308,7 @@ bool InputEventKey::is_pressed() const { void InputEventKey::set_keycode(uint32_t p_keycode) { keycode = p_keycode; + emit_changed(); } uint32_t InputEventKey::get_keycode() const { @@ -307,6 +317,7 @@ uint32_t InputEventKey::get_keycode() const { void InputEventKey::set_physical_keycode(uint32_t p_keycode) { physical_keycode = p_keycode; + emit_changed(); } uint32_t InputEventKey::get_physical_keycode() const { @@ -315,6 +326,7 @@ uint32_t InputEventKey::get_physical_keycode() const { void InputEventKey::set_unicode(uint32_t p_unicode) { unicode = p_unicode; + emit_changed(); } uint32_t InputEventKey::get_unicode() const { @@ -323,6 +335,7 @@ uint32_t InputEventKey::get_unicode() const { void InputEventKey::set_echo(bool p_enable) { echo = p_enable; + emit_changed(); } bool InputEventKey::is_echo() const { @@ -469,6 +482,7 @@ void InputEventKey::_bind_methods() { void InputEventMouse::set_button_mask(int p_mask) { button_mask = p_mask; + emit_changed(); } int InputEventMouse::get_button_mask() const { @@ -518,6 +532,7 @@ float InputEventMouseButton::get_factor() const { void InputEventMouseButton::set_button_index(MouseButton p_index) { button_index = p_index; + emit_changed(); } MouseButton InputEventMouseButton::get_button_index() const { @@ -847,6 +862,7 @@ void InputEventMouseMotion::_bind_methods() { void InputEventJoypadMotion::set_axis(JoyAxis p_axis) { axis = p_axis; + emit_changed(); } JoyAxis InputEventJoypadMotion::get_axis() const { @@ -855,6 +871,7 @@ JoyAxis InputEventJoypadMotion::get_axis() const { void InputEventJoypadMotion::set_axis_value(float p_value) { axis_value = p_value; + emit_changed(); } float InputEventJoypadMotion::get_axis_value() const { @@ -949,6 +966,7 @@ void InputEventJoypadMotion::_bind_methods() { void InputEventJoypadButton::set_button_index(JoyButton p_index) { button_index = p_index; + emit_changed(); } JoyButton InputEventJoypadButton::get_button_index() const { diff --git a/core/io/compression.cpp b/core/io/compression.cpp index 6de626db99..ca56509253 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -238,7 +238,10 @@ int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_s case Z_DATA_ERROR: case Z_MEM_ERROR: case Z_STREAM_ERROR: - WARN_PRINT(strm.msg); + case Z_BUF_ERROR: + if (strm.msg) { + WARN_PRINT(strm.msg); + } (void)inflateEnd(&strm); p_dst_vect->resize(0); return ret; diff --git a/core/io/http_client_tcp.cpp b/core/io/http_client_tcp.cpp index f9b3165a07..f291086808 100644 --- a/core/io/http_client_tcp.cpp +++ b/core/io/http_client_tcp.cpp @@ -590,6 +590,7 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() { } } if (err != OK) { + ret.resize(_offset); break; } } diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 51ba8800e4..84f3608e0b 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -85,7 +85,7 @@ const MultiplayerAPI::RPCConfig _get_rpc_config_by_id(Node *p_node, uint16_t p_i if (id & (1 << 15)) { id = id & ~(1 << 15); config = p_node->get_node_rpc_methods(); - } else { + } else if (p_node->get_script_instance()) { config = p_node->get_script_instance()->get_rpc_methods(); } if (id < config.size()) { diff --git a/core/object/object.cpp b/core/object/object.cpp index 1c8db89e5e..296d876701 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -1769,42 +1769,41 @@ uint32_t Object::get_edited_version() const { } #endif -void *Object::get_script_instance_binding(int p_script_language_index) { -#ifdef DEBUG_ENABLED - ERR_FAIL_INDEX_V(p_script_language_index, MAX_SCRIPT_INSTANCE_BINDINGS, nullptr); -#endif - - //it's up to the script language to make this thread safe, if the function is called twice due to threads being out of sync - //just return the same pointer. - //if you want to put a big lock in the entire function and keep allocated pointers in a map or something, feel free to do it - //as it should not really affect performance much (won't be called too often), as in far most cases the condition below will be false afterwards - - if (!_script_instance_bindings[p_script_language_index]) { - void *script_data = ScriptServer::get_language(p_script_language_index)->alloc_instance_binding_data(this); - if (script_data) { - instance_binding_count.increment(); - _script_instance_bindings[p_script_language_index] = script_data; +void *Object::get_instance_binding(void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks) { + void *binding = nullptr; + _instance_binding_mutex.lock(); + for (uint32_t i = 0; i < _instance_binding_count; i++) { + if (_instance_bindings[i].token == p_token) { + binding = _instance_bindings[i].binding; + break; } } + if (unlikely(!binding)) { + uint32_t current_size = next_power_of_2(_instance_binding_count); + uint32_t new_size = next_power_of_2(_instance_binding_count + 1); - return _script_instance_bindings[p_script_language_index]; -} + if (current_size == 0 || new_size > current_size) { + _instance_bindings = (InstanceBinding *)memrealloc(_instance_bindings, new_size * sizeof(InstanceBinding)); + } -bool Object::has_script_instance_binding(int p_script_language_index) { - return _script_instance_bindings[p_script_language_index] != nullptr; -} + _instance_bindings[_instance_binding_count].free_callback = p_callbacks->free_callback; + _instance_bindings[_instance_binding_count].reference_callback = p_callbacks->reference_callback; + _instance_bindings[_instance_binding_count].token = p_token; -void Object::set_script_instance_binding(int p_script_language_index, void *p_data) { -#ifdef DEBUG_ENABLED - CRASH_COND(_script_instance_bindings[p_script_language_index] != nullptr); -#endif - _script_instance_bindings[p_script_language_index] = p_data; + binding = p_callbacks->create_callback(p_token, this); + _instance_bindings[_instance_binding_count].binding = binding; + + _instance_binding_count++; + } + + _instance_binding_mutex.unlock(); + + return binding; } void Object::_construct_object(bool p_reference) { type_is_reference = p_reference; _instance_id = ObjectDB::add_instance(this); - memset(_script_instance_bindings, 0, sizeof(void *) * MAX_SCRIPT_INSTANCE_BINDINGS); ClassDB::instance_get_native_extension_data(&_extension, &_extension_instance); @@ -1864,12 +1863,13 @@ Object::~Object() { _instance_id = ObjectID(); _predelete_ok = 2; - if (!ScriptServer::are_languages_finished()) { - for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) { - if (_script_instance_bindings[i]) { - ScriptServer::get_language(i)->free_instance_binding_data(_script_instance_bindings[i]); + if (_instance_bindings != nullptr) { + for (uint32_t i = 0; i < _instance_binding_count; i++) { + if (_instance_bindings[i].free_callback) { + _instance_bindings[i].free_callback(_instance_bindings[i].token, _instance_bindings[i].binding, this); } } + memfree(_instance_bindings); } } @@ -1887,7 +1887,6 @@ void ObjectDB::debug_objects(DebugFunc p_func) { for (uint32_t i = 0, count = slot_count; i < slot_max && count != 0; i++) { if (object_slots[i].validator) { p_func(object_slots[i].object); - count--; } } diff --git a/core/object/object.h b/core/object/object.h index e6eb6d1aaf..8389d80afc 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -480,10 +480,6 @@ public: }; private: - enum { - MAX_SCRIPT_INSTANCE_BINDINGS = 8 - }; - #ifdef DEBUG_ENABLED friend struct _ObjectDebugLock; #endif @@ -542,12 +538,35 @@ private: friend class RefCounted; bool type_is_reference = false; - SafeNumeric<uint32_t> instance_binding_count; - void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS]; + + std::mutex _instance_binding_mutex; + struct InstanceBinding { + void *binding; + void *token; + GDNativeInstanceBindingFreeCallback free_callback = nullptr; + GDNativeInstanceBindingReferenceCallback reference_callback = nullptr; + }; + InstanceBinding *_instance_bindings = nullptr; + uint32_t _instance_binding_count = 0; Object(bool p_reference); protected: + _FORCE_INLINE_ bool _instance_binding_reference(bool p_reference) { + bool can_die = true; + if (_instance_bindings) { + _instance_binding_mutex.lock(); + for (uint32_t i = 0; i < _instance_binding_count; i++) { + if (_instance_bindings[i].reference_callback) { + if (!_instance_bindings[i].reference_callback(_instance_bindings[i].token, _instance_bindings[i].binding, p_reference)) { + can_die = false; + } + } + } + _instance_binding_mutex.unlock(); + } + return can_die; + } friend class NativeExtensionMethodBind; _ALWAYS_INLINE_ const ObjectNativeExtension *_get_extension() const { return _extension; } _ALWAYS_INLINE_ GDExtensionClassInstancePtr _get_extension_instance() const { return _extension_instance; } @@ -785,9 +804,7 @@ public: #endif //used by script languages to store binding data - void *get_script_instance_binding(int p_script_language_index); - bool has_script_instance_binding(int p_script_language_index); - void set_script_instance_binding(int p_script_language_index, void *p_data); + void *get_instance_binding(void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks); void clear_internal_resource_paths(); diff --git a/core/object/ref_counted.cpp b/core/object/ref_counted.cpp index 9862624972..2833f774dc 100644 --- a/core/object/ref_counted.cpp +++ b/core/object/ref_counted.cpp @@ -65,13 +65,8 @@ bool RefCounted::reference() { if (_get_extension() && _get_extension()->reference) { _get_extension()->reference(_get_extension_instance()); } - if (instance_binding_count.get() > 0 && !ScriptServer::are_languages_finished()) { - for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) { - if (_script_instance_bindings[i]) { - ScriptServer::get_language(i)->refcount_incremented_instance_binding(this); - } - } - } + + _instance_binding_reference(true); } return success; @@ -89,14 +84,8 @@ bool RefCounted::unreference() { if (_get_extension() && _get_extension()->unreference) { _get_extension()->unreference(_get_extension_instance()); } - if (instance_binding_count.get() > 0 && !ScriptServer::are_languages_finished()) { - for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) { - if (_script_instance_bindings[i]) { - bool script_ret = ScriptServer::get_language(i)->refcount_decremented_instance_binding(this); - die = die && script_ret; - } - } - } + + die = die && _instance_binding_reference(false); } return die; diff --git a/core/os/os.h b/core/os/os.h index 444f67431f..301718a8b3 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -58,8 +58,6 @@ class OS { int _orientation; bool _allow_hidpi = false; bool _allow_layered = false; - bool _use_vsync; - bool _vsync_via_compositor; bool _stdout_enabled = true; bool _stderr_enabled = true; diff --git a/core/templates/list.h b/core/templates/list.h index 010e35eed8..6047b89670 100644 --- a/core/templates/list.h +++ b/core/templates/list.h @@ -135,6 +135,83 @@ public: _FORCE_INLINE_ Element() {} }; + typedef T ValueType; + + struct Iterator { + _FORCE_INLINE_ T &operator*() const { + return E->get(); + } + _FORCE_INLINE_ T *operator->() const { return &E->get(); } + _FORCE_INLINE_ Iterator &operator++() { + E = E->next(); + return *this; + } + _FORCE_INLINE_ Iterator &operator--() { + E = E->prev(); + return *this; + } + + _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; } + _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; } + + Iterator(Element *p_E) { E = p_E; } + Iterator() {} + Iterator(const Iterator &p_it) { E = p_it.E; } + + private: + Element *E = nullptr; + }; + + struct ConstIterator { + _FORCE_INLINE_ const T &operator*() const { + return E->get(); + } + _FORCE_INLINE_ const T *operator->() const { return &E->get(); } + _FORCE_INLINE_ ConstIterator &operator++() { + E = E->next(); + return *this; + } + _FORCE_INLINE_ ConstIterator &operator--() { + E = E->prev(); + return *this; + } + + _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; } + _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; } + + _FORCE_INLINE_ ConstIterator(const Element *p_E) { E = p_E; } + _FORCE_INLINE_ ConstIterator() {} + _FORCE_INLINE_ ConstIterator(const ConstIterator &p_it) { E = p_it.E; } + + private: + const Element *E = nullptr; + }; + + _FORCE_INLINE_ Iterator begin() { + return Iterator(front()); + } + _FORCE_INLINE_ Iterator end() { + return Iterator(nullptr); + } + +#if 0 + //to use when replacing find() + _FORCE_INLINE_ Iterator find(const K &p_key) { + return Iterator(find(p_key)); + } +#endif + _FORCE_INLINE_ ConstIterator begin() const { + return ConstIterator(front()); + } + _FORCE_INLINE_ ConstIterator end() const { + return ConstIterator(nullptr); + } +#if 0 + //to use when replacing find() + _FORCE_INLINE_ ConstIterator find(const K &p_key) const { + return ConstIterator(find(p_key)); + } +#endif private: struct _Data { Element *first = nullptr; diff --git a/core/templates/map.h b/core/templates/map.h index 7dfee13d2c..a47547d355 100644 --- a/core/templates/map.h +++ b/core/templates/map.h @@ -33,6 +33,7 @@ #include "core/error/error_macros.h" #include "core/os/memory.h" +#include "core/templates/pair.h" // based on the very nice implementation of rb-trees by: // https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html @@ -55,11 +56,12 @@ public: Element *parent = nullptr; Element *_next = nullptr; Element *_prev = nullptr; - K _key; - V _value; - //_Data *data; + KeyValue<K, V> _data; public: + KeyValue<K, V> &key_value() { return _data; } + const KeyValue<K, V> &key_value() const { return _data; } + const Element *next() const { return _next; } @@ -73,23 +75,106 @@ public: return _prev; } const K &key() const { - return _key; + return _data.key; } V &value() { - return _value; + return _data.value; } const V &value() const { - return _value; + return _data.value; } V &get() { - return _value; + return _data.value; } const V &get() const { - return _value; + return _data.value; } - Element() {} + Element(const KeyValue<K, V> &p_data) : + _data(p_data) {} }; + typedef KeyValue<K, V> ValueType; + + struct Iterator { + _FORCE_INLINE_ KeyValue<K, V> &operator*() const { + return E->key_value(); + } + _FORCE_INLINE_ KeyValue<K, V> *operator->() const { return &E->key_value(); } + _FORCE_INLINE_ Iterator &operator++() { + E = E->next(); + return *this; + } + _FORCE_INLINE_ Iterator &operator--() { + E = E->prev(); + return *this; + } + + _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; } + _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; } + + Iterator(Element *p_E) { E = p_E; } + Iterator() {} + Iterator(const Iterator &p_it) { E = p_it.E; } + + private: + Element *E = nullptr; + }; + + struct ConstIterator { + _FORCE_INLINE_ const KeyValue<K, V> &operator*() const { + return E->key_value(); + } + _FORCE_INLINE_ const KeyValue<K, V> *operator->() const { return &E->key_value(); } + _FORCE_INLINE_ ConstIterator &operator++() { + E = E->next(); + return *this; + } + _FORCE_INLINE_ ConstIterator &operator--() { + E = E->prev(); + return *this; + } + + _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return E == b.E; } + _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return E != b.E; } + + ConstIterator(const Element *p_E) { E = p_E; } + ConstIterator() {} + ConstIterator(const ConstIterator &p_it) { E = p_it.E; } + + private: + const Element *E = nullptr; + }; + + _FORCE_INLINE_ Iterator begin() { + return Iterator(front()); + } + _FORCE_INLINE_ Iterator end() { + return Iterator(nullptr); + } + +#if 0 + //to use when replacing find() + _FORCE_INLINE_ Iterator find(const K &p_key) { + return Iterator(find(p_key)); + } +#endif + _FORCE_INLINE_ void remove(const Iterator &p_iter) { + return erase(p_iter.E); + } + + _FORCE_INLINE_ ConstIterator begin() const { + return ConstIterator(front()); + } + _FORCE_INLINE_ ConstIterator end() const { + return ConstIterator(nullptr); + } + +#if 0 + //to use when replacing find() + _FORCE_INLINE_ ConstIterator find(const K &p_key) const { + return ConstIterator(find(p_key)); + } +#endif private: struct _Data { Element *_root = nullptr; @@ -107,7 +192,7 @@ private: } void _create_root() { - _root = memnew_allocator(Element, A); + _root = memnew_allocator(Element(KeyValue<K, V>(K(), V())), A); _root->parent = _root->left = _root->right = _nil; _root->color = BLACK; } @@ -216,9 +301,9 @@ private: C less; while (node != _data._nil) { - if (less(p_key, node->_key)) { + if (less(p_key, node->_data.key)) { node = node->left; - } else if (less(node->_key, p_key)) { + } else if (less(node->_data.key, p_key)) { node = node->right; } else { return node; // found @@ -236,9 +321,9 @@ private: while (node != _data._nil) { prev = node; - if (less(p_key, node->_key)) { + if (less(p_key, node->_data.key)) { node = node->left; - } else if (less(node->_key, p_key)) { + } else if (less(node->_data.key, p_key)) { node = node->right; } else { return node; // found @@ -249,7 +334,7 @@ private: return nullptr; // tree empty } - if (less(p_key, prev->_key)) { + if (less(p_key, prev->_data.key)) { prev = prev->_prev; } @@ -312,25 +397,25 @@ private: while (node != _data._nil) { new_parent = node; - if (less(p_key, node->_key)) { + if (less(p_key, node->_data.key)) { node = node->left; - } else if (less(node->_key, p_key)) { + } else if (less(node->_data.key, p_key)) { node = node->right; } else { - node->_value = p_value; + node->_data.value = p_value; return node; // Return existing node with new value } } - Element *new_node = memnew_allocator(Element, A); + typedef KeyValue<K, V> KV; + Element *new_node = memnew_allocator(Element(KV(p_key, p_value)), A); new_node->parent = new_parent; new_node->right = _data._nil; new_node->left = _data._nil; - new_node->_key = p_key; - new_node->_value = p_value; + //new_node->data=_data; - if (new_parent == _data._root || less(p_key, new_parent->_key)) { + if (new_parent == _data._root || less(p_key, new_parent->_data.key)) { new_parent->left = new_node; } else { new_parent->right = new_node; @@ -575,7 +660,7 @@ public: CRASH_COND(!_data._root); const Element *e = find(p_key); CRASH_COND(!e); - return e->_value; + return e->_data.value; } V &operator[](const K &p_key) { @@ -588,7 +673,7 @@ public: e = insert(p_key, V()); } - return e->_value; + return e->_data.value; } Element *front() const { diff --git a/core/templates/pair.h b/core/templates/pair.h index bc1a764694..31706b6ecb 100644 --- a/core/templates/pair.h +++ b/core/templates/pair.h @@ -31,6 +31,8 @@ #ifndef PAIR_H #define PAIR_H +#include "core/typedefs.h" + template <class F, class S> struct Pair { F first; @@ -64,4 +66,37 @@ struct PairSort { } }; +template <class K, class V> +struct KeyValue { + const K key; + V value; + + void operator=(const KeyValue &p_kv) = delete; + _FORCE_INLINE_ KeyValue(const KeyValue &p_kv) : + key(p_kv.key), + value(p_kv.value) { + } + _FORCE_INLINE_ KeyValue(const K &p_key, const V &p_value) : + key(p_key), + value(p_value) { + } +}; + +template <class K, class V> +bool operator==(const KeyValue<K, V> &pair, const KeyValue<K, V> &other) { + return (pair.key == other.key) && (pair.value == other.value); +} + +template <class K, class V> +bool operator!=(const KeyValue<K, V> &pair, const KeyValue<K, V> &other) { + return (pair.key != other.key) || (pair.value != other.value); +} + +template <class K, class V> +struct KeyValueSort { + bool operator()(const KeyValue<K, V> &A, const KeyValue<K, V> &B) const { + return A.key < B.key; + } +}; + #endif // PAIR_H diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h index e4964f744e..4f5c74ca46 100644 --- a/core/templates/rid_owner.h +++ b/core/templates/rid_owner.h @@ -193,7 +193,7 @@ public: if (THREAD_SAFE) { spin_lock.unlock(); } - if (validator_chunks[idx_chunk][idx_element] & 0x80000000) { + if ((validator_chunks[idx_chunk][idx_element] & 0x80000000) && validator_chunks[idx_chunk][idx_element] != 0xFFFFFFFF) { ERR_FAIL_V_MSG(nullptr, "Attempting to use an uninitialized RID"); } return nullptr; diff --git a/core/templates/set.h b/core/templates/set.h index 3036ecf27d..245c174862 100644 --- a/core/templates/set.h +++ b/core/templates/set.h @@ -77,6 +77,85 @@ public: Element() {} }; + typedef T ValueType; + + struct Iterator { + _FORCE_INLINE_ T &operator*() const { + return E->get(); + } + _FORCE_INLINE_ T *operator->() const { return &E->get(); } + _FORCE_INLINE_ Iterator &operator++() { + E = E->next(); + return *this; + } + _FORCE_INLINE_ Iterator &operator--() { + E = E->prev(); + return *this; + } + + _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; } + _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; } + + Iterator(Element *p_E) { E = p_E; } + Iterator() {} + Iterator(const Iterator &p_it) { E = p_it.E; } + + private: + Element *E = nullptr; + }; + + struct ConstIterator { + _FORCE_INLINE_ const T &operator*() const { + return E->get(); + } + _FORCE_INLINE_ const T *operator->() const { return &E->get(); } + _FORCE_INLINE_ ConstIterator &operator++() { + E = E->next(); + return *this; + } + _FORCE_INLINE_ ConstIterator &operator--() { + E = E->prev(); + return *this; + } + + _FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; } + _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; } + + _FORCE_INLINE_ ConstIterator(const Element *p_E) { E = p_E; } + _FORCE_INLINE_ ConstIterator() {} + _FORCE_INLINE_ ConstIterator(const ConstIterator &p_it) { E = p_it.E; } + + private: + const Element *E = nullptr; + }; + + _FORCE_INLINE_ Iterator begin() { + return Iterator(front()); + } + _FORCE_INLINE_ Iterator end() { + return Iterator(nullptr); + } + +#if 0 + //to use when replacing find() + _FORCE_INLINE_ Iterator find(const K &p_key) { + return Iterator(find(p_key)); + } +#endif + + _FORCE_INLINE_ ConstIterator begin() const { + return ConstIterator(front()); + } + _FORCE_INLINE_ ConstIterator end() const { + return ConstIterator(nullptr); + } + +#if 0 + //to use when replacing find() + _FORCE_INLINE_ ConstIterator find(const K &p_key) const { + return ConstIterator(find(p_key)); + } +#endif private: struct _Data { Element *_root = nullptr; diff --git a/core/templates/vector.h b/core/templates/vector.h index dae8874a87..08cbef6ba4 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -187,6 +187,70 @@ public: return false; } + struct Iterator { + _FORCE_INLINE_ T &operator*() const { + return *elem_ptr; + } + _FORCE_INLINE_ T *operator->() const { return elem_ptr; } + _FORCE_INLINE_ Iterator &operator++() { + elem_ptr++; + return *this; + } + _FORCE_INLINE_ Iterator &operator--() { + elem_ptr--; + return *this; + } + + _FORCE_INLINE_ bool operator==(const Iterator &b) const { return elem_ptr == b.elem_ptr; } + _FORCE_INLINE_ bool operator!=(const Iterator &b) const { return elem_ptr != b.elem_ptr; } + + Iterator(T *p_ptr) { elem_ptr = p_ptr; } + Iterator() {} + Iterator(const Iterator &p_it) { elem_ptr = p_it.elem_ptr; } + + private: + T *elem_ptr = nullptr; + }; + + struct ConstIterator { + _FORCE_INLINE_ const T &operator*() const { + return *elem_ptr; + } + _FORCE_INLINE_ const T *operator->() const { return elem_ptr; } + _FORCE_INLINE_ ConstIterator &operator++() { + elem_ptr++; + return *this; + } + _FORCE_INLINE_ ConstIterator &operator--() { + elem_ptr--; + return *this; + } + + _FORCE_INLINE_ bool operator==(const ConstIterator &b) const { return elem_ptr == b.elem_ptr; } + _FORCE_INLINE_ bool operator!=(const ConstIterator &b) const { return elem_ptr != b.elem_ptr; } + + ConstIterator(T *p_ptr) { elem_ptr = p_ptr; } + ConstIterator() {} + ConstIterator(const ConstIterator &p_it) { elem_ptr = p_it.elem_ptr; } + + private: + const T *elem_ptr = nullptr; + }; + + _FORCE_INLINE_ Iterator begin() { + return Iterator(ptrw()); + } + _FORCE_INLINE_ Iterator end() { + return Iterator(ptrw() + size()); + } + + _FORCE_INLINE_ ConstIterator begin() const { + return ConstIterator(ptr()); + } + _FORCE_INLINE_ ConstIterator end() const { + return ConstIterator(ptr() + size()); + } + _FORCE_INLINE_ Vector() {} _FORCE_INLINE_ Vector(const Vector &p_from) { _cowdata._ref(p_from._cowdata); } diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index e61ce1eeaa..86d5ae7f38 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -1204,16 +1204,32 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin r_tag.name = ""; r_tag.fields.clear(); - while (true) { - char32_t c = p_stream->get_char(); - if (p_stream->is_eof()) { - r_err_str = "Unexpected EOF while parsing simple tag"; - return ERR_PARSE_ERROR; + if (p_stream->is_utf8()) { + CharString cs; + while (true) { + char c = p_stream->get_char(); + if (p_stream->is_eof()) { + r_err_str = "Unexpected EOF while parsing simple tag"; + return ERR_PARSE_ERROR; + } + if (c == ']') { + break; + } + cs += c; } - if (c == ']') { - break; + r_tag.name.parse_utf8(cs.get_data(), cs.length()); + } else { + while (true) { + char32_t c = p_stream->get_char(); + if (p_stream->is_eof()) { + r_err_str = "Unexpected EOF while parsing simple tag"; + return ERR_PARSE_ERROR; + } + if (c == ']') { + break; + } + r_tag.name += String::chr(c); } - r_tag.name += String::chr(c); } r_tag.name = r_tag.name.strip_edges(); |