Skip to content

Commit

Permalink
Unified instance tracking (#744)
Browse files Browse the repository at this point in the history
* instances_of

* first work

* more

* fix
  • Loading branch information
Kapu1178 authored Feb 11, 2024
1 parent e7b3dd7 commit 643bbcf
Show file tree
Hide file tree
Showing 130 changed files with 501 additions and 267 deletions.
42 changes: 42 additions & 0 deletions code/__HELPERS/atlas.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/// A massive nested associative list that tracks type instances, set by the below macros.
GLOBAL_REAL_VAR(list/atlas) = list()

#define IS_TRACKED(x) (!!atlas[x])

#define SET_TRACKING(x) \
if(isnull(::atlas[x])) { \
::atlas[x] = list(); \
} \
::atlas[x][src] = 1;

#define UNSET_TRACKING(x) (::atlas[x] -= src)

#ifndef DEBUG_ATLAS
/// Returns a list of tracked instances of a given value.
#define INSTANCES_OF(x) (::atlas[x])
#else
/proc/instances_of(foo)
if(!IS_TRACKED(foo))
CRASH("Attempted to get instances of untracked key [foo]")

return ::atlas[foo]

#endif

#define INSTANCES_OF_COPY(x) (::atlas[x]:Copy())

// Tracking keys
/// Key used for things that can call the shuttle
#define TRACKING_KEY_SHUTTLE_CALLER "shuttle_caller"
#define TRACKING_KEY_RCD "rcds"

/proc/list_debug()
var/list/lists = list()
for(var/V in GLOB.vars)
if(islist(GLOB.vars[V]))
lists[V] = GLOB.vars[V]

sortTim(lists, GLOBAL_PROC_REF(cmp_list_length), TRUE)

for(var/name in lists)
to_chat(world, "[name] - [length(lists[name])]")
4 changes: 4 additions & 0 deletions code/__HELPERS/cmp.dm
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,7 @@ GLOBAL_VAR_INIT(cmp_field, "name")
/// Orders designs by name
/proc/cmp_design_name(datum/design/A, datum/design/B)
return sorttext(B.name, A.name)

/// Orders lists by the size of lists in their contents
/proc/cmp_list_length(list/A, list/B)
return length(A) - length(B)
2 changes: 1 addition & 1 deletion code/__HELPERS/game.dm
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@

///Disable power in the station APCs
/proc/power_fail(duration_min, duration_max)
for(var/obj/machinery/power/apc/current_apc as anything in GLOB.apcs_list)
for(var/obj/machinery/power/apc/current_apc as anything in INSTANCES_OF(/obj/machinery/power/apc))
if(!current_apc.cell || !SSmapping.level_trait(current_apc.z, ZTRAIT_STATION))
continue
var/area/apc_area = current_apc.area
Expand Down
6 changes: 6 additions & 0 deletions code/_compile_options.dm
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@
///Useful for measuring performance of specific systems with more reliability.
//#define DISABLE_RUINS

/// Uncomment this to assert INSTANCES_OF() is running on valid lists.
//#define DEBUG_ATLAS

/// Uncomment this to enable debugging tools for map making.
//#define DEBUG_MAPS

/////////////////////// REFERENCE TRACKING

///Used to find the sources of harddels, quite laggy, don't be surpised if it freezes your client for a good while
Expand Down
30 changes: 11 additions & 19 deletions code/_globalvars/lists/objects.dm
Original file line number Diff line number Diff line change
@@ -1,35 +1,21 @@
GLOBAL_LIST_EMPTY(cable_list) //Index for all cables, so that powernets don't have to look through the entire world all the time
GLOBAL_LIST_EMPTY(portals) //list of all /obj/effect/portal
GLOBAL_LIST_EMPTY(airlocks) //list of all airlocks
GLOBAL_LIST_EMPTY(curtains) //list of all curtains
GLOBAL_LIST_EMPTY(mechas_list) //list of all mechs. Used by hostile mobs target tracking.
GLOBAL_LIST_EMPTY(shuttle_caller_list) //list of all communication consoles and AIs, for automatic shuttle calls when there are none.
GLOBAL_LIST_EMPTY(machines) //NOTE: this is a list of ALL machines now. The processing machines list is SSmachine.processing !
GLOBAL_LIST_EMPTY(navigation_computers) //list of all /obj/machinery/computer/camera_advanced/shuttle_docker
GLOBAL_LIST_EMPTY(syndicate_shuttle_boards) //important to keep track of for managing nukeops war declarations.
GLOBAL_LIST_EMPTY(navbeacons) //list of all bot nagivation beacons, used for patrolling.
GLOBAL_LIST_EMPTY(teleportbeacons) //list of all tracking beacons used by teleporters
/// List of all navbeacons by Z level
GLOBAL_LIST_EMPTY(navbeacons)
/// List of beacons set to delivery mode
GLOBAL_LIST_EMPTY(deliverybeacons) //list of all MULEbot delivery beacons.
/// List of tags belonging to beacons set to delivery mode
GLOBAL_LIST_EMPTY(deliverybeacontags) //list of all tags associated with delivery beacons.
GLOBAL_LIST_EMPTY(nuke_list)
GLOBAL_LIST_EMPTY(alarmdisplay) //list of all machines or programs that can display station alerts

GLOBAL_LIST_EMPTY_TYPED(singularities, /datum/component/singularity) //list of all singularities on the station
GLOBAL_LIST_EMPTY(mechpad_list) //list of all /obj/machinery/mechpad

GLOBAL_LIST_EMPTY(tech_list) //list of all /datum/tech datums indexed by id.
GLOBAL_LIST_EMPTY(surgeries_list) //list of all surgeries by name, associated with their path.
GLOBAL_LIST_EMPTY(crafting_recipes) //list of all table craft recipes
GLOBAL_LIST_EMPTY(rcd_list) //list of Rapid Construction Devices.
GLOBAL_LIST_EMPTY(intercoms_list) //list of wallmounted intercom radios.
GLOBAL_LIST_EMPTY(apcs_list) //list of all Area Power Controller machines, separate from machines for powernet speeeeeeed.
GLOBAL_LIST_EMPTY(tracked_implants) //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented...
GLOBAL_LIST_EMPTY(tracked_chem_implants) //list of implants the prisoner console can track and send inject commands too
GLOBAL_LIST_EMPTY(pinpointer_list) //list of all pinpointers. Used to change stuff they are pointing to all at once.
GLOBAL_LIST_EMPTY(zombie_infection_list) // A list of all zombie_infection organs, for any mass "animation"
GLOBAL_LIST_EMPTY(meteor_list) // List of all meteors.
GLOBAL_LIST_EMPTY(active_jammers) // List of active radio jammers
GLOBAL_LIST_EMPTY(ladders)
GLOBAL_LIST_EMPTY(stairs)
GLOBAL_LIST_EMPTY(janitor_devices)
GLOBAL_LIST_EMPTY(trophy_cases)
GLOBAL_LIST_EMPTY(experiment_handlers)
Expand All @@ -49,3 +35,9 @@ GLOBAL_LIST_EMPTY(air_vent_names) // Name list of all air vents

GLOBAL_LIST_EMPTY(roundstart_station_borgcharger_areas) // List of area names of roundstart station cyborg rechargers, for the low charge/no charge cyborg screen alert tooltips.
GLOBAL_LIST_EMPTY(roundstart_station_mechcharger_areas) // List of area names of roundstart station mech rechargers, for the low charge/no charge mech screen alert tooltips.

/// Contains all atmospheric machinery, only used if DEBUG_MAPS is defined.
GLOBAL_REAL_VAR(list/atmospherics) = list()

/// Is a real global for speed
GLOBAL_REAL_VAR(list/cable_list) = list()
5 changes: 0 additions & 5 deletions code/_globalvars/lists/typecache.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@ GLOBAL_LIST_INIT(typecache_living, typecacheof(/mob/living))

GLOBAL_LIST_INIT(typecache_stack, typecacheof(/obj/item/stack))

GLOBAL_LIST_INIT(typecache_machine_or_structure, typecacheof(list(
/obj/machinery,
/obj/structure,
)))

/// A typecache listing structures that are considered to have surfaces that you can place items on that are higher than the floor. This, of course, should be restricted to /atom/movables. This is primarily used for food decomposition code.
GLOBAL_LIST_INIT(typecache_elevated_structures, typecacheof(list(
/obj/machinery/conveyor,
Expand Down
2 changes: 1 addition & 1 deletion code/controllers/subsystem/communications.dm
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ SUBSYSTEM_DEF(communications)
message_admins("[ADMIN_LOOKUPFLW(user)] has called an emergency meeting.")

/datum/controller/subsystem/communications/proc/send_message(datum/comm_message/sending,print = TRUE,unique = FALSE)
for(var/obj/machinery/computer/communications/C in GLOB.machines)
for(var/obj/machinery/computer/communications/C as anything in INSTANCES_OF(/obj/machinery/computer/communications))
if(!(C.machine_stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
if(unique)
C.add_message(sending)
Expand Down
2 changes: 1 addition & 1 deletion code/controllers/subsystem/economy.dm
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ SUBSYSTEM_DEF(economy)
if(HAS_TRAIT(src, TRAIT_MARKET_CRASHING))
multiplier = 4

for(var/obj/machinery/vending/V in GLOB.machines)
for(var/obj/machinery/vending/V as anything in INSTANCES_OF(/obj/machinery/vending))
if(istype(V, /obj/machinery/vending/custom))
continue
if(!is_station_level(V.z))
Expand Down
2 changes: 1 addition & 1 deletion code/controllers/subsystem/machines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ SUBSYSTEM_DEF(machines)
qdel(power_network)
powernets.Cut()

for(var/obj/structure/cable/power_cable as anything in GLOB.cable_list)
for(var/obj/structure/cable/power_cable as anything in ::cable_list)
if(!power_cable.powernet)
var/datum/powernet/new_powernet = new()
new_powernet.add_cable(power_cable)
Expand Down
2 changes: 1 addition & 1 deletion code/controllers/subsystem/nightshift.dm
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ SUBSYSTEM_DEF(nightshift)
/datum/controller/subsystem/nightshift/proc/update_nightshift(active, announce = TRUE, resumed = FALSE)
set waitfor = FALSE
if(!resumed)
currentrun = GLOB.apcs_list.Copy()
currentrun = INSTANCES_OF_COPY(/obj/machinery/power/apc)
nightshift_active = active
if(announce)
if (active)
Expand Down
5 changes: 2 additions & 3 deletions code/controllers/subsystem/shuttle.dm
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ SUBSYSTEM_DEF(shuttle)

var/callShuttle = TRUE

for(var/thing in GLOB.shuttle_caller_list)
for(var/thing in INSTANCES_OF(TRACKING_KEY_SHUTTLE_CALLER))
if(isAI(thing))
var/mob/living/silicon/ai/AI = thing
if(AI.deployed_shell && !AI.deployed_shell.client)
Expand Down Expand Up @@ -739,8 +739,7 @@ SUBSYSTEM_DEF(shuttle)
hidden_shuttle_turf_images -= remove_images
hidden_shuttle_turf_images += add_images

for(var/V in GLOB.navigation_computers)
var/obj/machinery/computer/camera_advanced/shuttle_docker/C = V
for(var/obj/machinery/computer/camera_advanced/shuttle_docker/C as anything in INSTANCES_OF(/obj/machinery/computer/camera_advanced/shuttle_docker))
C.update_hidden_docking_ports(remove_images, add_images)

QDEL_LIST(remove_images)
Expand Down
2 changes: 1 addition & 1 deletion code/datums/station_traits/negative_traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@

/datum/station_trait/blackout/on_round_start()
. = ..()
for(var/obj/machinery/power/apc/apc as anything in GLOB.apcs_list)
for(var/obj/machinery/power/apc/apc as anything in INSTANCES_OF(/obj/machinery/power/apc))
if(is_station_level(apc.z) && prob(60))
apc.overload_lighting()

Expand Down
2 changes: 1 addition & 1 deletion code/datums/vote.dm
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
return

SSshuttle.autoEnd()
var/obj/machinery/computer/communications/C = locate() in GLOB.machines
var/obj/machinery/computer/communications/C = locate() in INSTANCES_OF(/obj/machinery/computer/communications)
if(C)
C.post_status("shuttle")

Expand Down
2 changes: 1 addition & 1 deletion code/datums/world_topic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@

minor_announce(input["message"], "Incoming message from [input["message_sender"]]")
message_admins("Receiving a message from [input["sender_ckey"]] at [input["source"]]")
for(var/obj/machinery/computer/communications/communications_console in GLOB.machines)
for(var/obj/machinery/computer/communications/communications_console as anything in INSTANCES_OF(/obj/machinery/computer/communications))
communications_console.override_cooldown()

/datum/world_topic/news_report
Expand Down
2 changes: 1 addition & 1 deletion code/game/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@
* proc must return the hint
* [INITIALIZE_HINT_LATELOAD] otherwise you will never be called.
*
* useful for doing things like finding other machines on GLOB.machines because you can guarantee
* useful for doing things like finding other machines using INSTANCES_OF() because you can guarantee
* that all atoms will actually exist in the "WORLD" at this time and that all their Intialization
* code has been run
*/
Expand Down
2 changes: 1 addition & 1 deletion code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@
/datum/dynamic_ruleset/midround/from_ghosts/xenomorph/execute()
// 50% chance of being incremented by one
required_candidates += prob(50)
for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in GLOB.machines)
for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent as anything in INSTANCES_OF(/obj/machinery/atmospherics/components/unary/vent_pump))
if(QDELETED(temp_vent))
continue
if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
Expand Down
2 changes: 1 addition & 1 deletion code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,7 @@
/datum/dynamic_ruleset/roundstart/nuclear/clown_ops/pre_execute()
. = ..()
if(.)
var/obj/machinery/nuclearbomb/syndicate/syndicate_nuke = locate() in GLOB.nuke_list
var/obj/machinery/nuclearbomb/syndicate/syndicate_nuke = locate() in INSTANCES_OF(/obj/machinery/nuclearbomb)
if(syndicate_nuke)
var/turf/nuke_turf = get_turf(syndicate_nuke)
if(nuke_turf)
Expand Down
11 changes: 6 additions & 5 deletions code/game/gamemodes/events.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/proc/power_failure()
priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", sound_type = ANNOUNCER_POWEROFF)
for(var/obj/machinery/power/smes/S in GLOB.machines)
for(var/obj/machinery/power/smes/S as anything in INSTANCES_OF(/obj/machinery/power/smes))
if(istype(get_area(S), /area/station/ai_monitored/turret_protected) || !is_station_level(S.z))
continue
S.charge = 0
Expand All @@ -20,7 +20,7 @@
A.power_environ = FALSE
A.power_change()

for(var/obj/machinery/power/apc/C in GLOB.apcs_list)
for(var/obj/machinery/power/apc/C as anything in INSTANCES_OF(/obj/machinery/power/apc))
if(C.cell && is_station_level(C.z))
var/area/A = C.area
if(GLOB.typecache_powerfailure_safe_areas[A.type])
Expand All @@ -31,11 +31,12 @@
/proc/power_restore()

priority_announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", sound_type = ANNOUNCER_POWERON)
for(var/obj/machinery/power/apc/C in GLOB.machines)
for(var/obj/machinery/power/apc/C as anything in INSTANCES_OF(/obj/machinery/power/apc))
if(C.cell && is_station_level(C.z))
C.cell.charge = C.cell.maxcharge
COOLDOWN_RESET(C, failure_timer)
for(var/obj/machinery/power/smes/S in GLOB.machines)

for(var/obj/machinery/power/smes/S as anything in INSTANCES_OF(/obj/machinery/power/smes))
if(!is_station_level(S.z))
continue
S.charge = S.capacity
Expand All @@ -55,7 +56,7 @@
/proc/power_restore_quick()

priority_announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", sound_type = ANNOUNCER_POWERON)
for(var/obj/machinery/power/smes/S in GLOB.machines)
for(var/obj/machinery/power/smes/S as anything in INSTANCES_OF(/obj/machinery/power/smes))
if(!is_station_level(S.z))
continue
S.charge = S.capacity
Expand Down
3 changes: 0 additions & 3 deletions code/game/machinery/_machinery.dm
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,6 @@ GLOBAL_REAL_VAR(machinery_default_armor) = list()
SETUP_SMOOTHING()
QUEUE_SMOOTH(src)

GLOB.machines += src

if(ispath(circuit, /obj/item/circuitboard))
circuit = new circuit(src)
circuit.apply_default_parts(src)
Expand Down Expand Up @@ -223,7 +221,6 @@ GLOBAL_REAL_VAR(machinery_default_armor) = list()
link_to_jack()

/obj/machinery/Destroy()
GLOB.machines.Remove(src)
end_processing()
dump_inventory_contents()
QDEL_LIST(component_parts)
Expand Down
3 changes: 3 additions & 0 deletions code/game/machinery/camera/camera.dm
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0)

/obj/machinery/camera/Initialize(mapload, obj/structure/camera_assembly/old_assembly)
. = ..()
SET_TRACKING(__TYPE__)

for(var/i in network)
network -= i
network += lowertext(i)
Expand Down Expand Up @@ -117,6 +119,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0)
create_prox_monitor()

/obj/machinery/camera/Destroy()
UNSET_TRACKING(__TYPE__)
if(can_use())
toggle_cam(null, 0) //kick anyone viewing out and remove from the camera chunks
GLOB.cameranet.removeCamera(src)
Expand Down
4 changes: 2 additions & 2 deletions code/game/machinery/camera/motion.dm
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
return
localMotionTargets |= WEAKREF(AM)
if (!detectTime)
for(var/obj/machinery/computer/security/telescreen/entertainment/TV in GLOB.machines)
for(var/obj/machinery/computer/security/telescreen/entertainment/TV as anything in INSTANCES_OF(/obj/machinery/computer/security/telescreen/entertainment))
TV.notify(TRUE)
detectTime = world.time + 30 SECONDS

Expand All @@ -103,5 +103,5 @@
detectTime = world.time + 30 SECONDS
else if (world.time > detectTime)
detectTime = 0
for(var/obj/machinery/computer/security/telescreen/entertainment/TV in GLOB.machines)
for(var/obj/machinery/computer/security/telescreen/entertainment/TV as anything in INSTANCES_OF(/obj/machinery/computer/security/telescreen/entertainment))
TV.notify(FALSE)
2 changes: 1 addition & 1 deletion code/game/machinery/civilian_bounties.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
/obj/machinery/computer/piratepad_control/civilian/LateInitialize()
. = ..()
if(cargo_hold_id)
for(var/obj/machinery/piratepad/civilian/C in GLOB.machines)
for(var/obj/machinery/piratepad/civilian/C in INSTANCES_OF(/obj/machinery/piratepad))
if(C.cargo_hold_id == cargo_hold_id)
pad_ref = WEAKREF(C)
return
Expand Down
8 changes: 4 additions & 4 deletions code/game/machinery/computer/apc_control.dm
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
for(var/entry in logs)
data["logs"] += list(list("entry" = entry))

for(var/apc in GLOB.apcs_list)
for(var/apc in INSTANCES_OF(/obj/machinery/power/apc))
if(check_apc(apc))
var/obj/machinery/power/apc/A = apc
var/has_cell = (A.cell) ? TRUE : FALSE
Expand Down Expand Up @@ -121,7 +121,7 @@
if("access-apc")
var/ref = params["ref"]
playsound(src, SFX_TERMINAL_TYPE, 50, FALSE)
var/obj/machinery/power/apc/APC = locate(ref) in GLOB.apcs_list
var/obj/machinery/power/apc/APC = locate(ref) in INSTANCES_OF(/obj/machinery/power/apc)
if(!APC)
return
if(active_apc)
Expand Down Expand Up @@ -153,7 +153,7 @@
var/ref = params["ref"]
var/type = params["type"]
var/value = params["value"]
var/obj/machinery/power/apc/target = locate(ref) in GLOB.apcs_list
var/obj/machinery/power/apc/target = locate(ref) in INSTANCES_OF(/obj/machinery/power/apc)
if(!target)
return

Expand Down Expand Up @@ -182,7 +182,7 @@
log_game("[key_name(operator)] Set APC [target.area.name] [type] to [setTo]]")
if("breaker")
var/ref = params["ref"]
var/obj/machinery/power/apc/target = locate(ref) in GLOB.apcs_list
var/obj/machinery/power/apc/target = locate(ref) in INSTANCES_OF(/obj/machinery/power/apc)
target.toggle_breaker()
var/setTo = target.operating ? "On" : "Off"
log_activity("Turned APC [target.area.name]'s breaker [setTo]")
Expand Down
Loading

0 comments on commit 643bbcf

Please sign in to comment.