mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-09 07:46:20 +00:00
## About The Pull Request it's - conjunction of "it" and "is" its - possessive form of "it" grammar is hard, and there were a lot of places where "it's" was used where it shouldn't have been. i went and painstakingly searched the entire repository for these instances, spending a few hours on it. i completely ignored the changelog archive, and i may have missed some outliers. most player-facing ones should be corrected, though ## Why It's Good For The Game proper grammar is good ## Changelog 🆑 spellcheck: Numerous instances of "it's" have been properly replaced with "its" /🆑
129 lines
4.9 KiB
Plaintext
129 lines
4.9 KiB
Plaintext
/**
|
|
* 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 its 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._listen_lookup ||= list())
|
|
|
|
var/exists = target_procs[signal_type]
|
|
target_procs[signal_type] = proctype
|
|
|
|
if(exists)
|
|
if(!override)
|
|
var/override_message = "[signal_type] overridden. Use override = TRUE to suppress this warning.\nTarget: [target] ([target.type]) Existing Proc: [exists] New Proc: [proctype]"
|
|
log_signal(override_message)
|
|
stack_trace(override_message)
|
|
return
|
|
|
|
var/list/looked_up = lookup[signal_type]
|
|
|
|
if(isnull(looked_up)) // Nothing has registered here yet
|
|
lookup[signal_type] = src
|
|
else if(!islist(looked_up)) // One other thing registered here
|
|
lookup[signal_type] = list(looked_up, src)
|
|
else // Many other things have registered here
|
|
looked_up += src
|
|
|
|
/// 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._listen_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 _listen_lookup")
|
|
if(src in lookup[sig])
|
|
lookup -= sig
|
|
if(!length(lookup))
|
|
target._listen_lookup = null
|
|
break
|
|
if(0)
|
|
if(lookup[sig] != src)
|
|
continue
|
|
lookup -= sig
|
|
if(!length(lookup))
|
|
target._listen_lookup = null
|
|
break
|
|
else
|
|
lookup[sig] -= src
|
|
|
|
_signal_procs[target] -= sig_type_or_types
|
|
if(!_signal_procs[target].len)
|
|
_signal_procs -= target
|
|
|
|
/**
|
|
* Internal proc to handle most all of the signaling procedure
|
|
*
|
|
* Will runtime if used on datums with an empty lookup list
|
|
*
|
|
* Use the [SEND_SIGNAL] define instead
|
|
*/
|
|
/datum/proc/_SendSignal(sigtype, list/arguments)
|
|
var/target = _listen_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()
|
|
// This should be faster than doing `var/datum/listening_datum as anything in target` as it does not implicitly copy the list
|
|
for(var/i in 1 to length(target))
|
|
var/datum/listening_datum = target[i]
|
|
queued_calls.Add(listening_datum, listening_datum._signal_procs[src][sigtype])
|
|
for(var/i in 1 to length(queued_calls) step 2)
|
|
. |= call(queued_calls[i], queued_calls[i + 1])(arglist(arguments))
|