From b44e31951d017e83be3101e681e46c823c7d1629 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Wed, 8 Nov 2017 22:48:03 -0800 Subject: [PATCH 1/4] Weakrefs --- code/__DEFINES/is_helpers.dm | 2 ++ code/__HELPERS/unsorted.dm | 20 ++++++++++++++++++- code/datums/datum.dm | 6 ++++++ code/datums/weakrefs.dm | 19 ++++++++++++++++++ code/game/area/ai_monitored.dm | 7 ++++++- code/game/machinery/camera/motion.dm | 30 ++++++++++++++++++---------- tgstation.dme | 1 + 7 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 code/datums/weakrefs.dm diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index fbd15e1ef6..31a3ccae1e 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -10,6 +10,8 @@ #define isatom(A) (istype(A, /atom)) +#define isweakref(D) (istype(D, /datum/weakref)) + //Turfs //#define isturf(A) (istype(A, /turf)) This is actually a byond built-in. Added here for completeness sake. diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 6b3c03b180..61a825e651 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1441,4 +1441,22 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) var/time_clock = num2hex(TICK_DELTA_TO_MS(world.tick_usage), 3) - return "{[time_high]-[time_mid]-[GUID_VERSION][time_low]-[GUID_VARIANT][time_clock]-[node_id]}" \ No newline at end of file +<<<<<<< HEAD + return "{[time_high]-[time_mid]-[GUID_VERSION][time_low]-[GUID_VARIANT][time_clock]-[node_id]}" +======= + return "{[time_high]-[time_mid]-[GUID_VERSION][time_low]-[GUID_VARIANT][time_clock]-[node_id]}" + +// \ref behaviour got changed in 512 so this is necesary to replicate old behaviour. +// If it ever becomes necesary to get a more performant REF(), this lies here in wait +// #define REF(thing) (thing && istype(thing, /datum) && thing:use_tag && thing:tag ? "[thing:tag]" : "\ref[thing]") +/proc/REF(input) + if(istype(input, /datum)) + var/datum/thing = input + if(thing.use_tag) + if(!thing.tag) + WARNING("A ref was requested of an object with use_tag set but no tag: [thing]") + thing.use_tag = FALSE + else + return "\[[url_encode(thing.tag)]\]" + return "\ref[input]" +>>>>>>> 4edd802... Weak references + Cameras now use them (#32504) diff --git a/code/datums/datum.dm b/code/datums/datum.dm index dc74e72713..6694f827db 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -3,6 +3,11 @@ var/list/active_timers //for SStimer var/list/datum_components //for /datum/components var/ui_screen = "home" //for tgui +<<<<<<< HEAD +======= + var/use_tag = FALSE + var/datum/weakref/weak_reference +>>>>>>> 4edd802... Weak references + Cameras now use them (#32504) #ifdef TESTING var/running_find_references @@ -14,6 +19,7 @@ // Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE. /datum/proc/Destroy(force=FALSE, ...) tag = null + weak_reference = null //ensure prompt GCing of weakref. var/list/timers = active_timers active_timers = null for(var/thing in timers) diff --git a/code/datums/weakrefs.dm b/code/datums/weakrefs.dm new file mode 100644 index 0000000000..09193aea57 --- /dev/null +++ b/code/datums/weakrefs.dm @@ -0,0 +1,19 @@ + +/proc/WEAKREF(datum/input) + if(istype(input) && !QDELETED(input)) + if(!input.weak_reference) + input.weak_reference = new /datum/weakref(input) + return input.weak_reference + +/datum/weakref + var/reference + +/datum/weakref/New(datum/thing) + reference = REF(thing) + +/datum/weakref/Destroy() + return QDEL_HINT_LETMELIVE //Let BYOND autoGC thiswhen nothing is using it anymore. + +/datum/weakref/proc/resolve() + var/datum/D = locate(reference) + return D.weak_reference == src? D : null diff --git a/code/game/area/ai_monitored.dm b/code/game/area/ai_monitored.dm index e21d4e273b..18d1f82239 100644 --- a/code/game/area/ai_monitored.dm +++ b/code/game/area/ai_monitored.dm @@ -2,7 +2,7 @@ name = "AI Monitored Area" clockwork_warp_allowed = FALSE var/list/obj/machinery/camera/motioncameras = list() - var/list/motionTargets = list() + var/list/datum/weakref/motionTargets = list() /area/ai_monitored/Initialize(mapload) . = ..() @@ -27,5 +27,10 @@ if (ismob(O) && motioncameras.len) for(var/X in motioncameras) var/obj/machinery/camera/cam = X +<<<<<<< HEAD cam.lostTarget(O) return +======= + cam.lostTargetRef(WEAKREF(O)) + return +>>>>>>> 4edd802... Weak references + Cameras now use them (#32504) diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm index 6ac7e1249d..349a0c7e20 100644 --- a/code/game/machinery/camera/motion.dm +++ b/code/game/machinery/camera/motion.dm @@ -1,6 +1,6 @@ /obj/machinery/camera - var/list/localMotionTargets = list() + var/list/datum/weakref/localMotionTargets = list() var/detectTime = 0 var/area/ai_monitored/area_motion = null var/alarm_delay = 30 // Don't forget, there's another 3 seconds in queueAlarm() @@ -15,11 +15,11 @@ if (elapsed > alarm_delay) triggerAlarm() else if (detectTime == -1) - for (var/targetref in getTargetList()) - var/mob/target = locate(targetref) in GLOB.mob_list - if (QDELETED(target) || target.stat == DEAD || (!area_motion && !in_range(src, target))) + for (var/datum/weakref/targetref in getTargetList()) + var/mob/target = targetref.resolve() + if(QDELETED(target) || target.stat == DEAD || (!area_motion && !in_range(src, target))) //If not part of a monitored area and the camera is not in range or the target is dead - lostTarget(target) + lostTargetRef(targetref) /obj/machinery/camera/proc/getTargetList() if(area_motion) @@ -28,22 +28,32 @@ /obj/machinery/camera/proc/newTarget(mob/target) if(isAI(target)) - return 0 + return FALSE if (detectTime == 0) detectTime = world.time // start the clock var/list/targets = getTargetList() +<<<<<<< HEAD targets |= "\ref[target]" return 1 +======= + targets |= WEAKREF(target) + return TRUE +>>>>>>> 4edd802... Weak references + Cameras now use them (#32504) /obj/machinery/camera/Destroy() var/area/ai_monitored/A = get_area(src) + localMotionTargets = null if(istype(A)) A.motioncameras -= src return ..() -/obj/machinery/camera/proc/lostTarget(mob/target) +/obj/machinery/camera/proc/lostTargetRef(datum/weakref/R) var/list/targets = getTargetList() +<<<<<<< HEAD targets -= "\ref[target]" +======= + targets -= R +>>>>>>> 4edd802... Weak references + Cameras now use them (#32504) if (targets.len == 0) cancelAlarm() @@ -53,16 +63,16 @@ if (status) aiPlayer.cancelAlarm("Motion", get_area(src), src) detectTime = 0 - return 1 + return TRUE /obj/machinery/camera/proc/triggerAlarm() if (!detectTime) - return 0 + return FALSE for (var/mob/living/silicon/aiPlayer in GLOB.player_list) if (status) aiPlayer.triggerAlarm("Motion", get_area(src), list(src), src) detectTime = -1 - return 1 + return TRUE /obj/machinery/camera/HasProximity(atom/movable/AM as mob|obj) // Motion cameras outside of an "ai monitored" area will use this to detect stuff. diff --git a/tgstation.dme b/tgstation.dme index 1d3c9ff601..21f4b04537 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -304,6 +304,7 @@ #include "code\datums\soullink.dm" #include "code\datums\spawners_menu.dm" #include "code\datums\verbs.dm" +#include "code\datums\weakrefs.dm" #include "code\datums\world_topic.dm" #include "code\datums\actions\flightsuit.dm" #include "code\datums\actions\ninja.dm" From 2230c79af38d2e7e88deb9eb7052aff2a6350f1b Mon Sep 17 00:00:00 2001 From: LetterJay Date: Thu, 9 Nov 2017 03:17:35 -0600 Subject: [PATCH 2/4] Update unsorted.dm --- code/__HELPERS/unsorted.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 61a825e651..4e2b793069 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1440,10 +1440,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) var/time_low = num2hex(world.time, 3) var/time_clock = num2hex(TICK_DELTA_TO_MS(world.tick_usage), 3) - -<<<<<<< HEAD - return "{[time_high]-[time_mid]-[GUID_VERSION][time_low]-[GUID_VARIANT][time_clock]-[node_id]}" -======= return "{[time_high]-[time_mid]-[GUID_VERSION][time_low]-[GUID_VARIANT][time_clock]-[node_id]}" // \ref behaviour got changed in 512 so this is necesary to replicate old behaviour. @@ -1459,4 +1455,3 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) else return "\[[url_encode(thing.tag)]\]" return "\ref[input]" ->>>>>>> 4edd802... Weak references + Cameras now use them (#32504) From 45a64018c5dae462b3f770a55cf883aa9d77fc95 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Thu, 9 Nov 2017 03:17:52 -0600 Subject: [PATCH 3/4] Update motion.dm --- code/game/machinery/camera/motion.dm | 9 --------- 1 file changed, 9 deletions(-) diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm index 349a0c7e20..6a48954b6c 100644 --- a/code/game/machinery/camera/motion.dm +++ b/code/game/machinery/camera/motion.dm @@ -32,13 +32,8 @@ if (detectTime == 0) detectTime = world.time // start the clock var/list/targets = getTargetList() -<<<<<<< HEAD - targets |= "\ref[target]" - return 1 -======= targets |= WEAKREF(target) return TRUE ->>>>>>> 4edd802... Weak references + Cameras now use them (#32504) /obj/machinery/camera/Destroy() var/area/ai_monitored/A = get_area(src) @@ -49,11 +44,7 @@ /obj/machinery/camera/proc/lostTargetRef(datum/weakref/R) var/list/targets = getTargetList() -<<<<<<< HEAD - targets -= "\ref[target]" -======= targets -= R ->>>>>>> 4edd802... Weak references + Cameras now use them (#32504) if (targets.len == 0) cancelAlarm() From b0439afd0828b9a17c8be61ce67f69b45f4a43bf Mon Sep 17 00:00:00 2001 From: LetterJay Date: Thu, 9 Nov 2017 03:17:59 -0600 Subject: [PATCH 4/4] Update ai_monitored.dm --- code/game/area/ai_monitored.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/game/area/ai_monitored.dm b/code/game/area/ai_monitored.dm index 18d1f82239..a5216fb44c 100644 --- a/code/game/area/ai_monitored.dm +++ b/code/game/area/ai_monitored.dm @@ -27,10 +27,5 @@ if (ismob(O) && motioncameras.len) for(var/X in motioncameras) var/obj/machinery/camera/cam = X -<<<<<<< HEAD - cam.lostTarget(O) - return -======= cam.lostTargetRef(WEAKREF(O)) return ->>>>>>> 4edd802... Weak references + Cameras now use them (#32504)