diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index 1c9c33f21a..f7b0f726d3 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -58,3 +58,4 @@ GLOBAL_VAR_INIT(cmp_field, "name") . = B.failures - A.failures if (!.) . = B.qdels - A.qdels + diff --git a/code/_compile_options.dm b/code/_compile_options.dm index 1c1ad2e692..1f20614c17 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -5,8 +5,10 @@ #ifdef TESTING //#define GC_FAILURE_HARD_LOOKUP //makes paths that fail to GC call find_references before del'ing. - //Also allows for recursive reference searching of datums. - //Sets world.loop_checks to false and prevents find references from sleeping + //implies FIND_REF_NO_CHECK_TICK + +//#define FIND_REF_NO_CHECK_TICK //Sets world.loop_checks to false and prevents find references from sleeping + //#define VISUALIZE_ACTIVE_TURFS //Highlights atmos active turfs in green #endif @@ -58,6 +60,11 @@ #warn compiling in TESTING mode. testing() debug messages will be visible. #endif + +#ifdef GC_FAILURE_HARD_LOOKUP +#define FIND_REF_NO_CHECK_TICK +#endif + #ifdef TRAVISTESTING #define TESTING #endif diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm index 689ff83935..ccfc041b21 100644 --- a/code/controllers/subsystem/garbage.dm +++ b/code/controllers/subsystem/garbage.dm @@ -362,9 +362,17 @@ SUBSYSTEM_DEF(garbage) testing("Beginning search for references to a [type].") last_find_references = world.time - DoSearchVar(GLOB) - for(var/datum/thing in world) - DoSearchVar(thing, "WorldRef: [thing]") + + DoSearchVar(GLOB) //globals + for(var/datum/thing in world) //atoms (don't beleive it's lies) + DoSearchVar(thing, "World -> [thing]") + + for (var/datum/thing) //datums + DoSearchVar(thing, "World -> [thing]") + + for (var/client/thing) //clients + DoSearchVar(thing, "World -> [thing]") + testing("Completed search for references to a [type].") if(usr && usr.client) usr.client.running_find_references = null @@ -384,35 +392,44 @@ SUBSYSTEM_DEF(garbage) if(!running_find_references) find_references(TRUE) -/datum/proc/DoSearchVar(X, Xname) +/datum/proc/DoSearchVar(X, Xname, recursive_limit = 64) if(usr && usr.client && !usr.client.running_find_references) return + if (!recursive_limit) + return + if(istype(X, /datum)) var/datum/D = X if(D.last_find_references == last_find_references) return + D.last_find_references = last_find_references - for(var/V in D.vars) - for(var/varname in D.vars) - var/variable = D.vars[varname] - if(variable == src) - testing("Found [src.type] \ref[src] in [D.type]'s [varname] var. [Xname]") - else if(islist(variable)) - if(src in variable) - testing("Found [src.type] \ref[src] in [D.type]'s [varname] list var. Global: [Xname]") -#ifdef GC_FAILURE_HARD_LOOKUP - for(var/I in variable) - DoSearchVar(I, TRUE) - else - DoSearchVar(variable, "[Xname]: [varname]") -#endif + var/list/L = D.vars + + for(var/varname in L) + if (varname == "vars") + continue + var/variable = L[varname] + + if(variable == src) + testing("Found [src.type] \ref[src] in [D.type]'s [varname] var. [Xname]") + + else if(islist(variable)) + DoSearchVar(variable, "[Xname] -> list", recursive_limit-1) + else if(islist(X)) - if(src in X) - testing("Found [src.type] \ref[src] in list [Xname].") -#ifdef GC_FAILURE_HARD_LOOKUP + var/normal = IS_NORMAL_LIST(X) for(var/I in X) - DoSearchVar(I, Xname + ": list") -#else + if (I == src) + testing("Found [src.type] \ref[src] in list [Xname].") + + else if (I && !isnum(I) && normal && X[I] == src) + testing("Found [src.type] \ref[src] in list [Xname]\[[I]\]") + + else if (islist(I)) + DoSearchVar(I, "[Xname] -> list", recursive_limit-1) + +#ifndef FIND_REF_NO_CHECK_TICK CHECK_TICK #endif