Merge pull request #3867 from Citadel-Station-13/upstream-merge-32504
[MIRROR] Weakrefs
This commit is contained in:
@@ -10,6 +10,8 @@
|
||||
|
||||
#define isatom(A) (isloc(A))
|
||||
|
||||
#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.
|
||||
|
||||
|
||||
@@ -1440,7 +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)
|
||||
|
||||
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.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
var/list/datum_components //for /datum/components
|
||||
var/ui_screen = "home" //for tgui
|
||||
var/use_tag = FALSE
|
||||
var/datum/weakref/weak_reference
|
||||
|
||||
#ifdef TESTING
|
||||
var/running_find_references
|
||||
@@ -15,6 +16,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)
|
||||
|
||||
@@ -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
|
||||
@@ -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,5 @@
|
||||
if (ismob(O) && motioncameras.len)
|
||||
for(var/X in motioncameras)
|
||||
var/obj/machinery/camera/cam = X
|
||||
cam.lostTarget(O)
|
||||
cam.lostTargetRef(WEAKREF(O))
|
||||
return
|
||||
|
||||
@@ -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,23 @@
|
||||
|
||||
/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()
|
||||
targets |= "[REF(target)]"
|
||||
return 1
|
||||
targets |= WEAKREF(target)
|
||||
return TRUE
|
||||
|
||||
/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()
|
||||
targets -= "[REF(target)]"
|
||||
targets -= R
|
||||
if (targets.len == 0)
|
||||
cancelAlarm()
|
||||
|
||||
@@ -53,19 +54,20 @@
|
||||
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.
|
||||
if (!area_motion)
|
||||
if(isliving(AM))
|
||||
newTarget(AM)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user