mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-12 09:54:03 +00:00
* Adds SIGNAL_HANDLER and SIGNAL_HANDLER_DOES_SLEEP to prevent signal callbacks from blocking (#52761) Adds SIGNAL_HANDLER, a macro that sets SHOULD_NOT_SLEEP(TRUE). This should ideally be required on all new signal callbacks. Adds BLOCKING_SIGNAL_HANDLER, a macro that does nothing except symbolize "this is an older signal that didn't necessitate a code rewrite". It should not be allowed for new work. This comes from discussion around #52735, which yields by calling input, and (though it sets the return type beforehand) will not properly return the flag to prevent attack from slapping. To fix 60% of the yielding cases, WrapAdminProcCall no longer waits for another admin's proc call to finish. I'm not an admin, so I don't know how many behinds this has saved, but if this is problematic for admins I can just make it so that it lets you do it anyway. I'm not sure what the point of this babysitting was anyway. Requested by @optimumtact. Changelog cl admin: Calling a proc while another admin is calling one will no longer wait for the first to finish. You will simply just have to call it again. /cl * Adds SIGNAL_HANDLER and SIGNAL_HANDLER_DOES_SLEEP to prevent signal callbacks from blocking Co-authored-by: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com>
58 lines
1.9 KiB
Plaintext
58 lines
1.9 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
|
|
*
|
|
* Is only used when flags contains [ELEMENT_BESPOKE]
|
|
*
|
|
* This is infinity so you must explicitly set this
|
|
*/
|
|
var/id_arg_index = INFINITY
|
|
|
|
/// Activates the functionality defined by the element on the given target datum
|
|
/datum/element/proc/Attach(datum/target)
|
|
SHOULD_CALL_PARENT(1)
|
|
if(type == /datum/element)
|
|
return ELEMENT_INCOMPATIBLE
|
|
SEND_SIGNAL(target, COMSIG_ELEMENT_ATTACH, src)
|
|
if(element_flags & ELEMENT_DETACH)
|
|
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/Detach, override = TRUE)
|
|
|
|
/// Deactivates the functionality defines by the element on the given datum
|
|
/datum/element/proc/Detach(datum/source, force)
|
|
SIGNAL_HANDLER
|
|
|
|
SEND_SIGNAL(source, COMSIG_ELEMENT_DETACH, src)
|
|
SHOULD_CALL_PARENT(1)
|
|
UnregisterSignal(source, COMSIG_PARENT_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)
|
|
var/datum/element/ele = SSdcs.GetElement(arguments)
|
|
arguments[1] = src
|
|
if(ele.Attach(arglist(arguments)) == ELEMENT_INCOMPATIBLE)
|
|
CRASH("Incompatible [arguments[1]] 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)
|
|
ele.Detach(src)
|