mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-23 08:31:57 +00:00
* My heart is dragging me down into... ...oblivion! * drifting closer to the edge but she won't have me * ever round me we are dead before we meet her * for the last time * wake up in sweat * n * fff * uff --------- Co-authored-by: Matt Atlas <liermattia@gmail.com>
205 lines
5.8 KiB
Plaintext
205 lines
5.8 KiB
Plaintext
#define SUBSYSTEM_INIT_SOURCE "subsystem init"
|
|
|
|
#define BAD_INIT_QDEL_BEFORE 1
|
|
#define BAD_INIT_DIDNT_INIT 2
|
|
#define BAD_INIT_SLEPT 4
|
|
#define BAD_INIT_NO_HINT 8
|
|
|
|
SUBSYSTEM_DEF(atoms)
|
|
name = "Atoms"
|
|
init_order = SS_INIT_ATOMS
|
|
flags = SS_NO_FIRE
|
|
|
|
/// A stack of list(source, desired initialized state)
|
|
/// We read the source of init changes from the last entry, and assert that all changes will come with a reset
|
|
var/list/initialized_state = list()
|
|
var/base_initialized
|
|
|
|
var/initialized = INITIALIZATION_INSSATOMS
|
|
var/old_initialized
|
|
|
|
var/list/late_misc_firers // this is a list of things that fire when late misc init is called
|
|
|
|
var/list/late_loaders
|
|
var/list/created_atoms
|
|
var/list/late_qdel
|
|
|
|
var/list/BadInitializeCalls = list()
|
|
|
|
/datum/controller/subsystem/atoms/Initialize(timeofday)
|
|
initialized = INITIALIZATION_INNEW_MAPLOAD
|
|
InitializeAtoms()
|
|
initialized = INITIALIZATION_INNEW_REGULAR
|
|
return ..()
|
|
|
|
/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms)
|
|
if(initialized == INITIALIZATION_INSSATOMS)
|
|
return
|
|
|
|
set_tracked_initalized(INITIALIZATION_INNEW_MAPLOAD, SUBSYSTEM_INIT_SOURCE)
|
|
|
|
LAZYINITLIST(late_loaders)
|
|
LAZYINITLIST(late_qdel)
|
|
|
|
var/count
|
|
var/list/mapload_arg = list(TRUE)
|
|
if(atoms)
|
|
created_atoms = list()
|
|
count = atoms.len
|
|
for(var/I in 1 to atoms.len)
|
|
var/atom/A = atoms[I]
|
|
InitAtom(A, mapload_arg)
|
|
CHECK_TICK
|
|
else
|
|
count = 0
|
|
for(var/atom/A as anything in world)
|
|
if(!A.initialized)
|
|
InitAtom(A, mapload_arg)
|
|
++count
|
|
CHECK_TICK
|
|
|
|
admin_notice(SPAN_DANGER("Initialized [count] atoms."), R_DEBUG)
|
|
log_subsystem("atoms", "Initialized [count] atoms.")
|
|
|
|
clear_tracked_initalize(SUBSYSTEM_INIT_SOURCE)
|
|
|
|
if(late_loaders.len)
|
|
for(var/I in 1 to late_loaders.len)
|
|
var/atom/A = late_loaders[I]
|
|
if(QDELETED(A))
|
|
continue
|
|
A.LateInitialize()
|
|
admin_notice(SPAN_DANGER("Late-initialized [late_loaders.len] atoms."), R_DEBUG)
|
|
log_subsystem("atoms", "Late initialized [late_loaders.len] atoms")
|
|
late_loaders.Cut()
|
|
|
|
if(late_qdel.len)
|
|
var/num_qdels = late_qdel.len
|
|
for(var/thing in late_qdel)
|
|
qdel(thing)
|
|
|
|
admin_notice(SPAN_DANGER("Late-qdeleted [num_qdels] atoms."), R_DEBUG)
|
|
log_subsystem("atoms", "Late qdeleted [num_qdels] atoms.")
|
|
|
|
late_qdel.Cut()
|
|
|
|
if(atoms)
|
|
. = created_atoms + atoms
|
|
created_atoms = null
|
|
// Note this doesn't actually do anything because we didn't finish porting TG init :^)
|
|
|
|
/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments)
|
|
var/the_type = A.type
|
|
if(QDELING(A))
|
|
BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE
|
|
return TRUE
|
|
|
|
var/start_tick = world.time
|
|
|
|
var/result = A.Initialize(arglist(arguments))
|
|
|
|
if(start_tick != world.time)
|
|
BadInitializeCalls[the_type] |= BAD_INIT_SLEPT
|
|
|
|
if(result !=INITIALIZE_HINT_NORMAL)
|
|
switch(result)
|
|
if(INITIALIZE_HINT_LATELOAD)
|
|
if(arguments[1]) //mapload
|
|
late_loaders += A
|
|
else
|
|
A.LateInitialize()
|
|
if(INITIALIZE_HINT_QDEL)
|
|
qdel(A)
|
|
return TRUE
|
|
if(INITIALIZE_HINT_LATEQDEL)
|
|
if(arguments[1]) //mapload
|
|
late_qdel += A
|
|
else
|
|
qdel(A)
|
|
return TRUE
|
|
else
|
|
BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT
|
|
|
|
if(!A) //possible harddel
|
|
return TRUE
|
|
else if(!A.initialized)
|
|
BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT
|
|
|
|
return QDELETED(A)
|
|
|
|
/datum/controller/subsystem/atoms/proc/ForceInitializeContents(atom/A)
|
|
var/list/mload_args = list(TRUE)
|
|
var/loaded = 0
|
|
|
|
set_tracked_initalized(INITIALIZATION_INNEW_MAPLOAD, SUBSYSTEM_INIT_SOURCE+"- ForceInitializeContents: [text_ref(A)]")
|
|
|
|
for (var/thing in A)
|
|
var/atom/movable/AM = thing
|
|
if (!AM.initialized)
|
|
InitAtom(AM, mload_args)
|
|
++loaded
|
|
|
|
clear_tracked_initalize(SUBSYSTEM_INIT_SOURCE+"- ForceInitializeContents: [text_ref(A)]")
|
|
|
|
LOG_DEBUG("atoms: force-loaded [loaded] out of [A.contents.len] atoms in [A].")
|
|
|
|
/datum/controller/subsystem/atoms/proc/InitLog()
|
|
. = ""
|
|
for(var/path in BadInitializeCalls)
|
|
. += "Path : [path] \n"
|
|
var/fails = BadInitializeCalls[path]
|
|
if(fails & BAD_INIT_DIDNT_INIT)
|
|
. += "- Didn't call atom/Initialize()\n"
|
|
if(fails & BAD_INIT_NO_HINT)
|
|
. += "- Didn't return an Initialize hint\n"
|
|
if(fails & BAD_INIT_QDEL_BEFORE)
|
|
. += "- Qdel'd in New()\n"
|
|
if(fails & BAD_INIT_SLEPT)
|
|
. += "- Slept during Initialize()\n"
|
|
|
|
/*datum/controller/subsystem/atoms/Shutdown()
|
|
var/initlog = InitLog()
|
|
if(initlog)
|
|
world.log << initlog*/
|
|
|
|
/datum/controller/subsystem/atoms/Recover()
|
|
initialized = SSatoms.initialized
|
|
if(initialized == INITIALIZATION_INNEW_MAPLOAD)
|
|
InitializeAtoms()
|
|
initialized_state = SSatoms.initialized_state
|
|
BadInitializeCalls = SSatoms.BadInitializeCalls
|
|
|
|
/datum/controller/subsystem/atoms/proc/map_loader_begin(source)
|
|
set_tracked_initalized(INITIALIZATION_INSSATOMS, source)
|
|
|
|
/datum/controller/subsystem/atoms/proc/map_loader_stop(source)
|
|
clear_tracked_initalize(source)
|
|
|
|
/// Use this to set initialized to prevent error states where the old initialized is overriden, and we end up losing all context
|
|
/// Accepts a state and a source, the most recent state is used, sources exist to prevent overriding old values accidentially
|
|
/datum/controller/subsystem/atoms/proc/set_tracked_initalized(state, source)
|
|
if(!length(initialized_state))
|
|
base_initialized = initialized
|
|
initialized_state += list(list(source, state))
|
|
initialized = state
|
|
|
|
/datum/controller/subsystem/atoms/proc/clear_tracked_initalize(source)
|
|
if(!length(initialized_state))
|
|
return
|
|
for(var/i in length(initialized_state) to 1 step -1)
|
|
if(initialized_state[i][1] == source)
|
|
initialized_state.Cut(i, i+1)
|
|
break
|
|
|
|
if(!length(initialized_state))
|
|
initialized = base_initialized
|
|
base_initialized = INITIALIZATION_INNEW_REGULAR
|
|
return
|
|
initialized = initialized_state[length(initialized_state)][2]
|
|
|
|
/// Returns TRUE if anything is currently being initialized
|
|
/datum/controller/subsystem/atoms/proc/initializing_something()
|
|
return length(initialized_state) > 1
|
|
|
|
#undef SUBSYSTEM_INIT_SOURCE
|