datum
var/tmp
__weakrefs = 0
proc
__weakref(weakref/r)
if(__weakrefs<=0)
global.__weakrefs[r.id] = list(r)
__weakrefs = 1
else
global.__weakrefs[r.id] += r
++__weakrefs
__weakderef(weakref/r)
if(__weakrefs<=1)
global.__weakrefs -= r.id
__weakrefs = 0
else
global.__weakrefs[r.id] -= r
--__weakrefs
r.id = null
Weakref()
var/weakref/r = new/weakref(src)
__weakref(r)
return r
Del()
if(__weakrefs)
var/ref = "\ref[src]"
var/list/l = global.__weakrefs[ref]
for(var/weakref/r in l)
r.id = null
__weakrefs = 0
global.__weakrefs -= ref
..()
var
list/__weakrefs = list()
weakref
var/tmp
id
proc
ref()
if(id)
return locate(id)
else
return null
New(datum/ref)
if(ref)
id = "\ref[ref]"
Del()
if(id)
ref()?.__weakderef(src)
if(id)
id = null
..()
An example for a potential use of this snippet:
ui_element
var
weakref/owner
New(mob/owner)
src.owner = owner.Weakref()
owner.client.screen += src
loc = null
..()
if you ever need to get the owner, you can do this quickly in a local variable via the weakref datum's ref() proc. Thanks to 512's proc chaining, you can operate directly on the result, or you can cache the result in a local variable:
owner.ref().client.screen += contents
or:
var/mob/m = owner.ref()
m.client.screen += contents
Be aware that ref() can return null if the object you are weak referencing gets deleted, and weakrefs will not be fully destroyed if this is the case. They will simply no longer resolve after the relationship is broken.