diff --git a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm index 13a6befbd04..63fe801d7b0 100644 --- a/code/controllers/subsystem/atoms.dm +++ b/code/controllers/subsystem/atoms.dm @@ -1,11 +1,13 @@ +#define SUBSYSTEM_INIT_SOURCE "subsystem init" SUBSYSTEM_DEF(atoms) name = "Atoms" init_order = INIT_ORDER_ATOMS flags = SS_NO_FIRE - 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 + /// 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/list/late_loaders = list() @@ -39,11 +41,11 @@ SUBSYSTEM_DEF(atoms) if(initialized == INITIALIZATION_INSSATOMS) return - set_tracked_initalized(INITIALIZATION_INNEW_MAPLOAD) + set_tracked_initalized(INITIALIZATION_INNEW_MAPLOAD, SUBSYSTEM_INIT_SOURCE) // 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, atoms_to_return) - clear_tracked_initalize() + clear_tracked_initalize(SUBSYSTEM_INIT_SOURCE) if(late_loaders.len) for(var/I in 1 to late_loaders.len) @@ -158,35 +160,41 @@ SUBSYSTEM_DEF(atoms) return qdeleted || QDELING(A) -/datum/controller/subsystem/atoms/proc/map_loader_begin() - set_tracked_initalized(INITIALIZATION_INSSATOMS) +/datum/controller/subsystem/atoms/proc/map_loader_begin(source) + set_tracked_initalized(INITIALIZATION_INSSATOMS, source) -/datum/controller/subsystem/atoms/proc/map_loader_stop() - clear_tracked_initalize() +/datum/controller/subsystem/atoms/proc/map_loader_stop(source) + clear_tracked_initalize(source) -/// 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 +/// 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() - initialized_changed -= 1 - if(!initialized_changed) - initialized = old_initialized +/datum/controller/subsystem/atoms/proc/clear_tracked_initalize(source) + for(var/i in length(initialized_state) to 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 initialized_changed > 0 + return length(initialized_state) > 1 /datum/controller/subsystem/atoms/Recover() initialized = SSatoms.initialized if(initialized == INITIALIZATION_INNEW_MAPLOAD) InitializeAtoms() - old_initialized = SSatoms.old_initialized + initialized_state = SSatoms.initialized_state BadInitializeCalls = SSatoms.BadInitializeCalls /datum/controller/subsystem/atoms/proc/setupGenetics() @@ -238,3 +246,5 @@ SUBSYSTEM_DEF(atoms) var/initlog = InitLog() if(initlog) text2file(initlog, "[GLOB.log_directory]/initialize.log") + +#undef SUBSYSTEM_INIT_SOURCE diff --git a/code/modules/mapping/reader.dm b/code/modules/mapping/reader.dm index 33d545f551a..d620ddfb69a 100644 --- a/code/modules/mapping/reader.dm +++ b/code/modules/mapping/reader.dm @@ -249,9 +249,9 @@ #define MAPLOADING_CHECK_TICK \ if(TICK_CHECK) { \ - SSatoms.map_loader_stop(); \ + SSatoms.map_loader_stop(REF(src)); \ stoplag(); \ - SSatoms.map_loader_begin(); \ + SSatoms.map_loader_begin(REF(src)); \ } // Do not call except via load() above. @@ -259,7 +259,7 @@ PRIVATE_PROC(TRUE) // Tell ss atoms that we're doing maploading // We'll have to account for this in the following tick_checks so it doesn't overflow - SSatoms.map_loader_begin() + SSatoms.map_loader_begin(REF(src)) // Loading used to be done in this proc // We make the assumption that if the inner procs runtime, we WANT to do cleanup on them, but we should stil tell our parents we failed @@ -272,7 +272,7 @@ sucessful = _dmm_load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z) // And we are done lads, call it off - SSatoms.map_loader_stop() + SSatoms.map_loader_stop(REF(src)) if(new_z) for(var/z_index in bounds[MAP_MINZ] to bounds[MAP_MAXZ]) @@ -409,7 +409,7 @@ var/list/cache = modelCache[gset.gridLines[i]] if(!cache) - SSatoms.map_loader_stop() + SSatoms.map_loader_stop(REF(src)) CRASH("Undefined model key in DMM: [gset.gridLines[i]]") build_coordinate(cache, locate(true_xcrd, ycrd, zcrd), no_afterchange, placeOnTop, new_z) @@ -542,7 +542,7 @@ continue var/list/cache = modelCache[model_key] if(!cache) - SSatoms.map_loader_stop() + SSatoms.map_loader_stop(REF(src)) CRASH("Undefined model key in DMM: [model_key]") build_coordinate(cache, locate(xcrd, ycrd, zcrd), no_afterchange, placeOnTop, new_z) @@ -956,6 +956,7 @@ GLOBAL_LIST_EMPTY(map_model_default) /datum/parsed_map/Destroy() ..() + SSatoms.map_loader_stop(REF(src)) // Just in case, I don't want to double up here if(turf_blacklist) turf_blacklist.Cut() parsed_bounds.Cut()