Files
Bubberstation/code/controllers/subsystems.dm
Kyle Spier-Swenson 6b92275c66 Tweaks mc's default dynamic wait buffer down a bit.
dynamic wait buffer is the amount subtracted off of the process cost before calculating the new dynamic wait.

1.5 was too much and dynamic wait wasn't kicking in until after atmos was causing lag, 0.7 seems much better after testing on sybil.
2015-10-04 18:58:28 -07:00

63 lines
3.0 KiB
Plaintext

#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;}
/datum/subsystem
//things you will want to define
var/name //name of the subsystem
var/priority = 0 //priority affects order of initialization. Higher priorities are initialized first, lower priorities later. Can be decimal and negative values.
var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer.
//Dynamic Wait - A system for scaling a subsystem's fire rate based on lag
//The algorithm is: (cost-dwait_buffer+AvgCostOfAllOtherSSPerSecond)*dwait_delta
//defaults are pretty sane for most use cases.
//you can change how quickly it starts scaling back with dwait_buffer,
//and you can change how much it scales back with dwait_delta
var/dynamic_wait = 0 //changes the wait based on the amount of time it took to process
var/dwait_upper = 20 //longest wait can be under dynamic_wait
var/dwait_lower = 5 //shortest wait can be under dynamic_wait
var/dwait_delta = 7 //How much should processing time effect dwait. or basically: wait = cost*dwait_delta
var/dwait_buffer = 0.7 //This number is subtracted from the processing time before calculating its new wait
//things you will probably want to leave alone
var/can_fire = 0 //prevent fire() calls
var/last_fire = 0 //last world.time we called fire()
var/next_fire = 0 //scheduled world.time for next fire()
var/cost = 0 //average time to execute
var/times_fired = 0 //number of times we have called fire()
//used to initialize the subsystem BEFORE the map has loaded
/datum/subsystem/New()
//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.
//fire(), and the procs it calls, SHOULD NOT HAVE ANY SLEEP OPERATIONS in them!
//YE BE WARNED!
/datum/subsystem/proc/fire()
can_fire = 0
//used to initialize the subsystem AFTER the map has loaded
/datum/subsystem/proc/Initialize(start_timeofday, zlevel)
var/time = (world.timeofday - start_timeofday) / 10
var/msg = "Initialized [name] SubSystem within [time] seconds"
if (zlevel)
testing(msg)
return
world << "<span class='boldannounce'>[msg]</span>"
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
/datum/subsystem/proc/stat_entry(msg)
var/dwait = ""
if (dynamic_wait)
dwait = "DWait:[round(wait,0.1)]ds "
stat(name, "[round(cost,0.001)]ds\t[dwait][msg]")
//could be used to postpone a costly subsystem for (default one) var/cycles, cycles
//for instance, during cpu intensive operations like explosions
/datum/subsystem/proc/postpone(cycles = 1)
if(next_fire - world.time < wait)
next_fire += (wait*cycles)
//usually called via datum/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/subsystem/proc/Recover()