Skip to content

Commit 4795f2b

Browse files
authored
Stamina container optimizations (#5869)
## About The Pull Request frees up some processing time processing stamina on things that do not care about stamina. ## Changelog :cl: refactor: The Stamina subsystem no longer wastes time trying to process stamina on dead mobs, or mobs that don't even care about stamina in the first place. /:cl:
1 parent c023760 commit 4795f2b

File tree

4 files changed

+74
-7
lines changed

4 files changed

+74
-7
lines changed

code/modules/mob/living/living.dm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/mob/living/Initialize(mapload)
22
. = ..()
3-
stamina = new(src)
3+
stamina = new(src) // monkestation edit: stamina rework
44
if(current_size != RESIZE_DEFAULT_SIZE)
55
update_transform(current_size)
66
AddElement(/datum/element/movetype_handler)

monkestation/code/controllers/subsystem/stamina.dm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ SUBSYSTEM_DEF(stamina)
1818
//cache for sanic speed (lists are references anyways)
1919
var/list/current_run = currentrun
2020

21+
var/seconds_per_tick = world.tick_lag * wait * 0.1
2122
while(length(current_run))
2223
var/datum/stamina_container/thing = current_run[length(current_run)]
2324
current_run.len--
24-
thing.update(world.tick_lag * wait * 0.1)
25+
thing.update(seconds_per_tick)
2526
if (MC_TICK_CHECK)
2627
return

monkestation/code/datums/stamina_container.dm

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,22 @@
1717
var/is_regenerating = TRUE
1818
//unga bunga
1919
var/process_stamina = TRUE
20+
/// Used to determine when the stamina changes, to properly run on_stamina_update on the parent.
21+
VAR_PRIVATE/should_notify_parent = FALSE
2022

2123
///cooldowns
2224
///how long until we can lose stamina again
2325
COOLDOWN_DECLARE(stamina_grace_period)
2426
///how long stamina is paused for
2527
COOLDOWN_DECLARE(paused_stamina)
2628

29+
/// Signals which we react in order to re-check if we should be processing or not.
30+
var/static/list/update_on_signals = list(
31+
COMSIG_MOB_STATCHANGE,
32+
SIGNAL_ADDTRAIT(TRAIT_NO_TRANSFORM),
33+
SIGNAL_REMOVETRAIT(TRAIT_NO_TRANSFORM),
34+
)
35+
2736
/datum/stamina_container/New(parent, maximum = STAMINA_MAX, regen_rate = STAMINA_REGEN)
2837
if(maximum <= 0)
2938
stack_trace("Attempted to initialize stamina container with an invalid maximum limit of [maximum], defaulting to [STAMINA_MAX]")
@@ -32,15 +41,21 @@
3241
src.maximum = maximum
3342
src.regen_rate = regen_rate
3443
src.current = maximum
35-
START_PROCESSING(SSstamina, src)
44+
RegisterSignals(parent, update_on_signals, PROC_REF(update_process))
45+
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(nullspace_move_check))
46+
update_process()
3647

3748
/datum/stamina_container/Destroy()
38-
parent?.stamina = null
49+
if(!isnull(parent))
50+
parent.stamina = null
51+
UnregisterSignal(parent, update_on_signals)
52+
UnregisterSignal(parent, COMSIG_MOVABLE_MOVED)
3953
parent = null
4054
STOP_PROCESSING(SSstamina, src)
4155
return ..()
4256

4357
/datum/stamina_container/proc/update(seconds_per_tick = 1)
58+
var/last_current = current
4459
if(process_stamina == TRUE)
4560
if(!is_regenerating)
4661
if(!COOLDOWN_FINISHED(src, paused_stamina))
@@ -49,8 +64,10 @@
4964

