Pulls apart the vestiges of components still hanging onto signals (#75914)

## About The Pull Request

Signals were initially only usable with component listeners, which while
no longer the case has lead to outdated documentation, names, and a
similar location in code.

This pr pulls the two apart. Partially because mso thinks we should, but
also because they really aren't directly linked anymore, and having them
in this midstate just confuses people.

[Renames comp_lookup to listen_lookup, since that's what it
does](https://github.com/tgstation/tgstation/commit/102b79694fa8eb57ecf7b36032616a9e368ccced)

[Moves signal procs over to their own
file](https://github.com/tgstation/tgstation/commit/33d07d01fd336726b4f6f6f1b61bb0b3f11a00dc)

[Renames the PREQDELETING and QDELETING comsigs to drop the parent bit
since they can hook to more then just comps
now](https://github.com/tgstation/tgstation/commit/335ea4ad081ec63c42cfa05856e582cca833af6e)

[Does something similar to the attackby comsigs (PARENT ->
ATOM)](https://github.com/tgstation/tgstation/commit/210e57051df63f88dac3dd83321236da825aae5e)

[And finally passes over the examine
signals](https://github.com/tgstation/tgstation/commit/65917658fb8a1e7d28ae23c9437a583d646f0302)

## Why It's Good For The Game

Code makes more sense, things are better teased apart, s just good imo

## Changelog
🆑
refactor: Pulled apart the last vestiges of names/docs directly linking
signals to components
/🆑
This commit is contained in:
LemonInTheDark
2023-06-09 06:14:31 +00:00
committed by GitHub
parent c0ae81032b
commit ae5a4f955d
335 changed files with 913 additions and 913 deletions
+1 -126
View File
@@ -189,109 +189,6 @@
if(!LAZYLEN(sources))
qdel(src)
/**
* Register to listen for a signal from the passed in target
*
* This sets up a listening relationship such that when the target object emits a signal
* the source datum this proc is called upon, will receive a callback to the given proctype
* Use PROC_REF(procname), TYPE_PROC_REF(type,procname) or GLOBAL_PROC_REF(procname) macros to validate the passed in proc at compile time.
* PROC_REF for procs defined on current type or it's ancestors, TYPE_PROC_REF for procs defined on unrelated type and GLOBAL_PROC_REF for global procs.
* Return values from procs registered must be a bitfield
*
* Arguments:
* * datum/target The target to listen for signals from
* * signal_type A signal name
* * proctype The proc to call back when the signal is emitted
* * override If a previous registration exists you must explicitly set this
*/
/datum/proc/RegisterSignal(datum/target, signal_type, proctype, override = FALSE)
if(QDELETED(src) || QDELETED(target))
return
if (islist(signal_type))
var/static/list/known_failures = list()
var/list/signal_type_list = signal_type
var/message = "([target.type]) is registering [signal_type_list.Join(", ")] as a list, the older method. Change it to RegisterSignals."
if (!(message in known_failures))
known_failures[message] = TRUE
stack_trace("[target] [message]")
RegisterSignals(target, signal_type, proctype, override)
return
var/list/procs = (_signal_procs ||= list())
var/list/target_procs = (procs[target] ||= list())
var/list/lookup = (target._comp_lookup ||= list())
if(!override && target_procs[signal_type])
var/override_message = "[signal_type] overridden. Use override = TRUE to suppress this warning.\nTarget: [target] ([target.type]) Proc: [proctype]"
log_signal(override_message)
stack_trace(override_message)
target_procs[signal_type] = proctype
var/list/looked_up = lookup[signal_type]
if(isnull(looked_up)) // Nothing has registered here yet
lookup[signal_type] = src
else if(looked_up == src) // We already registered here
return
else if(!length(looked_up)) // One other thing registered here
lookup[signal_type] = list((looked_up) = TRUE, (src) = TRUE)
else // Many other things have registered here
looked_up[src] = TRUE
/// Registers multiple signals to the same proc.
/datum/proc/RegisterSignals(datum/target, list/signal_types, proctype, override = FALSE)
for (var/signal_type in signal_types)
RegisterSignal(target, signal_type, proctype, override)
/**
* Stop listening to a given signal from target
*
* Breaks the relationship between target and source datum, removing the callback when the signal fires
*
* Doesn't care if a registration exists or not
*
* Arguments:
* * datum/target Datum to stop listening to signals from
* * sig_typeor_types Signal string key or list of signal keys to stop listening to specifically
*/
/datum/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)
if(!_signal_procs[target][sig])
if(!istext(sig))
stack_trace("We're unregistering with something that isn't a valid signal \[[sig]\], you fucked up")
continue
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)
if(lookup[sig] != src)
continue
lookup -= sig
if(!length(lookup))
target._comp_lookup = null
break
else
lookup[sig] -= src
_signal_procs[target] -= sig_type_or_types
if(!_signal_procs[target].len)
_signal_procs -= target
/**
* Called on a component when a component of the same type was added to the same parent
*
@@ -344,29 +241,7 @@
//and since most components are root level + 1, this won't even have to run
while (current_type != /datum/component)
current_type = type2parent(current_type)
. += current_type
/**
* Internal proc to handle most all of the signaling procedure
*
* Will runtime if used on datums with an empty comp_lookup list
*
* Use the [SEND_SIGNAL] define instead
*/
/datum/proc/_SendSignal(sigtype, list/arguments)
var/target = _comp_lookup[sigtype]
if(!length(target))
var/datum/listening_datum = target
return NONE | call(listening_datum, listening_datum._signal_procs[src][sigtype])(arglist(arguments))
. = NONE
// This exists so that even if one of the signal receivers unregisters the signal,
// all the objects that are receiving the signal get the signal this final time.
// AKA: No you can't cancel the signal reception of another object by doing an unregister in the same signal.
var/list/queued_calls = list()
for(var/datum/listening_datum as anything in target)
queued_calls[listening_datum] = listening_datum._signal_procs[src][sigtype]
for(var/datum/listening_datum as anything in queued_calls)
. |= call(listening_datum, queued_calls[listening_datum])(arglist(arguments))
. += current_type
// The type arg is casted so initial works, you shouldn't be passing a real instance into this
/**