Verbs subsystem (#20333)

What it says on the can; now we can better compensate for processing
spikes by queueing and accounting for verb times (assuming we actually
use this framework to invoke the bulk of them). I have added its use to
some of them, more can be ported as time goes on, eventually everything
but the most trivial ones should go through this.

No player facing changes. Hopefully.

Praise be the omnissiah.
This commit is contained in:
Fluffy
2025-01-13 12:17:37 +00:00
committed by GitHub
parent 0890f9a1e1
commit be92376296
16 changed files with 444 additions and 29 deletions
+39
View File
@@ -46,6 +46,14 @@
/// A weak reference to another datum
var/datum/weakref/weak_reference
/*
* Lazy associative list of currently active cooldowns.
*
* cooldowns [ COOLDOWN_INDEX ] = add_timer()
* add_timer() returns the truthy value of -1 when not stoppable, and else a truthy numeric index
*/
var/list/cooldowns
/// Used to avoid unnecessary refstring creation in Destroy().
var/tmp/has_state_machine = FALSE
@@ -147,6 +155,37 @@
for(var/target in _signal_procs)
UnregisterSignal(target, _signal_procs[target])
/**
* Callback called by a timer to end an associative-list-indexed cooldown.
*
* Arguments:
* * source - datum storing the cooldown
* * index - string index storing the cooldown on the cooldowns associative list
*
* This sends a signal reporting the cooldown end.
*/
/proc/end_cooldown(datum/source, index)
if(QDELETED(source))
return
SEND_SIGNAL(source, COMSIG_CD_STOP(index))
TIMER_COOLDOWN_END(source, index)
/**
* Proc used by stoppable timers to end a cooldown before the time has ran out.
*
* Arguments:
* * source - datum storing the cooldown
* * index - string index storing the cooldown on the cooldowns associative list
*
* This sends a signal reporting the cooldown end, passing the time left as an argument.
*/
/proc/reset_cooldown(datum/source, index)
if(QDELETED(source))
return
SEND_SIGNAL(source, COMSIG_CD_RESET(index), S_TIMER_COOLDOWN_TIMELEFT(source, index))
TIMER_COOLDOWN_END(source, index)
///Generate a tag for this /datum, if it implements one
///Should be called as early as possible, best would be in New, to avoid weakref mistargets
///Really just don't use this, you don't need it, global lists will do just fine MOST of the time
+29
View File
@@ -0,0 +1,29 @@
///like normal callbacks but they also record their creation time for measurement purposes
///they also require the same usr/user that made the callback to both still exist and to still have a client in order to execute
/datum/callback/verb_callback
///the tick this callback datum was created in. used for testing latency
var/creation_time = 0
/datum/callback/verb_callback/New(thingtocall, proctocall, ...)
creation_time = DS2TICKS(world.time)
. = ..()
#ifndef UNIT_TESTS
/datum/callback/verb_callback/Invoke(...)
var/mob/our_user = user?.resolve()
if(QDELETED(our_user) || isnull(our_user.client))
return
var/mob/temp = usr
. = ..()
usr = temp
/datum/callback/verb_callback/InvokeAsync(...)
var/mob/our_user = user?.resolve()
if(QDELETED(our_user) || isnull(our_user.client))
return
var/mob/temp = usr
. = ..()
usr = temp
#endif