diff options
Diffstat (limited to 'core')
| -rw-r--r-- | core/core_bind.cpp | 2 | ||||
| -rw-r--r-- | core/input/input.cpp | 10 | ||||
| -rw-r--r-- | core/io/resource_loader.cpp | 4 | ||||
| -rw-r--r-- | core/io/resource_loader.h | 2 | ||||
| -rw-r--r-- | core/object/undo_redo.cpp | 2 | ||||
| -rw-r--r-- | core/templates/cowdata.h | 32 | ||||
| -rw-r--r-- | core/templates/safe_refcount.h | 10 |
7 files changed, 43 insertions, 19 deletions
diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 2fcaac3688..0da6680a7b 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -135,7 +135,7 @@ void _ResourceLoader::_bind_methods() { ClassDB::bind_method(D_METHOD("load_threaded_get_status", "path", "progress"), &_ResourceLoader::load_threaded_get_status, DEFVAL(Array())); ClassDB::bind_method(D_METHOD("load_threaded_get", "path"), &_ResourceLoader::load_threaded_get); - ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "no_cache"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(CACHE_MODE_REUSE)); + ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "cache_mode"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(CACHE_MODE_REUSE)); ClassDB::bind_method(D_METHOD("get_recognized_extensions_for_type", "type"), &_ResourceLoader::get_recognized_extensions_for_type); ClassDB::bind_method(D_METHOD("set_abort_on_missing_resources", "abort"), &_ResourceLoader::set_abort_on_missing_resources); ClassDB::bind_method(D_METHOD("get_dependencies", "path"), &_ResourceLoader::get_dependencies); diff --git a/core/input/input.cpp b/core/input/input.cpp index 90d96e3876..94a18b5b4f 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -97,11 +97,11 @@ void Input::_bind_methods() { ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &Input::is_key_pressed); ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &Input::is_mouse_button_pressed); ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &Input::is_joy_button_pressed); - ClassDB::bind_method(D_METHOD("is_action_pressed", "action", "exact"), &Input::is_action_pressed, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action", "exact"), &Input::is_action_just_pressed, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("is_action_just_released", "action", "exact"), &Input::is_action_just_released, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("get_action_strength", "action", "exact"), &Input::get_action_strength, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("get_action_raw_strength", "action", "exact"), &Input::get_action_strength, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("is_action_pressed", "action", "exact_match"), &Input::is_action_pressed, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action", "exact_match"), &Input::is_action_just_pressed, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("is_action_just_released", "action", "exact_match"), &Input::is_action_just_released, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_action_strength", "action", "exact_match"), &Input::get_action_strength, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("get_action_raw_strength", "action", "exact_match"), &Input::get_action_strength, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_axis", "negative_action", "positive_action"), &Input::get_axis); ClassDB::bind_method(D_METHOD("get_vector", "negative_x", "positive_x", "negative_y", "positive_y", "deadzone"), &Input::get_vector, DEFVAL(-1.0f)); ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &Input::add_joy_mapping, DEFVAL(false)); diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index b34a083f1e..cba9a47187 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -174,6 +174,10 @@ void ResourceFormatLoader::_bind_methods() { ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_resource_type", PropertyInfo(Variant::STRING, "path"))); ClassDB::add_virtual_method(get_class_static(), MethodInfo("get_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "add_types"))); ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "rename_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "renames"))); + + BIND_ENUM_CONSTANT(CACHE_MODE_IGNORE); + BIND_ENUM_CONSTANT(CACHE_MODE_REUSE); + BIND_ENUM_CONSTANT(CACHE_MODE_REPLACE); } /////////////////////////////////// diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 38a756c52f..914d988caa 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -66,6 +66,8 @@ public: virtual ~ResourceFormatLoader() {} }; +VARIANT_ENUM_CAST(ResourceFormatLoader::CacheMode) + typedef void (*ResourceLoadErrorNotify)(void *p_ud, const String &p_text); typedef void (*DependencyErrorNotify)(void *p_ud, const String &p_loading, const String &p_which, const String &p_type); diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp index 3b1165b8f6..e8735e335c 100644 --- a/core/object/undo_redo.cpp +++ b/core/object/undo_redo.cpp @@ -532,7 +532,7 @@ void UndoRedo::_bind_methods() { ClassDB::bind_method(D_METHOD("get_history_count"), &UndoRedo::get_history_count); ClassDB::bind_method(D_METHOD("get_current_action"), &UndoRedo::get_current_action); - ClassDB::bind_method(D_METHOD("get_action_name"), &UndoRedo::get_action_name); + ClassDB::bind_method(D_METHOD("get_action_name", "id"), &UndoRedo::get_action_name); ClassDB::bind_method(D_METHOD("clear_history", "increase_version"), &UndoRedo::clear_history, DEFVAL(true)); ClassDB::bind_method(D_METHOD("get_current_action_name"), &UndoRedo::get_current_action_name); diff --git a/core/templates/cowdata.h b/core/templates/cowdata.h index 6077f5f107..525d9e77cb 100644 --- a/core/templates/cowdata.h +++ b/core/templates/cowdata.h @@ -45,8 +45,9 @@ class CharString; template <class T, class V> class VMap; -// CowData is relying on this to be true -static_assert(sizeof(SafeNumeric<uint32_t>) == sizeof(uint32_t)); +#if !defined(NO_THREADS) +SAFE_NUMERIC_TYPE_PUN_GUARANTEES(uint32_t) +#endif template <class T> class CowData { @@ -114,7 +115,7 @@ private: void _unref(void *p_data); void _ref(const CowData *p_from); void _ref(const CowData &p_from); - void _copy_on_write(); + uint32_t _copy_on_write(); public: void operator=(const CowData<T> &p_from) { _ref(p_from); } @@ -217,20 +218,21 @@ void CowData<T>::_unref(void *p_data) { } template <class T> -void CowData<T>::_copy_on_write() { +uint32_t CowData<T>::_copy_on_write() { if (!_ptr) { - return; + return 0; } SafeNumeric<uint32_t> *refc = _get_refcount(); - if (unlikely(refc->get() > 1)) { + uint32_t rc = refc->get(); + if (unlikely(rc > 1)) { /* in use by more than me */ uint32_t current_size = *_get_size(); uint32_t *mem_new = (uint32_t *)Memory::alloc_static(_get_alloc_size(current_size), true); - reinterpret_cast<SafeNumeric<uint32_t> *>(mem_new - 2)->set(1); //refcount + new (mem_new - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(1); //refcount *(mem_new - 1) = current_size; //size T *_data = (T *)(mem_new); @@ -247,7 +249,10 @@ void CowData<T>::_copy_on_write() { _unref(_ptr); _ptr = _data; + + rc = 1; } + return rc; } template <class T> @@ -268,7 +273,7 @@ Error CowData<T>::resize(int p_size) { } // possibly changing size, copy on write - _copy_on_write(); + uint32_t rc = _copy_on_write(); size_t current_alloc_size = _get_alloc_size(current_size); size_t alloc_size; @@ -281,13 +286,15 @@ Error CowData<T>::resize(int p_size) { uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true); ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY); *(ptr - 1) = 0; //size, currently none - reinterpret_cast<SafeNumeric<uint32_t> *>(ptr - 2)->set(1); //refcount + new (ptr - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(1); //refcount _ptr = (T *)ptr; } else { - void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true); + uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true); ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY); + new (_ptrnew - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(rc); //refcount + _ptr = (T *)(_ptrnew); } } @@ -314,8 +321,9 @@ Error CowData<T>::resize(int p_size) { } if (alloc_size != current_alloc_size) { - void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true); + uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true); ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY); + new (_ptrnew - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(rc); //refcount _ptr = (T *)(_ptrnew); } @@ -362,7 +370,7 @@ void CowData<T>::_ref(const CowData &p_from) { return; //nothing to do } - if (p_from._get_refcount()->increment() > 0) { // could reference + if (p_from._get_refcount()->conditional_increment() > 0) { // could reference _ptr = p_from._ptr; } } diff --git a/core/templates/safe_refcount.h b/core/templates/safe_refcount.h index 6aebc24ec3..cdc9908a5f 100644 --- a/core/templates/safe_refcount.h +++ b/core/templates/safe_refcount.h @@ -47,10 +47,18 @@ // value and, as an important benefit, you can be sure the value is properly synchronized // even with threads that are already running. +// This is used in very specific areas of the engine where it's critical that these guarantees are held +#define SAFE_NUMERIC_TYPE_PUN_GUARANTEES(m_type) \ + static_assert(sizeof(SafeNumeric<m_type>) == sizeof(m_type)); \ + static_assert(alignof(SafeNumeric<m_type>) == alignof(m_type)); \ + static_assert(std::is_trivially_destructible<std::atomic<m_type>>::value); + template <class T> class SafeNumeric { std::atomic<T> value; + static_assert(std::atomic<T>::is_always_lock_free); + public: _ALWAYS_INLINE_ void set(T p_value) { value.store(p_value, std::memory_order_release); @@ -128,6 +136,8 @@ public: class SafeFlag { std::atomic_bool flag; + static_assert(std::atomic_bool::is_always_lock_free); + public: _ALWAYS_INLINE_ bool is_set() const { return flag.load(std::memory_order_acquire); |