Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimization pass focused on foam code (saves about 30% of cpu usage I think) #76104

Merged
merged 24 commits into from
Jul 17, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d409bd4
Optimizes reagent processing somewhat
LemonInTheDark Jun 16, 2023
5cc56a6
Optimizes foam spreading in its most accursed aspect, reagent copying
LemonInTheDark Jun 16, 2023
b005e09
I don't care, also fixes docs a tad
LemonInTheDark Jun 16, 2023
941d067
Fixes runtimes from the forced gravity element being applied more the…
LemonInTheDark Jun 16, 2023
de1c760
Removes connect_loc usage in atmos_sensitive, replaces it with direct…
LemonInTheDark Jun 16, 2023
744da36
Micros foam code slightly by inlining a LinkBlockedWithAccess call, t…
LemonInTheDark Jun 16, 2023
4bc80ec
Reduces timer insertion cost by 80%
LemonInTheDark Jun 17, 2023
ee5e633
whoops missed a spot
LemonInTheDark Jun 17, 2023
e7a5d7f
Removes STOPPABLE flag from QDEL_IN, moves it to a bespoke macro. It'…
LemonInTheDark Jun 17, 2023
91f9f23
Moves tgui's open_uis_by_src from the subsystem onto datums
LemonInTheDark Jun 17, 2023
811797f
Bumps fluid priority closer to heavy eaters, moves it off background.…
LemonInTheDark Jun 17, 2023
8d9a7e7
whoops
LemonInTheDark Jun 17, 2023
61448d6
whoops again
LemonInTheDark Jun 17, 2023
595f2f8
Whoops, didn't notice that
LemonInTheDark Jun 17, 2023
8e5fe32
wraps atmos sensitive signal work
LemonInTheDark Jun 17, 2023
8984031
dodges a spurious runtime
LemonInTheDark Jun 17, 2023
4a1e39a
Revert "Reduces timer insertion cost by 80%"
LemonInTheDark Jun 21, 2023
f47ddf0
Revert "Removes STOPPABLE flag from QDEL_IN, moves it to a bespoke ma…
LemonInTheDark Jun 21, 2023
6ce4f5c
Revert "whoops again"
LemonInTheDark Jun 21, 2023
8429e5d
Revert "Whoops, didn't notice that"
LemonInTheDark Jun 21, 2023
a85b31b
Revert "Moves tgui's open_uis_by_src from the subsystem onto datums"
LemonInTheDark Jun 21, 2023
4a31dc3
missed a spot
LemonInTheDark Jun 21, 2023
9960caf
Merge branch 'master' of https://github.com/tgstation/tgstation into …
LemonInTheDark Jul 14, 2023
07fe4c0
Single letter rename
LemonInTheDark Jul 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions code/__DEFINES/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@
#define FIRE_PRIORITY_GARBAGE 15
#define FIRE_PRIORITY_DATABASE 16
#define FIRE_PRIORITY_WET_FLOORS 20
#define FIRE_PRIORITY_FLUIDS 20
#define FIRE_PRIORITY_AIR 20
#define FIRE_PRIORITY_NPC 20
#define FIRE_PRIORITY_ASSETS 20
#define FIRE_PRIORITY_HYPERSPACE_DRIFT 20
#define FIRE_PRIORITY_NPC_MOVEMENT 21
#define FIRE_PRIORITY_NPC_ACTIONS 22
Expand All @@ -215,8 +215,8 @@
#define FIRE_PRIORITY_DEFAULT 50
#define FIRE_PRIORITY_PARALLAX 65
#define FIRE_PRIORITY_INSTRUMENTS 80
#define FIRE_PRIORITY_FLUIDS 80
#define FIRE_PRIORITY_MOBS 100
#define FIRE_PRIORITY_ASSETS 105
#define FIRE_PRIORITY_TGUI 110
#define FIRE_PRIORITY_TICKER 200
#define FIRE_PRIORITY_STATPANEL 390
Expand Down
8 changes: 4 additions & 4 deletions code/__HELPERS/reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@
/proc/add_chemical_reaction(datum/chemical_reaction/R)
if(!GLOB.chemical_reactions_list_reactant_index || !R.required_reagents || !R.required_reagents.len)
return
var/primary_reagent = R.required_reagents[1]
if(!GLOB.chemical_reactions_list_reactant_index[primary_reagent])
GLOB.chemical_reactions_list_reactant_index[primary_reagent] = list()
GLOB.chemical_reactions_list_reactant_index[primary_reagent] += R
var/rand_reagent = pick(R.required_reagents)
if(!GLOB.chemical_reactions_list_reactant_index[rand_reagent])
GLOB.chemical_reactions_list_reactant_index[rand_reagent] = list()
GLOB.chemical_reactions_list_reactant_index[rand_reagent] += R

//Creates foam from the reagent. Metaltype is for metal foam, notification is what to show people in textbox
/datum/reagents/proc/create_foam(foamtype, foam_volume, result_type = null, notification = null, log = FALSE)
Expand Down
24 changes: 7 additions & 17 deletions code/controllers/subsystem/fluids.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
SUBSYSTEM_DEF(fluids)
name = "Fluid"
wait = 0 // Will be autoset to whatever makes the most sense given the spread and effect waits.
flags = SS_BACKGROUND|SS_KEEP_TIMING
flags = SS_KEEP_TIMING
runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME
priority = FIRE_PRIORITY_FLUIDS

// Fluid spread processing:
/// The amount of time (in deciseconds) before a fluid node is created and when it spreads.
Expand All @@ -34,8 +35,6 @@ SUBSYSTEM_DEF(fluids)
var/spread_bucket_index
/// The set of fluid nodes we are currently processing spreading for.
var/list/currently_spreading
/// Whether the subsystem has resumed spreading fluid.
var/resumed_spreading

// Fluid effect processing:
/// The amount of time (in deciseconds) between effect processing ticks for each fluid node.
Expand All @@ -48,8 +47,6 @@ SUBSYSTEM_DEF(fluids)
var/effect_bucket_index
/// The set of fluid nodes we are currently processing effects for.
var/list/currently_processing
/// Whether the subsystem has resumed processing fluid effects.
var/resumed_effect_processing

/datum/controller/subsystem/fluids/Initialize()
initialize_waits()
Expand Down Expand Up @@ -121,14 +118,15 @@ SUBSYSTEM_DEF(fluids)
var/seconds_per_tick
var/cached_bucket_index
var/list/obj/effect/particle_effect/fluid/currentrun
// Ok so like I get the lighting style splittick but why are we doing this churn thing
// It seems like a bad idea for processing to get out of step with spreading
MC_SPLIT_TICK_INIT(2)

MC_SPLIT_TICK // Start processing fluid spread:
if(!resumed_spreading)
MC_SPLIT_TICK // Start processing fluid spread (we take a lot of cpu for ourselves, spreading is more important after all)
if(!resumed)
spread_bucket_index = WRAP_UP(spread_bucket_index, num_spread_buckets)
currently_spreading = spread_carousel[spread_bucket_index]
spread_carousel[spread_bucket_index] = list() // Reset the bucket so we don't process an _entire station's worth of foam_ spreading every 2 ticks when the foam flood event happens.
resumed_spreading = TRUE

seconds_per_tick = spread_wait / (1 SECONDS)
currentrun = currently_spreading
Expand All @@ -143,15 +141,11 @@ SUBSYSTEM_DEF(fluids)
if (MC_TICK_CHECK)
break

if(!currentrun.len)
resumed_spreading = FALSE

MC_SPLIT_TICK // Start processing fluid effects:
if(!resumed_effect_processing)
if(!resumed)
effect_bucket_index = WRAP_UP(effect_bucket_index, num_effect_buckets)
var/list/tmp_list = effect_carousel[effect_bucket_index]
currently_processing = tmp_list.Copy()
resumed_effect_processing = TRUE

