Merge pull request #3853 from Citadel-Station-13/upstream-merge-32351

[MIRROR] fixes null parent in destroy for components
This commit is contained in:
LetterJay
2017-11-08 01:46:47 -06:00
committed by GitHub
4 changed files with 15 additions and 17 deletions

View File

@@ -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

View File

@@ -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`

View File

@@ -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))

View File

@@ -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