diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm index ccfc041b21..f773e3c92d 100644 --- a/code/controllers/subsystem/garbage.dm +++ b/code/controllers/subsystem/garbage.dm @@ -263,7 +263,7 @@ SUBSYSTEM_DEF(garbage) // Should be treated as a replacement for the 'del' keyword. // Datums passed to this will be given a chance to clean up references to allow the GC to collect them. -/proc/qdel(datum/D, force=FALSE) +/proc/qdel(datum/D, force=FALSE, ...) if(!istype(D)) del(D) return @@ -278,7 +278,7 @@ SUBSYSTEM_DEF(garbage) D.gc_destroyed = GC_CURRENTLY_BEING_QDELETED var/start_time = world.time var/start_tick = world.tick_usage - var/hint = D.Destroy(force) // Let our friend know they're about to get fucked up. + var/hint = D.Destroy(arglist(args.Copy(2))) // Let our friend know they're about to get fucked up. if(world.time != start_time) I.slept_destroy++ else diff --git a/code/datums/components/README.md b/code/datums/components/README.md index eeb6615a63..11cbf1858d 100644 --- a/code/datums/components/README.md +++ b/code/datums/components/README.md @@ -87,9 +87,11 @@ Stands have a lot of procs which mimic mob procs. Rather than inserting hooks fo * Signals will not be recieved while this function is running * Component may be deleted after this function completes without being attached * Do not call `qdel(src)` from this function -1. `/datum/component/Destroy()` (virtual, no-sleep) +1. `/datum/component/Destroy(force(bool), silent(bool))` (virtual, no-sleep) * Sends the `COMSIG_COMPONENT_REMOVING` signal to the parent datum if the `parent` isn't being qdeleted * Properly removes the component from `parent` and cleans up references + * Setting `force` makes it not check for and remove the component from the parent + * Setting `silent` deletes the component without sending a `COMSIG_COMPONENT_REMOVING` signal 1. `/datum/component/proc/InheritComponent(datum/component/C, i_am_original(boolean))` (abstract, no-sleep) * Called on a component when a component of the same type was added to the same parent * See `/datum/component/var/dupe_mode` diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 3a593a8d14..bb60350cbf 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -14,8 +14,7 @@ var/list/arguments = args.Copy() arguments.Cut(1, 2) if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE) - parent = null - qdel(src) + qdel(src, TRUE, TRUE) return _CheckDupesAndJoinParent(P) @@ -36,13 +35,11 @@ switch(dm) if(COMPONENT_DUPE_UNIQUE) old.InheritComponent(src, TRUE) - parent = null //prevent COMPONENT_REMOVING signal, no _RemoveFromParent because we aren't in their list yet - qdel(src) + qdel(src, TRUE, TRUE) return if(COMPONENT_DUPE_HIGHLANDER) InheritComponent(old, FALSE) - old._RemoveFromParent() - qdel(old) + qdel(old, FALSE, TRUE) //provided we didn't eat someone if(!old) @@ -83,12 +80,14 @@ /datum/component/proc/Initialize(...) return -/datum/component/Destroy() +/datum/component/Destroy(force=FALSE, silent=FALSE) enabled = FALSE var/datum/P = parent - if(P) + if(!force) _RemoveFromParent() + if(!silent) P.SendSignal(COMSIG_COMPONENT_REMOVING, src) + parent = null LAZYCLEARLIST(signal_procs) return ..() @@ -107,7 +106,6 @@ dc -= I if(!dc.len) P.datum_components = null - parent = null /datum/component/proc/RegisterSignal(sig_type_or_types, proc_or_callback, override = FALSE) if(QDELETED(src)) diff --git a/code/datums/datum.dm b/code/datums/datum.dm index 00dd796f47..dc74e72713 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -12,7 +12,7 @@ // Default implementation of clean-up code. // This should be overridden to remove all references pointing to the object being destroyed. // Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE. -/datum/proc/Destroy(force=FALSE) +/datum/proc/Destroy(force=FALSE, ...) tag = null var/list/timers = active_timers active_timers = null @@ -27,11 +27,9 @@ if(length(all_components)) for(var/I in all_components) var/datum/component/C = I - C._RemoveFromParent() - qdel(C) + qdel(C, FALSE, TRUE) else var/datum/component/C = all_components - C._RemoveFromParent() - qdel(C) + qdel(C, FALSE, TRUE) dc.Cut() return QDEL_HINT_QUEUE