[MIRROR] Removes SIGNAL_HANDLER_DOES_SLEEP and makes signals synchronous (#5845)

* Removes SIGNAL_HANDLER_DOES_SLEEP and makes signals synchronous (#59176)

* Removes SIGNAL_HANDLER_DOES_SLEEP and makes signals synchronous

* a

* Update peacekeeper_clothing.dm

* Update peacekeeper_clothing.dm

* Update peacekeeper_clothing.dm

Co-authored-by: Kylerace <kylerlumpkin1@gmail.com>
Co-authored-by: Gandalf <jzo123@hotmail.com>
This commit is contained in:
SkyratBot
2021-05-21 14:51:00 +01:00
committed by GitHub
co-authored by Kylerace Gandalf
parent 07a719c2e3
commit 22a553a0c4
16 changed files with 98 additions and 69 deletions
+1 -1
View File
@@ -463,7 +463,7 @@ All procs that are registered to listen for signals using `RegisterSignal()` mus
```
This is to ensure that it is clear the proc handles signals and turns on a lint to ensure it does not sleep.
There exists `SIGNAL_HANDLER_DOES_SLEEP`, but this is only for legacy signal handlers that still sleep, new/changed code should not use this.
Any sleeping behaviour that you need to perform inside a `SIGNAL_HANDLER` proc must be called asynchronously (e.g. with `INVOKE_ASYNC()`) or be redone to work asynchronously.
### Enforcing parent calling
When adding new signals to root level procs, eg;
-4
View File
@@ -10,10 +10,6 @@
/// Every proc you pass to RegisterSignal must have this.
#define SIGNAL_HANDLER SHOULD_NOT_SLEEP(TRUE)
/// Signifies that this proc is used to handle signals, but also sleeps.
/// Do not use this for new work.
#define SIGNAL_HANDLER_DOES_SLEEP
/// A wrapper for _AddElement that allows us to pretend we're using normal named arguments
#define AddElement(arguments...) _AddElement(list(##arguments))
/// A wrapper for _RemoveElement that allows us to pretend we're using normal named arguments
+2 -2
View File
@@ -316,14 +316,14 @@
if(!(C.datum_flags & DF_SIGNAL_ENABLED))
return NONE
var/proctype = C.signal_procs[src][sigtype]
return NONE | CallAsync(C, proctype, arguments)
return NONE | call(C, proctype)(arglist(arguments))
. = NONE
for(var/I in target)
var/datum/C = I
if(!(C.datum_flags & DF_SIGNAL_ENABLED))
continue
var/proctype = C.signal_procs[src][sigtype]
. |= CallAsync(C, proctype, arguments)
. |= call(C, proctype)(arglist(arguments))
// The type arg is casted so initial works, you shouldn't be passing a real instance into this
/**
+2 -2
View File
@@ -32,9 +32,9 @@
update_parent(index)
/datum/component/construction/proc/action(datum/source, obj/item/I, mob/living/user)
SIGNAL_HANDLER_DOES_SLEEP
SIGNAL_HANDLER
return check_step(I, user)
return INVOKE_ASYNC(src, .proc/check_step, I, user)
/datum/component/construction/proc/update_index(diff)
index += diff
+5 -1
View File
@@ -185,12 +185,16 @@
/// Called when a carbon with an object embedded/stuck to them inspects themselves and clicks the appropriate link to begin ripping the item out. This handles the ripping attempt, descriptors, and dealing damage, then calls safe_remove()
/datum/component/embedded/proc/ripOut(datum/source, obj/item/I, obj/item/bodypart/limb)
SIGNAL_HANDLER_DOES_SLEEP
SIGNAL_HANDLER
if(I != weapon || src.limb != limb)
return
var/mob/living/carbon/victim = parent
var/time_taken = rip_time * weapon.w_class
INVOKE_ASYNC(src, .proc/complete_rip_out, victim, I, limb, time_taken)
/// everything async that ripOut used to do
/datum/component/embedded/proc/complete_rip_out(mob/living/carbon/victim, obj/item/I, obj/item/bodypart/limb, time_taken)
victim.visible_message("<span class='warning'>[victim] attempts to remove [weapon] from [victim.p_their()] [limb.name].</span>","<span class='notice'>You attempt to remove [weapon] from your [limb.name]... (It will take [DisplayTimeText(time_taken)].)</span>")
if(!do_after(victim, time_taken, target = victim))
return
+3 -1
View File
@@ -117,8 +117,10 @@
///Bang bang, we're firing a charged shot off
/datum/component/gunpoint/proc/trigger_reaction()
SIGNAL_HANDLER_DOES_SLEEP
SIGNAL_HANDLER
INVOKE_ASYNC(src, .proc/async_trigger_reaction)
/datum/component/gunpoint/proc/async_trigger_reaction()
var/mob/living/shooter = parent
shooter.remove_status_effect(STATUS_EFFECT_HOLDUP) // try doing these before the trigger gets pulled since the target (or shooter even) may not exist after pulling the trigger, dig?
target.remove_status_effect(STATUS_EFFECT_HELDUP, shooter)
+3 -3
View File
@@ -51,7 +51,7 @@
* We do the prob() at the beginning to A. add some tension for /when/ it will strike, and B. (more importantly) ameliorate the fact that we're checking up to 5 turfs's contents each time
*/
/datum/component/omen/proc/check_accident(atom/movable/our_guy)
SIGNAL_HANDLER_DOES_SLEEP
SIGNAL_HANDLER
if(!isliving(our_guy))
return
@@ -66,7 +66,7 @@
to_chat(living_guy, "<span class='warning'>A malevolent force launches your body to the floor...</span>")
var/obj/machinery/door/airlock/darth_airlock = turf_content
living_guy.apply_status_effect(STATUS_EFFECT_PARALYZED, 10)
darth_airlock.close(force_crush = TRUE)
INVOKE_ASYNC(darth_airlock, /obj/machinery/door/airlock.proc/close, TRUE)
if(!permanent)
qdel(src)
return
@@ -84,7 +84,7 @@
for(var/obj/machinery/vending/darth_vendor in the_turf)
if(darth_vendor.tiltable)
to_chat(living_guy, "<span class='warning'>A malevolent force tugs at the [darth_vendor]...</span>")
darth_vendor.tilt(living_guy)
INVOKE_ASYNC(darth_vendor, /obj/machinery/vending.proc/tilt, living_guy)
if(!permanent)
qdel(src)
return
@@ -8,11 +8,6 @@
var/obj/item/storage/wallet/A = parent
if(istype(A) && A.front_id && !issilicon(user) && !(A.item_flags & IN_STORAGE)) //if it's a wallet in storage seeing the full inventory is more useful
var/obj/item/I = A.front_id
A.add_fingerprint(user)
remove_from_storage(I, get_turf(user))
if(!user.put_in_hands(I))
to_chat(user, "<span class='notice'>You fumble for [I] and it falls on the floor.</span>")
return
user.visible_message("<span class='warning'>[user] draws [I] from [parent]!</span>", "<span class='notice'>You draw [I] from [parent].</span>")
INVOKE_ASYNC(src, .proc/attempt_put_in_hands, I, user)
return
..()
return ..()
+29 -19
View File
@@ -194,7 +194,7 @@
INVOKE_ASYNC(src, .proc/quick_empty, M)
/datum/component/storage/proc/preattack_intercept(datum/source, obj/O, mob/M, params)
SIGNAL_HANDLER_DOES_SLEEP
SIGNAL_HANDLER
if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE))
return FALSE
@@ -209,19 +209,23 @@
return
if(!isturf(I.loc))
return
var/list/things = I.loc.contents.Copy()
INVOKE_ASYNC(src, .proc/async_preattack_intercept, I, M)
///async functionality from preattack_intercept
/datum/component/storage/proc/async_preattack_intercept(obj/item/attack_item, mob/pre_attack_mob)
var/list/things = attack_item.loc.contents.Copy()
if(collection_mode == COLLECT_SAME)
things = typecache_filter_list(things, typecacheof(I.type))
things = typecache_filter_list(things, typecacheof(attack_item.type))
var/len = length(things)
if(!len)
to_chat(M, "<span class='warning'>You failed to pick up anything with [parent]!</span>")
to_chat(pre_attack_mob, "<span class='warning'>You failed to pick up anything with [parent]!</span>")
return
var/datum/progressbar/progress = new(M, len, I.loc)
var/datum/progressbar/progress = new(pre_attack_mob, len, attack_item.loc)
var/list/rejections = list()
while(do_after(M, 1 SECONDS, parent, NONE, FALSE, CALLBACK(src, .proc/handle_mass_pickup, things, I.loc, rejections, progress)))
while(do_after(pre_attack_mob, 1 SECONDS, parent, NONE, FALSE, CALLBACK(src, .proc/handle_mass_pickup, things, attack_item.loc, rejections, progress)))
stoplag(1)
progress.end_progress()
to_chat(M, "<span class='notice'>You put everything you could [insert_preposition] [parent].</span>")
to_chat(pre_attack_mob, "<span class='notice'>You put everything you could [insert_preposition] [parent].</span>")
/datum/component/storage/proc/handle_mass_item_insertion(list/things, datum/component/storage/src_object, mob/user, datum/progressbar/progress)
var/atom/source_real_location = src_object.real_location()
@@ -758,7 +762,7 @@
return max(0, max_items - real_location.contents.len)
/datum/component/storage/proc/signal_fill_type(datum/source, type, amount = 20, force = FALSE)
SIGNAL_HANDLER_DOES_SLEEP
SIGNAL_HANDLER
var/atom/real_location = real_location()
if(!force)
@@ -766,9 +770,8 @@
for(var/i in 1 to amount)
if(!handle_item_insertion(new type(real_location), TRUE))
return i > 1 //return TRUE only if at least one insertion has been successful.
if(CHECK_TICK)
if(QDELETED(src))
return TRUE
if(QDELETED(src))
return TRUE
return TRUE
@@ -833,7 +836,7 @@
return hide_from(target)
/datum/component/storage/proc/on_alt_click(datum/source, mob/user)
SIGNAL_HANDLER_DOES_SLEEP
SIGNAL_HANDLER
if(!isliving(user) || !user.CanReach(parent) || user.incapacitated())
return
@@ -849,15 +852,22 @@
A.do_jiggle() //SKYRAT EDIT ADDITION - AESTHETICS
return
var/obj/item/I = locate() in real_location()
if(!I)
var/obj/item/to_remove = locate() in real_location()
if(!to_remove)
return
A.add_fingerprint(user)
remove_from_storage(I, get_turf(user))
if(!user.put_in_hands(I))
to_chat(user, "<span class='notice'>You fumble for [I] and it falls on the floor.</span>")
INVOKE_ASYNC(src, .proc/attempt_put_in_hands, to_remove, user)
///attempt to put an item from contents into the users hands
/datum/component/storage/proc/attempt_put_in_hands(obj/item/to_remove, mob/user)
var/atom/parent_as_atom = parent
parent_as_atom.add_fingerprint(user)
remove_from_storage(to_remove, get_turf(user))
if(!user.put_in_hands(to_remove))
to_chat(user, "<span class='notice'>You fumble for [to_remove] and it falls on the floor.</span>")
return
user.visible_message("<span class='warning'>[user] draws [I] from [parent]!</span>", "<span class='notice'>You draw [I] from [parent].</span>")
user.visible_message("<span class='warning'>[user] draws [to_remove] from [parent]!</span>", "<span class='notice'>You draw [to_remove] from [parent].</span>")
/datum/component/storage/proc/action_trigger(datum/signal_source, datum/action/source)
SIGNAL_HANDLER
+4 -4
View File
@@ -141,7 +141,7 @@
* Finally, we return a bitflag to [COMSIG_MOVABLE_IMPACT] that forces the hitpush to false so that we don't knock them away.
*/
/datum/component/tackler/proc/sack(mob/living/carbon/user, atom/hit)
SIGNAL_HANDLER_DOES_SLEEP
SIGNAL_HANDLER
if(!tackling || !tackle)
return
@@ -149,7 +149,7 @@
user.toggle_throw_mode()
if(!iscarbon(hit))
if(hit.density)
return splat(user, hit)
INVOKE_ASYNC(src, .proc/splat, user, hit)
return
var/mob/living/carbon/target = hit
@@ -210,7 +210,7 @@
target.Paralyze(5)
target.Knockdown(30)
if(ishuman(target) && ishuman(user))
S.dna.species.grab(S, T)
INVOKE_ASYNC(S.dna.species, /datum/species.proc/grab, S, T)
S.setGrabState(GRAB_PASSIVE)
if(5 to INFINITY) // absolutely BODIED
@@ -224,7 +224,7 @@
target.Paralyze(5)
target.Knockdown(30)
if(ishuman(target) && ishuman(user))
S.dna.species.grab(S, T)
INVOKE_ASYNC(S.dna.species, /datum/species.proc/grab, S, T)
S.setGrabState(GRAB_AGGRESSIVE)
@@ -156,13 +156,13 @@
///Handles stinging without verbs.
/datum/antagonist/changeling/proc/stingAtom(mob/living/carbon/ling, atom/A)
SIGNAL_HANDLER_DOES_SLEEP
SIGNAL_HANDLER
if(!chosen_sting || A == ling || !istype(ling) || ling.stat)
return
if(!chosen_sting.try_to_sting(ling, A))
return
ling.changeNext_move(CLICK_CD_MELEE)
INVOKE_ASYNC(chosen_sting, /datum/action/changeling/sting.proc/try_to_sting, ling, A)
return COMSIG_MOB_CANCEL_CLICKON
/datum/antagonist/changeling/proc/has_sting(datum/action/changeling/power)
@@ -53,6 +53,7 @@ the same goes for Remove(). if you override Remove(), call parent or else your p
if(sting_action(user, target))
sting_feedback(user, target)
c.chem_charges -= chemical_cost
user.changeNext_move(CLICK_CD_MELEE)
return TRUE
return FALSE
@@ -96,16 +96,6 @@
spreadFire(AM)
/mob/living/carbon/human/Topic(href, href_list)
if(href_list["embedded_object"] && usr.canUseTopic(src, BE_CLOSE, NO_DEXTERITY))
var/obj/item/bodypart/L = locate(href_list["embedded_limb"]) in bodyparts
if(!L)
return
var/obj/item/I = locate(href_list["embedded_object"]) in L.embedded_objects
if(!I || I.loc != src) //no item, no limb, or item is not in limb or in the person anymore
return
SEND_SIGNAL(src, COMSIG_CARBON_EMBED_RIP, I, L)
return
if(href_list["item"]) //canUseTopic check for this is handled by mob/Topic()
var/slot = text2num(href_list["item"])
if(check_obscured_slots(TRUE) & slot)
@@ -421,7 +421,7 @@
outer_plating_amount=1
/datum/component/construction/mecha/gygax/action(datum/source, atom/used_atom, mob/user)
return check_step(used_atom,user)
return INVOKE_ASYNC(src, .proc/check_step, used_atom,user)
/datum/component/construction/mecha/gygax/custom_action(obj/item/I, mob/living/user, diff)
if(!..())
@@ -181,8 +181,6 @@
component_type = /datum/component/storage/concrete/peacekeeper
/datum/component/storage/concrete/peacekeeper/on_alt_click(datum/source, mob/user)
SIGNAL_HANDLER_DOES_SLEEP
if(!isliving(user) || !user.CanReach(parent) || user.incapacitated())
return
if(locked)
@@ -191,16 +189,14 @@
var/atom/A = parent
var/obj/item/gun/ballistic/automatic/pistol/P = locate() in real_location()
if(!P)
return
var/obj/item/gun/ballistic/automatic/pistol/gun_to_draw = locate() in real_location()
if(!gun_to_draw)
return ..()
A.add_fingerprint(user)
remove_from_storage(P, get_turf(user))
remove_from_storage(gun_to_draw, get_turf(user))
playsound(parent, 'modular_skyrat/modules/sec_haul/sound/holsterout.ogg', 50, TRUE, -5)
if(!user.put_in_hands(P))
to_chat(user, "<span class='notice'>You fumble for [P] and it falls on the floor.</span>")
return
user.visible_message("<span class='warning'>[user] draws [P] from [parent]!</span>", "<span class='notice'>You draw [P] from [parent].</span>")
INVOKE_ASYNC(user, /mob/.proc/put_in_hands, gun_to_draw)
user.visible_message("<span class='warning'>[user] draws [gun_to_draw] from [parent]!</span>", "<span class='notice'>You draw [gun_to_draw] from [parent].</span>")
/datum/component/storage/concrete/peacekeeper/mob_item_insertion_feedback(mob/user, mob/M, obj/item/I, override = FALSE)
@@ -0,0 +1,35 @@
/proc/send_ooc_to_other_server(ckey, message)
if(!CONFIG_GET(flag/secondary_server_enabled))
return
var/list/ooc_information = list()
ooc_information["server_name"] = CONFIG_GET(string/our_server_name)
ooc_information["expected_ckey"] = ckey(ckey)
ooc_information["message"] = message
var/second_server = CONFIG_GET(string/server_two_ip)
if(!second_server)
message_admins("SERVER CONTROL CRITICAL ERROR: No second server IP set in config!")
return
send2otherserver(station_name(), null, "incoming_ooc_message", second_server, ooc_information)
/datum/world_topic/incoming_ooc_message
keyword = "incoming_ooc_message"
require_comms_key = TRUE
/datum/world_topic/incoming_ooc_message/Run(list/input)
var/server_name = input["server_name"]
var/exp_ckey = ckey(input["expected_ckey"])
var/message = input["message"]
send_ooc_message("[server_name] - [exp_ckey]", message)
/proc/send_ooc_message(sender_name, message)
if(!GLOB.ooc_allowed)
return
for(var/client/C in GLOB.clients)
if(C.prefs.chat_toggles & CHAT_OOC)
if(GLOB.OOC_COLOR)
to_chat(C, "<span class='oocplain'><font color='[GLOB.OOC_COLOR]'><b><span class='prefix'>OOC:</span> <EM>[sender_name]:</EM> <span class='message linkify'>[message]</span></b></font></span>")
else
to_chat(C, "<span class='ooc'><span class='prefix'>OOC:</span> <EM>[sender_name]:</EM> <span class='message linkify'>[message]</span></span>")