mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-24 16:41:48 +00:00
Alsonce scrubbers only wake up if something they can filter is on the tile an existing bug where scrubbers dont filter very small but non garbage collectable amounts of a gas becomes a big issue, as in without changing scrubbing rates you can breathe once on a tile with a scrubber set to scrub co2 and that co2 wont go away barring any other factors and the scrubber wont go to sleep. so now with the idea of rohesie and permission of lemon i changed how scrubbers removed small molar amounts of gas from their turf. now scrubbers will look through 100% of the turfs air mix for filtering, but will only remove up to gas moles * (scrubber volume / turf volume) * (gas moles / total filterable moles) moles from each filterable gas in the turfs mix unless that amount is less than either MOLAR_ACCURACY * 100 or the number of moles of that filterable gas, in which case all of the moles of that gas are subtracted from the mix. this is to make it easier for the scrubber to remove very small amounts of gas with filters without changing how fast they scrub large amounts of gas, thus making scrubbers able to go to sleep faster only after a gas has been reduced to near zero scrubbers are the biggest proportion of SSair's machine processing cost which is a non trivial amount of SSair's total cost. now they will only do most of their work if they can actually scrub anything on the tile which is a minority of the time.
197 lines
5.0 KiB
Plaintext
197 lines
5.0 KiB
Plaintext
SUBSYSTEM_DEF(overlays)
|
|
name = "Overlay"
|
|
flags = SS_TICKER
|
|
wait = 1
|
|
priority = FIRE_PRIORITY_OVERLAYS
|
|
init_order = INIT_ORDER_OVERLAY
|
|
|
|
var/list/queue
|
|
var/list/stats
|
|
|
|
/datum/controller/subsystem/overlays/PreInit()
|
|
queue = list()
|
|
stats = list()
|
|
|
|
/datum/controller/subsystem/overlays/Initialize()
|
|
initialized = TRUE
|
|
fire(mc_check = FALSE)
|
|
return ..()
|
|
|
|
|
|
/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
|
|
if(length(atom_to_compile.overlays) >= MAX_ATOM_OVERLAYS)
|
|
//Break it real GOOD
|
|
stack_trace("Too many overlays on [atom_to_compile.type] - [length(atom_to_compile.overlays)], refusing to update and cutting")
|
|
atom_to_compile.overlays.Cut()
|
|
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(mc_check)
|
|
if(MC_TICK_CHECK)
|
|
break
|
|
else
|
|
CHECK_TICK
|
|
if (count)
|
|
queue.Cut(1,count+1)
|
|
count = 0
|
|
|
|
|
|
/proc/iconstate2appearance(icon, iconstate)
|
|
var/static/image/stringbro = new()
|
|
stringbro.icon = icon
|
|
stringbro.icon_state = iconstate
|
|
return stringbro.appearance
|
|
|
|
/proc/icon2appearance(icon)
|
|
var/static/image/iconbro = new()
|
|
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)
|
|
if(!overlay)
|
|
continue
|
|
if (istext(overlay))
|
|
#ifdef UNIT_TESTS
|
|
// This is too expensive to run normally but running it during CI is a good test
|
|
var/list/icon_states_available = icon_states(icon)
|
|
if(!(overlay in icon_states_available))
|
|
var/icon_file = "[icon]" || "Unknown Generated Icon"
|
|
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)
|
|
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
|
|
|
|
#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
|
|
|
|
//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)
|
|
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
|
|
|
|
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)
|
|
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
|
|
|
|
/atom/proc/copy_overlays(atom/other, cut_old) //copys our_overlays from another atom
|
|
if(!other)
|
|
if(cut_old)
|
|
cut_overlays()
|
|
return
|
|
|
|
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
|
|
|
|
//TODO: Better solution for these?
|
|
/image/proc/add_overlay(x)
|
|
overlays |= x
|
|
|
|
/image/proc/cut_overlay(x)
|
|
overlays -= x
|
|
|
|
/image/proc/cut_overlays(x)
|
|
overlays.Cut()
|
|
|
|
/image/proc/copy_overlays(atom/other, cut_old)
|
|
if(!other)
|
|
if(cut_old)
|
|
cut_overlays()
|
|
return
|
|
|
|
var/list/cached_other = other.overlays.Copy()
|
|
if(cached_other)
|
|
if(cut_old || !overlays.len)
|
|
overlays = cached_other
|
|
else
|
|
overlays |= cached_other
|
|
else if(cut_old)
|
|
cut_overlays()
|