massage subsystem definition for read/maintain

This commit is contained in:
spookerton
2022-03-31 20:02:19 +01:00
parent 21ee12ae4b
commit 01b1a22a11
32 changed files with 97 additions and 105 deletions

View File

@@ -32,17 +32,48 @@
var/static/list/failure_strikes //How many times we suspect a subsystem type has crashed the MC, 3 strikes and you're out!
//Do not override
///datum/controller/subsystem/New()
// Used to initialize the subsystem BEFORE the map has loaded
// Called AFTER Recover if that is called
// Prefer to use Initialize if possible
/datum/controller/subsystem/Destroy()
dequeue()
can_fire = 0
flags |= SS_NO_FIRE
Master.subsystems -= src
return ..()
/// Initializes the subsystem AFTER map load. The preferred initialization proc.
/datum/controller/subsystem/Initialize(start_timeofday)
subsystem_initialized = TRUE
var/time = (REALTIMEOFDAY - start_timeofday) / 10
var/msg = "Initialized [name] subsystem within [time] second[time == 1 ? "" : "s"]!"
to_chat(world, "<span class='boldannounce'>[msg]</span>")
log_world(msg)
return time
/// Initializes the subsystem BEFORE map load. Called after recover, if recover is called.
/datum/controller/subsystem/proc/PreInit()
return
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
/datum/controller/subsystem/stat_entry(msg)
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
if(SS_NO_FIRE & flags)
msg = "NO FIRE\t[msg]"
else if(can_fire <= 0)
msg = "OFFLINE\t[msg]"
else
msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]"
var/title = name
if (can_fire)
title = "\[[state_letter()]][title]"
stat(title, statclick.update(msg))
//This is used so the mc knows when the subsystem sleeps. do not override.
/datum/controller/subsystem/proc/ignite(resumed = 0)
/datum/controller/subsystem/proc/ignite(resumed)
set waitfor = 0
. = SS_SLEEPING
fire(resumed)
@@ -55,19 +86,17 @@
state = SS_PAUSED
queued_time = QT
//previously, this would have been named 'process()' but that name is used everywhere for different things!
//fire() seems more suitable. This is the procedure that gets called every 'wait' deciseconds.
//Sleeping in here prevents future fires until returned.
/datum/controller/subsystem/proc/fire(resumed = 0)
/**
* The periodic behavior of this subsystem, if it has any, every 'wait' deciseconds.
* Sleeping prevents future fires until returned.
* "resumed" is truthy when the previous fire did not complete and there is work left to do.
* "no_mc_tick" is truthy when fire should run to the end, and damn the torpedoes.
*/
/datum/controller/subsystem/proc/fire(resumed, no_mc_tick)
flags |= SS_NO_FIRE
throw EXCEPTION("Subsystem [src]([type]) does not fire() but did not set the SS_NO_FIRE flag. Please add the SS_NO_FIRE flag to any subsystem that doesn't fire so it doesn't get added to the processing list and waste cpu.")
/datum/controller/subsystem/Destroy()
dequeue()
can_fire = 0
flags |= SS_NO_FIRE
Master.subsystems -= src
return ..()
//Queue it to run.
// (we loop thru a linked list until we get to the end or find the right point)
@@ -78,23 +107,19 @@
var/datum/controller/subsystem/queue_node
var/queue_node_priority
var/queue_node_flags
for (queue_node = Master.queue_head; queue_node; queue_node = queue_node.queue_next)
queue_node_priority = queue_node.queued_priority
queue_node_flags = queue_node.flags
if (queue_node_flags & SS_TICKER)
if (!(SS_flags & SS_TICKER))
continue
if (queue_node_priority < SS_priority)
break
else if (queue_node_flags & SS_BACKGROUND)
if (!(SS_flags & SS_BACKGROUND))
break
if (queue_node_priority < SS_priority)
break
else
if (SS_flags & SS_BACKGROUND)
continue
@@ -102,7 +127,6 @@
break
if (queue_node_priority < SS_priority)
break
queued_time = world.time
queued_priority = SS_priority
state = SS_QUEUED
@@ -110,7 +134,6 @@
Master.queue_priority_count_bg += SS_priority
else
Master.queue_priority_count += SS_priority
queue_next = queue_node
if (!queue_node)//we stopped at the end, add to tail
queue_prev = Master.queue_tail
@@ -119,7 +142,6 @@
else //empty queue, we also need to set the head
Master.queue_head = src
Master.queue_tail = src
else if (queue_node == Master.queue_head)//insert at start of list
Master.queue_head.queue_prev = src
Master.queue_head = src
@@ -153,33 +175,26 @@
state = SS_PAUSING
//used to initialize the subsystem AFTER the map has loaded
/datum/controller/subsystem/Initialize(start_timeofday)
subsystem_initialized = TRUE
var/time = (REALTIMEOFDAY - start_timeofday) / 10
var/msg = "Initialized [name] subsystem within [time] second[time == 1 ? "" : "s"]!"
to_chat(world, "<span class='boldannounce'>[msg]</span>")
log_world(msg)
return time
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
/datum/controller/subsystem/stat_entry(msg)
if(!statclick)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
//could be used to postpone a costly subsystem for (default one) var/cycles, cycles
//for instance, during cpu intensive operations like explosions
/datum/controller/subsystem/proc/postpone(cycles = 1)
if(next_fire - world.time < wait)
next_fire += (wait*cycles)
if(SS_NO_FIRE & flags)
msg = "NO FIRE\t[msg]"
else if(can_fire <= 0)
msg = "OFFLINE\t[msg]"
else
msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]"
// Suspends this subsystem from being queued for running. If already in the queue, sleeps until idle. Returns FALSE if the subsystem was already suspended.
/datum/controller/subsystem/proc/suspend()
. = (can_fire > 0) // Return true if we were previously runnable, false if previously suspended.
can_fire = FALSE
// Safely sleep in a loop until the subsystem is idle, (or its been un-suspended somehow)
while(can_fire <= 0 && state != SS_IDLE)
stoplag() // Safely sleep in a loop until
var/title = name
if (can_fire)
title = "\[[state_letter()]][title]"
stat(title, statclick.update(msg))
// Wakes a suspended subsystem.
/datum/controller/subsystem/proc/wake()
can_fire = TRUE
/datum/controller/subsystem/proc/state_letter()
switch (state)
@@ -193,25 +208,3 @@
. = "S"
if (SS_IDLE)
. = " "
//could be used to postpone a costly subsystem for (default one) var/cycles, cycles
//for instance, during cpu intensive operations like explosions
/datum/controller/subsystem/proc/postpone(cycles = 1)
if(next_fire - world.time < wait)
next_fire += (wait*cycles)
//usually called via datum/controller/subsystem/New() when replacing a subsystem (i.e. due to a recurring crash)
//should attempt to salvage what it can from the old instance of subsystem
/datum/controller/subsystem/Recover()
// Suspends this subsystem from being queued for running. If already in the queue, sleeps until idle. Returns FALSE if the subsystem was already suspended.
/datum/controller/subsystem/proc/suspend()
. = (can_fire > 0) // Return true if we were previously runnable, false if previously suspended.
can_fire = FALSE
// Safely sleep in a loop until the subsystem is idle, (or its been un-suspended somehow)
while(can_fire <= 0 && state != SS_IDLE)
stoplag() // Safely sleep in a loop until
// Wakes a suspended subsystem.
/datum/controller/subsystem/proc/wake()
can_fire = TRUE

