Initial Commit

This commit is contained in:
Tobba
2016-03-06 20:52:14 +01:00
commit b181d0b552
4325 changed files with 579453 additions and 0 deletions
@@ -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)
+16
View File
@@ -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.")
+39
View File
@@ -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)")
+44
View File
@@ -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
+22
View File
@@ -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)*/
+66
View File
@@ -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>"
+317
View File
@@ -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()
+14
View File
@@ -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()
+29
View File
@@ -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