1
0
Fork 0
This commit is contained in:
moondog 2025-02-28 01:36:02 +01:00 committed by GitHub
commit b26889ebb2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 25 additions and 0 deletions

View File

@ -84,6 +84,7 @@ public:
const StringName bind = StaticCString::create("bind");
const StringName notification = StaticCString::create("notification");
const StringName property_list_changed = StaticCString::create("property_list_changed");
const StringName freeing = StaticCString::create("freeing");
};
#define CoreStringName(m_name) CoreStringNames::get_singleton()->m_name

View File

@ -228,6 +228,9 @@ Object::Connection::Connection(const Variant &p_variant) {
bool Object::_predelete() {
_predelete_ok = 1;
notification(NOTIFICATION_PREDELETE, true);
if (_emit_free && _predelete_ok) {
emit_signal(CoreStringName(freeing)); // Emit signal early so cancel_free can still occur.
}
if (_predelete_ok) {
_class_name_ptr = nullptr; // Must restore, so constructors/destructors have proper class name access at each stage.
notification(NOTIFICATION_PREDELETE_CLEANUP, true);
@ -1765,12 +1768,14 @@ void Object::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_translation_domain", "domain"), &Object::set_translation_domain);
ClassDB::bind_method(D_METHOD("is_queued_for_deletion"), &Object::is_queued_for_deletion);
ClassDB::bind_method(D_METHOD("set_emit_freeing", "enable"), &Object::set_emit_freeing);
ClassDB::bind_method(D_METHOD("cancel_free"), &Object::cancel_free);
ClassDB::add_virtual_method("Object", MethodInfo("free"), false);
ADD_SIGNAL(MethodInfo("script_changed"));
ADD_SIGNAL(MethodInfo("property_list_changed"));
ADD_SIGNAL(MethodInfo("freeing"));
#define BIND_OBJ_CORE_METHOD(m_method) \
::ClassDB::add_virtual_method(get_class_static(), m_method, true, Vector<String>(), true);
@ -1930,6 +1935,10 @@ bool Object::is_queued_for_deletion() const {
return _is_queued_for_deletion;
}
void Object::set_emit_freeing(bool p_emit) {
_emit_free = p_emit;
}
#ifdef TOOLS_ENABLED
void Object::set_edited(bool p_edited) {
_edited = p_edited;

View File

@ -628,6 +628,7 @@ private:
SafeRefCount _lock_index;
#endif
bool _block_signals = false;
bool _emit_free = false;
int _predelete_ok = 0;
ObjectID _instance_id;
bool _predelete();
@ -998,6 +999,7 @@ public:
_ALWAYS_INLINE_ bool is_ref_counted() const { return type_is_reference; }
void set_emit_freeing(bool p_emit);
void cancel_free();
Object();

View File

@ -1036,6 +1036,13 @@
[b]Note:[/b] In C#, [param property] must be in snake_case when referring to built-in Godot properties. Prefer using the names exposed in the [code]PropertyName[/code] class to avoid allocating a new [StringName] on each call.
</description>
</method>
<method name="set_emit_freeing">
<return type="void" />
<param index="0" name="enable" type="bool" />
<description>
If set to [code]true[/code], the object will emit [signal freeing] upon cleanup.
</description>
</method>
<method name="set_indexed">
<return type="void" />
<param index="0" name="property_path" type="NodePath" />
@ -1126,6 +1133,12 @@
</method>
</methods>
<signals>
<signal name="freeing">
<description>
Emitted when the object is about to be freed. Only emitted after [method set_emit_freeing] is called.
This signal is emitted [i]after[/i] the related [constant NOTIFICATION_PREDELETE] notification.
</description>
</signal>
<signal name="property_list_changed">
<description>
Emitted when [method notify_property_list_changed] is called.