[MIRROR] Optimizes particle holders [MDB IGNORE] (#20599)

* Optimizes particle holders (#74524)

## About The Pull Request

It isn't really an issue now, but these will be used more in future, so
let's start off strong.

There's a lot of work going on here that doesn't really need to be
happening, mostly off not knowing a trickTM.

Biggest one is vis_locs and vis_contents are linked lists, being in one
requires being in another. Atoms clear out their vis_locs on Destroy, so
we do not need to "own" references to things that have us in their
vis_contents.

This combined with knowing our old loc's loc off Moved made the use of
weakrefs here unneeded. Similarly, atoms inside atom movables qdel on
when the upper layer is deleted, so most cases of the qdeleting signal
were unneeded.

Also, we only cared about movement if we were an item (speaking of
which, I swapped out the isitem stuff with a flag that gets passed into
the new() call)

## Why It's Good For The Game

Speed

* Optimizes particle holders

---------

Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-04-17 00:59:20 +02:00
committed by GitHub
parent bf12bda240
commit 9cee4ee779
5 changed files with 40 additions and 45 deletions
+5
View File
@@ -0,0 +1,5 @@
// /obj/effect/abstract/particle_holder/var/particle_flags
// Flags that effect how a particle holder displays something
/// If we're inside something inside a mob, display off that mob too
#define PARTICLE_ATTACH_MOB (1<<0)
+1 -1
View File
@@ -68,7 +68,7 @@
//barticles
if(particles_path && ismovable(linked_song.parent))
particle_holder = new(linked_song.parent, particles_path)
particle_holder = new(linked_song.parent, particles_path, PARTICLE_ATTACH_MOB)
//filters
linked_song.parent?.add_filter("smooth_tunes_outline", 9, list("type" = "outline", "color" = glow_color))
+1 -1
View File
@@ -64,7 +64,7 @@
//barticles
if(flaming)
ash = new(owner, /particles/smoke/ash)
ash = new(owner, /particles/smoke/ash, PARTICLE_ATTACH_MOB)
var/clear_in = rand(15 SECONDS, 25 SECONDS)
if(duration != -1)
clear_in = min(duration, clear_in)
+32 -43
View File
@@ -5,66 +5,55 @@
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
layer = ABOVE_ALL_MOB_LAYER
vis_flags = VIS_INHERIT_PLANE
///typepath of the last location we're in, if it's different when moved then we need to update vis contents
var/last_attached_location_type
///the main item we're attached to at the moment, particle holders hold particles for something
var/datum/weakref/weak_attached
///besides the item we're also sometimes attached to other stuff! (items held emitting particles on a mob)
var/datum/weakref/weak_additional
/// Holds info about how this particle emitter works
/// See \code\__DEFINES\particles.dm
var/particle_flags = NONE
/obj/effect/abstract/particle_holder/Initialize(mapload, particle_path = /particles/smoke)
/obj/effect/abstract/particle_holder/Initialize(mapload, particle_path = /particles/smoke, particle_flags = NONE)
. = ..()
if(!loc)
stack_trace("particle holder was created with no loc!")
return INITIALIZE_HINT_QDEL
if(ismovable(loc))
RegisterSignal(loc, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
RegisterSignal(loc, COMSIG_PARENT_QDELETING, PROC_REF(on_qdel))
weak_attached = WEAKREF(loc)
// We assert this isn't an /area
src.particle_flags = particle_flags
particles = new particle_path
update_visual_contents(loc)
// /atom doesn't have vis_contents, /turf and /atom/movable do
var/atom/movable/lie_about_areas = loc
lie_about_areas.vis_contents += src
if(!ismovable(loc))
RegisterSignal(loc, COMSIG_PARENT_QDELETING, PROC_REF(immovable_deleted))
if(particle_flags & PARTICLE_ATTACH_MOB)
RegisterSignal(loc, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
on_move(loc, null, NORTH)
/obj/effect/abstract/particle_holder/Destroy(force)
var/atom/movable/attached = weak_attached.resolve()
var/atom/movable/additional_attached
if(weak_additional)
additional_attached = weak_additional.resolve()
if(attached)
attached.vis_contents -= src
UnregisterSignal(loc, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING))
if(additional_attached)
additional_attached.vis_contents -= src
QDEL_NULL(particles)
return ..()
///signal called when parent is moved
/// Non movables don't delete contents on destroy, so we gotta do this
/obj/effect/abstract/particle_holder/proc/immovable_deleted(datum/source)
SIGNAL_HANDLER
qdel(src)
/// signal called when a parent that's been hooked into this moves
/// does a variety of checks to ensure overrides work out properly
/obj/effect/abstract/particle_holder/proc/on_move(atom/movable/attached, atom/oldloc, direction)
SIGNAL_HANDLER
if(attached.loc.type != last_attached_location_type)
update_visual_contents(attached)
///signal called when parent is deleted
/obj/effect/abstract/particle_holder/proc/on_qdel(atom/movable/attached, force)
SIGNAL_HANDLER
qdel(src)//our parent is gone and we need to be as well
if(!(particle_flags & PARTICLE_ATTACH_MOB))
return
///logic proc for particle holders, aka where they move.
///subtypes of particle holders can override this for particles that should always be turf level or do special things when repositioning.
///this base subtype has some logic for items, as the loc of items becomes mobs very often hiding the particles
/obj/effect/abstract/particle_holder/proc/update_visual_contents(atom/movable/attached_to)
//remove old
if(weak_additional)
var/atom/movable/resolved_location = weak_additional.resolve()
if(resolved_location)
resolved_location.vis_contents -= src
//add to new
if(isitem(attached_to) && ismob(attached_to.loc)) //special case we want to also be emitting from the mob
var/mob/particle_mob = attached_to.loc
last_attached_location_type = attached_to.loc
weak_additional = WEAKREF(particle_mob)
if(ismob(oldloc))
var/mob/particle_mob = oldloc
particle_mob.vis_contents -= src
// If we're sitting in a mob, we want to emit from it too, for vibes and shit
if(ismob(attached.loc))
var/mob/particle_mob = attached.loc
particle_mob.vis_contents += src
//readd to ourselves
attached_to.vis_contents |= src
/// Sets the particles position to the passed coordinate list (X, Y, Z)
/// See [https://www.byond.com/docs/ref/#/{notes}/particles] for position documentation
+1
View File
@@ -161,6 +161,7 @@
#include "code\__DEFINES\pai.dm"
#include "code\__DEFINES\paintings.dm"
#include "code\__DEFINES\paper.dm"
#include "code\__DEFINES\particles.dm"
#include "code\__DEFINES\path.dm"
#include "code\__DEFINES\perf_test.dm"
#include "code\__DEFINES\pinpointers.dm"