| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | /*  ref_counted.cpp                                                      */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2021-01-01 20:13:46 +01:00
										 |  |  | /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* 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.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | #include "ref_counted.h"
 | 
					
						
							| 
									
										
										
										
											2017-01-16 08:04:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-07 19:33:38 -03:00
										 |  |  | #include "core/object/script_language.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | bool RefCounted::init_ref() { | 
					
						
							| 
									
										
										
										
											2017-08-19 19:41:11 +07:00
										 |  |  | 	if (reference()) { | 
					
						
							| 
									
										
										
										
											2019-09-04 00:04:37 +08:00
										 |  |  | 		if (!is_referenced() && refcount_init.unref()) { | 
					
						
							| 
									
										
										
										
											2017-08-19 19:41:11 +07:00
										 |  |  | 			unreference(); // first referencing is already 1, so compensate for the ref above
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | void RefCounted::_bind_methods() { | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("init_ref"), &RefCounted::init_ref); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("reference"), &RefCounted::reference); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("unreference"), &RefCounted::unreference); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | int RefCounted::reference_get_count() const { | 
					
						
							| 
									
										
										
										
											2015-04-18 19:06:58 -03:00
										 |  |  | 	return refcount.get(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | bool RefCounted::reference() { | 
					
						
							| 
									
										
										
										
											2019-09-04 00:04:37 +08:00
										 |  |  | 	uint32_t rc_val = refcount.refval(); | 
					
						
							|  |  |  | 	bool success = rc_val != 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (success && rc_val <= 2 /* higher is not relevant */) { | 
					
						
							| 
									
										
										
										
											2018-02-22 15:34:08 +01:00
										 |  |  | 		if (get_script_instance()) { | 
					
						
							|  |  |  | 			get_script_instance()->refcount_incremented(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-06-04 14:33:48 -03:00
										 |  |  | 		if (_get_extension() && _get_extension()->reference) { | 
					
						
							|  |  |  | 			_get_extension()->reference(_get_extension_instance()); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-07-08 16:16:02 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		_instance_binding_reference(true); | 
					
						
							| 
									
										
										
										
											2016-06-21 19:34:45 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-08-19 19:41:11 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return success; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-08-19 19:41:11 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | bool RefCounted::unreference() { | 
					
						
							| 
									
										
										
										
											2019-09-04 00:04:37 +08:00
										 |  |  | 	uint32_t rc_val = refcount.unrefval(); | 
					
						
							|  |  |  | 	bool die = rc_val == 0; | 
					
						
							| 
									
										
										
										
											2016-06-21 19:34:45 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 00:04:37 +08:00
										 |  |  | 	if (rc_val <= 1 /* higher is not relevant */) { | 
					
						
							| 
									
										
										
										
											2018-02-22 15:34:08 +01:00
										 |  |  | 		if (get_script_instance()) { | 
					
						
							|  |  |  | 			bool script_ret = get_script_instance()->refcount_decremented(); | 
					
						
							|  |  |  | 			die = die && script_ret; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-06-04 14:33:48 -03:00
										 |  |  | 		if (_get_extension() && _get_extension()->unreference) { | 
					
						
							|  |  |  | 			_get_extension()->unreference(_get_extension_instance()); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-07-08 16:16:02 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		die = die && _instance_binding_reference(false); | 
					
						
							| 
									
										
										
										
											2016-06-21 19:34:45 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return die; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | RefCounted::RefCounted() : | 
					
						
							| 
									
										
										
										
											2020-02-13 16:03:10 -03:00
										 |  |  | 		Object(true) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	refcount.init(); | 
					
						
							|  |  |  | 	refcount_init.init(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Variant WeakRef::get_ref() const { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (ref.is_null()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return Variant(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Object *obj = ObjectDB::get_instance(ref); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!obj) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return Variant(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | 	RefCounted *r = cast_to<RefCounted>(obj); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (r) { | 
					
						
							|  |  |  | 		return REF(r); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return obj; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void WeakRef::set_obj(Object *p_object) { | 
					
						
							| 
									
										
										
										
											2020-02-12 14:24:06 -03:00
										 |  |  | 	ref = p_object ? p_object->get_instance_id() : ObjectID(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void WeakRef::set_ref(const REF &p_ref) { | 
					
						
							| 
									
										
										
										
											2020-02-12 14:24:06 -03:00
										 |  |  | 	ref = p_ref.is_valid() ? p_ref->get_instance_id() : ObjectID(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void WeakRef::_bind_methods() { | 
					
						
							| 
									
										
										
										
											2017-08-09 13:19:41 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_ref"), &WeakRef::get_ref); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } |