* Optimization pass focused on foam code (saves about 30% of cpu usage I think) (#76104)
## About The Pull Request
Foam is crummy at high load rn, both because it runs on a low priority
background subsystem, and because it wastes a bit of time.
Let's reduce usage (while speeding up a bunch of other stuff too), and
give it more cpu generally.
[Optimizes reagent processing
somewhat](https://github.com/tgstation/tgstation/commit/d409bd4afc3c208cd6f00ff406e1e9f78d5ac5ad)
Turns out most of the cost of foam is the reagents it carries, and the
varying effects they have
I'm doing my best here to optimize them without touching "user space"
too much
That means doing things like prechecking if we're gonna spawn on top of
an existing decal (from glitter, flour, etc), and using that same proc
to also avoid spawning on unacceptable turfs (I had to convert
inheritance to a bitflag system to make this work, but I think that's ok
since we want it imparative anyhow)
It's actually nice for code quality too, since it lets me clean up code
that was using raw locates and weird var pong.
god I wish I had implied types man
[Optimizes foam spreading in its most accursed aspect, reagent
copying](https://github.com/tgstation/tgstation/commit/5cc56a64ad1a22ba7467cb0446b9558560259437)
Holy shit reagent code is a lot.
I'm doing a bunch of small things here. istype in init -> typecache,
removing procs that are called once and loop over a list we JUST looped
over (ph and the caching for reactions in particular)
I am mainly trying to optimize copy_to here, since that's what foam
spams
As a part of this, I removed a pair of update_total and handle_reactions
calls that were done on the reagents we are copying FROM
I have no god damn idea why you would want to do that, but if anything
is relying on the copy proc modifying the source, then that code
deserves to break
Speaking of, I cleaned up handle_reaction's main filter loop a lot,
removed a lot of redundant vars and changed it from a full loop w
tracker vars to an early exit pattern
This meant using a loop label, which is unfortunate, but this is the
fastest method, and it does end up cleaning up the code significantly,
Which is nice
Oh also I made the required_other var function even if there is no atom
attached to the reaction, since I don't see why it wouldn't
This last bit is gonna get a bit esoteric so bear with me
Failing calls (which are most of them) to handle_reactions are going to
be fastest if they need to check as few reactions as possible
One reagent in a reaction's required list is marked as the "primary",
and thus gets to trigger checking it.
We need all the reagents to react anyhow, so we might as well only check
if we have one particular one to avoid double checking
Anyhow, in order to make most calls the fastest, we want these reactions
distributed as evenly as possible across all our reagents.
The current way of doing this is just taking the first reagent in the
requirements list and using it, which is not ideal
Instead of that, lets figure out how many reactions each reagent is in,
then divy reactions up based off that and the currently divvied
reactions
This doubles the reagent index count, and takes the most common reagent,
water, from 67 reactions to I think like 22
Does some other general cleaning in reagent code too, etc etc etc
[Fixes runtimes from the forced gravity element being applied more then
once](https://github.com/tgstation/tgstation/commit/941d0676114fd455a585f2c65ffc79b81e8438b7)
I feel like this element should take a trait source or something to make
them potentially unique, it's too easy to accidentally override one with
another
[Removes connect_loc usage in atmos_sensitive, replaces it with direct
reg/unreg](https://github.com/tgstation/tgstation/commit/de1c76029d5c49dff152f0ea168b9e6c4a4a04aa)
I only really used it because I liked the componentization, but it costs
like 0.2 seconds off init alone which is really stupid, so let's just do
this the very slightly harder way
[Micros foam code slightly by inlining a LinkBlockedWithAccess
call](https://github.com/tgstation/tgstation/commit/744da3694cd4a85b3bdf44d754de57d7570bdd1c)
This is in the space of like 0.05 seconds kinda save so I can put it
back if you'd like, the double loop just felt silly
[Changes how foam processes
slightly](https://github.com/tgstation/tgstation/commit/ee5e633e3256fe7df229af71d78424d502459c16)
Rather then treating spreading and processing as separate actions, we do
both in sync.
This makes foam fade faster when spreading, which is good cause the
whole spread but unclearing foam thing looks silly.
It also avoids the potential bad ending of foam spreading into itself,
backwards and forwards. This is better I promise.
[Bumps fluid priority closer to heavy eaters, moves it off
background](https://github.com/tgstation/tgstation/commit/811797f09db7b060f75f15ad06d0ce8982375f47)
Also fixes a bug where foam would travel under public access airlocks.
## Why It's Good For The Game
Saves a lot of cpu just in general, from both init and live.
In theory makes foam faster, tho I'd have to test that on live at
highpop to see if I've actually succeeded or not. Guess we'll see.
* Optimization pass focused on foam code (saves about 30% of cpu usage I think)
---------
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: Bloop <vinylspiders@gmail.com>
* Remove ELEMENT_DETACH on everything that doesn't need it, rename to ELEMENT_DETACH_ON_HOST_DESTROY + a PSA (about 0.2s init time savings) (#70972)
ELEMENT_DETACH is **not** a requirement to having `Detach` called.
Detach is always called when the element itself is destroyed.
ELEMENT_DETACH is a flag that when set, makes sure Detach is called when
the atom destroys.
Sometimes you want this, for instance:
```dm
/datum/element/point_of_interest/Detach(datum/target)
SSpoints_of_interest.on_poi_element_removed(target)
return ..()
```
This Detach cleans up a reference that would have hung if target was
destroyed without this being called.
However, most uses of Detach are cleaning up signals. Signals are
automatically cleaned up when something is destroyed. You do not need
ELEMENT_DETACH in this case, and it slows down init. This also includes
somewhat more complex stuff, like removing overlays on the source
object. It's getting deleted anyway, you don't care!
I have removed all uses of ELEMENT_DETACH that seemed superfluous. I
have also renamed it to `ELEMENT_DETACH_ON_HOST_DESTROY` to make its
purpose more clear, as me and a lot of other maintainers misunderstood
what it did,
---
An update to this, ELEMENT_DETACH *is* needed for anything that can
register to a turf, as turfs do not clear their signals on destroy.
* Remove ELEMENT_DETACH on everything that doesn't need it, rename to ELEMENT_DETACH_ON_HOST_DESTROY + a PSA (about 0.2s init time savings)
* skyrat elements
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
Co-authored-by: tastyfish <crazychris32@gmail.com>
* (code bounty) The tram is now unstoppably powerful. it cannot be stopped, it cannot be slowed, it cannot be reasoned with. YOU HAVE NO IDEA HOW READY YOU ARE
* fex
* fex
Co-authored-by: Kylerace <kylerlumpkin1@gmail.com>
Co-authored-by: Gandalf <9026500+Gandalf2k15@users.noreply.github.com>
* Makes turfs persist their signals, uses this to optimize connect_loc (#59608)
* Makes turfs persist signals
* Splits connect_loc up into two elements, one for stuff that wishes to connect on behalf of something, and one for stuff that just wants to connect normally. Connecting on behalf of someone has a significant amount of overhead, so let's do this to keep things clear
* Converts all uses of connect_loc over to the new patterns
* Adds some comments, actually makes turfs persist signals
* There's no need to detach connect loc anymore, since all it does is unregister signals. Unregisters a signal from formorly decal'd turfs, and makes the changeturf signal persistance stuff actually work
* bro fuck documentation
* Changes from a var to a proc, prevents admemems and idiots
* Extra detail on why we do the copy post qdel
* Makes turfs persist their signals, uses this to optimize connect_loc
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
* Converts the atmos senstive component over to connect_loc (#58266)
* Makes all uses of atmos_senstive pass in mapload as context
* Converts atmos senstive to connect_loc, does some general cleanup to the element, and makes it check the state of the tile the thing is on assuming creation didn't happen as a part of map loading
* Updates connect loc to match the new arg list
* Converts the atmos senstive component over to connect_loc
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
* Allows the connect_loc element to have a listener different from the tracked object (#58276)
* Allows the connect_loc element to have a listener different from the tracked object
Co-authored-by: Emmett Gaines <ninjanomnom@gmail.com>
* Increases the clarity of firealarms (#56188)
## About The Pull Request
Makes firelocks closed by atmos issues open when those issues are resolved
Adds a finished proc to atmos_sensitive
Adds a new overlay for fire alarms that are currently triggered due to atmos issues
Makes the detecting var work properly instead of shutting off behavior until the next activity (This avenue needs more work put into it, but that's out of scope for this pr)
## Why It's Good For The Game
I've been getting "complaints" from players about firelocks and cold, and while I think part of it is stuff that will smooth out over time, they do have a point. So let's make fixing firelocks less of a shot in the dark, and more of a minigame.
* Increases the clarity of firealarms
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>