From aefb664a582a7607fb9c70e0ceeead85809bffff Mon Sep 17 00:00:00 2001 From: Krausus Date: Mon, 5 Sep 2016 22:33:10 -0400 Subject: [PATCH] Implements UIDs and initial topic integration --- code/__HELPERS/unique_ids.dm | 46 +++++++++++++++++++++++++++++ code/modules/client/client procs.dm | 9 ++++++ paradise.dme | 1 + 3 files changed, 56 insertions(+) create mode 100644 code/__HELPERS/unique_ids.dm diff --git a/code/__HELPERS/unique_ids.dm b/code/__HELPERS/unique_ids.dm new file mode 100644 index 00000000000..bd77c358aa8 --- /dev/null +++ b/code/__HELPERS/unique_ids.dm @@ -0,0 +1,46 @@ +// Unique Datum Identifiers + +// Basically, a replacement for plain \refs that ensure the reference still +// points to the exact same datum/client, but doesn't prevent GC like tags do. + +// Turns this: +// var/myref = "\ref[mydatum]" +// var/datum/D = locate(myref) +// into this: +// var/myUID = mydatum.UID() +// var/datum/D = locateUID(myUID) + +var/global/next_unique_datum_id = 1 + +/datum/var/tmp/unique_datum_id = null +/client/var/tmp/unique_datum_id = null + +/datum/proc/UID() + if(!unique_datum_id) + var/tag_backup = tag + tag = null // Grab the raw ref, not the tag + unique_datum_id = "\ref[src]_[next_unique_datum_id++]" + tag = tag_backup + return unique_datum_id + +/client/proc/UID() + if(!unique_datum_id) + unique_datum_id = "\ref[src]_[next_unique_datum_id++]" + return unique_datum_id + +/proc/locateUID(uid) + if(!istext(uid)) + return null + + var/splitat = findlasttext(uid, "_") + + if(!splitat) + return null + + var/datum/D = locate(copytext(uid, 1, splitat)) + + // We might locate a client instead of a datum, but just using : is easier + // than actually checking and typecasting + if(D && D:unique_datum_id == uid) + return D + return null diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 254b890e7b3..37035fbea72 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -29,6 +29,15 @@ if(!usr || usr != mob) //stops us calling Topic for somebody else's client. Also helps prevent usr=null return + // src should always be a UID; if it isn't, warn instead of failing entirely + if(href_list["src"]) + hsrc = locateUID(href_list["src"]) + if(!hsrc) + hsrc = locate(href_list["src"]) + if(hsrc) + var/hsrc_info = datum_info_line(hsrc) || "[hsrc]" + log_runtime(EXCEPTION("Got \\ref-based src in topic from [src] for [hsrc_info], should be UID: [href]")) + #if defined(TOPIC_DEBUGGING) to_chat(world, "[src]'s Topic: [href] destined for [hsrc].") #endif diff --git a/paradise.dme b/paradise.dme index 7246870bf24..5c300cf1936 100644 --- a/paradise.dme +++ b/paradise.dme @@ -66,6 +66,7 @@ #include "code\__HELPERS\text.dm" #include "code\__HELPERS\time.dm" #include "code\__HELPERS\type2type.dm" +#include "code\__HELPERS\unique_ids.dm" #include "code\__HELPERS\unsorted.dm" #include "code\_DATASTRUCTURES\heap.dm" #include "code\_DATASTRUCTURES\linked_lists.dm"