mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
* Adds grep for mapload and var in Args * vars in args * some more * stuff * Update shuttle_creator.dm * Update __techweb_helpers.dm * fix * Update discoball.dm * Update check_grep.sh * Update check_grep.sh * Update check_grep.sh * Update check_grep.sh * I'll finish this later * datum and lateinit maploads * componentinit stuff * mapload fixes * why isnt CI catching these major issues * MERGE CONFLICT FUCKED MY PR OVER * Update check_grep.sh * Update food.dm
220 lines
6.2 KiB
Plaintext
220 lines
6.2 KiB
Plaintext
#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 = INIT_ORDER_ATOMS
|
|
flags = SS_NO_FIRE
|
|
loading_points = 30 SECONDS // Yogs -- smarter loading times
|
|
|
|
var/old_initialized
|
|
/// A count of how many initalize changes we've made. We want to prevent old_initialize being overriden by some other value, breaking init code
|
|
var/initialized_changed = 0
|
|
|
|
var/list/late_loaders = list()
|
|
|
|
var/list/BadInitializeCalls = list()
|
|
|
|
var/init_start_time
|
|
|
|
/// Atoms that will be deleted once the subsystem is initialized
|
|
var/list/queued_deletions = list()
|
|
|
|
initialized = INITIALIZATION_INSSATOMS
|
|
|
|
/datum/controller/subsystem/atoms/Initialize(timeofday)
|
|
init_start_time = world.time
|
|
GLOB.fire_overlay.appearance_flags = RESET_COLOR
|
|
setupGenetics() //to set the mutations' sequence
|
|
|
|
initialized = INITIALIZATION_INNEW_MAPLOAD
|
|
InitializeAtoms()
|
|
initialized = INITIALIZATION_INNEW_REGULAR
|
|
|
|
return SS_INIT_SUCCESS
|
|
|
|
/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms)
|
|
if(initialized == INITIALIZATION_INSSATOMS)
|
|
return
|
|
|
|
set_tracked_initalized(INITIALIZATION_INNEW_MAPLOAD)
|
|
|
|
// This may look a bit odd, but if the actual atom creation runtimes for some reason, we absolutely need to set initialized BACK
|
|
CreateAtoms(atoms)
|
|
clear_tracked_initalize()
|
|
|
|
if(late_loaders.len)
|
|
for(var/I in 1 to late_loaders.len)
|
|
var/atom/A = late_loaders[I]
|
|
//I hate that we need this
|
|
if(QDELETED(A))
|
|
continue
|
|
A.LateInitialize()
|
|
testing("Late initialized [late_loaders.len] atoms")
|
|
late_loaders.Cut()
|
|
|
|
for (var/queued_deletion in queued_deletions)
|
|
qdel(queued_deletion)
|
|
|
|
testing("[queued_deletions.len] atoms were queued for deletion.")
|
|
queued_deletions.Cut()
|
|
|
|
/// Actually creates the list of atoms. Exists soley so a runtime in the creation logic doesn't cause initalized to totally break
|
|
/datum/controller/subsystem/atoms/proc/CreateAtoms(list/atoms)
|
|
#ifdef TESTING
|
|
var/count
|
|
#endif
|
|
|
|
var/list/mapload_arg = list(TRUE)
|
|
|
|
if(atoms)
|
|
#ifdef TESTING
|
|
count = atoms.len
|
|
#endif
|
|
|
|
for(var/I in 1 to atoms.len)
|
|
var/atom/A = atoms[I]
|
|
if(!(A.flags_1 & INITIALIZED_1))
|
|
CHECK_TICK
|
|
InitAtom(A, mapload_arg)
|
|
else
|
|
#ifdef TESTING
|
|
count = 0
|
|
#endif
|
|
|
|
for(var/atom/A as anything in world)
|
|
if(!(A.flags_1 & INITIALIZED_1))
|
|
InitAtom(A, mapload_arg)
|
|
#ifdef TESTING
|
|
++count
|
|
#endif
|
|
CHECK_TICK
|
|
|
|
testing("Initialized [count] atoms")
|
|
|
|
/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments)
|
|
var/the_type = A.type
|
|
if(QDELING(A))
|
|
// Check init_start_time to not worry about atoms created before the atoms SS that are cleaned up before this
|
|
if (A.gc_destroyed > init_start_time)
|
|
BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE
|
|
return TRUE
|
|
|
|
#ifdef UNIT_TESTS
|
|
var/start_tick = world.time
|
|
#endif
|
|
|
|
var/result = A.Initialize(arglist(arguments))
|
|
|
|
#ifdef UNIT_TESTS
|
|
if(start_tick != world.time)
|
|
BadInitializeCalls[the_type] |= BAD_INIT_SLEPT
|
|
#endif
|
|
|
|
var/qdeleted = FALSE
|
|
|
|
switch(result)
|
|
if (INITIALIZE_HINT_NORMAL)
|
|
// pass
|
|
if (INITIALIZE_HINT_LATELOAD)
|
|
if(arguments[1]) //mapload
|
|
late_loaders += A
|
|
else
|
|
A.LateInitialize()
|
|
if (INITIALIZE_HINT_QDEL)
|
|
qdel(A)
|
|
qdeleted = TRUE
|
|
else
|
|
BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT
|
|
|
|
if(!A) //possible harddel
|
|
qdeleted = TRUE
|
|
else if(!(A.flags_1 & INITIALIZED_1))
|
|
BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT
|
|
|
|
return qdeleted || QDELING(A)
|
|
|
|
/datum/controller/subsystem/atoms/proc/map_loader_begin()
|
|
set_tracked_initalized(INITIALIZATION_INSSATOMS)
|
|
|
|
/datum/controller/subsystem/atoms/proc/map_loader_stop()
|
|
clear_tracked_initalize()
|
|
|
|
/// Use this to set initialized to prevent error states where old_initialized is overriden. It keeps happening and it's cheesing me off
|
|
/datum/controller/subsystem/atoms/proc/set_tracked_initalized(value)
|
|
if(!initialized_changed)
|
|
old_initialized = initialized
|
|
initialized = value
|
|
else
|
|
stack_trace("We started maploading while we were already maploading. You doing something odd?")
|
|
initialized_changed += 1
|
|
|
|
/datum/controller/subsystem/atoms/proc/clear_tracked_initalize()
|
|
initialized_changed -= 1
|
|
if(!initialized_changed)
|
|
initialized = old_initialized
|
|
|
|
/datum/controller/subsystem/atoms/Recover()
|
|
initialized = SSatoms.initialized
|
|
if(initialized == INITIALIZATION_INNEW_MAPLOAD)
|
|
InitializeAtoms()
|
|
old_initialized = SSatoms.old_initialized
|
|
BadInitializeCalls = SSatoms.BadInitializeCalls
|
|
|
|
/datum/controller/subsystem/atoms/proc/setupGenetics()
|
|
var/list/mutations = subtypesof(/datum/mutation/human)
|
|
shuffle_inplace(mutations)
|
|
for(var/A in subtypesof(/datum/generecipe))
|
|
var/datum/generecipe/GR = A
|
|
GLOB.mutation_recipes[initial(GR.required)] = initial(GR.result)
|
|
for(var/i in 1 to LAZYLEN(mutations))
|
|
var/path = mutations[i] //byond gets pissy when we do it in one line
|
|
var/datum/mutation/human/B = new path ()
|
|
B.alias = "Mutation [i]"
|
|
GLOB.all_mutations[B.type] = B
|
|
GLOB.full_sequences[B.type] = generate_gene_sequence(B.blocks)
|
|
GLOB.alias_mutations[B.alias] = B.type
|
|
if(B.locked)
|
|
continue
|
|
if(B.quality == POSITIVE)
|
|
GLOB.good_mutations |= B
|
|
else if(B.quality == NEGATIVE)
|
|
GLOB.bad_mutations |= B
|
|
else if(B.quality == MINOR_NEGATIVE)
|
|
GLOB.not_good_mutations |= B
|
|
CHECK_TICK
|
|
|
|
/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(mapload)\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(mapload)\n"
|
|
|
|
/// Prepares an atom to be deleted once the atoms SS is initialized.
|
|
/datum/controller/subsystem/atoms/proc/prepare_deletion(atom/target)
|
|
if (initialized == INITIALIZATION_INNEW_REGULAR)
|
|
// Atoms SS has already completed, just kill it now.
|
|
qdel(target)
|
|
else
|
|
queued_deletions += WEAKREF(target)
|
|
|
|
/datum/controller/subsystem/atoms/Shutdown()
|
|
var/initlog = InitLog()
|
|
if(initlog)
|
|
text2file(initlog, "[GLOB.log_directory]/initialize.log")
|
|
|
|
#undef BAD_INIT_QDEL_BEFORE
|
|
#undef BAD_INIT_DIDNT_INIT
|
|
#undef BAD_INIT_SLEPT
|
|
#undef BAD_INIT_NO_HINT
|