View File

@@ -14,7 +14,7 @@ SUBSYSTEM_DEF(ai)
msg += "P:[processing.len]"
..(msg.Join())
/datum/controller/subsystem/ai/fire(resumed = 0)
/datum/controller/subsystem/ai/fire(resumed, no_mc_tick)
if (!resumed)
src.currentrun = processing.Copy()

View File

@@ -14,7 +14,7 @@ SUBSYSTEM_DEF(aifast)
msg += "P:[processing.len]"
..(msg.Join())
/datum/controller/subsystem/aifast/fire(resumed = 0)
/datum/controller/subsystem/aifast/fire(resumed, no_mc_tick)
if (!resumed)
src.currentrun = processing.Copy()

View File

@@ -65,7 +65,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
..()
/datum/controller/subsystem/air/fire(resumed = 0)
/datum/controller/subsystem/air/fire(resumed, no_mc_tick)
var/timer
if(!resumed)
// Santity checks to make sure we don't somehow have items left over from last cycle

View File

@@ -19,7 +19,7 @@ SUBSYSTEM_DEF(airflow)
var/list/processing = list()
var/list/currentrun = list()
/datum/controller/subsystem/airflow/fire(resumed = FALSE)
/datum/controller/subsystem/airflow/fire(resumed, no_mc_tick)
if (!resumed)
currentrun = processing.Copy()

