diff options
-rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 4 | ||||
-rw-r--r-- | modules/mono/csharp_script.cpp | 54 | ||||
-rw-r--r-- | modules/mono/csharp_script.h | 8 | ||||
-rw-r--r-- | modules/mono/glue/base_object_glue.cpp | 1 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_internals.cpp | 4 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_utils.cpp | 1 | ||||
-rw-r--r-- | modules/squish/image_compress_squish.cpp | 2 | ||||
-rw-r--r-- | modules/squish/image_compress_squish.h | 2 | ||||
-rw-r--r-- | modules/squish/register_types.cpp | 2 | ||||
-rw-r--r-- | platform/haiku/detect.py | 2 | ||||
-rw-r--r-- | platform/server/detect.py | 2 | ||||
-rw-r--r-- | platform/x11/detect.py | 2 | ||||
-rw-r--r-- | scene/gui/scroll_container.cpp | 12 |
13 files changed, 79 insertions, 17 deletions
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 3c056fc004..fc2e626795 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -7046,12 +7046,10 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat return_type = _type_from_property(mi.return_val, false); -#ifdef DEBUG_ENABLED // Check all arguments beforehand to solve warnings for (int i = 1; i < p_call->arguments.size(); i++) { _reduce_node_type(p_call->arguments[i]); } -#endif // DEBUG_ENABLED // Check arguments @@ -7079,12 +7077,10 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat ERR_FAIL_V(DataType()); } -#ifdef DEBUG_ENABLED // Check all arguments beforehand to solve warnings for (int i = arg_id + 1; i < p_call->arguments.size(); i++) { _reduce_node_type(p_call->arguments[i]); } -#endif // DEBUG_ENABLED IdentifierNode *func_id = static_cast<IdentifierNode *>(p_call->arguments[arg_id]); callee_name = func_id->name; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index d82e78d080..8a024eef13 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -159,6 +159,19 @@ void CSharpLanguage::finish() { // Clear here, after finalizing all domains to make sure there is nothing else referencing the elements. script_bindings.clear(); +#ifdef DEBUG_ENABLED + for (List<ObjectID>::Element *E = unsafely_referenced_objects.front(); E; E = E->next()) { + const ObjectID &id = E->get(); + Object *obj = ObjectDB::get_instance(id); + + if (obj) { + ERR_PRINTS("Leaked unsafe reference to object: " + obj->get_class() + ":" + itos(id)); + } else { + ERR_PRINTS("Leaked unsafe reference to deleted object: " + itos(id)); + } + } +#endif + finalizing = false; } @@ -615,6 +628,23 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec } #endif +void CSharpLanguage::post_unsafe_reference(Object *p_obj) { +#ifdef DEBUG_ENABLED + ObjectID id = p_obj->get_instance_id(); + ERR_FAIL_COND_MSG(unsafely_referenced_objects.find(id), "Multiple unsafe references for object: " + p_obj->get_class() + ":" + itos(id)); + unsafely_referenced_objects.push_back(id); +#endif +} + +void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) { +#ifdef DEBUG_ENABLED + ObjectID id = p_obj->get_instance_id(); + List<ObjectID>::Element *elem = unsafely_referenced_objects.find(id); + ERR_FAIL_NULL(elem); + unsafely_referenced_objects.erase(elem); +#endif +} + void CSharpLanguage::frame() { if (gdmono && gdmono->is_runtime_initialized() && gdmono->get_core_api_assembly() != NULL) { @@ -1286,6 +1316,7 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b // See: godot_icall_Reference_Dtor(MonoObject *p_obj, Object *p_ptr) ref->reference(); + CSharpLanguage::get_singleton()->post_unsafe_reference(ref); } return true; @@ -1736,9 +1767,12 @@ bool CSharpInstance::_reference_owner_unsafe() { // See: _unreference_owner_unsafe() // May not me referenced yet, so we must use init_ref() instead of reference() - bool success = Object::cast_to<Reference>(owner)->init_ref(); - unsafe_referenced = success; - return success; + if (static_cast<Reference *>(owner)->init_ref()) { + CSharpLanguage::get_singleton()->post_unsafe_reference(owner); + unsafe_referenced = true; + } + + return unsafe_referenced; } bool CSharpInstance::_unreference_owner_unsafe() { @@ -1759,6 +1793,7 @@ bool CSharpInstance::_unreference_owner_unsafe() { // See: _reference_owner_unsafe() // Destroying the owner here means self destructing, so we defer the owner destruction to the caller. + CSharpLanguage::get_singleton()->pre_unsafe_unreference(owner); return static_cast<Reference *>(owner)->unreference(); } @@ -2243,7 +2278,11 @@ bool CSharpScript::_update_exports() { MonoException *ctor_exc = NULL; ctor->invoke(tmp_object, NULL, &ctor_exc); + Object *tmp_native = GDMonoMarshal::unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(tmp_object)); + if (ctor_exc) { + // TODO: Should we free 'tmp_native' if the exception was thrown after its creation? + MonoGCHandle::free_handle(tmp_pinned_gchandle); tmp_object = NULL; @@ -2322,6 +2361,15 @@ bool CSharpScript::_update_exports() { MonoGCHandle::free_handle(tmp_pinned_gchandle); tmp_object = NULL; + + if (tmp_native && !Object::cast_to<Reference>(tmp_native)) { + Node *node = Object::cast_to<Node>(tmp_native); + if (node && node->is_inside_tree()) { + ERR_PRINTS("Temporary instance was added to the scene tree."); + } else { + memdelete(tmp_native); + } + } } placeholder_fallback_enabled = false; diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 027f429125..30f56e00bd 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -307,6 +307,11 @@ class CSharpLanguage : public ScriptLanguage { Map<Object *, CSharpScriptBinding> script_bindings; +#ifdef DEBUG_ENABLED + // List of unsafely referenced objects + List<ObjectID> unsafely_referenced_objects; +#endif + struct StringNameCache { StringName _signal_callback; @@ -458,6 +463,9 @@ public: Vector<StackInfo> stack_trace_get_info(MonoObject *p_stack_trace); #endif + void post_unsafe_reference(Object *p_obj); + void pre_unsafe_unreference(Object *p_obj); + CSharpLanguage(); ~CSharpLanguage(); }; diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp index 04a489f1f9..02246b2f2f 100644 --- a/modules/mono/glue/base_object_glue.cpp +++ b/modules/mono/glue/base_object_glue.cpp @@ -108,6 +108,7 @@ void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolea // Unsafe refcount decrement. The managed instance also counts as a reference. // See: CSharpLanguage::alloc_instance_binding_data(Object *p_object) + CSharpLanguage::get_singleton()->pre_unsafe_unreference(ref); if (ref->unreference()) { memdelete(ref); } else { diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index 8669182c4e..75aa77c7b0 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -83,7 +83,9 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { // See: godot_icall_Reference_Dtor(MonoObject *p_obj, Object *p_ptr) // May not me referenced yet, so we must use init_ref() instead of reference() - ref->init_ref(); + if (ref->init_ref()) { + CSharpLanguage::get_singleton()->post_unsafe_reference(ref); + } } // The object was just created, no script instance binding should have been attached diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 3c8aa0c727..6bb9f28a32 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -115,6 +115,7 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) { // but the managed instance is alive, the refcount will be 1 instead of 0. // See: godot_icall_Reference_Dtor(MonoObject *p_obj, Object *p_ptr) ref->reference(); + CSharpLanguage::get_singleton()->post_unsafe_reference(ref); } return mono_object; diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp index ef4ea93e57..58b8115dfc 100644 --- a/modules/squish/image_compress_squish.cpp +++ b/modules/squish/image_compress_squish.cpp @@ -73,7 +73,6 @@ void image_decompress_squish(Image *p_image) { p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); } -#ifdef TOOLS_ENABLED void image_compress_squish(Image *p_image, float p_lossy_quality, Image::CompressSource p_source) { if (p_image->get_format() >= Image::FORMAT_DXT1) @@ -203,4 +202,3 @@ void image_compress_squish(Image *p_image, float p_lossy_quality, Image::Compres p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); } } -#endif diff --git a/modules/squish/image_compress_squish.h b/modules/squish/image_compress_squish.h index 2666815e47..b5a209ceb9 100644 --- a/modules/squish/image_compress_squish.h +++ b/modules/squish/image_compress_squish.h @@ -33,9 +33,7 @@ #include "core/image.h" -#ifdef TOOLS_ENABLED void image_compress_squish(Image *p_image, float p_lossy_quality, Image::CompressSource p_source); -#endif void image_decompress_squish(Image *p_image); #endif // IMAGE_COMPRESS_SQUISH_H diff --git a/modules/squish/register_types.cpp b/modules/squish/register_types.cpp index 1cd551defb..2a0cf82b56 100644 --- a/modules/squish/register_types.cpp +++ b/modules/squish/register_types.cpp @@ -33,9 +33,7 @@ void register_squish_types() { -#ifdef TOOLS_ENABLED Image::set_compress_bc_func(image_compress_squish); -#endif Image::_image_decompress_bc = image_decompress_squish; } diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index 2a3e165069..dd72294816 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -95,7 +95,7 @@ def configure(env): if not env['builtin_enet']: env.ParseConfig('pkg-config libenet --cflags --libs') - if not env['builtin_squish'] and env['tools']: + if not env['builtin_squish']: env.ParseConfig('pkg-config libsquish --cflags --libs') if not env['builtin_zstd']: diff --git a/platform/server/detect.py b/platform/server/detect.py index b6028c20e3..d82df77957 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -162,7 +162,7 @@ def configure(env): if not env['builtin_enet']: env.ParseConfig('pkg-config libenet --cflags --libs') - if not env['builtin_squish'] and env['tools']: + if not env['builtin_squish']: env.ParseConfig('pkg-config libsquish --cflags --libs') if not env['builtin_zstd']: diff --git a/platform/x11/detect.py b/platform/x11/detect.py index b8ff97279d..a961072bd6 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -232,7 +232,7 @@ def configure(env): if not env['builtin_enet']: env.ParseConfig('pkg-config libenet --cflags --libs') - if not env['builtin_squish'] and env['tools']: + if not env['builtin_squish']: env.ParseConfig('pkg-config libsquish --cflags --libs') if not env['builtin_zstd']: diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index dc1183df74..4712f4cb9d 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -420,6 +420,9 @@ void ScrollContainer::update_scrollbars() { v_scroll->hide(); scroll.y = 0; + + // modify the horizontal scrollbar's right anchor to fill the container's width + h_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0); } else { v_scroll->show(); @@ -431,12 +434,18 @@ void ScrollContainer::update_scrollbars() { } scroll.y = v_scroll->get_value(); + + // modify the horizontal scrollbar's right anchor to stop at the left of the vertical scrollbar + h_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, -vmin.width); } if (hide_scroll_h) { h_scroll->hide(); scroll.x = 0; + + // modify the vertical scrollbar's bottom anchor to fill the container's height + v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0); } else { h_scroll->show(); @@ -448,6 +457,9 @@ void ScrollContainer::update_scrollbars() { } scroll.x = h_scroll->get_value(); + + // modify the vertical scrollbar's bottom anchor to stop at the top of the horizontal scrollbar + v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, -hmin.height); } } |