Icon smoothing and icon update refactor (#17569)

* Atomization

* asdfsadf

* sdfas

---------

Co-authored-by: FluffyGhost <FluffyGhost>
This commit is contained in:
Fluffy
2023-10-12 23:23:28 +02:00
committed by GitHub
parent bb4d89a498
commit 8bb0ecfcd3
7 changed files with 223 additions and 48 deletions
+18 -4
View File
@@ -24,12 +24,17 @@ SUBSYSTEM_DEF(icon_smooth)
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
var/list/smooth_queue = list()
///Like `smooth_queue`, but contains atoms that didn't initialize yet, to be reran
var/list/deferred = list()
var/list/typecachecache = list()
var/explosion_in_progress = FALSE
/datum/controller/subsystem/icon_smooth/Recover()
smooth_queue = SSicon_smooth.smooth_queue
deferred = SSicon_smooth.deferred
/datum/controller/subsystem/icon_smooth/stat_entry(msg)
msg = "Q:[smooth_queue.len]"
@@ -50,13 +55,20 @@ SUBSYSTEM_DEF(icon_smooth)
if(QDELETED(smoothing_atom) || !(smoothing_atom.smoothing_flags & SMOOTH_QUEUED))
continue
smooth_icon(smoothing_atom)
if(smoothing_atom.initialized && !(smoothing_atom.icon_update_queued))
smooth_icon(smoothing_atom)
else
deferred += smoothing_atom
if (MC_TICK_CHECK)
return
if (!length(smooth_queue_cache))
can_fire = FALSE
if(deferred.len)
smooth_queue = deferred
deferred = smooth_queue_cache
else
can_fire = FALSE
/datum/controller/subsystem/icon_smooth/ExplosionStart()
explosion_in_progress = TRUE
@@ -91,8 +103,9 @@ SUBSYSTEM_DEF(icon_smooth)
/datum/controller/subsystem/icon_smooth/proc/add_to_queue(atom/thing)
SHOULD_NOT_SLEEP(TRUE)
if(thing.smoothing_flags & SMOOTH_QUEUED)
if(QDELETED(thing) || thing.smoothing_flags & SMOOTH_QUEUED)
return
thing.smoothing_flags |= SMOOTH_QUEUED
smooth_queue += thing
@@ -103,7 +116,7 @@ SUBSYSTEM_DEF(icon_smooth)
SHOULD_NOT_SLEEP(TRUE)
for(var/atom/neighbor as anything in orange(1,thing))
if(neighbor.smoothing_flags)
if(!QDELETED(neighbor) && neighbor.smoothing_flags)
SSICONSMOOTH_ADD_TO_QUEUE(neighbor)
/datum/controller/subsystem/icon_smooth/proc/remove_from_queues(atom/thing)
@@ -111,5 +124,6 @@ SUBSYSTEM_DEF(icon_smooth)
thing.smoothing_flags &= ~SMOOTH_QUEUED
smooth_queue -= thing
deferred -= thing
#undef SSICONSMOOTH_ADD_TO_QUEUE
+91 -28
View File
@@ -5,13 +5,20 @@ SUBSYSTEM_DEF(icon_update)
priority = SS_PRIORITY_ICON_UPDATE
init_order = SS_INIT_ICON_UPDATE
var/list/queue = list()
/**
* Associative list of atoms -> callback params
* A list of `/atoms` that are waiting to have its icon updated
*/
VAR_PRIVATE/list/icon_update_queue = list()
///Deferred list, contains atoms that were not ready to be processed in the previous run
VAR_PRIVATE/list/deferred = list()
/datum/controller/subsystem/icon_update/New()
NEW_SS_GLOBAL(SSicon_update)
/datum/controller/subsystem/icon_update/stat_entry(msg)
msg = "QU:[queue.len]"
msg = "QU:[icon_update_queue.len]"
return ..()
/datum/controller/subsystem/icon_update/Initialize()
@@ -19,45 +26,101 @@ SUBSYSTEM_DEF(icon_update)
..()
/datum/controller/subsystem/icon_update/fire(resumed = FALSE, no_mc_tick = FALSE)
var/list/curr = queue
var/list/icon_update_queue_cache = icon_update_queue
if (!curr.len)
suspend()
return
while (length(icon_update_queue_cache))
var/atom/A = icon_update_queue_cache[length(icon_update_queue_cache)]
var/list/argv = icon_update_queue_cache[A]
icon_update_queue_cache.len--
while (curr.len)
var/atom/A = curr[curr.len]
var/list/argv = curr[A]
curr.len--
if(A.initialized)
A.icon_update_queued = FALSE
A.icon_update_queued = FALSE
//Do not target qdeleted atoms
if(QDELETED(A))
continue
//Do not target qdeleted atoms
if(QDELETED(A))
continue
if (islist(argv))
A.update_icon(arglist(argv))
else
A.update_icon()
A.update_above()
A.last_icon_update = world.time
if (islist(argv))
A.update_icon(arglist(argv))
else
A.update_icon()
A.update_above()
A.last_icon_update = world.time
src.deferred[A] = argv
if (no_mc_tick)
CHECK_TICK
else if (MC_TICK_CHECK)
return
if (!length(icon_update_queue_cache))
if(deferred.len)
icon_update_queue = deferred
deferred = icon_update_queue_cache
else
can_fire = FALSE
/**
* Adds an atom to the queue to have its icon updated
*
* * item - An `/atom` to add to the queue
* * parameters - Parameters that will be passed to `update_icon()` on callback
*/
/datum/controller/subsystem/icon_update/proc/add_to_queue(var/atom/item, ...)
SHOULD_NOT_SLEEP(TRUE)
var/atom/item_cache = item
//Skip atoms that are being deleted
if(QDELETED(item_cache))
return
if(!item_cache.icon_update_queued && (!item_cache.icon_update_delay || (item_cache.last_icon_update + item_cache.icon_update_delay < world.time)))
item_cache.icon_update_queued = TRUE
//Determine if we got any parameter, and if we do set it in the associative list, otherwise just set it to TRUE
var/list/calling_arguments = length(args) > 1 ? args.Copy(2) : TRUE
src.icon_update_queue[item_cache] = calling_arguments
if(!src.can_fire)
can_fire = TRUE
/**
* Removes an atom from the queue of atoms waiting to have its icon updated
*
* * item - An `/atom` to add to the queue
* * VARIPARAM - Parameters that will be passed to `update_icon()` on callback
*/
/datum/controller/subsystem/icon_update/proc/remove_from_queue(var/atom/item)
SHOULD_NOT_SLEEP(TRUE)
var/atom/item_cache = item
if(item_cache.icon_update_queued)
item_cache.icon_update_queued = FALSE
src.icon_update_queue -= item_cache
src.deferred -= item_cache
/atom
var/tmp/last_icon_update
var/tmp/icon_update_queued
var/icon_update_delay
///When was the last time (in `world.time`) that the icon of this atom was updated via `SSicon_update`
var/tmp/last_icon_update = null
///If the atom is currently queued to have it's icon updated in `SSicon_update`
var/tmp/icon_update_queued = FALSE
///Delay to apply before updating the icon in `SSicon_update`
var/icon_update_delay = null
/atom/proc/update_icon()
/atom/proc/queue_icon_update(...)
if (!icon_update_queued && (!icon_update_delay || (last_icon_update + icon_update_delay < world.time)))
icon_update_queued = TRUE
SSicon_update.queue[src] = args.len ? args : TRUE
if (SSicon_update.suspended)
SSicon_update.wake()
/**
* DO NOT USE
*
* Left for backward compatibility, use `SSicon_update.add_to_queue(thing)`
*/
/atom/proc/queue_icon_update()
//Skip if we're being deleted
if(QDELETED(src))
return
SSicon_update.add_to_queue(src)