diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/object.cpp | 7 | ||||
-rw-r--r-- | core/object.h | 6 | ||||
-rw-r--r-- | core/reference.cpp | 29 | ||||
-rw-r--r-- | core/script_language.h | 2 |
4 files changed, 36 insertions, 8 deletions
diff --git a/core/object.cpp b/core/object.cpp index e83abaece7..24a31930a0 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1916,7 +1916,11 @@ void *Object::get_script_instance_binding(int p_script_language_index) { //as it should not really affect performance much (won't be called too often), as in far most caes the condition below will be false afterwards if (!_script_instance_bindings[p_script_language_index]) { - _script_instance_bindings[p_script_language_index] = ScriptServer::get_language(p_script_language_index)->alloc_instance_binding_data(this); + void *script_data = ScriptServer::get_language(p_script_language_index)->alloc_instance_binding_data(this); + if (script_data) { + atomic_increment(&instance_binding_count); + _script_instance_bindings[p_script_language_index] = script_data; + } } return _script_instance_bindings[p_script_language_index]; @@ -1931,6 +1935,7 @@ Object::Object() { _instance_ID = ObjectDB::add_instance(this); _can_translate = true; _is_queued_for_deletion = false; + instance_binding_count = 0; memset(_script_instance_bindings, 0, sizeof(void *) * MAX_SCRIPT_INSTANCE_BINDINGS); script_instance = NULL; #ifdef TOOLS_ENABLED diff --git a/core/object.h b/core/object.h index d741371306..43e1cf4785 100644 --- a/core/object.h +++ b/core/object.h @@ -490,10 +490,12 @@ private: void _set_indexed_bind(const NodePath &p_name, const Variant &p_value); Variant _get_indexed_bind(const NodePath &p_name) const; - void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS]; - void property_list_changed_notify(); + friend class Reference; + uint32_t instance_binding_count; + void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS]; + protected: virtual void _initialize_classv() { initialize_class(); } virtual bool _setv(const StringName &p_name, const Variant &p_property) { return false; }; diff --git a/core/reference.cpp b/core/reference.cpp index c33a7c683c..6e1520d81d 100644 --- a/core/reference.cpp +++ b/core/reference.cpp @@ -66,8 +66,17 @@ int Reference::reference_get_count() const { bool Reference::reference() { bool success = refcount.ref(); - if (success && get_script_instance()) { - get_script_instance()->refcount_incremented(); + if (success && refcount.get() <= 2 /* higher is not relevant */) { + if (get_script_instance()) { + get_script_instance()->refcount_incremented(); + } + if (instance_binding_count > 0) { + for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) { + if (_script_instance_bindings[i]) { + ScriptServer::get_language(i)->refcount_incremented_instance_binding(this); + } + } + } } return success; @@ -77,9 +86,19 @@ bool Reference::unreference() { bool die = refcount.unref(); - if (get_script_instance()) { - bool script_ret = get_script_instance()->refcount_decremented(); - die = die && script_ret; + if (refcount.get() <= 1 /* higher is not relevant */) { + if (get_script_instance()) { + bool script_ret = get_script_instance()->refcount_decremented(); + die = die && script_ret; + } + if (instance_binding_count > 0) { + 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; + } + } + } } return die; diff --git a/core/script_language.h b/core/script_language.h index 71b705e960..573e7b4fa1 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -311,6 +311,8 @@ public: virtual void *alloc_instance_binding_data(Object *p_object) { return NULL; } //optional, not used by all languages virtual void free_instance_binding_data(void *p_data) {} //optional, not used by all languages + virtual void refcount_incremented_instance_binding(Object *p_object) {} //optional, not used by all languages + virtual bool refcount_decremented_instance_binding(Object *p_object) { return true; } //return true if it can die //optional, not used by all languages virtual void frame(); |