5065
if(seconds_per_tick)
5166
current = min(current + (regen_rate*seconds_per_tick), maximum)
52-
if(seconds_per_tick && decrement)
53-
current = max(current + (-decrement*seconds_per_tick), 0)
67+
if(decrement)
68+
current = max(current + (-decrement*seconds_per_tick), 0)
69+
if(current != last_current)
70+
should_notify_parent = TRUE
5471
loss = maximum - current
5572
loss_as_percent = loss ? (loss == maximum ? 0 : loss / maximum * 100) : 0
5673

@@ -59,7 +76,9 @@
5976
else if(!(current == maximum))
6077
process_stamina = TRUE
6178

62-
parent.on_stamina_update()
79+
if(should_notify_parent)
80+
parent.on_stamina_update()
81+
should_notify_parent = FALSE
6382

6483
///Pause stamina regeneration for some period of time. Does not support doing this from multiple sources at once because I do not do that and I will add it later if I want to.
6584
/datum/stamina_container/proc/pause(time)
@@ -86,7 +105,10 @@
86105
var/modify = parent.pre_stamina_change(amt, forced)
87106
if(base_modify)
88107
modify = amt
108+
var/old_current = current
89109
current = round(clamp(current + modify, 0, maximum), DAMAGE_PRECISION)
110+
if(current != old_current)
111+
should_notify_parent = TRUE
90112
update()
91113
if((amt < 0) && is_regenerating)
92114
pause(STAMINA_REGEN_TIME)
@@ -104,12 +126,42 @@
104126
if(stamina_after_loss < lowest_stamina_value)
105127
amount = current - lowest_stamina_value
106128

129+
var/old_current = current
107130
current = round(clamp(current + amount, 0, maximum), DAMAGE_PRECISION)
131+
if(current != old_current)
132+
should_notify_parent = TRUE
108133
update()
109134
if((amount < 0) && is_regenerating)
110135
pause(STAMINA_REGEN_TIME)
111136
return amount
112137

138+
/// Signal handler for COMSIG_MOVABLE_MOVED to ensure that update_process() gets called whenever moving to/from nullspace.
139+
/datum/stamina_container/proc/nullspace_move_check(atom/movable/mover, atom/old_loc, dir, force)
140+
SIGNAL_HANDLER
141+
if(isnull(old_loc) || isnull(mover.loc))
142+
update_process()
143+
144+
/// Returns if the container should currently be processing or not.
145+
/datum/stamina_container/proc/should_process()
146+
SHOULD_BE_PURE(TRUE)
147+
if(QDELETED(parent) || isnull(parent.loc))
148+
return FALSE
149+
if(!parent.uses_stamina)
150+
return FALSE
151+
if(parent.stat == DEAD)
152+
return FALSE
153+
if(HAS_TRAIT(parent, TRAIT_NO_TRANSFORM))
154+
return FALSE
155+
return TRUE
156+
157+
/// Checks to see if the container should be processing, and starts/stops it.
158+
/datum/stamina_container/proc/update_process()
159+
SIGNAL_HANDLER
160+
if(should_process())
161+
START_PROCESSING(SSstamina, src)
162+
else
163+
STOP_PROCESSING(SSstamina, src)
164+
113165
/// Sets the maximum amount of stamina.
114166
/// Always use this instead of directly setting the stamina var, as this has sanity checks, and immediately updates afterwards.
115167
/datum/stamina_container/proc/set_maximum(value = STAMINA_MAX)
@@ -122,3 +174,15 @@
122174
maximum = value
123175
update()
124176
return TRUE
177+
178+
/mob/living/carbon
179+
uses_stamina = TRUE
180+
181+
/mob/living/carbon/alien
182+
uses_stamina = FALSE
183+
184+
/mob/living/basic
185+
uses_stamina = TRUE
186+
187+
/mob/living/simple_animal
188+
uses_stamina = TRUE

monkestation/code/modules/mob/living/living_defines.dm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@
77
///The talk chime set to use when speaking.
88
var/voice_type
99

10+
/// If TRUE, then this mob has a stamina container initialized, and will use stamina.
11+
var/uses_stamina = FALSE

0 commit comments

Comments
 (0)