seconds_per_tick = effect_wait / (1 SECONDS)
cached_bucket_index = effect_bucket_index
Expand All @@ -168,10 +162,6 @@ SUBSYSTEM_DEF(fluids)
if (MC_TICK_CHECK)
break

if(!currentrun.len)
resumed_effect_processing = FALSE


/**
* Queues a fluid node to spread later after one full carousel rotation.
*
Expand Down
27 changes: 15 additions & 12 deletions code/datums/elements/atmos_sensitive.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,38 @@
//Don't put it on things that tend to clump into one spot, you will cause lag spikes.
/datum/element/atmos_sensitive
element_flags = ELEMENT_DETACH_ON_HOST_DESTROY
var/static/list/pass_on = list(COMSIG_TURF_EXPOSE = /atom/proc/check_atmos_process)

/datum/element/atmos_sensitive/Attach(datum/target, mapload)
if(!isatom(target)) //How
return ELEMENT_INCOMPATIBLE
var/atom/to_track = target
to_track.AddElement(/datum/element/connect_loc, pass_on)
if(to_track.loc)
to_track.RegisterSignal(to_track.loc, COMSIG_TURF_EXPOSE, TYPE_PROC_REF(/atom, check_atmos_process))
RegisterSignal(to_track, COMSIG_MOVABLE_MOVED, PROC_REF(react_to_move))

if(!mapload && isopenturf(to_track.loc))
to_track.atmos_conditions_changed() //Make sure you're properly registered

return ..()

/datum/element/atmos_sensitive/Detach(datum/source)
var/atom/us = source
us.RemoveElement(/datum/element/connect_loc, pass_on)
/datum/element/atmos_sensitive/Detach(atom/source)
if(source.loc)
UnregisterSignal(source.loc, COMSIG_TURF_EXPOSE)
UnregisterSignal(source, COMSIG_MOVABLE_MOVED)
if(us.flags_1 & ATMOS_IS_PROCESSING_1)
us.atmos_end()
SSair.atom_process -= us
us.flags_1 &= ~ATMOS_IS_PROCESSING_1
if(source.flags_1 & ATMOS_IS_PROCESSING_1)
source.atmos_end()
SSair.atom_process -= source
source.flags_1 &= ~ATMOS_IS_PROCESSING_1
return ..()

/datum/element/atmos_sensitive/proc/react_to_move(datum/source, atom/movable/oldloc, direction, forced)
/datum/element/atmos_sensitive/proc/react_to_move(atom/source, atom/movable/oldloc, direction, forced)
SIGNAL_HANDLER

var/atom/atom_source = source
atom_source.atmos_conditions_changed() //Make sure you're properly registered
if(oldloc)
source.UnregisterSignal(oldloc, COMSIG_TURF_EXPOSE)
if(source.loc)
source.RegisterSignal(source.loc, COMSIG_TURF_EXPOSE, TYPE_PROC_REF(/atom, check_atmos_process))
source.atmos_conditions_changed() //Make sure you're properly registered

/atom/proc/check_atmos_process(datum/source, datum/gas_mixture/air, exposed_temperature)
SIGNAL_HANDLER
Expand Down
9 changes: 6 additions & 3 deletions code/datums/elements/forced_gravity.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@
if(!isatom(target))
return ELEMENT_INCOMPATIBLE

var/our_ref = REF(src)
if(HAS_TRAIT_FROM(target, TRAIT_FORCED_GRAVITY, our_ref))
return

src.gravity = gravity
src.ignore_turf_gravity = ignore_turf_gravity

RegisterSignal(target, COMSIG_ATOM_HAS_GRAVITY, PROC_REF(gravity_check))
if(isturf(target))
RegisterSignal(target, COMSIG_TURF_HAS_GRAVITY, PROC_REF(turf_gravity_check))

ADD_TRAIT(target, TRAIT_FORCED_GRAVITY, REF(src))
ADD_TRAIT(target, TRAIT_FORCED_GRAVITY, our_ref)

/datum/element/forced_gravity/Detach(datum/source)
. = ..()
Expand All @@ -37,5 +41,4 @@

/datum/element/forced_gravity/proc/turf_gravity_check(datum/source, atom/checker, list/gravs)
SIGNAL_HANDLER

return gravity_check(null, source, gravs)
gravity_check(null, source, gravs)
8 changes: 8 additions & 0 deletions code/decal.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Bitflags that describes what turfs a decal is NOT ok with sittin on

/// Blocks closed turfs
#define DECAL_BLOCK_CLOSED_TURF (1<<0)
/// Blocks groundless turfs
#define DECAL_BLOCK_GROUNDLESS_TURF (1<<1)
/// Allows groundless turfs IF the turf below exists
#define DECAL_GROUNDLESS_ALLOW_FLOOR_BELOW_TURF (1<<2)
12 changes: 12 additions & 0 deletions code/game/objects/effects/decals/cleanable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@
///The amount of reagent this decal holds, if decal_reagent is defined
var/reagent_amount = 0

/// Creates a cleanable decal on a turf
/// Use this if your decal is one of one, and thus we should not spawn it if it's there already
/// Returns either the existing cleanable, the one we created, or null if we can't spawn on that turf
/turf/proc/spawn_unique_cleanable(obj/effect/decal/cleanable/cleanable_type)
// There is no need to spam unique cleanables, they don't stack and it just chews cpu
var/obj/effect/decal/cleanable/existing = locate(cleanable_type) in src
if(existing)
return existing
if(decal_turf_compatability(src, initial(cleanable_type.turf_loc_flags)))
return null
return new cleanable_type(src)

/obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases)
. = ..()
if (random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/effects/decals/cleanable/humans.dm
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
layer = ABOVE_WINDOW_LAYER
plane = GAME_PLANE
vis_flags = VIS_INHERIT_PLANE
turf_loc_check = FALSE
turf_loc_flags = NONE
alpha = 180

/obj/effect/decal/cleanable/blood/tracks
Expand Down Expand Up @@ -103,7 +103,7 @@
plane = GAME_PLANE
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
mergeable_decal = FALSE
turf_loc_check = FALSE
turf_loc_flags = NONE

dryname = "rotting gibs"
drydesc = "They look bloody and gruesome while some terrible smell fills the air."
Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/effects/decals/cleanable/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
pixel_x = base_pixel_x + rand(-5, 5)
pixel_y = base_pixel_y + rand(-5, 5)

/obj/effect/decal/cleanable/ash/crematorium
//crematoriums need their own ash cause default ash deletes itself if created in an obj
turf_loc_check = FALSE
/obj/effect/decal/cleanable/ash/crematorium
turf_loc_flags = NONE

/obj/effect/decal/cleanable/ash/large
name = "large pile of ashes"
Expand Down
4 changes: 1 addition & 3 deletions code/game/objects/effects/decals/crayon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
plane = GAME_PLANE //makes the graffiti visible over a wall.
mergeable_decal = FALSE
flags_1 = ALLOW_DARK_PAINTS_1
turf_loc_flags = DECAL_BLOCK_GROUNDLESS_TURF
var/do_icon_rotate = TRUE
var/rotation = 0
var/paint_colour = "#FFFFFF"
Expand All @@ -31,9 +32,6 @@
add_atom_colour(paint_colour, FIXED_COLOUR_PRIORITY)
RegisterSignal(src, COMSIG_OBJ_PAINTED, PROC_REF(on_painted))

/obj/effect/decal/cleanable/crayon/NeverShouldHaveComeHere(turf/T)
return isgroundlessturf(T)

/obj/effect/decal/cleanable/crayon/proc/on_painted(datum/source, mob/user, obj/item/toy/crayon/spraycan/spraycan, is_dark_color)
SIGNAL_HANDLER
var/cost = spraycan.all_drawables[icon_state] || CRAYON_COST_DEFAULT
Expand Down
21 changes: 13 additions & 8 deletions code/game/objects/effects/decals/decal.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
plane = FLOOR_PLANE
anchored = TRUE
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
///Boolean on whether this decal can be placed inside of groundless turfs/walls. If FALSE, will runtime and delete if it happens.
var/turf_loc_check = TRUE
/// Bitfield that describes what turfs this decal is ok with spawning on. Read only, as we read it using initial() in some places
var/turf_loc_flags = DECAL_BLOCK_CLOSED_TURF|DECAL_BLOCK_GROUNDLESS_TURF|DECAL_GROUNDLESS_ALLOW_FLOOR_BELOW_TURF

/obj/effect/decal/Initialize(mapload)
. = ..()
if(turf_loc_check && NeverShouldHaveComeHere(loc))
if(turf_loc_flags && decal_turf_compatability(loc, turf_loc_flags))
#ifdef UNIT_TESTS
stack_trace("[name] spawned in a bad turf ([loc]) at [AREACOORD(src)] in \the [get_area(src)]. Please remove it or set turf_loc_check to FALSE on the decal if intended.")
stack_trace("[name] spawned in a bad turf ([loc]) at [AREACOORD(src)] in \the [get_area(src)]. Please remove it or set turf_loc_flags to NONE on the decal if intended.")
#else
return INITIALIZE_HINT_QDEL
#endif
Expand All @@ -23,9 +23,6 @@
if(B && B.loc == loc)
qdel(src)

/obj/effect/decal/proc/NeverShouldHaveComeHere(turf/T)
return isclosedturf(T) || (isgroundlessturf(T) && !SSmapping.get_turf_below(T))

/obj/effect/decal/ex_act(severity, target)
qdel(src)
return TRUE
Expand All @@ -39,9 +36,17 @@
post_change_callbacks += CALLBACK(src, PROC_REF(sanity_check_self))

/obj/effect/decal/proc/sanity_check_self(turf/changed)
if(changed == loc && NeverShouldHaveComeHere(changed))
if(changed == loc && decal_turf_compatability(changed, turf_loc_flags))
qdel(src)

/proc/decal_turf_compatability(turf/check, flags)
if(flags & DECAL_BLOCK_CLOSED_TURF && isclosedturf(check))
return TRUE
if(flags & DECAL_BLOCK_GROUNDLESS_TURF && isgroundlessturf(check))
if(!(flags & DECAL_GROUNDLESS_ALLOW_FLOOR_BELOW_TURF) || !SSmapping.get_turf_below(check))
return TRUE
return FALSE

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/obj/effect/turf_decal
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/effects/decals/remains.dm
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@

/obj/effect/decal/remains/plasma
icon_state = "remainsplasma"
turf_loc_check = FALSE
turf_loc_flags = NONE

/obj/effect/decal/remains/xeno
desc = "They look like the remains of something... alien. They have a strange aura about them."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,11 @@
if(!istype(location))
return FALSE

for(var/turf/spread_turf as anything in location.reachableAdjacentTurfs(no_id = TRUE))
for(var/iter_dir in GLOB.cardinals)
var/turf/spread_turf = get_step(src, iter_dir)
if(spread_turf?.density || spread_turf.LinkBlockedWithAccess(spread_turf, no_id = TRUE))
continue

var/obj/effect/particle_effect/fluid/foam/foundfoam = locate() in spread_turf //Don't spread foam where there's already foam!
if(foundfoam)
continue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,8 @@
new /obj/item/book/granter/crafting_recipe/boneyard_notes(src)

/obj/effect/decal/remains/human/grave
turf_loc_check = FALSE
turf_loc_flags = NONE


//***Fluff items for lore/intrigue
/obj/item/paper/crumpled/muddy/fluff/elephant_graveyard
Expand Down
Loading