View File

@@ -20,7 +20,7 @@ SUBSYSTEM_DEF(alarm)
all_handlers = list(atmosphere_alarm, camera_alarm, fire_alarm, motion_alarm, power_alarm)
. = ..()
/datum/controller/subsystem/alarm/fire(resumed = FALSE)
/datum/controller/subsystem/alarm/fire(resumed, no_mc_tick)
if(!resumed)
src.currentrun = all_handlers.Copy()
active_alarm_cache.Cut()

View File

@@ -23,7 +23,7 @@ SUBSYSTEM_DEF(character_setup)
new_player.deferred_login()
. = ..()
*/ //Might be useful if we ever switch to Bay prefs.
/datum/controller/subsystem/character_setup/fire(resumed = FALSE)
/datum/controller/subsystem/character_setup/fire(resumed, no_mc_tick)
while(save_queue.len)
var/datum/preferences/prefs = save_queue[save_queue.len]
save_queue.len--

View File

@@ -11,7 +11,7 @@ SUBSYSTEM_DEF(chat)
init_vchat()
..()
/datum/controller/subsystem/chat/fire()
/datum/controller/subsystem/chat/fire(resumed, no_mc_tick)
var/list/msg_queue = src.msg_queue // Local variable for sanic speed.
for(var/i in msg_queue)
var/client/C = i

View File

@@ -23,7 +23,7 @@ SUBSYSTEM_DEF(events)
GLOB.overmap_event_handler.create_events(global.using_map.overmap_z, global.using_map.overmap_size, global.using_map.overmap_event_areas)
return ..()
/datum/controller/subsystem/events/fire(resumed)
/datum/controller/subsystem/events/fire(resumed, no_mc_tick)
if (!resumed)
src.currentrun = active_events.Copy()

View File

@@ -13,7 +13,7 @@ SUBSYSTEM_DEF(event_ticker)
var/list/finished_events = list()
// Process active events.
/datum/controller/subsystem/event_ticker/fire(resumed)
/datum/controller/subsystem/event_ticker/fire(resumed, no_mc_tick)
for(var/E in active_events)
var/datum/event2/event/event = E
event.process()

View File

@@ -38,7 +38,7 @@ SUBSYSTEM_DEF(game_master)
return ..()
/datum/controller/subsystem/game_master/fire(resumed)
/datum/controller/subsystem/game_master/fire(resumed, no_mc_tick)
adjust_staleness(1)
adjust_danger(-1)

View File

@@ -83,7 +83,7 @@ SUBSYSTEM_DEF(garbage)
dellog += "\tNo hint: [I.no_hint] times"
text2file(dellog.Join(), "[log_path]-qdel.log")
/datum/controller/subsystem/garbage/fire()
/datum/controller/subsystem/garbage/fire(resumed, no_mc_tick)
//the fact that this resets its processing each fire (rather then resume where it left off) is intentional.
var/queue = GC_QUEUE_PREQUEUE

View File

@@ -5,7 +5,7 @@ SUBSYSTEM_DEF(inactivity)
var/tmp/list/client_list
var/number_kicked = 0
/datum/controller/subsystem/inactivity/fire(resumed = FALSE)
/datum/controller/subsystem/inactivity/fire(resumed, no_mc_tick)
if (!config.kick_inactive)
can_fire = FALSE
return

View File

@@ -42,7 +42,7 @@ SUBSYSTEM_DEF(lighting)
internal_process_overlays(FALSE, TRUE)
return ..()
/datum/controller/subsystem/lighting/fire(resumed = FALSE)
/datum/controller/subsystem/lighting/fire(resumed, no_mc_tick)
var/timer
if(!resumed)
// Santity checks to make sure we don't somehow have items left over from last cycle

View File

