Files
Bubberstation/code/datums/components/slippery.dm
SkyratBot e65a48e91f [MIRROR] Adds SIGNAL_HANDLER and SIGNAL_HANDLER_DOES_SLEEP to prevent signal callbacks from blocking (#430)
* 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>
2020-08-19 20:17:28 -04:00

41 lines
1.6 KiB
Plaintext

/datum/component/slippery
var/force_drop_items = FALSE
var/knockdown_time = 0
var/paralyze_time = 0
var/lube_flags
var/datum/callback/callback
/datum/component/slippery/Initialize(_knockdown, _lube_flags = NONE, datum/callback/_callback, _paralyze, _force_drop = FALSE)
knockdown_time = max(_knockdown, 0)
paralyze_time = max(_paralyze, 0)
force_drop_items = _force_drop
lube_flags = _lube_flags
callback = _callback
RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip)
RegisterSignal(parent, COMSIG_ITEM_WEARERCROSSED, .proc/Slip_on_wearer)
/datum/component/slippery/proc/Slip(datum/source, atom/movable/AM)
SIGNAL_HANDLER
var/mob/victim = AM
if(istype(victim) && !victim.is_flying() && victim.slip(knockdown_time, parent, lube_flags, paralyze_time, force_drop_items) && callback)
callback.Invoke(victim)
/datum/component/slippery/proc/Slip_on_wearer(datum/source, atom/movable/AM, mob/living/crossed)
SIGNAL_HANDLER
if(!(crossed.mobility_flags & MOBILITY_STAND) && !crossed.buckle_lying)
Slip(source, AM)
/datum/component/slippery/clowning //used for making the clown PDA only slip if the clown is wearing his shoes and the elusive banana-skin belt
/datum/component/slippery/clowning/Slip_on_wearer(datum/source, atom/movable/AM, mob/living/crossed)
var/obj/item/I = crossed.get_item_by_slot(ITEM_SLOT_FEET)
if(!(crossed.mobility_flags & MOBILITY_STAND) && !crossed.buckle_lying)
if(istype(I, /obj/item/clothing/shoes/clown_shoes))
Slip(source, AM)
else
to_chat(crossed,"<span class='warning'>[parent] failed to slip anyone. Perhaps I shouldn't have abandoned my legacy...</span>")