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();  |