@@ -39,7 +39,7 @@ SUBSYSTEM_DEF(machines)
fire()
..()
/datum/controller/subsystem/machines/fire(resumed = 0)
/datum/controller/subsystem/machines/fire(resumed, no_mc_tick)
var/timer = TICK_USAGE
INTERNAL_PROCESS_STEP(SSMACHINES_POWER_OBJECTS,FALSE,process_power_objects,cost_power_objects,SSMACHINES_PIPENETS) // Higher priority, damnit

View File

@@ -18,7 +18,7 @@ SUBSYSTEM_DEF(mobs)
/datum/controller/subsystem/mobs/stat_entry()
..("P: [global.mob_list.len] | S: [slept_mobs]")
/datum/controller/subsystem/mobs/fire(resumed = 0)
/datum/controller/subsystem/mobs/fire(resumed, no_mc_tick)
var/list/busy_z_levels = src.busy_z_levels
if (!resumed)

View File

@@ -16,7 +16,7 @@ SUBSYSTEM_DEF(nanoui)
/datum/controller/subsystem/nanoui/stat_entry()
return ..("[processing_uis.len] UIs")
/datum/controller/subsystem/nanoui/fire(resumed)
/datum/controller/subsystem/nanoui/fire(resumed, no_mc_tick)
for(var/thing in processing_uis)
var/datum/nanoui/UI = thing
UI.process()

View File

@@ -19,7 +19,7 @@ SUBSYSTEM_DEF(nightshift)
*/
return ..()
/datum/controller/subsystem/nightshift/fire(resumed = FALSE)
/datum/controller/subsystem/nightshift/fire(resumed, no_mc_tick)
if(round_duration_in_ds < nightshift_first_check)
return
check_nightshift()

View File

@@ -26,7 +26,7 @@ SUBSYSTEM_DEF(open_space)
flags |= SS_NO_INIT // Make extra sure we don't initialize twice.
. = ..()
/datum/controller/subsystem/open_space/fire(resumed = 0, init_tick_checks = FALSE)
/datum/controller/subsystem/open_space/fire(resumed, no_mc_tick)
// We use a different list so any additions to the update lists during a delay from MC_TICK_CHECK
// don't cause things to be cut from the list without being updated.
@@ -44,7 +44,7 @@ SUBSYSTEM_DEF(open_space)
counter += 1
if(!QDELETED(T))
update_turf(T)
if (init_tick_checks)
if (no_mc_tick)
CHECK_TICK // Used during initialization processing
else if (MC_TICK_CHECK)
src.counter = counter // Save for when we're resumed

View File

@@ -11,7 +11,7 @@ SUBSYSTEM_DEF(orbit)
..("P:[processing.len]")
/datum/controller/subsystem/orbit/fire(resumed = 0)
/datum/controller/subsystem/orbit/fire(resumed, no_mc_tick)
if (!resumed)
src.currentrun = processing.Copy()

View File

@@ -21,7 +21,7 @@ var/global/image/appearance_bro = new() // Temporarily super-global because of B
stats = list()
/datum/controller/subsystem/overlays/Initialize()
fire(mc_check = FALSE)
fire(FALSE, TRUE)
..()
/datum/controller/subsystem/overlays/stat_entry()
@@ -37,7 +37,7 @@ var/global/image/appearance_bro = new() // Temporarily super-global because of B
queue = SSoverlays.queue
/datum/controller/subsystem/overlays/fire(resumed = FALSE, mc_check = TRUE)
/datum/controller/subsystem/overlays/fire(resumed, no_mc_tick)
var/list/queue = src.queue
var/static/count = 0
if (count)
@@ -53,11 +53,10 @@ var/global/image/appearance_bro = new() // Temporarily super-global because of B
COMPILE_OVERLAYS(A)
STAT_STOP_STOPWATCH
STAT_LOG_ENTRY(stats, A.type)
if(mc_check)
if(MC_TICK_CHECK)
break
else
if (no_mc_tick)
CHECK_TICK
else if (MC_TICK_CHECK)
break
if (count)
queue.Cut(1,count+1)

View File

@@ -62,7 +62,7 @@ SUBSYSTEM_DEF(planets)
T.outdoors = OUTDOORS_NO
/datum/controller/subsystem/planets/fire(resumed = 0)
/datum/controller/subsystem/planets/fire(resumed, no_mc_tick)
if(!resumed)
src.currentrun = planets.Copy()

