Files
Bubberstation/code/controllers/subsystem/icon_smooth.dm
SkyratBot f1928357e3 [MIRROR] Fixes smoothing breaking if a map is loaded post init (#26553)
* Fixes smoothing breaking if a map is loaded post init (#81526)

## About The Pull Request

We'd finish a set of atom creation, then try and smooth those atoms The
problem is they might try and smooth with an uninitialized neighbor,
which wouldn't have its smoothing vars parsed.

This fixes that by pooling "to be smoothed" things into a list based off
the source of the init stoppage, which we then release when we're done.

Also fixes things staying in mapload, even during a sleep. This can
cause massive headaches so it's good to avoid.

This has a cost but it's minuscule (on the order of like 0.006s (6ms
over all of init), so I'm happy with it.

## Why It's Good For The Game

Closes #77040

## Changelog
🆑
fix: Maps loaded in after roundstart will no longer have broken
smoothing
/🆑

* Fixes smoothing breaking if a map is loaded post init

---------

Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
2024-02-19 01:23:33 +01:00

94 lines
3.1 KiB
Plaintext

SUBSYSTEM_DEF(icon_smooth)
name = "Icon Smoothing"
init_order = INIT_ORDER_ICON_SMOOTHING
wait = 1
priority = FIRE_PRIORITY_SMOOTHING
flags = SS_TICKER
///Blueprints assemble an image of what pipes/manifolds/wires look like on initialization, and thus should be taken after everything's been smoothed
var/list/blueprint_queue = list()
var/list/smooth_queue = list()
var/list/deferred = list()
var/list/deferred_by_source = list()
/datum/controller/subsystem/icon_smooth/fire()
// We do not want to smooth icons of atoms whose neighbors are not initialized yet,
// this causes runtimes.
// Icon smoothing SS runs after atoms, so this only happens for something like shuttles.
// This kind of map loading shouldn't take too long, so the delay is not a problem.
if (SSatoms.initializing_something())
return
var/list/smooth_queue_cache = smooth_queue
while(length(smooth_queue_cache))
var/atom/smoothing_atom = smooth_queue_cache[length(smooth_queue_cache)]
smooth_queue_cache.len--
if(QDELETED(smoothing_atom) || !(smoothing_atom.smoothing_flags & SMOOTH_QUEUED))
continue
if(smoothing_atom.flags_1 & INITIALIZED_1)
smoothing_atom.smooth_icon()
else
deferred += smoothing_atom
if (MC_TICK_CHECK)
return
if (!length(smooth_queue_cache))
if (deferred.len)
smooth_queue = deferred
deferred = smooth_queue_cache
else
can_fire = FALSE
/datum/controller/subsystem/icon_smooth/Initialize()
var/list/queue = smooth_queue
smooth_queue = list()
while(length(queue))
var/atom/smoothing_atom = queue[length(queue)]
queue.len--
if(QDELETED(smoothing_atom) || !(smoothing_atom.smoothing_flags & SMOOTH_QUEUED) || !smoothing_atom.z)
continue
smoothing_atom.smooth_icon()
CHECK_TICK
queue = blueprint_queue
blueprint_queue = null
for(var/atom/movable/movable_item as anything in queue)
if(!isturf(movable_item.loc))
continue
var/turf/item_loc = movable_item.loc
item_loc.add_blueprints(movable_item)
return SS_INIT_SUCCESS
/// Releases a pool of delayed smooth attempts from a particular source
/datum/controller/subsystem/icon_smooth/proc/free_deferred(source_to_free)
smooth_queue += deferred_by_source[source_to_free]
deferred_by_source -= source_to_free
if(!can_fire)
can_fire = TRUE
/datum/controller/subsystem/icon_smooth/proc/add_to_queue(atom/thing)
if(thing.smoothing_flags & SMOOTH_QUEUED)
return
thing.smoothing_flags |= SMOOTH_QUEUED
// If we're currently locked into mapload BY something
// Then put us in a deferred list that we release when this mapload run is finished
if(initialized && length(SSatoms.initialized_state) && SSatoms.initialized == INITIALIZATION_INNEW_MAPLOAD)
var/source = SSatoms.get_initialized_source()
LAZYADD(deferred_by_source[source], thing)
return
smooth_queue += thing
if(!can_fire)
can_fire = TRUE
/datum/controller/subsystem/icon_smooth/proc/remove_from_queues(atom/thing)
// Lack of removal from deferred_by_source is safe because the lack of SMOOTH_QUEUED will just free it anyway
// Hopefully this'll never cause a harddel (dies)
thing.smoothing_flags &= ~SMOOTH_QUEUED
smooth_queue -= thing
if(blueprint_queue)
blueprint_queue -= thing
deferred -= thing