mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-07-19 04:53:16 +01:00
Initial Commit
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
// handles timed player actions
|
||||
datum/controller/process/actions
|
||||
var/action_controler
|
||||
|
||||
setup()
|
||||
name = "Actions"
|
||||
schedule_interval = 5
|
||||
|
||||
action_controler = actions
|
||||
|
||||
doWork()
|
||||
actions.process()
|
||||
@@ -0,0 +1,12 @@
|
||||
datum/controller/process/ai_tracking
|
||||
|
||||
setup()
|
||||
name = "AI Tracking"
|
||||
schedule_interval = 10
|
||||
sleep_interval = 0.1
|
||||
|
||||
doWork()
|
||||
for(var/datum/ai_camera_tracker/T in global.tracking_list)
|
||||
T.process()
|
||||
|
||||
scheck()
|
||||
@@ -0,0 +1,16 @@
|
||||
// handles air processing.
|
||||
datum/controller/process/air_system
|
||||
setup()
|
||||
name = "Atmos"
|
||||
schedule_interval = 25 // 2.5 seconds
|
||||
|
||||
if(!air_master)
|
||||
air_master = new /datum/controller/air_system()
|
||||
air_master.setup(src)
|
||||
air_master.set_controller(src)
|
||||
|
||||
doWork()
|
||||
air_master.process()
|
||||
|
||||
copyStateFrom(var/datum/controller/process/target)
|
||||
air_master.set_controller(src)
|
||||
@@ -0,0 +1,16 @@
|
||||
datum/controller/process/arena
|
||||
var/list/arenas = list()
|
||||
|
||||
setup()
|
||||
name = "Arena"
|
||||
schedule_interval = 8 // 0.8 seconds
|
||||
|
||||
arenas += gauntlet_controller
|
||||
arenas += colosseum_controller
|
||||
|
||||
doWork()
|
||||
for (var/datum/arena/A in arenas)
|
||||
A.tick()
|
||||
|
||||
tickDetail()
|
||||
boutput(usr, "No statistics available.")
|
||||
@@ -0,0 +1,39 @@
|
||||
//Handles blobs without being pissy about it
|
||||
datum/controller/process/blob
|
||||
var/list/blobs = list()
|
||||
|
||||
var/tmp/list/detailed_count
|
||||
var/tmp/datum/updateQueue/blobUpdateQueue
|
||||
|
||||
setup()
|
||||
name = "Blob"
|
||||
schedule_interval = 31 // 3.1 seconds
|
||||
|
||||
detailed_count = new
|
||||
blobUpdateQueue = new
|
||||
|
||||
doWork()
|
||||
|
||||
for (var/obj/blob/B in blobs)
|
||||
if (B.runOnLife || B.poison)
|
||||
B.Life()
|
||||
scheck()
|
||||
|
||||
/*var/currentTick = ticks
|
||||
|
||||
for(var/obj/blob/B in blobs)
|
||||
if (prob (B.life_prob))
|
||||
B.Life()
|
||||
|
||||
detailed_count["[B.type]"]++
|
||||
|
||||
scheck(currentTick)*/
|
||||
|
||||
tickDetail()
|
||||
if (detailed_count && detailed_count.len)
|
||||
var/stats = "<b>Blob Stats:</b><br>"
|
||||
var/count
|
||||
for (var/thing in detailed_count)
|
||||
count = detailed_count[thing]
|
||||
stats += "[thing] processed [count] times. Total blobs: [blobs.len]<br>"
|
||||
boutput(usr, "<br>[stats]")
|
||||
@@ -0,0 +1,9 @@
|
||||
datum/controller/process/camnets
|
||||
|
||||
setup()
|
||||
name = "Camera Networks"
|
||||
schedule_interval = 30
|
||||
sleep_interval = 0.5
|
||||
|
||||
doWork()
|
||||
rebuild_camera_network() //Will only actually do something if it needs to.
|
||||
@@ -0,0 +1,12 @@
|
||||
datum/controller/process/chemistry
|
||||
var/tmp/datum/updateQueue/chemistryUpdateQueue
|
||||
|
||||
setup()
|
||||
name = "Chemistry"
|
||||
schedule_interval = 10
|
||||
chemistryUpdateQueue = new
|
||||
|
||||
doWork()
|
||||
for(var/datum/d in active_reagent_holders)
|
||||
d:process_reactions()
|
||||
scheck()
|
||||
@@ -0,0 +1,41 @@
|
||||
// handles critters
|
||||
datum/controller/process/critters
|
||||
var/tmp/list/detailed_count
|
||||
var/tmp/tick_counter
|
||||
var/tmp/list/critters
|
||||
|
||||
setup()
|
||||
name = "Critter"
|
||||
schedule_interval = 16 // 1.6 seconds
|
||||
|
||||
detailed_count = new
|
||||
src.critters = global.critters
|
||||
|
||||
doWork()
|
||||
var/i
|
||||
for(var/datum/c in global.critters)
|
||||
c:process()
|
||||
if (!(i++ % 10))
|
||||
scheck()
|
||||
|
||||
/*var/currentTick = ticks
|
||||
for(var/obj/critter in critters)
|
||||
tick_counter = world.timeofday
|
||||
|
||||
critter:process()
|
||||
|
||||
tick_counter = world.timeofday - tick_counter
|
||||
if (critter && tick_counter > 0)
|
||||
detailed_count["[critter.type]"] += tick_counter
|
||||
|
||||
scheck(currentTick)*/
|
||||
|
||||
tickDetail()
|
||||
if (detailed_count && detailed_count.len)
|
||||
var/stats = "<b>[name] ticks:</b>"
|
||||
var/count
|
||||
for (var/thing in detailed_count)
|
||||
count = detailed_count[thing]
|
||||
if (count > 4)
|
||||
stats += "[thing] used [count] ticks.<br>"
|
||||
boutput(usr, "<br>[stats]")
|
||||
@@ -0,0 +1,101 @@
|
||||
datum/controller/process/delete_queue
|
||||
var/tmp/delcount = 0
|
||||
var/tmp/gccount = 0
|
||||
var/tmp/deleteChunkSize = MIN_DELETE_CHUNK_SIZE
|
||||
//var/tmp/delpause = 1
|
||||
|
||||
// Timing vars
|
||||
var/tmp/start = 0
|
||||
var/tmp/list/timeTaken = new
|
||||
|
||||
setup()
|
||||
name = "DeleteQueue"
|
||||
schedule_interval = 1
|
||||
sleep_interval = 1
|
||||
|
||||
doWork()
|
||||
if(!global.delete_queue)
|
||||
boutput(world, "Error: there is no delete queue!")
|
||||
return 0
|
||||
|
||||
//var/datum/dynamicQueue/queue =
|
||||
if(global.delete_queue.isEmpty())
|
||||
return
|
||||
|
||||
start = world.timeofday
|
||||
|
||||
var/list/toDeleteRefs = delete_queue.dequeueMany(deleteChunkSize)
|
||||
var/numItems = toDeleteRefs.len
|
||||
#ifdef DELETE_QUEUE_DEBUG
|
||||
var/t
|
||||
#endif
|
||||
for(var/r in toDeleteRefs)
|
||||
var/datum/D = locate(r)
|
||||
|
||||
if (!istype(D) || !D.qdeled)
|
||||
// If we can't locate it, it got garbage collected.
|
||||
// If it isn't disposed, it got garbage collected and then a new thing used its ref.
|
||||
gccount++
|
||||
continue
|
||||
|
||||
#ifdef DELETE_QUEUE_DEBUG
|
||||
t = D.type
|
||||
// If we have been forced to delete the object, we do the following:
|
||||
detailed_delete_count[t]++
|
||||
detailed_delete_gc_count[t]--
|
||||
// Because we have already logged it into the gc count in qdel.
|
||||
#endif
|
||||
|
||||
// Delete that bitch
|
||||
delcount++
|
||||
D.qdeled = 0
|
||||
del(D)
|
||||
|
||||
scheck(0)
|
||||
|
||||
//if (delpause)
|
||||
//sleep(delpause)
|
||||
|
||||
// The amount of time taken for this run is recorded only if
|
||||
// the number of items considered is equal to the chunk size
|
||||
if(numItems == deleteChunkSize)
|
||||
timeTaken.len++
|
||||
timeTaken[timeTaken.len] = world.timeofday - start
|
||||
|
||||
// If the number of items processed is equal to the chunk size
|
||||
// and the average time taken by the delete queue is greater than the scheduled interval
|
||||
if (numItems == deleteChunkSize && averageTimeTaken() > schedule_interval && deleteChunkSize > MIN_DELETE_CHUNK_SIZE)
|
||||
deleteChunkSize--
|
||||
else if (numItems == deleteChunkSize && averageTimeTaken() < schedule_interval)
|
||||
deleteChunkSize++
|
||||
|
||||
proc
|
||||
averageTimeTaken()
|
||||
var/t = 0
|
||||
var/c = 0
|
||||
for(var/time in timeTaken)
|
||||
t += time
|
||||
c++
|
||||
|
||||
if (timeTaken.len > 10)
|
||||
timeTaken.Cut(1, 2)
|
||||
|
||||
if(c > 0)
|
||||
return t / c
|
||||
return c
|
||||
|
||||
tickDetail()
|
||||
#ifdef DELETE_QUEUE_DEBUG
|
||||
if (detailed_delete_count && detailed_delete_count.len)
|
||||
var/stats = "<b>Delete Stats:</b><br>"
|
||||
var/count
|
||||
for (var/thing in detailed_delete_count)
|
||||
count = detailed_delete_count[thing]
|
||||
stats += "[thing] deleted [count] times.<br>"
|
||||
for (var/thing in detailed_delete_gc_count)
|
||||
count = detailed_delete_gc_count[thing]
|
||||
stats += "[thing] gracefully deleted [count] times.<br>"
|
||||
boutput(usr, "<br>[stats]")
|
||||
#endif
|
||||
boutput(usr, "<b>Current Queue Length:</b> [delete_queue.count()]")
|
||||
boutput(usr, "<b>Total Items Deleted:</b> [delcount] (Explictly) [gccount] (Gracefully GC'd)")
|
||||
@@ -0,0 +1,44 @@
|
||||
// handles items
|
||||
datum/controller/process/items
|
||||
var/tmp/list/detailed_count
|
||||
var/tmp/tick_counter
|
||||
var/tmp/list/processing_items
|
||||
|
||||
setup()
|
||||
name = "Item"
|
||||
schedule_interval = 29
|
||||
|
||||
for(var/obj/object in world)
|
||||
object.initialize()
|
||||
|
||||
detailed_count = new
|
||||
|
||||
src.processing_items = global.processing_items
|
||||
|
||||
doWork()
|
||||
var/c
|
||||
for(var/datum/i in global.processing_items)
|
||||
i:process()
|
||||
if (!(c++ % 20))
|
||||
scheck()
|
||||
|
||||
/*for(var/obj/item/item in processing_items)
|
||||
tick_counter = world.timeofday
|
||||
|
||||
item.process()
|
||||
|
||||
tick_counter = world.timeofday - tick_counter
|
||||
if (item && tick_counter > 0)
|
||||
detailed_count["[item.type]"] += tick_counter
|
||||
|
||||
scheck(currentTick)
|
||||
*/
|
||||
tickDetail()
|
||||
if (detailed_count && detailed_count.len)
|
||||
var/stats = "<b>[name] ticks:</b><br>"
|
||||
var/count
|
||||
for (var/thing in detailed_count)
|
||||
count = detailed_count[thing]
|
||||
if (count > 4)
|
||||
stats += "[thing] used [count] ticks.<br>"
|
||||
boutput(usr, "<br>[stats]")
|
||||
@@ -0,0 +1,7 @@
|
||||
datum/controller/process/lighting
|
||||
setup()
|
||||
name = "Lighting"
|
||||
schedule_interval = 22
|
||||
|
||||
doWork()
|
||||
// TODO
|
||||
@@ -0,0 +1,81 @@
|
||||
// handles machines
|
||||
datum/controller/process/machines
|
||||
var/tmp/list/machines
|
||||
var/tmp/list/pipe_networks
|
||||
var/tmp/list/powernets
|
||||
var/tmp/list/atmos_machines
|
||||
|
||||
setup()
|
||||
name = "Machine"
|
||||
schedule_interval = 33
|
||||
|
||||
Station_VNet = new /datum/v_space/v_space_network()
|
||||
|
||||
doWork()
|
||||
src.atmos_machines = global.atmos_machines
|
||||
var/c = 0
|
||||
for(var/obj/machinery/atmospherics/machine in atmos_machines)
|
||||
#ifdef MACHINE_PROCESSING_DEBUG
|
||||
var/t = world.time
|
||||
#endif
|
||||
machine.process()
|
||||
#ifdef MACHINE_PROCESSING_DEBUG
|
||||
register_machine_time(machine, world.time - t)
|
||||
#endif
|
||||
|
||||
if (!(c++ % 100))
|
||||
scheck()
|
||||
|
||||
src.pipe_networks = global.pipe_networks
|
||||
for(var/datum/pipe_network/network in src.pipe_networks)
|
||||
#ifdef MACHINE_PROCESSING_DEBUG
|
||||
var/t = world.time
|
||||
#endif
|
||||
network.process()
|
||||
#ifdef MACHINE_PROCESSING_DEBUG
|
||||
register_machine_time(network, world.time - t)
|
||||
#endif
|
||||
if (!(c++ % 100))
|
||||
scheck()
|
||||
|
||||
src.powernets = global.powernets
|
||||
for(var/datum/powernet/PN in src.powernets)
|
||||
#ifdef MACHINE_PROCESSING_DEBUG
|
||||
var/t = world.time
|
||||
#endif
|
||||
PN.reset()
|
||||
#ifdef MACHINE_PROCESSING_DEBUG
|
||||
register_machine_time(PN, world.time - t)
|
||||
#endif
|
||||
if (!(c++ % 100))
|
||||
scheck()
|
||||
|
||||
src.machines = global.machines
|
||||
for(var/obj/machinery/machine in src.machines)
|
||||
#ifdef MACHINE_PROCESSING_DEBUG
|
||||
var/t = world.time
|
||||
#endif
|
||||
machine.process()
|
||||
#ifdef MACHINE_PROCESSING_DEBUG
|
||||
register_machine_time(machine, world.time - t)
|
||||
#endif
|
||||
if (!(c++ % 100))
|
||||
scheck()
|
||||
|
||||
|
||||
#ifdef MACHINE_PROCESSING_DEBUG
|
||||
proc/register_machine_time(var/datum/machine, var/time)
|
||||
if(!machine) return
|
||||
var/list/mtl = detailed_machine_timings[machine.type]
|
||||
if(!mtl)
|
||||
mtl = list()
|
||||
mtl.len = 2
|
||||
mtl[1] = 0 //The amount of time spent processing this machine in total
|
||||
mtl[2] = 0 //The amount of times this machine has been processed
|
||||
detailed_machine_timings[machine.type] = mtl
|
||||
|
||||
mtl[1] += time
|
||||
mtl[2]++
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
// handles critters
|
||||
datum/controller/process/mob_ai
|
||||
setup()
|
||||
name = "Mob AI"
|
||||
schedule_interval = 16 // 1.6 seconds
|
||||
|
||||
doWork()
|
||||
for(var/mob/living/carbon/human/H in mobs)
|
||||
H.ai_process()
|
||||
scheck()
|
||||
|
||||
/*var/currentTick = ticks
|
||||
for(var/obj/critter in critters)
|
||||
tick_counter = world.timeofday
|
||||
|
||||
critter:process()
|
||||
|
||||
tick_counter = world.timeofday - tick_counter
|
||||
if (critter && tick_counter > 0)
|
||||
detailed_count["[critter.type]"] += tick_counter
|
||||
|
||||
scheck(currentTick)*/
|
||||
@@ -0,0 +1,66 @@
|
||||
// handles mobs
|
||||
datum/controller/process/mobs
|
||||
var/tmp/list/detailed_count
|
||||
var/tmp/tick_counter
|
||||
var/list/mobs
|
||||
|
||||
var/list/living = list()
|
||||
var/list/wraiths = list()
|
||||
var/list/adminghosts = list()
|
||||
|
||||
setup()
|
||||
name = "Mob"
|
||||
schedule_interval = 20
|
||||
detailed_count = new
|
||||
src.mobs = global.mobs
|
||||
|
||||
copyStateFrom(var/datum/controller/process/mobs/other)
|
||||
detailed_count = other.detailed_count
|
||||
|
||||
doWork()
|
||||
var/currentTick = ticks
|
||||
|
||||
src.mobs = global.mobs
|
||||
var/c
|
||||
|
||||
for(var/mob/living/M in src.mobs)
|
||||
M.Life(src)
|
||||
if (!(c++ % 5))
|
||||
scheck(currentTick)
|
||||
|
||||
for(var/mob/wraith/W in src.mobs)
|
||||
W.Life(src)
|
||||
scheck(currentTick)
|
||||
|
||||
// For periodic antag overlay updates (Convair880).
|
||||
for (var/mob/dead/G in src.mobs)
|
||||
if (isadminghost(G))
|
||||
G:Life(src)
|
||||
scheck(currentTick)
|
||||
|
||||
/*
|
||||
for(var/mob/living/M in src.mobs)
|
||||
tick_counter = world.timeofday
|
||||
|
||||
M.Life(src)
|
||||
|
||||
tick_counter = world.timeofday - tick_counter
|
||||
if (M && tick_counter > 0)
|
||||
detailed_count["[M.type]-[M.name]"] += tick_counter
|
||||
|
||||
scheck(currentTick)
|
||||
|
||||
// a r g h
|
||||
for (var/mob/wraith/W in src.mobs)
|
||||
W.Life(src)
|
||||
scheck(currentTick)
|
||||
*/
|
||||
tickDetail()
|
||||
if (detailed_count && detailed_count.len)
|
||||
var/stats = "<b>[name] ticks:</b><br>"
|
||||
var/count
|
||||
for (var/thing in detailed_count)
|
||||
count = detailed_count[thing]
|
||||
if (count > 4)
|
||||
stats += "[thing] used [count] ticks.<br>"
|
||||
boutput(usr, "<br>[stats]")
|
||||
@@ -0,0 +1,17 @@
|
||||
datum/controller/process/networks
|
||||
var/tmp/datum/updateQueue/networkUpdateQueue
|
||||
|
||||
setup()
|
||||
name = "Networks"
|
||||
schedule_interval = 11
|
||||
networkUpdateQueue = new
|
||||
|
||||
doWork()
|
||||
for(var/datum/n in node_networks)
|
||||
n:update()
|
||||
scheck()
|
||||
/*
|
||||
var/currentTick = ticks
|
||||
for (var/datum/node_network/network in node_networks)
|
||||
network.update()
|
||||
scheck(currentTick)*/
|
||||
@@ -0,0 +1,18 @@
|
||||
datum/controller/process/particles
|
||||
var/datum/particleMaster/master
|
||||
|
||||
setup()
|
||||
name = "Particles"
|
||||
schedule_interval = 12
|
||||
|
||||
// putting this in a var so main loop varedit can get into the particleMaster
|
||||
master = particleMaster
|
||||
|
||||
doWork()
|
||||
// TODO roll the "loop" code from particleMaster back into this system
|
||||
master.Tick()
|
||||
|
||||
// regular timing doesn't really apply since particles abuse the shit out of spawn and sleep
|
||||
tickDetail()
|
||||
return "particle types: [master.particleTypes.len], particle systems: [master.particleSystems.len]<br>"
|
||||
|
||||
@@ -0,0 +1,317 @@
|
||||
// Process
|
||||
|
||||
/datum/controller/process
|
||||
/**
|
||||
* State vars
|
||||
*/
|
||||
// Main controller ref
|
||||
var/tmp/datum/controller/processScheduler/main
|
||||
|
||||
// 1 if process is not running or queued
|
||||
var/tmp/idle = 1
|
||||
|
||||
// 1 if process is queued
|
||||
var/tmp/queued = 0
|
||||
|
||||
// 1 if process is running
|
||||
var/tmp/running = 0
|
||||
|
||||
// 1 if process is blocked up
|
||||
var/tmp/hung = 0
|
||||
|
||||
// 1 if process was killed
|
||||
var/tmp/killed = 0
|
||||
|
||||
// Status text var
|
||||
var/tmp/status
|
||||
|
||||
// Previous status text var
|
||||
var/tmp/previousStatus
|
||||
|
||||
// 1 if process is disabled
|
||||
var/tmp/disabled = 0
|
||||
|
||||
/**
|
||||
* Config vars
|
||||
*/
|
||||
// Process name
|
||||
var/name
|
||||
|
||||
// Process schedule interval
|
||||
// This controls how often the process would run under ideal conditions.
|
||||
// If the process scheduler sees that the process has finished, it will wait until
|
||||
// this amount of time has elapsed from the start of the previous run to start the
|
||||
// process running again.
|
||||
var/tmp/schedule_interval = PROCESS_DEFAULT_SCHEDULE_INTERVAL // run every 50 ticks
|
||||
|
||||
// Process sleep interval
|
||||
// This controls how often the process will yield (call sleep(0)) while it is running.
|
||||
// Every concurrent process should sleep periodically while running in order to allow other
|
||||
// processes to execute concurrently.
|
||||
var/tmp/sleep_interval
|
||||
|
||||
// hang_warning_time - this is the time (in 1/10 seconds) after which the server will begin to show "maybe hung" in the context window
|
||||
var/tmp/hang_warning_time = PROCESS_DEFAULT_HANG_WARNING_TIME
|
||||
|
||||
// hang_alert_time - After this much time(in 1/10 seconds), the server will send an admin debug message saying the process may be hung
|
||||
var/tmp/hang_alert_time = PROCESS_DEFAULT_HANG_ALERT_TIME
|
||||
|
||||
// hang_restart_time - After this much time(in 1/10 seconds), the server will automatically kill and restart the process.
|
||||
var/tmp/hang_restart_time = PROCESS_DEFAULT_HANG_RESTART_TIME
|
||||
|
||||
// cpu_threshold - if world.cpu >= cpu_threshold, scheck() will call sleep(1) to defer further work until the next tick. This keeps a process from driving a tick into overtime (causing perceptible lag)
|
||||
var/tmp/cpu_threshold = PROCESS_DEFAULT_CPU_THRESHOLD
|
||||
|
||||
// How many times in the current run has the process deferred work till the next tick?
|
||||
var/tmp/cpu_defer_count = 0
|
||||
|
||||
/**
|
||||
* recordkeeping vars
|
||||
*/
|
||||
|
||||
// Records the time (1/10s timeofday) at which the process last finished sleeping
|
||||
var/tmp/last_slept = 0
|
||||
|
||||
// Records the time (1/10s timeofday) at which the process last began running
|
||||
var/tmp/run_start = 0
|
||||
|
||||
// Records the number of times this process has been killed and restarted
|
||||
var/tmp/times_killed
|
||||
|
||||
// Tick count
|
||||
var/tmp/ticks = 0
|
||||
|
||||
var/tmp/last_task = ""
|
||||
|
||||
var/tmp/last_object
|
||||
|
||||
datum/controller/process/New(var/datum/controller/processScheduler/scheduler)
|
||||
..()
|
||||
main = scheduler
|
||||
previousStatus = "idle"
|
||||
idle()
|
||||
name = "process"
|
||||
schedule_interval = 50
|
||||
sleep_interval = world.tick_lag / PROCESS_DEFAULT_SLEEP_INTERVAL
|
||||
last_slept = 0
|
||||
run_start = 0
|
||||
ticks = 0
|
||||
last_task = 0
|
||||
last_object = null
|
||||
|
||||
datum/controller/process/proc/started()
|
||||
// Initialize last_slept so we can know when to sleep
|
||||
last_slept = TimeOfHour
|
||||
|
||||
// Initialize run_start so we can detect hung processes.
|
||||
run_start = TimeOfHour
|
||||
|
||||
// Initialize defer count
|
||||
cpu_defer_count = 0
|
||||
|
||||
running()
|
||||
main.processStarted(src)
|
||||
|
||||
onStart()
|
||||
|
||||
datum/controller/process/proc/finished()
|
||||
ticks++
|
||||
idle()
|
||||
main.processFinished(src)
|
||||
|
||||
onFinish()
|
||||
|
||||
datum/controller/process/proc/doWork()
|
||||
|
||||
datum/controller/process/proc/setup()
|
||||
|
||||
datum/controller/process/proc/process()
|
||||
started()
|
||||
doWork()
|
||||
finished()
|
||||
|
||||
datum/controller/process/proc/running()
|
||||
idle = 0
|
||||
queued = 0
|
||||
running = 1
|
||||
hung = 0
|
||||
setStatus(PROCESS_STATUS_RUNNING)
|
||||
|
||||
datum/controller/process/proc/idle()
|
||||
queued = 0
|
||||
running = 0
|
||||
idle = 1
|
||||
hung = 0
|
||||
setStatus(PROCESS_STATUS_IDLE)
|
||||
|
||||
datum/controller/process/proc/queued()
|
||||
idle = 0
|
||||
running = 0
|
||||
queued = 1
|
||||
hung = 0
|
||||
setStatus(PROCESS_STATUS_QUEUED)
|
||||
|
||||
datum/controller/process/proc/hung()
|
||||
hung = 1
|
||||
setStatus(PROCESS_STATUS_HUNG)
|
||||
|
||||
datum/controller/process/proc/handleHung()
|
||||
var/datum/lastObj = last_object
|
||||
var/lastObjType = "null"
|
||||
if(istype(lastObj))
|
||||
lastObjType = lastObj.type
|
||||
|
||||
// If world.timeofday has rolled over, then we need to adjust.
|
||||
if (TimeOfHour < run_start)
|
||||
run_start -= 36000
|
||||
var/msg = "[name] process hung at tick #[ticks]. Process was unresponsive for [(TimeOfHour - run_start) / 10] seconds and was restarted. Last task: [last_task]. Last Object Type: [lastObjType]"
|
||||
logTheThing("debug", null, null, msg)
|
||||
logTheThing("diary", null, null, msg, "debug")
|
||||
message_admins(msg)
|
||||
|
||||
main.restartProcess(src.name)
|
||||
|
||||
datum/controller/process/proc/kill()
|
||||
if (!killed)
|
||||
var/msg = "[name] process was killed at tick #[ticks]."
|
||||
logTheThing("debug", null, null, msg)
|
||||
logTheThing("diary", null, null, msg, "debug")
|
||||
//finished()
|
||||
|
||||
// Allow inheritors to clean up if needed
|
||||
onKill()
|
||||
|
||||
// This should del
|
||||
del(src)
|
||||
|
||||
datum/controller/process/proc/scheck(var/tickId = 0)
|
||||
if (killed)
|
||||
// The kill proc is the only place where killed is set.
|
||||
// The kill proc should have deleted this datum, and all sleeping procs that are
|
||||
// owned by it.
|
||||
CRASH("A killed process is still running somehow...")
|
||||
if (hung)
|
||||
// This will only really help if the doWork proc ends up in an infinite loop.
|
||||
handleHung()
|
||||
CRASH("Process [name] hung and was restarted.")
|
||||
|
||||
// For each tick the process defers, it increments the cpu_defer_count so we don't
|
||||
// defer indefinitely
|
||||
if (main.getCurrentTickElapsedTime() > main.timeAllowance)
|
||||
sleep(world.tick_lag*1)
|
||||
cpu_defer_count++
|
||||
last_slept = TimeOfHour
|
||||
else
|
||||
var/t = TimeOfHour
|
||||
// If world.timeofday has rolled over, then we need to adjust.
|
||||
if (t < last_slept)
|
||||
last_slept -= 36000
|
||||
|
||||
if (t > last_slept + sleep_interval)
|
||||
// If we haven't slept in sleep_interval deciseconds, sleep to allow other work to proceed.
|
||||
sleep(0)
|
||||
last_slept = TimeOfHour
|
||||
|
||||
datum/controller/process/proc/update()
|
||||
// Clear delta
|
||||
if(previousStatus != status)
|
||||
setStatus(status)
|
||||
|
||||
var/elapsedTime = getElapsedTime()
|
||||
|
||||
if (hung)
|
||||
handleHung()
|
||||
return
|
||||
else if (elapsedTime > hang_restart_time)
|
||||
hung()
|
||||
else if (elapsedTime > hang_alert_time)
|
||||
setStatus(PROCESS_STATUS_PROBABLY_HUNG)
|
||||
else if (elapsedTime > hang_warning_time)
|
||||
setStatus(PROCESS_STATUS_MAYBE_HUNG)
|
||||
|
||||
|
||||
datum/controller/process/proc/getElapsedTime()
|
||||
if (TimeOfHour < run_start)
|
||||
return TimeOfHour - (run_start - 36000)
|
||||
return TimeOfHour - run_start
|
||||
|
||||
datum/controller/process/proc/tickDetail()
|
||||
return
|
||||
|
||||
datum/controller/process/proc/getContext()
|
||||
return "<tr><td>[name]</td><td>[main.averageRunTime(src)]</td><td>[main.last_run_time[src]]</td><td>[main.highest_run_time[src]]</td><td>[ticks]</td></tr>\n"
|
||||
|
||||
datum/controller/process/proc/getContextData()
|
||||
return list(
|
||||
"name" = name,
|
||||
"averageRunTime" = main.averageRunTime(src),
|
||||
"lastRunTime" = main.last_run_time[src],
|
||||
"highestRunTime" = main.highest_run_time[src],
|
||||
"ticks" = ticks,
|
||||
"schedule" = schedule_interval,
|
||||
"status" = getStatusText(),
|
||||
"disabled" = disabled
|
||||
)
|
||||
|
||||
datum/controller/process/proc/getStatus()
|
||||
return status
|
||||
|
||||
datum/controller/process/proc/getStatusText(var/s = 0)
|
||||
if(!s)
|
||||
s = status
|
||||
switch(s)
|
||||
if(PROCESS_STATUS_IDLE)
|
||||
return "idle"
|
||||
if(PROCESS_STATUS_QUEUED)
|
||||
return "queued"
|
||||
if(PROCESS_STATUS_RUNNING)
|
||||
return "running"
|
||||
if(PROCESS_STATUS_MAYBE_HUNG)
|
||||
return "maybe hung"
|
||||
if(PROCESS_STATUS_PROBABLY_HUNG)
|
||||
return "probably hung"
|
||||
if(PROCESS_STATUS_HUNG)
|
||||
return "HUNG"
|
||||
else
|
||||
return "UNKNOWN"
|
||||
|
||||
datum/controller/process/proc/getPreviousStatus()
|
||||
return previousStatus
|
||||
|
||||
datum/controller/process/proc/getPreviousStatusText()
|
||||
return getStatusText(previousStatus)
|
||||
|
||||
datum/controller/process/proc/setStatus(var/newStatus)
|
||||
previousStatus = status
|
||||
status = newStatus
|
||||
|
||||
datum/controller/process/proc/setLastTask(var/task, var/object)
|
||||
last_task = task
|
||||
last_object = object
|
||||
|
||||
datum/controller/process/proc/_copyStateFrom(var/datum/controller/process/target)
|
||||
main = target.main
|
||||
name = target.name
|
||||
schedule_interval = target.schedule_interval
|
||||
sleep_interval = target.sleep_interval
|
||||
last_slept = 0
|
||||
run_start = 0
|
||||
times_killed = target.times_killed
|
||||
ticks = target.ticks
|
||||
last_task = target.last_task
|
||||
last_object = target.last_object
|
||||
copyStateFrom(target)
|
||||
|
||||
datum/controller/process/proc/copyStateFrom(var/datum/controller/process/target)
|
||||
|
||||
datum/controller/process/proc/onKill()
|
||||
|
||||
datum/controller/process/proc/onStart()
|
||||
|
||||
datum/controller/process/proc/onFinish()
|
||||
|
||||
datum/controller/process/proc/disable()
|
||||
disabled = 1
|
||||
|
||||
datum/controller/process/proc/enable()
|
||||
disabled = 0
|
||||
@@ -0,0 +1,14 @@
|
||||
datum/controller/process/railway
|
||||
var/tmp/list/vehicles
|
||||
|
||||
setup()
|
||||
name = "Railways"
|
||||
schedule_interval = 5
|
||||
vehicles = global.railway_vehicles
|
||||
|
||||
doWork()
|
||||
var/c
|
||||
for(var/obj/railway_vehicle/v in global.railway_vehicles)
|
||||
v.process()
|
||||
if (!(c++ % 10))
|
||||
scheck()
|
||||
@@ -0,0 +1,19 @@
|
||||
// handles only materials research right now.
|
||||
datum/controller/process/research
|
||||
var/datum/materialResearchHolder/researchMaster
|
||||
|
||||
setup()
|
||||
name = "Research"
|
||||
schedule_interval = 10
|
||||
researchMaster = materialsResearch
|
||||
|
||||
doWork()
|
||||
researchMaster = materialsResearch
|
||||
if(researchMaster)
|
||||
for(var/x in researchMaster.research)
|
||||
var/datum/materialResearch/R = researchMaster.research[x]
|
||||
if(!R.completed)
|
||||
R.process()
|
||||
if(R.completed)
|
||||
researchMaster.completed.Add(R.id)
|
||||
researchMaster.completed[R.id] = R
|
||||
@@ -0,0 +1,9 @@
|
||||
/datum/controller/process/stock_market
|
||||
setup()
|
||||
name = "Stock Market"
|
||||
schedule_interval = 15
|
||||
|
||||
doWork()
|
||||
if (stockExchange)
|
||||
stockExchange.process()
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// handles telescope signals and whatnot
|
||||
datum/controller/process/telescope
|
||||
var/datum/telescope_manager/manager
|
||||
|
||||
setup()
|
||||
name = "Telescope"
|
||||
schedule_interval = 100
|
||||
|
||||
doWork()
|
||||
if(tele_man)
|
||||
if(!manager) manager = tele_man
|
||||
tele_man.tick()
|
||||
@@ -0,0 +1,14 @@
|
||||
// handles the game ticker
|
||||
datum/controller/process/ticker
|
||||
setup()
|
||||
name = "Game"
|
||||
schedule_interval = 5
|
||||
|
||||
if(!ticker)
|
||||
ticker = new /datum/controller/gameticker()
|
||||
|
||||
// start the pregame process
|
||||
spawn(1)
|
||||
ticker.pregame()
|
||||
doWork()
|
||||
ticker.process()
|
||||
@@ -0,0 +1,29 @@
|
||||
// handles various global init and the position of the sun.
|
||||
datum/controller/process/world
|
||||
var/shuttle
|
||||
|
||||
setup()
|
||||
name = "World"
|
||||
schedule_interval = 23
|
||||
|
||||
setupgenetics()
|
||||
if(genResearch) genResearch.setup()
|
||||
|
||||
setup_radiocodes()
|
||||
|
||||
emergency_shuttle = new /datum/shuttle_controller/emergency_shuttle()
|
||||
src.shuttle = emergency_shuttle
|
||||
|
||||
generate_access_name_lookup()
|
||||
|
||||
doWork()
|
||||
sun.calc_position()
|
||||
|
||||
if(genResearch) genResearch.progress()
|
||||
|
||||
for (var/byondkey in muted_keys)
|
||||
var/value = muted_keys[byondkey]
|
||||
if (value > 1)
|
||||
muted_keys[byondkey] = value - 1
|
||||
else if (value == 1 || value == 0)
|
||||
muted_keys -= byondkey
|
||||
Reference in New Issue
Block a user