View File

@@ -27,7 +27,7 @@ SUBSYSTEM_DEF(processing)
/datum/controller/subsystem/processing/stat_entry()
..("[stat_tag]:[processing.len]")
/datum/controller/subsystem/processing/fire(resumed = 0)
/datum/controller/subsystem/processing/fire(resumed, no_mc_tick)
if (!resumed)
currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)

View File

@@ -11,7 +11,7 @@ SUBSYSTEM_DEF(radiation)
var/tmp/list/current_res_cache = list()
var/tmp/list/listeners = list()
/datum/controller/subsystem/radiation/fire(resumed = FALSE)
/datum/controller/subsystem/radiation/fire(resumed, no_mc_tick)
if (!resumed)
current_sources = sources.Copy()
current_res_cache = resistance_cache.Copy()

View File

@@ -51,7 +51,7 @@ SUBSYSTEM_DEF(shuttles)
process_init_queues()
return ..()
/datum/controller/subsystem/shuttles/fire(resumed = 0)
/datum/controller/subsystem/shuttles/fire(resumed, no_mc_tick)
if (!resumed)
src.current_run = process_shuttles.Copy()

View File

@@ -3,5 +3,5 @@ SUBSYSTEM_DEF(sun)
wait = 600
var/static/datum/sun/sun = new
/datum/controller/subsystem/sun/fire()
/datum/controller/subsystem/sun/fire(resumed, no_mc_tick)
sun.calc_position()

View File

@@ -38,7 +38,7 @@ SUBSYSTEM_DEF(supply)
. = ..()
// Supply shuttle ticker - handles supply point regeneration. Just add points over time.
/datum/controller/subsystem/supply/fire()
/datum/controller/subsystem/supply/fire(resumed, no_mc_tick)
points += points_per_process
/datum/controller/subsystem/supply/stat_entry()

View File

@@ -30,7 +30,7 @@ SUBSYSTEM_DEF(tgui)
/datum/controller/subsystem/tgui/stat_entry()
..("P:[open_uis.len]")
/datum/controller/subsystem/tgui/fire(resumed = 0)
/datum/controller/subsystem/tgui/fire(resumed, no_mc_tick)
if(!resumed)
src.current_run = open_uis.Copy()
// Cache for sanic speed (lists are references anyways)

View File

@@ -63,7 +63,7 @@ var/global/datum/controller/subsystem/ticker/ticker
GLOB.autospeaker = new (null, null, null, 1) //Set up Global Announcer
return ..()
/datum/controller/subsystem/ticker/fire(resumed = FALSE)
/datum/controller/subsystem/ticker/fire(resumed, no_mc_tick)
switch(current_state)
if(GAME_STATE_INIT)
pregame_welcome()

View File

@@ -16,7 +16,7 @@ SUBSYSTEM_DEF(time_track)
var/last_tick_byond_time = 0
var/last_tick_tickcount = 0
/datum/controller/subsystem/time_track/fire()
/datum/controller/subsystem/time_track/fire(resumed, no_mc_tick)
var/current_realtime = REALTIMEOFDAY
var/current_byondtime = world.time

View File

@@ -36,7 +36,7 @@ SUBSYSTEM_DEF(timer)
/datum/controller/subsystem/timer/stat_entry(msg)
..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]")
/datum/controller/subsystem/timer/fire(resumed = FALSE)
/datum/controller/subsystem/timer/fire(resumed, no_mc_tick)
var/lit = last_invoke_tick
var/last_check = world.time - TICKS2DS(BUCKET_LEN*1.5)
var/list/bucket_list = src.bucket_list

View File

@@ -20,7 +20,7 @@ SUBSYSTEM_DEF(vote)
var/list/current_votes = list()
var/list/additional_text = list()
/datum/controller/subsystem/vote/fire(resumed)
/datum/controller/subsystem/vote/fire(resumed, no_mc_tick)
if(mode)
time_remaining = round((started_time + duration - world.time)/10)
if(mode == VOTE_GAMEMODE && ticker.current_state >= GAME_STATE_SETTING_UP)