Refactors component signals registration (#38798)

Datums know what signals are being listened for and components can now be registered to listen for signals on more than one object.
This commit is contained in:
Emmett Gaines
2018-07-04 17:56:39 -04:00
committed by vuonojenmustaturska
parent a088bde838
commit 34a3d2da4d
41 changed files with 203 additions and 202 deletions

View File

@@ -58,8 +58,8 @@
if(!silent)
SEND_SIGNAL(P, COMSIG_COMPONENT_REMOVING, src)
parent = null
SSdcs.UnregisterSignal(src, signal_procs)
LAZYCLEARLIST(signal_procs)
for(var/target in signal_procs)
UnregisterSignal(target, signal_procs[target])
return ..()
/datum/component/proc/_RemoveFromParent()
@@ -78,34 +78,69 @@
if(!dc.len)
P.datum_components = null
/datum/component/proc/RegisterSignal(sig_type_or_types, proc_or_callback, override = FALSE)
if(QDELETED(src))
/datum/component/proc/RegisterSignal(datum/target, sig_type_or_types, proc_or_callback, override = FALSE)
if(QDELETED(src) || QDELETED(target))
return
var/list/procs = signal_procs
if(!procs)
procs = list()
signal_procs = procs
signal_procs = procs = list()
if(!procs[target])
procs[target] = list()
var/list/lookup = target.comp_lookup
if(!lookup)
target.comp_lookup = lookup = list()
if(!istype(proc_or_callback, /datum/callback)) //if it wasnt a callback before, it is now
proc_or_callback = CALLBACK(src, proc_or_callback)
var/list/sig_types = islist(sig_type_or_types) ? sig_type_or_types : list(sig_type_or_types)
for(var/sig_type in sig_types)
if(!override && procs[sig_type])
if(!override && procs[target][sig_type])
stack_trace("[sig_type] overridden. Use override = TRUE to suppress this warning")
if(sig_type[1] == "!")
SSdcs.RegisterSignal(src, sig_type)
procs[sig_type] = proc_or_callback
procs[target][sig_type] = proc_or_callback
if(!lookup[sig_type]) // Nothing has registered here yet
lookup[sig_type] = src
else if(lookup[sig_type] == src) // We already registered here
continue
else if(!length(lookup[sig_type])) // One other thing registered here
lookup[sig_type] = list(lookup[sig_type]=TRUE)
lookup[sig_type][src] = TRUE
else // Many other things have registered here
lookup[sig_type][src] = TRUE
enabled = TRUE
/datum/component/proc/HasSignal(sig_type)
return signal_procs[sig_type] != null
/datum/component/proc/UnregisterSignal(datum/target, sig_type_or_types)
var/list/lookup = target.comp_lookup
if(!signal_procs || !signal_procs[target] || !lookup)
return
if(!islist(sig_type_or_types))
sig_type_or_types = list(sig_type_or_types)
for(var/sig in sig_type_or_types)
switch(length(lookup[sig]))
if(2)
lookup[sig] = (lookup[sig]-src)[1]
if(1)
stack_trace("[target] ([target.type]) somehow has single length list inside comp_lookup")
if(src in lookup[sig])
lookup -= sig
if(!length(lookup))
target.comp_lookup = null
break
if(0)
lookup -= sig
if(!length(lookup))
target.comp_lookup = null
break
else
lookup[sig] -= src
/datum/component/proc/UnregisterSignal(sig_type_or_types)
signal_procs -= sig_type_or_types
signal_procs[target] -= sig_type_or_types
if(!signal_procs[target].len)
signal_procs -= target
/datum/component/proc/InheritComponent(datum/component/C, i_am_original)
return
@@ -126,23 +161,19 @@
. += current_type
/datum/proc/_SendSignal(sigtype, list/arguments)
var/target = datum_components[/datum/component]
var/target = comp_lookup[sigtype]
if(!length(target))
var/datum/component/C = target
if(!C.enabled)
return NONE
var/datum/callback/CB = C.signal_procs[sigtype]
if(!CB)
return NONE
var/datum/callback/CB = C.signal_procs[src][sigtype]
return CB.InvokeAsync(arglist(arguments))
. = NONE
for(var/I in target)
var/datum/component/C = I
if(!C.enabled)
continue
var/datum/callback/CB = C.signal_procs[sigtype]
if(!CB)
continue
var/datum/callback/CB = C.signal_procs[src][sigtype]
. |= CB.InvokeAsync(arglist(arguments))
/datum/proc/GetComponent(c_type)