Files
CHOMPStation2/code/controllers/subsystems/processing/processing.dm
Cadyn ccad338c93 Tgpanel (#8007)
Co-authored-by: ItsSelis <selis@xynolabs.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
Co-authored-by: Raeschen <rycoop29@gmail.com>
2024-03-24 12:19:07 +01:00

123 lines
4.4 KiB
Plaintext

//Used to process objects. Fires once every second.
SUBSYSTEM_DEF(processing)
name = "Processing"
priority = FIRE_PRIORITY_PROCESS
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT
wait = 10
var/stat_tag = "P" //Used for logging
var/list/processing = list()
var/list/currentrun = list()
var/process_proc = /datum/proc/process
var/debug_last_thing
var/debug_original_process_proc // initial() does not work with procs
var/datum/current_thing
/datum/controller/subsystem/processing/Recover()
log_debug("[name] subsystem Recover().")
if(SSprocessing.current_thing)
log_debug("current_thing was: (\ref[SSprocessing.current_thing])[SSprocessing.current_thing]([SSprocessing.current_thing.type]) - currentrun: [SSprocessing.currentrun.len] vs total: [SSprocessing.processing.len]")
var/list/old_processing = SSprocessing.processing.Copy()
for(var/datum/D in old_processing)
if(CHECK_BITFIELD(D.datum_flags, DF_ISPROCESSING))
processing |= D
//CHOMPEdit Begin
/datum/controller/subsystem/processing/stat_entry(msg)
msg = "[stat_tag]:[processing.len]"
return ..()
//CHOMPEdit End
/datum/controller/subsystem/processing/fire(resumed = 0)
if (!resumed)
currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)
var/list/current_run = currentrun
while(current_run.len)
current_thing = current_run[current_run.len]
current_run.len--
if(QDELETED(current_thing))
processing -= current_thing
else if(current_thing.process(wait) == PROCESS_KILL)
// fully stop so that a future START_PROCESSING will work
STOP_PROCESSING(src, current_thing)
if (MC_TICK_CHECK)
current_thing = null
return
current_thing = null
/datum/controller/subsystem/processing/proc/toggle_debug()
if(!check_rights(R_DEBUG))
return
if(debug_original_process_proc)
process_proc = debug_original_process_proc
debug_original_process_proc = null
else
debug_original_process_proc = process_proc
process_proc = /datum/proc/DebugSubsystemProcess
to_chat(usr, "[name] - Debug mode [debug_original_process_proc ? "en" : "dis"]abled")
/datum/controller/subsystem/processing/proc/log_recent()
var/msg = "Debug output from the [name] subsystem:\n"
msg += "- Process subsystems are processed tail-first -\n"
if(!currentrun || !processing)
msg += "ERROR: A critical list [currentrun ? "processing" : "currentrun"] is gone!"
log_game(msg)
log_world(msg)
return
msg += "Lists: current_run: [currentrun.len], processing: [processing.len]\n"
if(!currentrun.len)
msg += "!!The subsystem just finished the processing list, and currentrun is empty (or has never run).\n"
msg += "!!The info below is the tail of processing instead of currentrun.\n"
var/datum/D = currentrun.len ? currentrun[currentrun.len] : processing[processing.len]
msg += "Tail entry: [describeThis(D)] (this is likely the item AFTER the problem item)\n"
var/position = processing.Find(D)
if(!position)
msg += "Unable to find context of tail entry in processing list.\n"
else
if(position != processing.len)
var/additional = processing.Find(D, position+1)
if(additional)
msg += "WARNING: Tail entry found more than once in processing list! Context is for the first found.\n"
var/start = clamp(position-2,1,processing.len)
var/end = clamp(position+2,1,processing.len)
msg += "2 previous elements, then tail, then 2 next elements of processing list for context:\n"
msg += "---\n"
for(var/i in start to end)
msg += "[describeThis(processing[i])][i == position ? " << TAIL" : ""]\n"
msg += "---\n"
log_game(msg)
log_world(msg)
/datum/controller/subsystem/processing/fail()
..()
log_recent()
/datum/controller/subsystem/processing/critfail()
..()
log_recent()
/datum/proc/DebugSubsystemProcess(var/wait, var/times_fired, var/datum/controller/subsystem/processing/subsystem)
subsystem.debug_last_thing = src
var/start_tick = world.time
var/start_tick_usage = world.tick_usage
. = call(src, subsystem.debug_original_process_proc)(wait, times_fired)
var/tick_time = world.time - start_tick
var/tick_use_limit = world.tick_usage - start_tick_usage - 100 // Current tick use - starting tick use - 100% (a full tick excess)
if(tick_time > 0)
stack_trace("[log_info_line(subsystem.debug_last_thing)] slept during processing. Spent [tick_time] tick\s.")
if(tick_use_limit > 0)
stack_trace("[log_info_line(subsystem.debug_last_thing)] took longer than a tick to process. Exceeded with [tick_use_limit]%")
/datum/proc/process()
set waitfor = 0
return PROCESS_KILL