Removes overlay queuing, saves 6/7 seconds of initialize. Lightly modifies stat tracking macros (#69696)

* Removes overlay queuing, saves 6/7 seconds of initialize. Lightly modifies stat tracking macros

So we have this overlay queuing system right? It's build with the assumption
that the "add to overlay list" operation is real expensive, and is
thus useful to queue removals or additions.

It turns out that it just isn't, at least during init. In my testing the
operation of queuing took LONGER then the actual overlay add/remove did.

That's ignoring the cost of the subsystem's work.

I've also modified part of the stat tracking macro, since it took a good
bit of cpu time, and didn't seem to well, do anything. So far as I can
tell it always evaluates to 1
This commit is contained in:
LemonInTheDark
2022-09-26 08:46:46 -07:00
committed by GitHub
parent 7e8f08a842
commit 72a5b79555
22 changed files with 95 additions and 191 deletions
+43 -123
View File
@@ -1,71 +1,16 @@
SUBSYSTEM_DEF(overlays)
name = "Overlay"
flags = SS_TICKER
wait = 1
priority = FIRE_PRIORITY_OVERLAYS
init_order = INIT_ORDER_OVERLAY
var/list/queue
flags = SS_NO_FIRE|SS_NO_INIT
var/list/stats
/datum/controller/subsystem/overlays/PreInit()
queue = list()
stats = list()
/datum/controller/subsystem/overlays/Initialize()
initialized = TRUE
fire(mc_check = FALSE)
return SS_INIT_SUCCESS
/datum/controller/subsystem/overlays/stat_entry(msg)
msg = "Ov:[length(queue)]"
return ..()
/datum/controller/subsystem/overlays/Shutdown()
text2file(render_stats(stats), "[GLOB.log_directory]/overlay.log")
/datum/controller/subsystem/overlays/Recover()
queue = SSoverlays.queue
/datum/controller/subsystem/overlays/fire(resumed = FALSE, mc_check = TRUE)
var/list/queue = src.queue
var/static/count = 0
if (count)
var/c = count
count = 0 //so if we runtime on the Cut, we don't try again.
queue.Cut(1,c+1)
for (var/atom/atom_to_compile as anything in queue)
count++
if(!atom_to_compile)
continue
STAT_START_STOPWATCH
COMPILE_OVERLAYS(atom_to_compile)
UNSETEMPTY(atom_to_compile.add_overlays)
UNSETEMPTY(atom_to_compile.remove_overlays)
STAT_STOP_STOPWATCH
STAT_LOG_ENTRY(stats, atom_to_compile.type)
if(length(atom_to_compile.overlays) >= MAX_ATOM_OVERLAYS)
//Break it real GOOD
var/text_lays = overlays2text(atom_to_compile.overlays)
stack_trace("Too many overlays on [atom_to_compile.type] - [length(atom_to_compile.overlays)], refusing to update and cutting.\
\n What follows is a printout of all existing overlays at the time of the overflow \n[text_lays]")
atom_to_compile.overlays.Cut()
//Let them know they fucked up
atom_to_compile.add_overlay(mutable_appearance('icons/testing/greyscale_error.dmi'))
continue
if(mc_check)
if(MC_TICK_CHECK)
break
else
CHECK_TICK
if (count)
queue.Cut(1,count+1)
count = 0
stats = SSoverlays.stats
/// Converts an overlay list into text for debug printing
/// Of note: overlays aren't actually mutable appearances, they're just appearances
@@ -92,13 +37,12 @@ SUBSYSTEM_DEF(overlays)
iconbro.icon = icon
return iconbro.appearance
/atom/proc/build_appearance_list(old_overlays)
var/static/image/appearance_bro = new()
var/list/new_overlays = list()
if (!islist(old_overlays))
old_overlays = list(old_overlays)
for (var/overlay in old_overlays)
/atom/proc/build_appearance_list(build_overlays)
if (!islist(build_overlays))
build_overlays = list(build_overlays)
for (var/overlay in build_overlays)
if(!overlay)
build_overlays -= overlay
continue
if (istext(overlay))
#ifdef UNIT_TESTS
@@ -109,64 +53,37 @@ SUBSYSTEM_DEF(overlays)
stack_trace("Invalid overlay: Icon object '[icon_file]' [REF(icon)] used in '[src]' [type] is missing icon state [overlay].")
continue
#endif
new_overlays += iconstate2appearance(icon, overlay)
build_overlays -= overlay
build_overlays += iconstate2appearance(icon, overlay)
else if(isicon(overlay))
new_overlays += icon2appearance(overlay)
else
if(isloc(overlay))
var/atom/A = overlay
if (A.flags_1 & OVERLAY_QUEUED_1)
COMPILE_OVERLAYS(A)
appearance_bro.appearance = overlay //this works for images and atoms too!
if(!ispath(overlay))
var/image/I = overlay
appearance_bro.dir = I.dir
new_overlays += appearance_bro.appearance
return new_overlays
build_overlays -= overlay
build_overlays += icon2appearance(overlay)
return build_overlays
#define NOT_QUEUED_ALREADY (!(flags_1 & OVERLAY_QUEUED_1))
#define QUEUE_FOR_COMPILE flags_1 |= OVERLAY_QUEUED_1; SSoverlays.queue += src;
/atom/proc/cut_overlays()
LAZYINITLIST(remove_overlays)
remove_overlays = overlays.Copy()
add_overlays = null
STAT_START_STOPWATCH
overlays = null
POST_OVERLAY_CHANGE(src)
STAT_STOP_STOPWATCH
STAT_LOG_ENTRY(SSoverlays.stats, type)
//If not already queued for work and there are overlays to remove
if(NOT_QUEUED_ALREADY && remove_overlays.len)
QUEUE_FOR_COMPILE
/atom/proc/cut_overlay(list/overlays)
/atom/proc/cut_overlay(list/remove_overlays)
if(!overlays)
return
overlays = build_appearance_list(overlays)
LAZYINITLIST(add_overlays)
LAZYINITLIST(remove_overlays)
var/a_len = add_overlays.len
var/r_len = remove_overlays.len
remove_overlays += overlays
add_overlays -= overlays
STAT_START_STOPWATCH
overlays -= build_appearance_list(remove_overlays)
POST_OVERLAY_CHANGE(src)
STAT_STOP_STOPWATCH
STAT_LOG_ENTRY(SSoverlays.stats, type)
var/fa_len = add_overlays.len
var/fr_len = remove_overlays.len
//If not already queued and there is work to be done
if(NOT_QUEUED_ALREADY && (fa_len != a_len || fr_len != r_len ))
QUEUE_FOR_COMPILE
UNSETEMPTY(add_overlays)
/atom/proc/add_overlay(list/overlays)
/atom/proc/add_overlay(list/add_overlays)
if(!overlays)
return
overlays = build_appearance_list(overlays)
LAZYINITLIST(add_overlays) //always initialized after this point
var/a_len = add_overlays.len
add_overlays += overlays
var/fa_len = add_overlays.len
if(NOT_QUEUED_ALREADY && fa_len != a_len)
QUEUE_FOR_COMPILE
STAT_START_STOPWATCH
overlays += build_appearance_list(add_overlays)
POST_OVERLAY_CHANGE(src)
STAT_STOP_STOPWATCH
STAT_LOG_ENTRY(SSoverlays.stats, type)
/atom/proc/copy_overlays(atom/other, cut_old) //copys our_overlays from another atom
if(!other)
@@ -174,18 +91,21 @@ SUBSYSTEM_DEF(overlays)
cut_overlays()
return
STAT_START_STOPWATCH
var/list/cached_other = other.overlays.Copy()
if(cached_other)
if(cut_old || !LAZYLEN(overlays))
remove_overlays = overlays
add_overlays = cached_other
if(NOT_QUEUED_ALREADY)
QUEUE_FOR_COMPILE
else if(cut_old)
cut_overlays()
#undef NOT_QUEUED_ALREADY
#undef QUEUE_FOR_COMPILE
if(cut_old)
if(cached_other)
overlays = cached_other
else
overlays = null
POST_OVERLAY_CHANGE(src)
STAT_STOP_STOPWATCH
STAT_LOG_ENTRY(SSoverlays.stats, type)
else if(cached_other)
overlays += cached_other
POST_OVERLAY_CHANGE(src)
STAT_STOP_STOPWATCH
STAT_LOG_ENTRY(SSoverlays.stats, type)
//TODO: Better solution for these?
/image/proc/add_overlay(x)