From fd584eee321d7db45d833a3f14aab42d647ecdbe Mon Sep 17 00:00:00 2001 From: Runa Dacino Date: Thu, 27 Jul 2023 13:36:13 +0200 Subject: [PATCH] perf: replaces references in entity narrate with weakrefs Replaces all direct references held in the /datum with WEAKREF(atom). This should reduce potential lag impacts from stuff getting blown up or dying or becoming invalid. --- code/modules/admin/verbs/entity_narrate.dm | 50 ++++++++++++++++++---- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/code/modules/admin/verbs/entity_narrate.dm b/code/modules/admin/verbs/entity_narrate.dm index cf52e6b4da..a0da92eb42 100644 --- a/code/modules/admin/verbs/entity_narrate.dm +++ b/code/modules/admin/verbs/entity_narrate.dm @@ -57,7 +57,7 @@ add_mob_for_narration(L) //Recursively calling ourselves until cancelled or a unique name is given. return holder.entity_names += unique_name - holder.entity_refs[unique_name] = L + holder.entity_refs[unique_name] = WEAKREF(L) log_and_message_admins("added [L.name] for their personal list to narrate", usr) //Logging here to avoid spam, while still safeguarding abuse //Covering functionality for turfs and objs. We need static type to access the name var @@ -70,7 +70,7 @@ add_mob_for_narration(A) return holder.entity_names += unique_name - holder.entity_refs[unique_name] = A + holder.entity_refs[unique_name] = WEAKREF(A) log_and_message_admins("added [A.name] for their personal list to narrate", usr) //Logging here to avoid spam, while still safeguarding abuse //Proc for keeping our ref list relevant, deleting mobs that are no longer relevant for our event @@ -164,8 +164,14 @@ //Separate definition for mob/living and /obj due to .say() code allowing us to engage with languages, stuttering etc //We also need this so we can check for .client - if(istype(holder.entity_refs[name], /mob/living)) - var/mob/living/our_entity = holder.entity_refs[name] + var/datum/weakref/wref = holder.entity_refs[name] + var/selection = wref.resolve() + if(!selection) + to_chat(usr, SPAN_NOTICE("[name] has invalid reference, deleting")) + holder.entity_names -= name + holder.entity_refs -= name + if(istype(selection, /mob/living)) + var/mob/living/our_entity = selection if(our_entity.client) //Making sure we can't speak for players log_and_message_admins("used entity-narrate to speak through [our_entity.ckey]'s mob", usr) if(!message) @@ -179,8 +185,8 @@ //This does cost us some code duplication, but I think it's worth it. //furthermore, objs/turfs require the usr to specify the verb when speaking, otherwise it looks like an emote. - else if(istype(holder.entity_refs[name], /atom)) - var/atom/our_entity = holder.entity_refs[name] + else if(istype(selection, /atom)) + var/atom/our_entity = selection if(!message) message = tgui_input_text(usr, "Input what you want [our_entity] to [mode]", "narrate", null) message = encode_html_emphasis(sanitize(message)) @@ -251,7 +257,16 @@ tgui_selected_id_multi = list() //Using the same var for ease of implementation. Thus, we must reset to empty each time. tgui_selected_id_multi += params["id_selected"] tgui_selected_id = params["id_selected"] - tgui_selected_refs = entity_refs[tgui_selected_id] + var/datum/weakref/wref = entity_refs[tgui_selected_id] + tgui_selected_refs = wref.resolve() + if(!tgui_selected_refs) + to_chat(usr, SPAN_NOTICE("[tgui_selected_id] has invalid reference, deleting")) + entity_names -= tgui_selected_id + entity_refs -= tgui_selected_id + tgui_selected_id = "" + tgui_selected_type = "" + tgui_selected_name = "" + tgui_selected_refs = null if(istype(tgui_selected_refs, /mob/living)) var/mob/living/L = tgui_selected_refs if(L.client) @@ -273,7 +288,14 @@ var/message = params["message"] //Sanitizing before speaking it if(tgui_selection_mode) for(var/entity in tgui_selected_id_multi) - var/ref = entity_refs[entity] + var/datum/weakref/wref = entity_refs[entity] + var/ref = wref.resolve() + if(!ref) + to_chat(usr, SPAN_NOTICE("[entity] has invalid reference, deleting")) + entity_names -= entity + entity_refs -= entity + tgui_selected_id_multi -= entity + continue if(istype(ref, /mob/living)) var/mob/living/L = ref if(L.client) @@ -283,7 +305,17 @@ var/atom/A = ref narrate_tgui_atom(A, message) else - var/ref = entity_refs[tgui_selected_id] + var/datum/weakref/wref = entity_refs[tgui_selected_id] + var/ref = wref.resolve() + if(!ref) + to_chat(usr, SPAN_NOTICE("[tgui_selected_id] has invalid reference, deleting")) + entity_names -= tgui_selected_id + entity_refs -= tgui_selected_id + tgui_selected_id = "" + tgui_selected_type = "" + tgui_selected_name = "" + tgui_selected_refs = null + return if(istype(ref, /mob/living)) var/mob/living/L = ref if(L.client)