mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
* This is PHASE 1 of a multi-phase conversion. In this first phase we implement the subsystem, but leave it processing the existing global list variables. In the next phase we will switch to use datum variables in the subsystem. The main reason for splitting into two phases is ease of code review; change the meaningful code without the hundreds of machines -> SSmachines.machinery substitutions. * We did declare macros for adding/removing things to the processing lists, and convert everywhere to use the macros. * Added var/is_processing to /datum to keep track of whether an instance is already in a processing list (prevents it being in the list twice!) and also debugging, making sure its not in two lists etc. * NOTE: The global machines list is **no longer sorted** for performance reasons. As far as I know, the only module that actually ever cared was cameras. Our camera system already handles its own sorting in the cameranets anyway, so it should no longer be needed.
83 lines
3.6 KiB
Plaintext
83 lines
3.6 KiB
Plaintext
#define MC_TICK_CHECK ( ( TICK_USAGE > Master.current_ticklimit || src.state != SS_RUNNING ) ? pause() : 0 )
|
|
|
|
// Used for splitting up your remaining time into phases, if you want to evenly divide it.
|
|
#define MC_SPLIT_TICK_INIT(phase_count) var/original_tick_limit = Master.current_ticklimit; var/split_tick_phases = ##phase_count
|
|
#define MC_SPLIT_TICK \
|
|
if(split_tick_phases > 1){\
|
|
Master.current_ticklimit = ((original_tick_limit - TICK_USAGE) / split_tick_phases) + TICK_USAGE;\
|
|
--split_tick_phases;\
|
|
} else {\
|
|
Master.current_ticklimit = original_tick_limit;\
|
|
}
|
|
|
|
// Boilerplate code for multi-step processors. See machines.dm for example use.
|
|
#define INTERNAL_PROCESS_STEP(this_step, initial_step, proc_to_call, cost_var, next_step)\
|
|
if(current_step == this_step || (initial_step && !resumed)) /* So we start at step 1 if not resumed.*/ {\
|
|
timer = TICK_USAGE;\
|
|
proc_to_call(resumed);\
|
|
cost_var = MC_AVERAGE(cost_var, TICK_DELTA_TO_MS(TICK_USAGE - timer));\
|
|
if(state != SS_RUNNING){\
|
|
return;\
|
|
}\
|
|
resumed = 0;\
|
|
current_step = next_step;\
|
|
}
|
|
|
|
// Used to smooth out costs to try and avoid oscillation.
|
|
#define MC_AVERAGE_FAST(average, current) (0.7 * (average) + 0.3 * (current))
|
|
#define MC_AVERAGE(average, current) (0.8 * (average) + 0.2 * (current))
|
|
#define MC_AVERAGE_SLOW(average, current) (0.9 * (average) + 0.1 * (current))
|
|
#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;}
|
|
|
|
#define START_PROCESSING(Processor, Datum) if (!Datum.isprocessing) {Datum.isprocessing = 1;Processor.processing += Datum}
|
|
#define STOP_PROCESSING(Processor, Datum) Datum.isprocessing = 0;Processor.processing -= Datum
|
|
|
|
//SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier)
|
|
|
|
//subsystem does not initialize.
|
|
#define SS_NO_INIT 1
|
|
|
|
//subsystem does not fire.
|
|
// (like can_fire = 0, but keeps it from getting added to the processing subsystems list)
|
|
// (Requires a MC restart to change)
|
|
#define SS_NO_FIRE 2
|
|
|
|
//subsystem only runs on spare cpu (after all non-background subsystems have ran that tick)
|
|
// SS_BACKGROUND has its own priority bracket
|
|
#define SS_BACKGROUND 4
|
|
|
|
//subsystem does not tick check, and should not run unless there is enough time (or its running behind (unless background))
|
|
#define SS_NO_TICK_CHECK 8
|
|
|
|
//Treat wait as a tick count, not DS, run every wait ticks.
|
|
// (also forces it to run first in the tick, above even SS_NO_TICK_CHECK subsystems)
|
|
// (implies all runlevels because of how it works)
|
|
// (overrides SS_BACKGROUND)
|
|
// This is designed for basically anything that works as a mini-mc (like SStimer)
|
|
#define SS_TICKER 16
|
|
|
|
//keep the subsystem's timing on point by firing early if it fired late last fire because of lag
|
|
// ie: if a 20ds subsystem fires say 5 ds late due to lag or what not, its next fire would be in 15ds, not 20ds.
|
|
#define SS_KEEP_TIMING 32
|
|
|
|
//Calculate its next fire after its fired.
|
|
// (IE: if a 5ds wait SS takes 2ds to run, its next fire should be 5ds away, not 3ds like it normally would be)
|
|
// This flag overrides SS_KEEP_TIMING
|
|
#define SS_POST_FIRE_TIMING 64
|
|
|
|
//SUBSYSTEM STATES
|
|
#define SS_IDLE 0 //aint doing shit.
|
|
#define SS_QUEUED 1 //queued to run
|
|
#define SS_RUNNING 2 //actively running
|
|
#define SS_PAUSED 3 //paused by mc_tick_check
|
|
#define SS_SLEEPING 4 //fire() slept.
|
|
#define SS_PAUSING 5 //in the middle of pausing
|
|
|
|
// Standard way to define a global subsystem, keep boilerplate organized here!
|
|
#define SUBSYSTEM_DEF(X) var/datum/controller/subsystem/##X/SS##X;\
|
|
/datum/controller/subsystem/##X/New(){\
|
|
NEW_SS_GLOBAL(SS##X);\
|
|
PreInit();\
|
|
}\
|
|
/datum/controller/subsystem/##X
|