From 04688b92fff1d6bbec9335b354f3751ddc473379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Fri, 4 Jun 2021 18:03:15 +0200 Subject: Rename Reference to RefCounted --- core/config/engine.cpp | 6 +- core/core_bind.cpp | 2 +- core/core_bind.h | 24 +- core/crypto/aes_context.h | 6 +- core/crypto/crypto.h | 10 +- core/crypto/crypto_core.h | 2 +- core/crypto/hashing_context.h | 6 +- core/debugger/remote_debugger_peer.h | 4 +- core/io/config_file.h | 6 +- core/io/dtls_server.h | 4 +- core/io/http_client.h | 6 +- core/io/json.h | 6 +- core/io/marshalls.cpp | 6 +- core/io/marshalls.h | 6 +- core/io/multiplayer_api.h | 6 +- core/io/net_socket.h | 4 +- core/io/packed_data_container.h | 4 +- core/io/packet_peer.h | 4 +- core/io/pck_packer.h | 6 +- core/io/resource.h | 6 +- core/io/resource_importer.h | 4 +- core/io/resource_loader.h | 4 +- core/io/resource_saver.h | 4 +- core/io/stream_peer.h | 6 +- core/io/tcp_server.h | 4 +- core/io/udp_server.h | 4 +- core/io/xml_parser.h | 6 +- core/math/a_star.h | 10 +- core/math/expression.cpp | 2 +- core/math/expression.h | 6 +- core/math/random_number_generator.h | 6 +- core/math/triangle_mesh.h | 6 +- core/object/object.cpp | 12 +- core/object/object.h | 6 +- core/object/object_id.h | 2 +- core/object/ref_counted.cpp | 138 ++++++++++ core/object/ref_counted.h | 297 +++++++++++++++++++++ core/object/reference.cpp | 138 ---------- core/object/reference.h | 297 --------------------- core/object/undo_redo.cpp | 24 +- core/object/undo_redo.h | 4 +- core/os/main_loop.h | 2 +- core/register_core_types.cpp | 2 +- core/variant/callable.cpp | 2 +- core/variant/variant.cpp | 38 +-- core/variant/variant_call.cpp | 2 +- core/variant/variant_construct.cpp | 6 +- core/variant/variant_internal.h | 2 +- core/variant/variant_parser.cpp | 2 +- core/variant/variant_setget.cpp | 6 +- core/variant/variant_utility.cpp | 2 +- doc/classes/AESContext.xml | 2 +- doc/classes/AStar.xml | 2 +- doc/classes/AStar2D.xml | 2 +- doc/classes/AnimationTrackEditPlugin.xml | 2 +- doc/classes/AudioEffectInstance.xml | 2 +- doc/classes/AudioStreamPlayback.xml | 2 +- doc/classes/CameraFeed.xml | 2 +- doc/classes/CharFXTransform.xml | 2 +- doc/classes/ConfigFile.xml | 2 +- doc/classes/Crypto.xml | 2 +- doc/classes/DTLSServer.xml | 2 +- doc/classes/Directory.xml | 2 +- doc/classes/EditorExportPlugin.xml | 2 +- doc/classes/EditorFeatureProfile.xml | 2 +- doc/classes/EditorInspectorPlugin.xml | 2 +- doc/classes/EditorResourceConversionPlugin.xml | 2 +- doc/classes/EditorResourcePreviewGenerator.xml | 2 +- doc/classes/EditorSceneImporter.xml | 2 +- doc/classes/EditorScenePostImport.xml | 2 +- doc/classes/EditorScript.xml | 2 +- doc/classes/EditorTranslationParserPlugin.xml | 2 +- doc/classes/EncodedObjectAsID.xml | 2 +- doc/classes/Expression.xml | 2 +- doc/classes/File.xml | 2 +- doc/classes/HMACContext.xml | 2 +- doc/classes/HTTPClient.xml | 2 +- doc/classes/HashingContext.xml | 2 +- doc/classes/JSONParseResult.xml | 2 +- doc/classes/JSONParser.xml | 2 +- doc/classes/JavaClass.xml | 2 +- doc/classes/JavaScriptObject.xml | 2 +- doc/classes/KinematicCollision2D.xml | 2 +- doc/classes/KinematicCollision3D.xml | 2 +- doc/classes/Lightmapper.xml | 2 +- doc/classes/MeshDataTool.xml | 2 +- doc/classes/MultiplayerAPI.xml | 2 +- doc/classes/Mutex.xml | 2 +- doc/classes/Node3DGizmo.xml | 2 +- doc/classes/Object.xml | 4 +- doc/classes/PCKPacker.xml | 2 +- doc/classes/PackedDataContainerRef.xml | 4 +- doc/classes/PacketPeer.xml | 2 +- doc/classes/PhysicsShapeQueryParameters2D.xml | 2 +- doc/classes/PhysicsShapeQueryParameters3D.xml | 2 +- doc/classes/PhysicsShapeQueryResult2D.xml | 2 +- doc/classes/PhysicsShapeQueryResult3D.xml | 2 +- doc/classes/PhysicsTestMotionResult2D.xml | 2 +- doc/classes/RDAttachmentFormat.xml | 2 +- doc/classes/RDPipelineColorBlendState.xml | 2 +- .../RDPipelineColorBlendStateAttachment.xml | 2 +- doc/classes/RDPipelineDepthStencilState.xml | 2 +- doc/classes/RDPipelineMultisampleState.xml | 2 +- doc/classes/RDPipelineRasterizationState.xml | 2 +- doc/classes/RDSamplerState.xml | 2 +- doc/classes/RDShaderSource.xml | 2 +- doc/classes/RDTextureFormat.xml | 2 +- doc/classes/RDTextureView.xml | 2 +- doc/classes/RDUniform.xml | 2 +- doc/classes/RDVertexAttribute.xml | 2 +- doc/classes/RandomNumberGenerator.xml | 2 +- doc/classes/RefCounted.xml | 43 +++ doc/classes/Reference.xml | 43 --- doc/classes/Resource.xml | 4 +- doc/classes/ResourceFormatLoader.xml | 2 +- doc/classes/ResourceFormatSaver.xml | 2 +- doc/classes/ResourceImporter.xml | 2 +- doc/classes/SceneState.xml | 2 +- doc/classes/SceneTreeTimer.xml | 2 +- doc/classes/Semaphore.xml | 2 +- doc/classes/SkinReference.xml | 2 +- doc/classes/StreamPeer.xml | 2 +- doc/classes/SurfaceTool.xml | 2 +- doc/classes/TCPServer.xml | 2 +- doc/classes/TextLine.xml | 2 +- doc/classes/TextParagraph.xml | 2 +- doc/classes/Thread.xml | 2 +- doc/classes/TriangleMesh.xml | 2 +- doc/classes/UDPServer.xml | 2 +- doc/classes/Variant.xml | 2 +- doc/classes/VelocityTracker3D.xml | 2 +- doc/classes/WeakRef.xml | 4 +- doc/classes/XMLParser.xml | 2 +- doc/classes/XRInterface.xml | 2 +- doc/classes/XRPositionalTracker.xml | 2 +- doc/translations/ar.po | 26 +- doc/translations/ca.po | 26 +- doc/translations/classes.pot | 26 +- doc/translations/cs.po | 26 +- doc/translations/de.po | 26 +- doc/translations/es.po | 28 +- doc/translations/fa.po | 26 +- doc/translations/fi.po | 26 +- doc/translations/fr.po | 26 +- doc/translations/id.po | 26 +- doc/translations/it.po | 26 +- doc/translations/ja.po | 26 +- doc/translations/ko.po | 26 +- doc/translations/nl.po | 26 +- doc/translations/pl.po | 26 +- doc/translations/pt_BR.po | 26 +- doc/translations/ro.po | 26 +- doc/translations/ru.po | 26 +- doc/translations/sr_Cyrl.po | 26 +- doc/translations/th.po | 26 +- doc/translations/tr.po | 26 +- doc/translations/uk.po | 26 +- doc/translations/zh_Hans.po | 26 +- doc/translations/zh_Hant.po | 26 +- editor/animation_track_editor.h | 4 +- editor/array_property_edit.h | 4 +- editor/audio_stream_preview.h | 4 +- editor/debugger/editor_debugger_server.h | 4 +- editor/dictionary_property_edit.h | 4 +- editor/editor_data.cpp | 2 +- editor/editor_export.h | 12 +- editor/editor_feature_profile.h | 6 +- editor/editor_help_search.h | 2 +- editor/editor_inspector.h | 4 +- editor/editor_properties.cpp | 2 +- editor/editor_properties_array_dict.h | 8 +- editor/editor_resource_preview.h | 4 +- editor/editor_run_script.h | 6 +- editor/editor_translation_parser.h | 6 +- editor/import/resource_importer_scene.h | 8 +- editor/multi_node_edit.h | 4 +- editor/plugins/visual_shader_editor_plugin.h | 8 +- editor/property_editor.h | 4 +- modules/csg/csg.h | 2 +- modules/fbx/data/fbx_bone.h | 2 +- modules/fbx/data/fbx_material.h | 6 +- modules/fbx/data/fbx_mesh_data.h | 2 +- modules/fbx/data/fbx_node.h | 2 +- modules/fbx/data/fbx_skeleton.h | 4 +- modules/fbx/data/pivot_transform.h | 4 +- modules/gdnative/doc_classes/GDNative.xml | 2 +- modules/gdnative/gdnative.h | 4 +- modules/gdnative/gdnative/variant.cpp | 12 +- modules/gdnative/nativescript/api_generator.cpp | 16 +- modules/gdnative/nativescript/nativescript.cpp | 4 +- .../gdnative/pluginscript/pluginscript_script.cpp | 4 +- modules/gdscript/gdscript.cpp | 20 +- modules/gdscript/gdscript.h | 10 +- modules/gdscript/gdscript_analyzer.cpp | 2 +- modules/gdscript/gdscript_analyzer.h | 2 +- modules/gdscript/gdscript_cache.h | 4 +- modules/gdscript/gdscript_compiler.cpp | 2 +- modules/gdscript/gdscript_function.h | 6 +- modules/gdscript/gdscript_lambda_callable.h | 2 +- modules/gdscript/gdscript_parser.h | 2 +- .../language_server/gdscript_language_protocol.h | 2 +- .../language_server/gdscript_text_document.h | 6 +- .../gdscript/language_server/gdscript_workspace.h | 4 +- modules/gdscript/language_server/lsp.hpp | 4 +- modules/gdscript/tests/gdscript_test_runner.cpp | 6 +- .../gdscript/tests/gdscript_test_runner_suite.h | 8 +- modules/mbedtls/ssl_context_mbedtls.h | 6 +- modules/mono/csharp_script.cpp | 106 ++++---- modules/mono/csharp_script.h | 4 +- .../GodotTools/GodotTools/Build/BuildInfo.cs | 2 +- .../GodotTools/GodotTools/Build/BuildOutputView.cs | 2 +- modules/mono/editor/bindings_generator.cpp | 14 +- modules/mono/editor/bindings_generator.h | 10 +- modules/mono/glue/base_object_glue.cpp | 20 +- modules/mono/glue/glue_header.h | 2 +- modules/mono/mono_gc_handle.h | 6 +- modules/mono/mono_gd/gd_mono_internals.cpp | 12 +- modules/mono/mono_gd/gd_mono_marshal.cpp | 4 +- modules/mono/mono_gd/gd_mono_utils.cpp | 10 +- modules/mono/mono_gd/gd_mono_utils.h | 2 +- modules/mono/signal_awaiter_utils.h | 2 +- modules/opensimplex/noise_texture.h | 2 +- modules/opensimplex/open_simplex_noise.h | 2 +- modules/pvr/image_compress_pvrtc.cpp | 2 +- modules/raycast/raycast_occlusion_cull.h | 2 +- modules/regex/doc_classes/RegEx.xml | 2 +- modules/regex/doc_classes/RegExMatch.xml | 2 +- modules/regex/regex.h | 10 +- modules/upnp/doc_classes/UPNP.xml | 2 +- modules/upnp/doc_classes/UPNPDevice.xml | 2 +- modules/upnp/upnp.h | 6 +- modules/upnp/upnp_device.h | 6 +- .../doc_classes/VisualScriptFunctionState.xml | 2 +- modules/visual_script/visual_script.h | 4 +- .../visual_script/visual_script_builtin_funcs.cpp | 2 +- .../webrtc/doc_classes/WebRTCPeerConnection.xml | 2 +- modules/webrtc/webrtc_multiplayer.h | 2 +- modules/webrtc/webrtc_peer_connection.h | 4 +- modules/websocket/emws_server.h | 2 +- modules/websocket/websocket_server.h | 2 +- modules/websocket/wsl_server.h | 2 +- platform/android/api/java_class_wrapper.h | 10 +- platform/android/java_class_wrapper.cpp | 4 +- platform/javascript/api/javascript_singleton.h | 6 +- platform/javascript/export/export.cpp | 2 +- scene/2d/physics_body_2d.h | 4 +- scene/3d/lightmapper.h | 12 +- scene/3d/node_3d.h | 4 +- scene/3d/physics_body_3d.h | 4 +- scene/3d/skeleton_3d.h | 4 +- scene/3d/velocity_tracker_3d.h | 4 +- scene/animation/animation_player.h | 4 +- scene/gui/rich_text_effect.h | 4 +- scene/main/scene_tree.h | 4 +- scene/resources/mesh_data_tool.h | 4 +- scene/resources/packed_scene.h | 4 +- scene/resources/surface_tool.h | 4 +- scene/resources/text_line.h | 4 +- scene/resources/text_paragraph.h | 4 +- servers/audio/audio_effect.h | 4 +- servers/audio/audio_stream.h | 4 +- servers/audio/effects/audio_effect_capture.h | 2 +- servers/camera/camera_feed.h | 4 +- servers/camera_server.h | 2 +- servers/physics_server_2d.h | 14 +- servers/physics_server_3d.h | 8 +- servers/rendering/rendering_device_binds.h | 48 ++-- servers/text_server.h | 2 +- servers/xr/xr_interface.h | 4 +- servers/xr/xr_positional_tracker.h | 4 +- servers/xr_server.h | 2 +- tests/test_class_db.h | 8 +- tests/test_object.h | 4 +- 273 files changed, 1375 insertions(+), 1375 deletions(-) create mode 100644 core/object/ref_counted.cpp create mode 100644 core/object/ref_counted.h delete mode 100644 core/object/reference.cpp delete mode 100644 core/object/reference.h create mode 100644 doc/classes/RefCounted.xml delete mode 100644 doc/classes/Reference.xml diff --git a/core/config/engine.cpp b/core/config/engine.cpp index c43e32868c..99ec1aeb5b 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -232,9 +232,9 @@ Engine::Singleton::Singleton(const StringName &p_name, Object *p_ptr) : name(p_name), ptr(p_ptr) { #ifdef DEBUG_ENABLED - Reference *ref = Object::cast_to(p_ptr); - if (ref && !ref->is_referenced()) { - WARN_PRINT("You must use Ref<> to ensure the lifetime of a Reference object intended to be used as a singleton."); + RefCounted *rc = Object::cast_to(p_ptr); + if (rc && !rc->is_referenced()) { + WARN_PRINT("You must use Ref<> to ensure the lifetime of a RefCounted object intended to be used as a singleton."); } #endif } diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 81d229ae92..b8d5572ecc 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -2074,7 +2074,7 @@ Variant _ClassDB::instance(const StringName &p_class) const { return Variant(); } - Reference *r = Object::cast_to(obj); + RefCounted *r = Object::cast_to(obj); if (r) { return REF(r); } else { diff --git a/core/core_bind.h b/core/core_bind.h index e47d6dc0d5..46a6b23cf8 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -353,8 +353,8 @@ public: _Geometry3D() { singleton = this; } }; -class _File : public Reference { - GDCLASS(_File, Reference); +class _File : public RefCounted { + GDCLASS(_File, RefCounted); FileAccess *f = nullptr; bool big_endian = false; @@ -455,8 +455,8 @@ public: VARIANT_ENUM_CAST(_File::ModeFlags); VARIANT_ENUM_CAST(_File::CompressionMode); -class _Directory : public Reference { - GDCLASS(_Directory, Reference); +class _Directory : public RefCounted { + GDCLASS(_Directory, RefCounted); DirAccess *d; bool dir_open = false; @@ -525,8 +525,8 @@ public: ~_Marshalls() { singleton = nullptr; } }; -class _Mutex : public Reference { - GDCLASS(_Mutex, Reference); +class _Mutex : public RefCounted { + GDCLASS(_Mutex, RefCounted); Mutex mutex; static void _bind_methods(); @@ -537,8 +537,8 @@ public: void unlock(); }; -class _Semaphore : public Reference { - GDCLASS(_Semaphore, Reference); +class _Semaphore : public RefCounted { + GDCLASS(_Semaphore, RefCounted); Semaphore semaphore; static void _bind_methods(); @@ -549,8 +549,8 @@ public: void post(); }; -class _Thread : public Reference { - GDCLASS(_Thread, Reference); +class _Thread : public RefCounted { + GDCLASS(_Thread, RefCounted); protected: Variant ret; @@ -666,8 +666,8 @@ public: class _JSON; -class JSONParseResult : public Reference { - GDCLASS(JSONParseResult, Reference); +class JSONParseResult : public RefCounted { + GDCLASS(JSONParseResult, RefCounted); friend class _JSON; diff --git a/core/crypto/aes_context.h b/core/crypto/aes_context.h index cc00b18fd2..2f8422f537 100644 --- a/core/crypto/aes_context.h +++ b/core/crypto/aes_context.h @@ -32,10 +32,10 @@ #define AES_CONTEXT_H #include "core/crypto/crypto_core.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" -class AESContext : public Reference { - GDCLASS(AESContext, Reference); +class AESContext : public RefCounted { + GDCLASS(AESContext, RefCounted); public: enum Mode { diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h index 9438fcfea5..a2ccbba58a 100644 --- a/core/crypto/crypto.h +++ b/core/crypto/crypto.h @@ -35,7 +35,7 @@ #include "core/io/resource.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" class CryptoKey : public Resource { GDCLASS(CryptoKey, Resource); @@ -67,8 +67,8 @@ public: virtual Error save(String p_path) = 0; }; -class HMACContext : public Reference { - GDCLASS(HMACContext, Reference); +class HMACContext : public RefCounted { + GDCLASS(HMACContext, RefCounted); protected: static void _bind_methods(); @@ -84,8 +84,8 @@ public: HMACContext() {} }; -class Crypto : public Reference { - GDCLASS(Crypto, Reference); +class Crypto : public RefCounted { + GDCLASS(Crypto, RefCounted); protected: static void _bind_methods(); diff --git a/core/crypto/crypto_core.h b/core/crypto/crypto_core.h index 27b380e838..7a2f4df589 100644 --- a/core/crypto/crypto_core.h +++ b/core/crypto/crypto_core.h @@ -31,7 +31,7 @@ #ifndef CRYPTO_CORE_H #define CRYPTO_CORE_H -#include "core/object/reference.h" +#include "core/object/ref_counted.h" class CryptoCore { public: diff --git a/core/crypto/hashing_context.h b/core/crypto/hashing_context.h index 892a48a4e8..31521a147c 100644 --- a/core/crypto/hashing_context.h +++ b/core/crypto/hashing_context.h @@ -31,10 +31,10 @@ #ifndef HASHING_CONTEXT_H #define HASHING_CONTEXT_H -#include "core/object/reference.h" +#include "core/object/ref_counted.h" -class HashingContext : public Reference { - GDCLASS(HashingContext, Reference); +class HashingContext : public RefCounted { + GDCLASS(HashingContext, RefCounted); public: enum HashType { diff --git a/core/debugger/remote_debugger_peer.h b/core/debugger/remote_debugger_peer.h index 652e2d9d20..8cba53a81c 100644 --- a/core/debugger/remote_debugger_peer.h +++ b/core/debugger/remote_debugger_peer.h @@ -32,12 +32,12 @@ #define REMOTE_DEBUGGER_PEER_H #include "core/io/stream_peer_tcp.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" #include "core/os/mutex.h" #include "core/os/thread.h" #include "core/string/ustring.h" -class RemoteDebuggerPeer : public Reference { +class RemoteDebuggerPeer : public RefCounted { protected: int max_queued_messages = 4096; diff --git a/core/io/config_file.h b/core/io/config_file.h index 3b2321b15a..dbba43ace5 100644 --- a/core/io/config_file.h +++ b/core/io/config_file.h @@ -32,12 +32,12 @@ #define CONFIG_FILE_H #include "core/io/file_access.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" #include "core/templates/ordered_hash_map.h" #include "core/variant/variant_parser.h" -class ConfigFile : public Reference { - GDCLASS(ConfigFile, Reference); +class ConfigFile : public RefCounted { + GDCLASS(ConfigFile, RefCounted); OrderedHashMap> values; diff --git a/core/io/dtls_server.h b/core/io/dtls_server.h index 92b6caf508..02a32533e1 100644 --- a/core/io/dtls_server.h +++ b/core/io/dtls_server.h @@ -34,8 +34,8 @@ #include "core/io/net_socket.h" #include "core/io/packet_peer_dtls.h" -class DTLSServer : public Reference { - GDCLASS(DTLSServer, Reference); +class DTLSServer : public RefCounted { + GDCLASS(DTLSServer, RefCounted); protected: static DTLSServer *(*_create)(); diff --git a/core/io/http_client.h b/core/io/http_client.h index ec4b86b26f..f70999836f 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -34,10 +34,10 @@ #include "core/io/ip.h" #include "core/io/stream_peer.h" #include "core/io/stream_peer_tcp.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" -class HTTPClient : public Reference { - GDCLASS(HTTPClient, Reference); +class HTTPClient : public RefCounted { + GDCLASS(HTTPClient, RefCounted); public: enum ResponseCode { diff --git a/core/io/json.h b/core/io/json.h index f2711d8c54..bfd2347725 100644 --- a/core/io/json.h +++ b/core/io/json.h @@ -31,7 +31,7 @@ #ifndef JSON_H #define JSON_H -#include "core/object/reference.h" +#include "core/object/ref_counted.h" #include "core/variant/variant.h" class JSON { enum TokenType { @@ -74,8 +74,8 @@ public: static Error parse(const String &p_json, Variant &r_ret, String &r_err_str, int &r_err_line); }; -class JSONParser : public Reference { - GDCLASS(JSONParser, Reference); +class JSONParser : public RefCounted { + GDCLASS(JSONParser, RefCounted); Variant data; String string; diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 18e1092c26..4c58c84c14 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -30,7 +30,7 @@ #include "marshalls.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" #include "core/os/keyboard.h" #include "core/string/print_string.h" @@ -489,8 +489,8 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int obj->set(str, value); } - if (Object::cast_to(obj)) { - REF ref = REF(Object::cast_to(obj)); + if (Object::cast_to(obj)) { + REF ref = REF(Object::cast_to(obj)); r_variant = ref; } else { r_variant = obj; diff --git a/core/io/marshalls.h b/core/io/marshalls.h index cc0e9ba301..7fac708f97 100644 --- a/core/io/marshalls.h +++ b/core/io/marshalls.h @@ -31,7 +31,7 @@ #ifndef MARSHALLS_H #define MARSHALLS_H -#include "core/object/reference.h" +#include "core/object/ref_counted.h" #include "core/typedefs.h" #include "core/variant/variant.h" @@ -165,8 +165,8 @@ static inline double decode_double(const uint8_t *p_arr) { return md.d; } -class EncodedObjectAsID : public Reference { - GDCLASS(EncodedObjectAsID, Reference); +class EncodedObjectAsID : public RefCounted { + GDCLASS(EncodedObjectAsID, RefCounted); ObjectID id; diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h index 6a251cf77b..43804a20ec 100644 --- a/core/io/multiplayer_api.h +++ b/core/io/multiplayer_api.h @@ -32,10 +32,10 @@ #define MULTIPLAYER_API_H #include "core/io/networked_multiplayer_peer.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" -class MultiplayerAPI : public Reference { - GDCLASS(MultiplayerAPI, Reference); +class MultiplayerAPI : public RefCounted { + GDCLASS(MultiplayerAPI, RefCounted); public: enum RPCMode { diff --git a/core/io/net_socket.h b/core/io/net_socket.h index 98ff9562d9..fd7d50c704 100644 --- a/core/io/net_socket.h +++ b/core/io/net_socket.h @@ -32,9 +32,9 @@ #define NET_SOCKET_H #include "core/io/ip.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" -class NetSocket : public Reference { +class NetSocket : public RefCounted { protected: static NetSocket *(*_create)(); diff --git a/core/io/packed_data_container.h b/core/io/packed_data_container.h index 7791e21bb3..40772bb2bf 100644 --- a/core/io/packed_data_container.h +++ b/core/io/packed_data_container.h @@ -80,8 +80,8 @@ public: PackedDataContainer() {} }; -class PackedDataContainerRef : public Reference { - GDCLASS(PackedDataContainerRef, Reference); +class PackedDataContainerRef : public RefCounted { + GDCLASS(PackedDataContainerRef, RefCounted); friend class PackedDataContainer; uint32_t offset = 0; diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h index 9e03c44750..9a345af3d0 100644 --- a/core/io/packet_peer.h +++ b/core/io/packet_peer.h @@ -35,8 +35,8 @@ #include "core/object/class_db.h" #include "core/templates/ring_buffer.h" -class PacketPeer : public Reference { - GDCLASS(PacketPeer, Reference); +class PacketPeer : public RefCounted { + GDCLASS(PacketPeer, RefCounted); Variant _bnd_get_var(bool p_allow_objects = false); diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h index dec8f8748d..3d2ce8f240 100644 --- a/core/io/pck_packer.h +++ b/core/io/pck_packer.h @@ -31,12 +31,12 @@ #ifndef PCK_PACKER_H #define PCK_PACKER_H -#include "core/object/reference.h" +#include "core/object/ref_counted.h" class FileAccess; -class PCKPacker : public Reference { - GDCLASS(PCKPacker, Reference); +class PCKPacker : public RefCounted { + GDCLASS(PCKPacker, RefCounted); FileAccess *file = nullptr; int alignment = 0; diff --git a/core/io/resource.h b/core/io/resource.h index 75a9f928f8..028fed1c6e 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -32,7 +32,7 @@ #define RESOURCE_H #include "core/object/class_db.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" #include "core/templates/safe_refcount.h" #include "core/templates/self_list.h" @@ -43,8 +43,8 @@ public: \ private: -class Resource : public Reference { - GDCLASS(Resource, Reference); +class Resource : public RefCounted { + GDCLASS(Resource, RefCounted); OBJ_CATEGORY("Resources"); public: diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index a14d6ba52c..2ceeb176e5 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -93,8 +93,8 @@ public: ResourceFormatImporter(); }; -class ResourceImporter : public Reference { - GDCLASS(ResourceImporter, Reference); +class ResourceImporter : public RefCounted { + GDCLASS(ResourceImporter, RefCounted); public: virtual String get_importer_name() const = 0; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 914d988caa..c656b9a69c 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -35,8 +35,8 @@ #include "core/os/semaphore.h" #include "core/os/thread.h" -class ResourceFormatLoader : public Reference { - GDCLASS(ResourceFormatLoader, Reference); +class ResourceFormatLoader : public RefCounted { + GDCLASS(ResourceFormatLoader, RefCounted); public: enum CacheMode { diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index 2c9e8f1aa3..07154aac4d 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -33,8 +33,8 @@ #include "core/io/resource.h" -class ResourceFormatSaver : public Reference { - GDCLASS(ResourceFormatSaver, Reference); +class ResourceFormatSaver : public RefCounted { + GDCLASS(ResourceFormatSaver, RefCounted); protected: static void _bind_methods(); diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h index 1e1a3e890c..effc3850af 100644 --- a/core/io/stream_peer.h +++ b/core/io/stream_peer.h @@ -31,10 +31,10 @@ #ifndef STREAM_PEER_H #define STREAM_PEER_H -#include "core/object/reference.h" +#include "core/object/ref_counted.h" -class StreamPeer : public Reference { - GDCLASS(StreamPeer, Reference); +class StreamPeer : public RefCounted { + GDCLASS(StreamPeer, RefCounted); OBJ_CATEGORY("Networking"); protected: diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h index abefa53c6f..10985a04d5 100644 --- a/core/io/tcp_server.h +++ b/core/io/tcp_server.h @@ -36,8 +36,8 @@ #include "core/io/stream_peer.h" #include "core/io/stream_peer_tcp.h" -class TCPServer : public Reference { - GDCLASS(TCPServer, Reference); +class TCPServer : public RefCounted { + GDCLASS(TCPServer, RefCounted); protected: enum { diff --git a/core/io/udp_server.h b/core/io/udp_server.h index 60d03f37f0..e49a559c51 100644 --- a/core/io/udp_server.h +++ b/core/io/udp_server.h @@ -34,8 +34,8 @@ #include "core/io/net_socket.h" #include "core/io/packet_peer_udp.h" -class UDPServer : public Reference { - GDCLASS(UDPServer, Reference); +class UDPServer : public RefCounted { + GDCLASS(UDPServer, RefCounted); protected: enum { diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h index 15722b611e..1113cce715 100644 --- a/core/io/xml_parser.h +++ b/core/io/xml_parser.h @@ -32,7 +32,7 @@ #define XML_PARSER_H #include "core/io/file_access.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" #include "core/string/ustring.h" #include "core/templates/vector.h" @@ -40,8 +40,8 @@ Based on irrXML (see their zlib license). Added mainly for compatibility with their Collada loader. */ -class XMLParser : public Reference { - GDCLASS(XMLParser, Reference); +class XMLParser : public RefCounted { + GDCLASS(XMLParser, RefCounted); public: //! Enumeration of all supported source text file formats diff --git a/core/math/a_star.h b/core/math/a_star.h index 4c61abd91c..44758cb046 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -31,7 +31,7 @@ #ifndef A_STAR_H #define A_STAR_H -#include "core/object/reference.h" +#include "core/object/ref_counted.h" #include "core/templates/oa_hash_map.h" /** @@ -40,8 +40,8 @@ @author Juan Linietsky */ -class AStar : public Reference { - GDCLASS(AStar, Reference); +class AStar : public RefCounted { + GDCLASS(AStar, RefCounted); friend class AStar2D; struct Point { @@ -157,8 +157,8 @@ public: ~AStar(); }; -class AStar2D : public Reference { - GDCLASS(AStar2D, Reference); +class AStar2D : public RefCounted { + GDCLASS(AStar2D, RefCounted); AStar astar; bool _solve(AStar::Point *begin_point, AStar::Point *end_point); diff --git a/core/math/expression.cpp b/core/math/expression.cpp index f7ac44d321..0146c345f0 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -33,7 +33,7 @@ #include "core/io/marshalls.h" #include "core/math/math_funcs.h" #include "core/object/class_db.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" #include "core/os/os.h" #include "core/variant/variant_parser.h" diff --git a/core/math/expression.h b/core/math/expression.h index a6b288ed6e..aecf662d0a 100644 --- a/core/math/expression.h +++ b/core/math/expression.h @@ -31,10 +31,10 @@ #ifndef EXPRESSION_H #define EXPRESSION_H -#include "core/object/reference.h" +#include "core/object/ref_counted.h" -class Expression : public Reference { - GDCLASS(Expression, Reference); +class Expression : public RefCounted { + GDCLASS(Expression, RefCounted); private: struct Input { diff --git a/core/math/random_number_generator.h b/core/math/random_number_generator.h index a396c2b7d7..06cd3999f3 100644 --- a/core/math/random_number_generator.h +++ b/core/math/random_number_generator.h @@ -32,10 +32,10 @@ #define RANDOM_NUMBER_GENERATOR_H #include "core/math/random_pcg.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" -class RandomNumberGenerator : public Reference { - GDCLASS(RandomNumberGenerator, Reference); +class RandomNumberGenerator : public RefCounted { + GDCLASS(RandomNumberGenerator, RefCounted); protected: RandomPCG randbase; diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h index 1d1dbc114b..463b0dd5c8 100644 --- a/core/math/triangle_mesh.h +++ b/core/math/triangle_mesh.h @@ -32,10 +32,10 @@ #define TRIANGLE_MESH_H #include "core/math/face3.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" -class TriangleMesh : public Reference { - GDCLASS(TriangleMesh, Reference); +class TriangleMesh : public RefCounted { + GDCLASS(TriangleMesh, RefCounted); struct Triangle { Vector3 normal; diff --git a/core/object/object.cpp b/core/object/object.cpp index 7e1c3855c0..799e63a512 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -769,7 +769,7 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; return Variant(); } - if (Object::cast_to(this)) { + if (Object::cast_to(this)) { r_error.argument = 0; r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; ERR_FAIL_V_MSG(Variant(), "Can't 'free' a reference."); @@ -1900,7 +1900,7 @@ ObjectID ObjectDB::add_instance(Object *p_object) { object_slots = (ObjectSlot *)memrealloc(object_slots, sizeof(ObjectSlot) * new_slot_max); for (uint32_t i = slot_max; i < new_slot_max; i++) { object_slots[i].object = nullptr; - object_slots[i].is_reference = false; + object_slots[i].is_ref_counted = false; object_slots[i].next_free = i; object_slots[i].validator = 0; } @@ -1913,7 +1913,7 @@ ObjectID ObjectDB::add_instance(Object *p_object) { ERR_FAIL_COND_V(object_slots[slot].object != nullptr, ObjectID()); } object_slots[slot].object = p_object; - object_slots[slot].is_reference = p_object->is_reference(); + object_slots[slot].is_ref_counted = p_object->is_ref_counted(); validator_counter = (validator_counter + 1) & OBJECTDB_VALIDATOR_MASK; if (unlikely(validator_counter == 0)) { validator_counter = 1; @@ -1924,7 +1924,7 @@ ObjectID ObjectDB::add_instance(Object *p_object) { id <<= OBJECTDB_SLOT_MAX_COUNT_BITS; id |= uint64_t(slot); - if (p_object->is_reference()) { + if (p_object->is_ref_counted()) { id |= OBJECTDB_REFERENCE_BIT; } @@ -1962,7 +1962,7 @@ void ObjectDB::remove_instance(Object *p_object) { object_slots[slot_count].next_free = slot; //invalidate, so checks against it fail object_slots[slot].validator = 0; - object_slots[slot].is_reference = false; + object_slots[slot].is_ref_counted = false; object_slots[slot].object = nullptr; spin_lock.unlock(); @@ -1997,7 +1997,7 @@ void ObjectDB::cleanup() { extra_info = " - Resource path: " + String(resource_get_path->call(obj, nullptr, 0, call_error)); } - uint64_t id = uint64_t(i) | (uint64_t(object_slots[i].validator) << OBJECTDB_VALIDATOR_BITS) | (object_slots[i].is_reference ? OBJECTDB_REFERENCE_BIT : 0); + uint64_t id = uint64_t(i) | (uint64_t(object_slots[i].validator) << OBJECTDB_VALIDATOR_BITS) | (object_slots[i].is_ref_counted ? OBJECTDB_REFERENCE_BIT : 0); print_line("Leaked instance: " + String(obj->get_class()) + ":" + itos(id) + extra_info); count--; diff --git a/core/object/object.h b/core/object/object.h index 137025f323..37b2e61dfe 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -545,7 +545,7 @@ private: _FORCE_INLINE_ void _construct_object(bool p_reference); - friend class Reference; + friend class RefCounted; bool type_is_reference = false; SafeNumeric instance_binding_count; void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS]; @@ -795,7 +795,7 @@ public: void clear_internal_resource_paths(); - _ALWAYS_INLINE_ bool is_reference() const { return type_is_reference; } + _ALWAYS_INLINE_ bool is_ref_counted() const { return type_is_reference; } Object(); virtual ~Object(); @@ -815,7 +815,7 @@ class ObjectDB { struct ObjectSlot { //128 bits per slot uint64_t validator : OBJECTDB_VALIDATOR_BITS; uint64_t next_free : OBJECTDB_SLOT_MAX_COUNT_BITS; - uint64_t is_reference : 1; + uint64_t is_ref_counted : 1; Object *object; }; diff --git a/core/object/object_id.h b/core/object/object_id.h index 7f2496ad48..0666ec0855 100644 --- a/core/object/object_id.h +++ b/core/object/object_id.h @@ -42,7 +42,7 @@ class ObjectID { uint64_t id = 0; public: - _ALWAYS_INLINE_ bool is_reference() const { return (id & (uint64_t(1) << 63)) != 0; } + _ALWAYS_INLINE_ bool is_ref_counted() const { return (id & (uint64_t(1) << 63)) != 0; } _ALWAYS_INLINE_ bool is_valid() const { return id != 0; } _ALWAYS_INLINE_ bool is_null() const { return id == 0; } _ALWAYS_INLINE_ operator uint64_t() const { return id; } diff --git a/core/object/ref_counted.cpp b/core/object/ref_counted.cpp new file mode 100644 index 0000000000..9862624972 --- /dev/null +++ b/core/object/ref_counted.cpp @@ -0,0 +1,138 @@ +/*************************************************************************/ +/* ref_counted.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#include "ref_counted.h" + +#include "core/object/script_language.h" + +bool RefCounted::init_ref() { + if (reference()) { + if (!is_referenced() && refcount_init.unref()) { + unreference(); // first referencing is already 1, so compensate for the ref above + } + + return true; + } else { + return false; + } +} + +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); +} + +int RefCounted::reference_get_count() const { + return refcount.get(); +} + +bool RefCounted::reference() { + uint32_t rc_val = refcount.refval(); + bool success = rc_val != 0; + + if (success && rc_val <= 2 /* higher is not relevant */) { + if (get_script_instance()) { + get_script_instance()->refcount_incremented(); + } + 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); + } + } + } + } + + return success; +} + +bool RefCounted::unreference() { + uint32_t rc_val = refcount.unrefval(); + bool die = rc_val == 0; + + if (rc_val <= 1 /* higher is not relevant */) { + if (get_script_instance()) { + bool script_ret = get_script_instance()->refcount_decremented(); + die = die && script_ret; + } + 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; + } + } + } + } + + return die; +} + +RefCounted::RefCounted() : + Object(true) { + refcount.init(); + refcount_init.init(); +} + +Variant WeakRef::get_ref() const { + if (ref.is_null()) { + return Variant(); + } + + Object *obj = ObjectDB::get_instance(ref); + if (!obj) { + return Variant(); + } + RefCounted *r = cast_to(obj); + if (r) { + return REF(r); + } + + return obj; +} + +void WeakRef::set_obj(Object *p_object) { + ref = p_object ? p_object->get_instance_id() : ObjectID(); +} + +void WeakRef::set_ref(const REF &p_ref) { + ref = p_ref.is_valid() ? p_ref->get_instance_id() : ObjectID(); +} + +void WeakRef::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_ref"), &WeakRef::get_ref); +} diff --git a/core/object/ref_counted.h b/core/object/ref_counted.h new file mode 100644 index 0000000000..3dd7cc456b --- /dev/null +++ b/core/object/ref_counted.h @@ -0,0 +1,297 @@ +/*************************************************************************/ +/* ref_counted.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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. */ +/*************************************************************************/ + +#ifndef REF_COUNTED_H +#define REF_COUNTED_H + +#include "core/object/class_db.h" +#include "core/templates/safe_refcount.h" + +class RefCounted : public Object { + GDCLASS(RefCounted, Object); + SafeRefCount refcount; + SafeRefCount refcount_init; + +protected: + static void _bind_methods(); + +public: + _FORCE_INLINE_ bool is_referenced() const { return refcount_init.get() != 1; } + bool init_ref(); + bool reference(); // returns false if refcount is at zero and didn't get increased + bool unreference(); + int reference_get_count() const; + + RefCounted(); + ~RefCounted() {} +}; + +template +class Ref { + T *reference = nullptr; + + void ref(const Ref &p_from) { + if (p_from.reference == reference) { + return; + } + + unref(); + + reference = p_from.reference; + if (reference) { + reference->reference(); + } + } + + void ref_pointer(T *p_ref) { + ERR_FAIL_COND(!p_ref); + + if (p_ref->init_ref()) { + reference = p_ref; + } + } + + //virtual RefCounted * get_reference() const { return reference; } +public: + _FORCE_INLINE_ bool operator==(const T *p_ptr) const { + return reference == p_ptr; + } + _FORCE_INLINE_ bool operator!=(const T *p_ptr) const { + return reference != p_ptr; + } + + _FORCE_INLINE_ bool operator<(const Ref &p_r) const { + return reference < p_r.reference; + } + _FORCE_INLINE_ bool operator==(const Ref &p_r) const { + return reference == p_r.reference; + } + _FORCE_INLINE_ bool operator!=(const Ref &p_r) const { + return reference != p_r.reference; + } + + _FORCE_INLINE_ T *operator->() { + return reference; + } + + _FORCE_INLINE_ T *operator*() { + return reference; + } + + _FORCE_INLINE_ const T *operator->() const { + return reference; + } + + _FORCE_INLINE_ const T *ptr() const { + return reference; + } + _FORCE_INLINE_ T *ptr() { + return reference; + } + + _FORCE_INLINE_ const T *operator*() const { + return reference; + } + + operator Variant() const { + return Variant(reference); + } + + void operator=(const Ref &p_from) { + ref(p_from); + } + + template + void operator=(const Ref &p_from) { + RefCounted *refb = const_cast(static_cast(p_from.ptr())); + if (!refb) { + unref(); + return; + } + Ref r; + r.reference = Object::cast_to(refb); + ref(r); + r.reference = nullptr; + } + + void operator=(const Variant &p_variant) { + Object *object = p_variant.get_validated_object(); + + if (object == reference) { + return; + } + + unref(); + + if (!object) { + return; + } + + T *r = Object::cast_to(object); + if (r && r->reference()) { + reference = r; + } + } + + template + void reference_ptr(T_Other *p_ptr) { + if (reference == p_ptr) { + return; + } + unref(); + + T *r = Object::cast_to(p_ptr); + if (r) { + ref_pointer(r); + } + } + + Ref(const Ref &p_from) { + ref(p_from); + } + + template + Ref(const Ref &p_from) { + RefCounted *refb = const_cast(static_cast(p_from.ptr())); + if (!refb) { + unref(); + return; + } + Ref r; + r.reference = Object::cast_to(refb); + ref(r); + r.reference = nullptr; + } + + Ref(T *p_reference) { + if (p_reference) { + ref_pointer(p_reference); + } + } + + Ref(const Variant &p_variant) { + Object *object = p_variant.get_validated_object(); + + if (!object) { + return; + } + + T *r = Object::cast_to(object); + if (r && r->reference()) { + reference = r; + } + } + + inline bool is_valid() const { return reference != nullptr; } + inline bool is_null() const { return reference == nullptr; } + + void unref() { + //TODO this should be moved to mutexes, since this engine does not really + // do a lot of referencing on references and stuff + // mutexes will avoid more crashes? + + if (reference && reference->unreference()) { + memdelete(reference); + } + reference = nullptr; + } + + void instance() { + ref(memnew(T)); + } + + Ref() {} + + ~Ref() { + unref(); + } +}; + +typedef Ref REF; + +class WeakRef : public RefCounted { + GDCLASS(WeakRef, RefCounted); + + ObjectID ref; + +protected: + static void _bind_methods(); + +public: + Variant get_ref() const; + void set_obj(Object *p_object); + void set_ref(const REF &p_ref); + + WeakRef() {} +}; + +template +struct PtrToArg> { + _FORCE_INLINE_ static Ref convert(const void *p_ptr) { + return Ref(const_cast(reinterpret_cast(p_ptr))); + } + + _FORCE_INLINE_ static void encode(Ref p_val, const void *p_ptr) { + *(Ref *)p_ptr = p_val; + } +}; + +template +struct PtrToArg &> { + _FORCE_INLINE_ static Ref convert(const void *p_ptr) { + return Ref((T *)p_ptr); + } +}; + +#ifdef DEBUG_METHODS_ENABLED + +template +struct GetTypeInfo> { + static const Variant::Type VARIANT_TYPE = Variant::OBJECT; + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; + + static inline PropertyInfo get_class_info() { + return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static()); + } +}; + +template +struct GetTypeInfo &> { + static const Variant::Type VARIANT_TYPE = Variant::OBJECT; + static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; + + static inline PropertyInfo get_class_info() { + return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static()); + } +}; + +#endif // DEBUG_METHODS_ENABLED + +#endif // REF_COUNTED_H diff --git a/core/object/reference.cpp b/core/object/reference.cpp deleted file mode 100644 index 086b761e95..0000000000 --- a/core/object/reference.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************/ -/* reference.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#include "reference.h" - -#include "core/object/script_language.h" - -bool Reference::init_ref() { - if (reference()) { - if (!is_referenced() && refcount_init.unref()) { - unreference(); // first referencing is already 1, so compensate for the ref above - } - - return true; - } else { - return false; - } -} - -void Reference::_bind_methods() { - ClassDB::bind_method(D_METHOD("init_ref"), &Reference::init_ref); - ClassDB::bind_method(D_METHOD("reference"), &Reference::reference); - ClassDB::bind_method(D_METHOD("unreference"), &Reference::unreference); -} - -int Reference::reference_get_count() const { - return refcount.get(); -} - -bool Reference::reference() { - uint32_t rc_val = refcount.refval(); - bool success = rc_val != 0; - - if (success && rc_val <= 2 /* higher is not relevant */) { - if (get_script_instance()) { - get_script_instance()->refcount_incremented(); - } - 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); - } - } - } - } - - return success; -} - -bool Reference::unreference() { - uint32_t rc_val = refcount.unrefval(); - bool die = rc_val == 0; - - if (rc_val <= 1 /* higher is not relevant */) { - if (get_script_instance()) { - bool script_ret = get_script_instance()->refcount_decremented(); - die = die && script_ret; - } - 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; - } - } - } - } - - return die; -} - -Reference::Reference() : - Object(true) { - refcount.init(); - refcount_init.init(); -} - -Variant WeakRef::get_ref() const { - if (ref.is_null()) { - return Variant(); - } - - Object *obj = ObjectDB::get_instance(ref); - if (!obj) { - return Variant(); - } - Reference *r = cast_to(obj); - if (r) { - return REF(r); - } - - return obj; -} - -void WeakRef::set_obj(Object *p_object) { - ref = p_object ? p_object->get_instance_id() : ObjectID(); -} - -void WeakRef::set_ref(const REF &p_ref) { - ref = p_ref.is_valid() ? p_ref->get_instance_id() : ObjectID(); -} - -void WeakRef::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_ref"), &WeakRef::get_ref); -} diff --git a/core/object/reference.h b/core/object/reference.h deleted file mode 100644 index d02cb12069..0000000000 --- a/core/object/reference.h +++ /dev/null @@ -1,297 +0,0 @@ -/*************************************************************************/ -/* reference.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* 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. */ -/*************************************************************************/ - -#ifndef REFERENCE_H -#define REFERENCE_H - -#include "core/object/class_db.h" -#include "core/templates/safe_refcount.h" - -class Reference : public Object { - GDCLASS(Reference, Object); - SafeRefCount refcount; - SafeRefCount refcount_init; - -protected: - static void _bind_methods(); - -public: - _FORCE_INLINE_ bool is_referenced() const { return refcount_init.get() != 1; } - bool init_ref(); - bool reference(); // returns false if refcount is at zero and didn't get increased - bool unreference(); - int reference_get_count() const; - - Reference(); - ~Reference() {} -}; - -template -class Ref { - T *reference = nullptr; - - void ref(const Ref &p_from) { - if (p_from.reference == reference) { - return; - } - - unref(); - - reference = p_from.reference; - if (reference) { - reference->reference(); - } - } - - void ref_pointer(T *p_ref) { - ERR_FAIL_COND(!p_ref); - - if (p_ref->init_ref()) { - reference = p_ref; - } - } - - //virtual Reference * get_reference() const { return reference; } -public: - _FORCE_INLINE_ bool operator==(const T *p_ptr) const { - return reference == p_ptr; - } - _FORCE_INLINE_ bool operator!=(const T *p_ptr) const { - return reference != p_ptr; - } - - _FORCE_INLINE_ bool operator<(const Ref &p_r) const { - return reference < p_r.reference; - } - _FORCE_INLINE_ bool operator==(const Ref &p_r) const { - return reference == p_r.reference; - } - _FORCE_INLINE_ bool operator!=(const Ref &p_r) const { - return reference != p_r.reference; - } - - _FORCE_INLINE_ T *operator->() { - return reference; - } - - _FORCE_INLINE_ T *operator*() { - return reference; - } - - _FORCE_INLINE_ const T *operator->() const { - return reference; - } - - _FORCE_INLINE_ const T *ptr() const { - return reference; - } - _FORCE_INLINE_ T *ptr() { - return reference; - } - - _FORCE_INLINE_ const T *operator*() const { - return reference; - } - - operator Variant() const { - return Variant(reference); - } - - void operator=(const Ref &p_from) { - ref(p_from); - } - - template - void operator=(const Ref &p_from) { - Reference *refb = const_cast(static_cast(p_from.ptr())); - if (!refb) { - unref(); - return; - } - Ref r; - r.reference = Object::cast_to(refb); - ref(r); - r.reference = nullptr; - } - - void operator=(const Variant &p_variant) { - Object *object = p_variant.get_validated_object(); - - if (object == reference) { - return; - } - - unref(); - - if (!object) { - return; - } - - T *r = Object::cast_to(object); - if (r && r->reference()) { - reference = r; - } - } - - template - void reference_ptr(T_Other *p_ptr) { - if (reference == p_ptr) { - return; - } - unref(); - - T *r = Object::cast_to(p_ptr); - if (r) { - ref_pointer(r); - } - } - - Ref(const Ref &p_from) { - ref(p_from); - } - - template - Ref(const Ref &p_from) { - Reference *refb = const_cast(static_cast(p_from.ptr())); - if (!refb) { - unref(); - return; - } - Ref r; - r.reference = Object::cast_to(refb); - ref(r); - r.reference = nullptr; - } - - Ref(T *p_reference) { - if (p_reference) { - ref_pointer(p_reference); - } - } - - Ref(const Variant &p_variant) { - Object *object = p_variant.get_validated_object(); - - if (!object) { - return; - } - - T *r = Object::cast_to(object); - if (r && r->reference()) { - reference = r; - } - } - - inline bool is_valid() const { return reference != nullptr; } - inline bool is_null() const { return reference == nullptr; } - - void unref() { - //TODO this should be moved to mutexes, since this engine does not really - // do a lot of referencing on references and stuff - // mutexes will avoid more crashes? - - if (reference && reference->unreference()) { - memdelete(reference); - } - reference = nullptr; - } - - void instance() { - ref(memnew(T)); - } - - Ref() {} - - ~Ref() { - unref(); - } -}; - -typedef Ref REF; - -class WeakRef : public Reference { - GDCLASS(WeakRef, Reference); - - ObjectID ref; - -protected: - static void _bind_methods(); - -public: - Variant get_ref() const; - void set_obj(Object *p_object); - void set_ref(const REF &p_ref); - - WeakRef() {} -}; - -template -struct PtrToArg> { - _FORCE_INLINE_ static Ref convert(const void *p_ptr) { - return Ref(const_cast(reinterpret_cast(p_ptr))); - } - - _FORCE_INLINE_ static void encode(Ref p_val, const void *p_ptr) { - *(Ref *)p_ptr = p_val; - } -}; - -template -struct PtrToArg &> { - _FORCE_INLINE_ static Ref convert(const void *p_ptr) { - return Ref((T *)p_ptr); - } -}; - -#ifdef DEBUG_METHODS_ENABLED - -template -struct GetTypeInfo> { - static const Variant::Type VARIANT_TYPE = Variant::OBJECT; - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; - - static inline PropertyInfo get_class_info() { - return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static()); - } -}; - -template -struct GetTypeInfo &> { - static const Variant::Type VARIANT_TYPE = Variant::OBJECT; - static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; - - static inline PropertyInfo get_class_info() { - return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static()); - } -}; - -#endif // DEBUG_METHODS_ENABLED - -#endif // REFERENCE_H diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp index e8735e335c..96c96c1efb 100644 --- a/core/object/undo_redo.cpp +++ b/core/object/undo_redo.cpp @@ -122,8 +122,8 @@ void UndoRedo::add_do_method(Object *p_object, const StringName &p_method, VARIA ERR_FAIL_COND((current_action + 1) >= actions.size()); Operation do_op; do_op.object = p_object->get_instance_id(); - if (Object::cast_to(p_object)) { - do_op.ref = Ref(Object::cast_to(p_object)); + if (Object::cast_to(p_object)) { + do_op.ref = Ref(Object::cast_to(p_object)); } do_op.type = Operation::TYPE_METHOD; @@ -148,8 +148,8 @@ void UndoRedo::add_undo_method(Object *p_object, const StringName &p_method, VAR Operation undo_op; undo_op.object = p_object->get_instance_id(); - if (Object::cast_to(p_object)) { - undo_op.ref = Ref(Object::cast_to(p_object)); + if (Object::cast_to(p_object)) { + undo_op.ref = Ref(Object::cast_to(p_object)); } undo_op.type = Operation::TYPE_METHOD; @@ -167,8 +167,8 @@ void UndoRedo::add_do_property(Object *p_object, const StringName &p_property, c ERR_FAIL_COND((current_action + 1) >= actions.size()); Operation do_op; do_op.object = p_object->get_instance_id(); - if (Object::cast_to(p_object)) { - do_op.ref = Ref(Object::cast_to(p_object)); + if (Object::cast_to(p_object)) { + do_op.ref = Ref(Object::cast_to(p_object)); } do_op.type = Operation::TYPE_PROPERTY; @@ -189,8 +189,8 @@ void UndoRedo::add_undo_property(Object *p_object, const StringName &p_property, Operation undo_op; undo_op.object = p_object->get_instance_id(); - if (Object::cast_to(p_object)) { - undo_op.ref = Ref(Object::cast_to(p_object)); + if (Object::cast_to(p_object)) { + undo_op.ref = Ref(Object::cast_to(p_object)); } undo_op.type = Operation::TYPE_PROPERTY; @@ -205,8 +205,8 @@ void UndoRedo::add_do_reference(Object *p_object) { ERR_FAIL_COND((current_action + 1) >= actions.size()); Operation do_op; do_op.object = p_object->get_instance_id(); - if (Object::cast_to(p_object)) { - do_op.ref = Ref(Object::cast_to(p_object)); + if (Object::cast_to(p_object)) { + do_op.ref = Ref(Object::cast_to(p_object)); } do_op.type = Operation::TYPE_REFERENCE; @@ -225,8 +225,8 @@ void UndoRedo::add_undo_reference(Object *p_object) { Operation undo_op; undo_op.object = p_object->get_instance_id(); - if (Object::cast_to(p_object)) { - undo_op.ref = Ref(Object::cast_to(p_object)); + if (Object::cast_to(p_object)) { + undo_op.ref = Ref(Object::cast_to(p_object)); } undo_op.type = Operation::TYPE_REFERENCE; diff --git a/core/object/undo_redo.h b/core/object/undo_redo.h index a08ca7792f..8f009830e3 100644 --- a/core/object/undo_redo.h +++ b/core/object/undo_redo.h @@ -32,7 +32,7 @@ #define UNDO_REDO_H #include "core/object/class_db.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" class UndoRedo : public Object { GDCLASS(UndoRedo, Object); @@ -61,7 +61,7 @@ private: }; Type type; - Ref ref; + Ref ref; ObjectID object; StringName name; Variant args[VARIANT_ARG_MAX]; diff --git a/core/os/main_loop.h b/core/os/main_loop.h index 25a09fe98f..34e944709b 100644 --- a/core/os/main_loop.h +++ b/core/os/main_loop.h @@ -32,7 +32,7 @@ #define MAIN_LOOP_H #include "core/input/input_event.h" -#include "core/object/reference.h" +#include "core/object/ref_counted.h" #include "core/object/script_language.h" class MainLoop : public Object { diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index f1b1b98bea..d68fc2a2c7 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -131,7 +131,7 @@ void register_core_types() { ClassDB::register_virtual_class