mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-31 12:01:47 +00:00
* Better errors for adding element to qdeling datum (#80927) ## About The Pull Request Got this from reading #80915 The actual name of the element is not reported anywhere in the stack trace, and while you might be able to figure it out from context clues based on the procs invoked in the stack trace... this isn't guaranteed and just makes it harder to diagnose these weird sporadic runtimes. ## Why It's Good For The Game easier to figure out a problem when you have as much useful information as possible ## Changelog irrelevant * Better errors for adding element to qdeling datum --------- Co-authored-by: san7890 <the@san7890.com>
78 lines
2.7 KiB
Plaintext
78 lines
2.7 KiB
Plaintext
/**
|
|
* A holder for simple behaviour that can be attached to many different types
|
|
*
|
|
* Only one element of each type is instanced during game init.
|
|
* Otherwise acts basically like a lightweight component.
|
|
*/
|
|
/datum/element
|
|
/// Option flags for element behaviour
|
|
var/element_flags = NONE
|
|
/**
|
|
* The index of the first attach argument to consider for duplicate elements
|
|
*
|
|
* All arguments from this index onwards (1 based) are hashed into the key to determine
|
|
* if this is a new unique element or one already exists
|
|
*
|
|
* Is only used when flags contains [ELEMENT_BESPOKE]
|
|
*
|
|
* This is infinity so you must explicitly set this
|
|
*/
|
|
var/argument_hash_start_idx = INFINITY
|
|
|
|
/// Activates the functionality defined by the element on the given target datum
|
|
/datum/element/proc/Attach(datum/target)
|
|
SHOULD_CALL_PARENT(TRUE)
|
|
if(type == /datum/element)
|
|
return ELEMENT_INCOMPATIBLE
|
|
SEND_SIGNAL(target, COMSIG_ELEMENT_ATTACH, src)
|
|
if(element_flags & ELEMENT_DETACH_ON_HOST_DESTROY)
|
|
RegisterSignal(target, COMSIG_QDELETING, PROC_REF(OnTargetDelete), override = TRUE)
|
|
|
|
/datum/element/proc/OnTargetDelete(datum/source, force)
|
|
SIGNAL_HANDLER
|
|
Detach(source)
|
|
|
|
/// Deactivates the functionality defines by the element on the given datum
|
|
/datum/element/proc/Detach(datum/source, ...)
|
|
SIGNAL_HANDLER
|
|
SHOULD_CALL_PARENT(TRUE)
|
|
|
|
SEND_SIGNAL(source, COMSIG_ELEMENT_DETACH, src)
|
|
UnregisterSignal(source, COMSIG_QDELETING)
|
|
|
|
/datum/element/Destroy(force)
|
|
if(!force)
|
|
return QDEL_HINT_LETMELIVE
|
|
SSdcs.elements_by_type -= type
|
|
return ..()
|
|
|
|
//DATUM PROCS
|
|
|
|
/// Finds the singleton for the element type given and attaches it to src
|
|
/datum/proc/_AddElement(list/arguments)
|
|
if(QDELING(src))
|
|
var/datum/element/element_type = arguments[1]
|
|
stack_trace("We just tried to add the element [element_type] to a qdeleted datum, something is fucked")
|
|
return
|
|
|
|
var/datum/element/ele = SSdcs.GetElement(arguments)
|
|
if(!ele) // We couldn't fetch the element, likely because it was not an element.
|
|
return // the crash message has already been sent
|
|
arguments[1] = src
|
|
if(ele.Attach(arglist(arguments)) == ELEMENT_INCOMPATIBLE)
|
|
CRASH("Incompatible element [ele.type] was assigned to a [type]! args: [json_encode(args)]")
|
|
|
|
/**
|
|
* Finds the singleton for the element type given and detaches it from src
|
|
* You only need additional arguments beyond the type if you're using [ELEMENT_BESPOKE]
|
|
*/
|
|
/datum/proc/_RemoveElement(list/arguments)
|
|
var/datum/element/ele = SSdcs.GetElement(arguments, FALSE)
|
|
if(!ele) // We couldn't fetch the element, likely because it didn't exist.
|
|
return
|
|
if(ele.element_flags & ELEMENT_COMPLEX_DETACH)
|
|
arguments[1] = src
|
|
ele.Detach(arglist(arguments))
|
|
else
|
|
ele.Detach(src)
|